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 {
|
class IREmitter : public IR::IREmitter {
|
||||||
public:
|
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;
|
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) {
|
IR::Block TranslateArm(LocationDescriptor descriptor, MemoryReadCodeFuncType memory_read_code) {
|
||||||
ArmTranslatorVisitor visitor{descriptor};
|
IR::Block block{descriptor};
|
||||||
|
ArmTranslatorVisitor visitor{block, descriptor};
|
||||||
|
|
||||||
bool should_continue = true;
|
bool should_continue = true;
|
||||||
while (should_continue && CondCanContinue(visitor.cond_state, visitor.ir)) {
|
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.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) {
|
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) {
|
bool ArmTranslatorVisitor::ConditionPassed(Cond cond) {
|
||||||
|
|
|
@ -26,7 +26,7 @@ enum class ConditionalState {
|
||||||
struct ArmTranslatorVisitor final {
|
struct ArmTranslatorVisitor final {
|
||||||
using instruction_return_type = bool;
|
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");
|
ASSERT_MSG(!descriptor.TFlag(), "The processor must be in Arm mode");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,7 @@ namespace {
|
||||||
struct ThumbTranslatorVisitor final {
|
struct ThumbTranslatorVisitor final {
|
||||||
using instruction_return_type = bool;
|
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");
|
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
|
} // local namespace
|
||||||
|
|
||||||
IR::Block TranslateThumb(LocationDescriptor descriptor, MemoryReadCodeFuncType memory_read_code) {
|
IR::Block TranslateThumb(LocationDescriptor descriptor, MemoryReadCodeFuncType memory_read_code) {
|
||||||
ThumbTranslatorVisitor visitor{descriptor};
|
IR::Block block{descriptor};
|
||||||
|
ThumbTranslatorVisitor visitor{block, descriptor};
|
||||||
|
|
||||||
bool should_continue = true;
|
bool should_continue = true;
|
||||||
while (should_continue) {
|
while (should_continue) {
|
||||||
|
@ -906,12 +907,12 @@ IR::Block TranslateThumb(LocationDescriptor descriptor, MemoryReadCodeFuncType m
|
||||||
|
|
||||||
s32 advance_pc = (inst_size == ThumbInstSize::Thumb16) ? 2 : 4;
|
s32 advance_pc = (inst_size == ThumbInstSize::Thumb16) ? 2 : 4;
|
||||||
visitor.ir.current_location = visitor.ir.current_location.AdvancePC(advance_pc);
|
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
|
} // namespace A32
|
||||||
|
|
|
@ -24,7 +24,7 @@ namespace A64 {
|
||||||
*/
|
*/
|
||||||
class IREmitter : public IR::IREmitter {
|
class IREmitter : public IR::IREmitter {
|
||||||
public:
|
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;
|
LocationDescriptor current_location;
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,7 @@ enum class MemOp {
|
||||||
struct TranslatorVisitor final {
|
struct TranslatorVisitor final {
|
||||||
using instruction_return_type = bool;
|
using instruction_return_type = bool;
|
||||||
|
|
||||||
explicit TranslatorVisitor(LocationDescriptor descriptor) : ir(descriptor) {}
|
explicit TranslatorVisitor(IR::Block& block, LocationDescriptor descriptor) : ir(block, descriptor) {}
|
||||||
|
|
||||||
A64::IREmitter ir;
|
A64::IREmitter ir;
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,8 @@ namespace Dynarmic {
|
||||||
namespace A64 {
|
namespace A64 {
|
||||||
|
|
||||||
IR::Block Translate(LocationDescriptor descriptor, MemoryReadCodeFuncType memory_read_code) {
|
IR::Block Translate(LocationDescriptor descriptor, MemoryReadCodeFuncType memory_read_code) {
|
||||||
TranslatorVisitor visitor{descriptor};
|
IR::Block block{descriptor};
|
||||||
|
TranslatorVisitor visitor{block, descriptor};
|
||||||
|
|
||||||
bool should_continue = true;
|
bool should_continue = true;
|
||||||
while (should_continue) {
|
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.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
|
} // namespace A64
|
||||||
|
|
|
@ -23,11 +23,20 @@ using MemoryReadCodeFuncType = std::function<u32(u64 vaddr)>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This function translates instructions in memory into our intermediate representation.
|
* 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.
|
* @param memory_read_code The function we should use to read emulated memory.
|
||||||
* @return A translated basic block in the intermediate representation.
|
* @return A translated basic block in the intermediate representation.
|
||||||
*/
|
*/
|
||||||
IR::Block Translate(LocationDescriptor descriptor, MemoryReadCodeFuncType memory_read_code);
|
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 A64
|
||||||
} // namespace Dynarmic
|
} // namespace Dynarmic
|
||||||
|
|
|
@ -60,9 +60,9 @@ struct ResultAndGE {
|
||||||
*/
|
*/
|
||||||
class IREmitter {
|
class IREmitter {
|
||||||
public:
|
public:
|
||||||
explicit IREmitter(IR::LocationDescriptor descriptor) : block(descriptor) {}
|
explicit IREmitter(Block& block) : block(block) {}
|
||||||
|
|
||||||
Block block;
|
Block& block;
|
||||||
|
|
||||||
void Unimplemented();
|
void Unimplemented();
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue