A32: Add Step

This commit is contained in:
MerryMage 2020-04-06 15:35:43 +01:00
parent f69c77391e
commit b6536115ef
6 changed files with 88 additions and 32 deletions

View file

@ -11,11 +11,12 @@
namespace Dynarmic::A32 {
std::ostream& operator<<(std::ostream& o, const LocationDescriptor& descriptor) {
o << fmt::format("{{{:08x},{},{},{:08x}}}",
o << fmt::format("{{{:08x},{},{},{:08x}{}}}",
descriptor.PC(),
descriptor.TFlag() ? "T" : "!T",
descriptor.EFlag() ? "E" : "!E",
descriptor.FPSCR().Value());
descriptor.FPSCR().Value(),
descriptor.SingleStepping() ? ",step" : "");
return o;
}

View file

@ -29,8 +29,12 @@ public:
static constexpr u32 CPSR_MODE_MASK = 0x0600FE20;
static constexpr u32 FPSCR_MODE_MASK = 0x07F70000;
LocationDescriptor(u32 arm_pc, PSR cpsr, FPSCR fpscr)
: arm_pc(arm_pc), cpsr(cpsr.Value() & CPSR_MODE_MASK), fpscr(fpscr.Value() & FPSCR_MODE_MASK) {}
LocationDescriptor(u32 arm_pc, PSR cpsr, FPSCR fpscr, bool single_stepping = false)
: arm_pc(arm_pc)
, cpsr(cpsr.Value() & CPSR_MODE_MASK)
, fpscr(fpscr.Value() & FPSCR_MODE_MASK)
, single_stepping(single_stepping)
{}
explicit LocationDescriptor(const IR::LocationDescriptor& o) {
arm_pc = static_cast<u32>(o.Value());
@ -38,6 +42,7 @@ public:
cpsr.E((o.Value() >> 32) & 2);
fpscr = (o.Value() >> 32) & FPSCR_MODE_MASK;
cpsr.IT(ITState{static_cast<u8>(o.Value() >> 40)});
single_stepping = (o.Value() >> 32) & 4;
}
u32 PC() const { return arm_pc; }
@ -48,8 +53,10 @@ public:
A32::PSR CPSR() const { return cpsr; }
A32::FPSCR FPSCR() const { return fpscr; }
bool SingleStepping() const { return single_stepping; }
bool operator == (const LocationDescriptor& o) const {
return std::tie(arm_pc, cpsr, fpscr) == std::tie(o.arm_pc, o.cpsr, o.fpscr);
return std::tie(arm_pc, cpsr, fpscr, single_stepping) == std::tie(o.arm_pc, o.cpsr, o.fpscr, single_stepping);
}
bool operator != (const LocationDescriptor& o) const {
@ -57,36 +64,40 @@ public:
}
LocationDescriptor SetPC(u32 new_arm_pc) const {
return LocationDescriptor(new_arm_pc, cpsr, fpscr);
return LocationDescriptor(new_arm_pc, cpsr, fpscr, single_stepping);
}
LocationDescriptor AdvancePC(int amount) const {
return LocationDescriptor(static_cast<u32>(arm_pc + amount), cpsr, fpscr);
return LocationDescriptor(static_cast<u32>(arm_pc + amount), cpsr, fpscr, single_stepping);
}
LocationDescriptor SetTFlag(bool new_tflag) const {
PSR new_cpsr = cpsr;
new_cpsr.T(new_tflag);
return LocationDescriptor(arm_pc, new_cpsr, fpscr);
return LocationDescriptor(arm_pc, new_cpsr, fpscr, single_stepping);
}
LocationDescriptor SetEFlag(bool new_eflag) const {
PSR new_cpsr = cpsr;
new_cpsr.E(new_eflag);
return LocationDescriptor(arm_pc, new_cpsr, fpscr);
return LocationDescriptor(arm_pc, new_cpsr, fpscr, single_stepping);
}
LocationDescriptor SetFPSCR(u32 new_fpscr) const {
return LocationDescriptor(arm_pc, cpsr, A32::FPSCR{new_fpscr & FPSCR_MODE_MASK});
return LocationDescriptor(arm_pc, cpsr, A32::FPSCR{new_fpscr & FPSCR_MODE_MASK}, single_stepping);
}
LocationDescriptor AdvanceIT() const {
PSR new_cpsr = cpsr;
new_cpsr.IT(new_cpsr.IT().Advance());
return LocationDescriptor(arm_pc, new_cpsr, fpscr);
return LocationDescriptor(arm_pc, new_cpsr, fpscr, single_stepping);
}
LocationDescriptor SetSingleStepping(bool new_single_stepping) const {
return LocationDescriptor(arm_pc, cpsr, fpscr, new_single_stepping);
}
u64 UniqueHash() const noexcept {
@ -96,8 +107,9 @@ public:
const u64 fpscr_u64 = fpscr.Value();
const u64 t_u64 = cpsr.T() ? 1 : 0;
const u64 e_u64 = cpsr.E() ? 2 : 0;
const u64 single_stepping_u64 = single_stepping ? 4 : 0;
const u64 it_u64 = u64(cpsr.IT().Value()) << 8;
const u64 upper = (fpscr_u64 | t_u64 | e_u64 | it_u64) << 32;
const u64 upper = (fpscr_u64 | t_u64 | e_u64 | single_stepping_u64 | it_u64) << 32;
return pc_u64 | upper;
}
@ -109,6 +121,7 @@ private:
u32 arm_pc; ///< Current program counter value.
PSR cpsr; ///< Current program status register.
A32::FPSCR fpscr; ///< Floating point status control register.
bool single_stepping;
};
/**

View file

@ -33,8 +33,9 @@ IR::Block TranslateArm(LocationDescriptor descriptor, MemoryReadCodeFuncType mem
IR::Block block{descriptor};
ArmTranslatorVisitor visitor{block, descriptor, options};
const bool single_step = descriptor.SingleStepping();
bool should_continue = true;
while (should_continue && CondCanContinue(visitor.cond_state, visitor.ir)) {
do {
const u32 arm_pc = visitor.ir.current_location.PC();
const u32 arm_instruction = memory_read_code(arm_pc);
@ -52,11 +53,15 @@ IR::Block TranslateArm(LocationDescriptor descriptor, MemoryReadCodeFuncType mem
visitor.ir.current_location = visitor.ir.current_location.AdvancePC(4);
block.CycleCount()++;
}
} while (should_continue && CondCanContinue(visitor.cond_state, visitor.ir) && !single_step);
if (visitor.cond_state == ConditionalState::Translating || visitor.cond_state == ConditionalState::Trailing) {
if (visitor.cond_state == ConditionalState::Translating || visitor.cond_state == ConditionalState::Trailing || single_step) {
if (should_continue) {
visitor.ir.SetTerm(IR::Term::LinkBlockFast{visitor.ir.current_location});
if (single_step) {
visitor.ir.SetTerm(IR::Term::LinkBlock{visitor.ir.current_location});
} else {
visitor.ir.SetTerm(IR::Term::LinkBlockFast{visitor.ir.current_location});
}
}
}

View file

@ -59,8 +59,9 @@ IR::Block TranslateThumb(LocationDescriptor descriptor, MemoryReadCodeFuncType m
IR::Block block{descriptor};
ThumbTranslatorVisitor visitor{block, descriptor, options};
const bool single_step = descriptor.SingleStepping();
bool should_continue = true;
while (should_continue) {
do {
const u32 arm_pc = visitor.ir.current_location.PC();
const auto [thumb_instruction, inst_size] = ReadThumbInstruction(arm_pc, memory_read_code);
@ -81,6 +82,10 @@ IR::Block TranslateThumb(LocationDescriptor descriptor, MemoryReadCodeFuncType m
const s32 advance_pc = (inst_size == ThumbInstSize::Thumb16) ? 2 : 4;
visitor.ir.current_location = visitor.ir.current_location.AdvancePC(advance_pc);
block.CycleCount()++;
} while (should_continue && !single_step);
if (single_step && should_continue) {
visitor.ir.SetTerm(IR::Term::LinkBlock{visitor.ir.current_location});
}
block.SetEndLocation(visitor.ir.current_location);