ir_emitter: Allow the insertion point for new instructions to be set
This commit is contained in:
parent
af793c2527
commit
e01b500aea
4 changed files with 33 additions and 5 deletions
|
@ -21,6 +21,10 @@
|
|||
namespace Dynarmic::IR {
|
||||
|
||||
void Block::AppendNewInst(Opcode opcode, std::initializer_list<IR::Value> args) {
|
||||
PrependNewInst(end(), opcode, args);
|
||||
}
|
||||
|
||||
Block::iterator Block::PrependNewInst(iterator insertion_point, Opcode opcode, std::initializer_list<Value> args) {
|
||||
IR::Inst* inst = new(instruction_alloc_pool->Alloc()) IR::Inst(opcode);
|
||||
ASSERT(args.size() == inst->NumArgs());
|
||||
|
||||
|
@ -29,7 +33,7 @@ void Block::AppendNewInst(Opcode opcode, std::initializer_list<IR::Value> args)
|
|||
index++;
|
||||
});
|
||||
|
||||
instructions.push_back(inst);
|
||||
return instructions.insert_before(insertion_point, inst);
|
||||
}
|
||||
|
||||
LocationDescriptor Block::Location() const {
|
||||
|
|
|
@ -69,7 +69,7 @@ public:
|
|||
const_reverse_iterator crend() const { return instructions.crend(); }
|
||||
|
||||
/**
|
||||
* Appends a new instruction to this basic block,
|
||||
* Appends a new instruction to the end of this basic block,
|
||||
* handling any allocations necessary to do so.
|
||||
*
|
||||
* @param op Opcode representing the instruction to add.
|
||||
|
@ -77,6 +77,17 @@ public:
|
|||
*/
|
||||
void AppendNewInst(Opcode op, std::initializer_list<Value> args);
|
||||
|
||||
/**
|
||||
* Prepends a new instruction to this basic block before the insertion point,
|
||||
* handling any allocations necessary to do so.
|
||||
*
|
||||
* @param insertion_point Where to insert the new instruction.
|
||||
* @param op Opcode representing the instruction to add.
|
||||
* @param args A sequence of Value instances used as arguments for the instruction.
|
||||
* @returns Iterator to the newly created instruction.
|
||||
*/
|
||||
iterator PrependNewInst(iterator insertion_point, Opcode op, std::initializer_list<Value> args);
|
||||
|
||||
/// Gets the starting location for this basic block.
|
||||
LocationDescriptor Location() const;
|
||||
/// Gets the end location for this basic block.
|
||||
|
|
|
@ -944,4 +944,12 @@ void IREmitter::SetTerm(const Terminal& terminal) {
|
|||
block.SetTerminal(terminal);
|
||||
}
|
||||
|
||||
void IREmitter::SetInsertionPoint(IR::Inst* new_insertion_point) {
|
||||
insertion_point = IR::Block::iterator{*new_insertion_point};
|
||||
}
|
||||
|
||||
void IREmitter::SetInsertionPoint(IR::Block::iterator new_insertion_point) {
|
||||
insertion_point = new_insertion_point;
|
||||
}
|
||||
|
||||
} // namespace Dynarmic::IR
|
||||
|
|
|
@ -55,7 +55,7 @@ struct ResultAndGE {
|
|||
*/
|
||||
class IREmitter {
|
||||
public:
|
||||
explicit IREmitter(Block& block) : block(block) {}
|
||||
explicit IREmitter(Block& block) : block(block), insertion_point(block.end()) {}
|
||||
|
||||
Block& block;
|
||||
|
||||
|
@ -247,11 +247,16 @@ public:
|
|||
|
||||
void SetTerm(const Terminal& terminal);
|
||||
|
||||
void SetInsertionPoint(IR::Inst* new_insertion_point);
|
||||
void SetInsertionPoint(IR::Block::iterator new_insertion_point);
|
||||
|
||||
protected:
|
||||
IR::Block::iterator insertion_point;
|
||||
|
||||
template<typename T = Value, typename ...Args>
|
||||
T Inst(Opcode op, Args ...args) {
|
||||
block.AppendNewInst(op, {Value(args)...});
|
||||
return T(Value(&block.back()));
|
||||
auto iter = block.PrependNewInst(insertion_point, op, {Value(args)...});
|
||||
return T(Value(&*iter));
|
||||
}
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue