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 {
|
namespace Dynarmic::IR {
|
||||||
|
|
||||||
void Block::AppendNewInst(Opcode opcode, std::initializer_list<IR::Value> args) {
|
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);
|
IR::Inst* inst = new(instruction_alloc_pool->Alloc()) IR::Inst(opcode);
|
||||||
ASSERT(args.size() == inst->NumArgs());
|
ASSERT(args.size() == inst->NumArgs());
|
||||||
|
|
||||||
|
@ -29,7 +33,7 @@ void Block::AppendNewInst(Opcode opcode, std::initializer_list<IR::Value> args)
|
||||||
index++;
|
index++;
|
||||||
});
|
});
|
||||||
|
|
||||||
instructions.push_back(inst);
|
return instructions.insert_before(insertion_point, inst);
|
||||||
}
|
}
|
||||||
|
|
||||||
LocationDescriptor Block::Location() const {
|
LocationDescriptor Block::Location() const {
|
||||||
|
|
|
@ -69,7 +69,7 @@ public:
|
||||||
const_reverse_iterator crend() const { return instructions.crend(); }
|
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.
|
* handling any allocations necessary to do so.
|
||||||
*
|
*
|
||||||
* @param op Opcode representing the instruction to add.
|
* @param op Opcode representing the instruction to add.
|
||||||
|
@ -77,6 +77,17 @@ public:
|
||||||
*/
|
*/
|
||||||
void AppendNewInst(Opcode op, std::initializer_list<Value> args);
|
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.
|
/// Gets the starting location for this basic block.
|
||||||
LocationDescriptor Location() const;
|
LocationDescriptor Location() const;
|
||||||
/// Gets the end location for this basic block.
|
/// Gets the end location for this basic block.
|
||||||
|
|
|
@ -944,4 +944,12 @@ void IREmitter::SetTerm(const Terminal& terminal) {
|
||||||
block.SetTerminal(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
|
} // namespace Dynarmic::IR
|
||||||
|
|
|
@ -55,7 +55,7 @@ struct ResultAndGE {
|
||||||
*/
|
*/
|
||||||
class IREmitter {
|
class IREmitter {
|
||||||
public:
|
public:
|
||||||
explicit IREmitter(Block& block) : block(block) {}
|
explicit IREmitter(Block& block) : block(block), insertion_point(block.end()) {}
|
||||||
|
|
||||||
Block& block;
|
Block& block;
|
||||||
|
|
||||||
|
@ -247,11 +247,16 @@ public:
|
||||||
|
|
||||||
void SetTerm(const Terminal& terminal);
|
void SetTerm(const Terminal& terminal);
|
||||||
|
|
||||||
|
void SetInsertionPoint(IR::Inst* new_insertion_point);
|
||||||
|
void SetInsertionPoint(IR::Block::iterator new_insertion_point);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
IR::Block::iterator insertion_point;
|
||||||
|
|
||||||
template<typename T = Value, typename ...Args>
|
template<typename T = Value, typename ...Args>
|
||||||
T Inst(Opcode op, Args ...args) {
|
T Inst(Opcode op, Args ...args) {
|
||||||
block.AppendNewInst(op, {Value(args)...});
|
auto iter = block.PrependNewInst(insertion_point, op, {Value(args)...});
|
||||||
return T(Value(&block.back()));
|
return T(Value(&*iter));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue