A64/translate: Add TranslateSingleInstruction function
This commit is contained in:
parent
aa74a8130b
commit
61125d6dd1
9 changed files with 52 additions and 22 deletions
|
@ -26,7 +26,7 @@ namespace A32 {
|
|||
*/
|
||||
class IREmitter : public IR::IREmitter {
|
||||
public:
|
||||
explicit IREmitter(LocationDescriptor descriptor) : IR::IREmitter(descriptor), current_location(descriptor) {}
|
||||
explicit IREmitter(IR::Block& block, LocationDescriptor descriptor) : IR::IREmitter(block), current_location(descriptor) {}
|
||||
|
||||
LocationDescriptor current_location;
|
||||
|
||||
|
|
|
@ -29,7 +29,8 @@ static bool CondCanContinue(ConditionalState cond_state, const A32::IREmitter& i
|
|||
}
|
||||
|
||||
IR::Block TranslateArm(LocationDescriptor descriptor, MemoryReadCodeFuncType memory_read_code) {
|
||||
ArmTranslatorVisitor visitor{descriptor};
|
||||
IR::Block block{descriptor};
|
||||
ArmTranslatorVisitor visitor{block, descriptor};
|
||||
|
||||
bool should_continue = true;
|
||||
while (should_continue && CondCanContinue(visitor.cond_state, visitor.ir)) {
|
||||
|
@ -49,7 +50,7 @@ IR::Block TranslateArm(LocationDescriptor descriptor, MemoryReadCodeFuncType mem
|
|||
}
|
||||
|
||||
visitor.ir.current_location = visitor.ir.current_location.AdvancePC(4);
|
||||
visitor.ir.block.CycleCount()++;
|
||||
block.CycleCount()++;
|
||||
}
|
||||
|
||||
if (visitor.cond_state == ConditionalState::Translating || visitor.cond_state == ConditionalState::Trailing) {
|
||||
|
@ -58,11 +59,11 @@ IR::Block TranslateArm(LocationDescriptor descriptor, MemoryReadCodeFuncType mem
|
|||
}
|
||||
}
|
||||
|
||||
ASSERT_MSG(visitor.ir.block.HasTerminal(), "Terminal has not been set");
|
||||
ASSERT_MSG(block.HasTerminal(), "Terminal has not been set");
|
||||
|
||||
visitor.ir.block.SetEndLocation(visitor.ir.current_location);
|
||||
block.SetEndLocation(visitor.ir.current_location);
|
||||
|
||||
return std::move(visitor.ir.block);
|
||||
return block;
|
||||
}
|
||||
|
||||
bool ArmTranslatorVisitor::ConditionPassed(Cond cond) {
|
||||
|
|
|
@ -26,7 +26,7 @@ enum class ConditionalState {
|
|||
struct ArmTranslatorVisitor final {
|
||||
using instruction_return_type = bool;
|
||||
|
||||
explicit ArmTranslatorVisitor(LocationDescriptor descriptor) : ir(descriptor) {
|
||||
explicit ArmTranslatorVisitor(IR::Block& block, LocationDescriptor descriptor) : ir(block, descriptor) {
|
||||
ASSERT_MSG(!descriptor.TFlag(), "The processor must be in Arm mode");
|
||||
}
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ namespace {
|
|||
struct ThumbTranslatorVisitor final {
|
||||
using instruction_return_type = bool;
|
||||
|
||||
explicit ThumbTranslatorVisitor(LocationDescriptor descriptor) : ir(descriptor) {
|
||||
explicit ThumbTranslatorVisitor(IR::Block& block, LocationDescriptor descriptor) : ir(block, descriptor) {
|
||||
ASSERT_MSG(descriptor.TFlag(), "The processor must be in Thumb mode");
|
||||
}
|
||||
|
||||
|
@ -878,7 +878,8 @@ std::tuple<u32, ThumbInstSize> ReadThumbInstruction(u32 arm_pc, MemoryReadCodeFu
|
|||
} // local namespace
|
||||
|
||||
IR::Block TranslateThumb(LocationDescriptor descriptor, MemoryReadCodeFuncType memory_read_code) {
|
||||
ThumbTranslatorVisitor visitor{descriptor};
|
||||
IR::Block block{descriptor};
|
||||
ThumbTranslatorVisitor visitor{block, descriptor};
|
||||
|
||||
bool should_continue = true;
|
||||
while (should_continue) {
|
||||
|
@ -906,12 +907,12 @@ IR::Block TranslateThumb(LocationDescriptor descriptor, MemoryReadCodeFuncType m
|
|||
|
||||
s32 advance_pc = (inst_size == ThumbInstSize::Thumb16) ? 2 : 4;
|
||||
visitor.ir.current_location = visitor.ir.current_location.AdvancePC(advance_pc);
|
||||
visitor.ir.block.CycleCount()++;
|
||||
block.CycleCount()++;
|
||||
}
|
||||
|
||||
visitor.ir.block.SetEndLocation(visitor.ir.current_location);
|
||||
block.SetEndLocation(visitor.ir.current_location);
|
||||
|
||||
return std::move(visitor.ir.block);
|
||||
return block;
|
||||
}
|
||||
|
||||
} // namespace A32
|
||||
|
|
|
@ -24,7 +24,7 @@ namespace A64 {
|
|||
*/
|
||||
class IREmitter : public IR::IREmitter {
|
||||
public:
|
||||
explicit IREmitter(LocationDescriptor descriptor) : IR::IREmitter(descriptor), current_location(descriptor) {}
|
||||
explicit IREmitter(IR::Block& block, LocationDescriptor descriptor) : IR::IREmitter(block), current_location(descriptor) {}
|
||||
|
||||
LocationDescriptor current_location;
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@ enum class MemOp {
|
|||
struct TranslatorVisitor final {
|
||||
using instruction_return_type = bool;
|
||||
|
||||
explicit TranslatorVisitor(LocationDescriptor descriptor) : ir(descriptor) {}
|
||||
explicit TranslatorVisitor(IR::Block& block, LocationDescriptor descriptor) : ir(block, descriptor) {}
|
||||
|
||||
A64::IREmitter ir;
|
||||
|
||||
|
|
|
@ -14,7 +14,8 @@ namespace Dynarmic {
|
|||
namespace A64 {
|
||||
|
||||
IR::Block Translate(LocationDescriptor descriptor, MemoryReadCodeFuncType memory_read_code) {
|
||||
TranslatorVisitor visitor{descriptor};
|
||||
IR::Block block{descriptor};
|
||||
TranslatorVisitor visitor{block, descriptor};
|
||||
|
||||
bool should_continue = true;
|
||||
while (should_continue) {
|
||||
|
@ -28,14 +29,32 @@ IR::Block Translate(LocationDescriptor descriptor, MemoryReadCodeFuncType memory
|
|||
}
|
||||
|
||||
visitor.ir.current_location = visitor.ir.current_location.AdvancePC(4);
|
||||
visitor.ir.block.CycleCount()++;
|
||||
block.CycleCount()++;
|
||||
}
|
||||
|
||||
ASSERT_MSG(visitor.ir.block.HasTerminal(), "Terminal has not been set");
|
||||
ASSERT_MSG(block.HasTerminal(), "Terminal has not been set");
|
||||
|
||||
visitor.ir.block.SetEndLocation(visitor.ir.current_location);
|
||||
block.SetEndLocation(visitor.ir.current_location);
|
||||
|
||||
return std::move(visitor.ir.block);
|
||||
return block;
|
||||
}
|
||||
|
||||
bool TranslateSingleInstruction(IR::Block& block, LocationDescriptor descriptor, u32 instruction) {
|
||||
TranslatorVisitor visitor{block, descriptor};
|
||||
|
||||
bool should_continue = true;
|
||||
if (auto decoder = Decode<TranslatorVisitor>(instruction)) {
|
||||
should_continue = decoder->call(visitor, instruction);
|
||||
} else {
|
||||
should_continue = visitor.InterpretThisInstruction();
|
||||
}
|
||||
|
||||
visitor.ir.current_location = visitor.ir.current_location.AdvancePC(4);
|
||||
block.CycleCount()++;
|
||||
|
||||
block.SetEndLocation(visitor.ir.current_location);
|
||||
|
||||
return should_continue;
|
||||
}
|
||||
|
||||
} // namespace A64
|
||||
|
|
|
@ -23,11 +23,20 @@ using MemoryReadCodeFuncType = std::function<u32(u64 vaddr)>;
|
|||
|
||||
/**
|
||||
* This function translates instructions in memory into our intermediate representation.
|
||||
* @param descriptor The starting location of the basic block. Includes information like PC, Thumb state, &c.
|
||||
* @param descriptor The starting location of the basic block. Includes information like PC, FPCR state, &c.
|
||||
* @param memory_read_code The function we should use to read emulated memory.
|
||||
* @return A translated basic block in the intermediate representation.
|
||||
*/
|
||||
IR::Block Translate(LocationDescriptor descriptor, MemoryReadCodeFuncType memory_read_code);
|
||||
|
||||
/**
|
||||
* This function translates a single provided instruction into our intermediate representation.
|
||||
* @param block The block to append the IR for the instruction to.
|
||||
* @param descriptor The location of the instruction. Includes information like PC, FPCR state, &c.
|
||||
* @param instruction The instruction to translate.
|
||||
* @return The translated instruction translated to the intermediate representation.
|
||||
*/
|
||||
bool TranslateSingleInstruction(IR::Block& block, LocationDescriptor descriptor, u32 instruction);
|
||||
|
||||
} // namespace A64
|
||||
} // namespace Dynarmic
|
||||
|
|
|
@ -60,9 +60,9 @@ struct ResultAndGE {
|
|||
*/
|
||||
class IREmitter {
|
||||
public:
|
||||
explicit IREmitter(IR::LocationDescriptor descriptor) : block(descriptor) {}
|
||||
explicit IREmitter(Block& block) : block(block) {}
|
||||
|
||||
Block block;
|
||||
Block& block;
|
||||
|
||||
void Unimplemented();
|
||||
|
||||
|
|
Loading…
Reference in a new issue