diff --git a/InstructionSets/ARM/Executor.hpp b/InstructionSets/ARM/Executor.hpp index eaf2dcdbc..6294235cd 100644 --- a/InstructionSets/ARM/Executor.hpp +++ b/InstructionSets/ARM/Executor.hpp @@ -175,6 +175,7 @@ struct Executor { break; } + const bool writes_pc = !is_comparison(flags.operation()) && fields.destination() == 15; if constexpr (flags.set_condition_codes()) { // "When Rd is a register other than R15, the condition code flags in the PSR may be // updated from the ALU flags as described above. When Rd is R15 and the S flag in @@ -185,11 +186,9 @@ struct Executor { // this case to update those PSR flags which are not protected by virtue of the // processor mode." - if(fields.destination() == 15) { - registers_.set_status(conditions); - if constexpr (!is_comparison(flags.operation())) { - registers_.set_pc(pc_proxy); - } + if(writes_pc) { + registers_.set_status(pc_proxy); + registers_.set_pc(pc_proxy); } else { // Set N and Z in a unified way. registers_.set_nz(conditions); @@ -201,7 +200,7 @@ struct Executor { } } else { // "If the S flag is clear when Rd is R15, only the 24 PC bits of R15 will be written." - if(fields.destination() == 15 && !is_comparison(flags.operation())) { + if(writes_pc) { registers_.set_pc(pc_proxy); } } diff --git a/OSBindings/Mac/Clock SignalTests/ARMDecoderTests.mm b/OSBindings/Mac/Clock SignalTests/ARMDecoderTests.mm index b2873bf60..5fa9b2690 100644 --- a/OSBindings/Mac/Clock SignalTests/ARMDecoderTests.mm +++ b/OSBindings/Mac/Clock SignalTests/ARMDecoderTests.mm @@ -396,7 +396,7 @@ struct MemoryLedger { // sheet specifically says for a shift-by-register that // "LSL by more than 32 has result zero, carry out zero" so I think // the test set is adrift on the following: - ignore_test = test_count == 15 - 1; + ignore_test = regs[2] >= 32; break; case 0xe090e00f: @@ -414,6 +414,9 @@ struct MemoryLedger { auto ®isters = test->registers(); if(label == "Before:") { // This is the start of a new test. + // TODO: establish implicit register values? + + // Apply provided state. registers.set_mode(Mode::Supervisor); // To make sure the actual mode is applied. registers.set_pc(regs[15] - 8); registers.set_status(regs[15]); @@ -427,7 +430,7 @@ struct MemoryLedger { continue; } - if(instruction == 0xe4931000 && test_count == 3) { + if(instruction == 0xe33ef000 && test_count == 1) { printf(""); }