diff --git a/include/cpu/cpu.hh b/include/cpu/cpu.hh index 54b394c..dadb870 100644 --- a/include/cpu/cpu.hh +++ b/include/cpu/cpu.hh @@ -98,7 +98,21 @@ class Cpu { void advance_pc_arm(); void advance_pc_thumb(); - void flush_pipeline(); + template + void flush_pipeline() { + if constexpr (S == State::Arm) { + opcodes[0] = bus->read_word(pc, CpuAccess::NonSequential); + advance_pc_arm(); + opcodes[1] = bus->read_word(pc, CpuAccess::Sequential); + advance_pc_arm(); + } else { + opcodes[0] = bus->read_halfword(pc, CpuAccess::NonSequential); + advance_pc_thumb(); + opcodes[1] = bus->read_halfword(pc, CpuAccess::Sequential); + advance_pc_thumb(); + } + next_access = CpuAccess::Sequential; + } #ifdef GDB_DEBUG friend class GdbRsp; diff --git a/src/cpu/arm/exec.cc b/src/cpu/arm/exec.cc index 1fb547d..b216cf7 100644 --- a/src/cpu/arm/exec.cc +++ b/src/cpu/arm/exec.cc @@ -705,13 +705,9 @@ Cpu::exec(arm::Instruction& instruction) { } }, instruction.data); - if (is_flushed) { - opcodes[0] = bus->read_word(pc, CpuAccess::NonSequential); - advance_pc_arm(); - opcodes[1] = bus->read_word(pc, CpuAccess::Sequential); - advance_pc_arm(); - next_access = CpuAccess::Sequential; - } else + if (is_flushed) + flush_pipeline(); + else advance_pc_arm(); } } diff --git a/src/cpu/cpu.cc b/src/cpu/cpu.cc index 8ebbc1c..95b72c6 100644 --- a/src/cpu/cpu.cc +++ b/src/cpu/cpu.cc @@ -14,7 +14,7 @@ Cpu::Cpu(std::shared_ptr bus) noexcept glogger.info("CPU successfully initialised"); // PC always points to two instructions ahead - flush_pipeline(); + flush_pipeline(); } /* change modes */ @@ -163,12 +163,10 @@ Cpu::advance_pc_arm() { rst_bit(pc, 1); pc += arm::INSTRUCTION_SIZE; }; + void Cpu::advance_pc_thumb() { rst_bit(pc, 0); pc += thumb::INSTRUCTION_SIZE; } - -void -Cpu::flush_pipeline() {}; } diff --git a/src/cpu/thumb/exec.cc b/src/cpu/thumb/exec.cc index 2578265..0bd9fe6 100644 --- a/src/cpu/thumb/exec.cc +++ b/src/cpu/thumb/exec.cc @@ -604,13 +604,9 @@ Cpu::exec(thumb::Instruction& instruction) { } }, instruction.data); - if (is_flushed) { - opcodes[0] = bus->read_halfword(pc, CpuAccess::NonSequential); - advance_pc_thumb(); - opcodes[1] = bus->read_halfword(pc, CpuAccess::Sequential); - advance_pc_thumb(); - next_access = CpuAccess::Sequential; - } else + if (is_flushed) + flush_pipeline(); + else advance_pc_thumb(); } }