From 47f4bbeec647fb948c3929bd9536ee800459fe06 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Thu, 5 May 2022 15:31:59 -0400 Subject: [PATCH] Switch to a contiguous block of 16 registers. --- InstructionSets/M68k/Executor.hpp | 2 +- .../Implementation/ExecutorImplementation.hpp | 89 ++++++++++--------- .../68000ComparativeTests.mm | 2 +- 3 files changed, 50 insertions(+), 43 deletions(-) diff --git a/InstructionSets/M68k/Executor.hpp b/InstructionSets/M68k/Executor.hpp index e3eeb7d58..9563c8efc 100644 --- a/InstructionSets/M68k/Executor.hpp +++ b/InstructionSets/M68k/Executor.hpp @@ -83,7 +83,7 @@ template class Executor { // Processor state. Status status_; CPU::SlicedInt32 program_counter_; - CPU::SlicedInt32 data_[8], address_[8]; + CPU::SlicedInt32 registers_[16]; // D0–D8, followed by A0–A8. CPU::SlicedInt32 stack_pointers_[2]; uint32_t instruction_address_; int active_stack_pointer_ = 0; diff --git a/InstructionSets/M68k/Implementation/ExecutorImplementation.hpp b/InstructionSets/M68k/Implementation/ExecutorImplementation.hpp index e75748a32..ff79df7d7 100644 --- a/InstructionSets/M68k/Implementation/ExecutorImplementation.hpp +++ b/InstructionSets/M68k/Implementation/ExecutorImplementation.hpp @@ -15,6 +15,8 @@ namespace InstructionSet { namespace M68k { +#define sp() registers_[8 + 7] + template Executor::Executor(BusHandler &handler) : bus_handler_(handler) { reset(); @@ -27,7 +29,7 @@ void Executor::reset() { did_update_status(); // Seed stack pointer and program counter. - data_[7].l = bus_handler_.template read(0); + sp().l = bus_handler_.template read(0); program_counter_.l = bus_handler_.template read(4); } @@ -81,7 +83,7 @@ uint32_t Executor::index_8bitdisplacement() { const auto extension = read_pc(); const auto offset = int8_t(extension); const int register_index = (extension >> 12) & 7; - const uint32_t displacement = (extension & 0x8000) ? address_[register_index].l : data_[register_index].l; + const uint32_t displacement = registers_[register_index + ((extension >> 12) & 0x08)].l; const uint32_t sized_displacement = (extension & 0x800) ? displacement : int16_t(displacement); return offset + sized_displacement; } @@ -100,11 +102,11 @@ typename Executor::EffectiveAddress Executor::EffectiveAddress Executor()); + ea.value.l = registers_[8 + instruction.reg(index)].l + int16_t(read_pc()); ea.requires_fetch = true; break; case AddressingMode::AddressRegisterIndirectWithIndex8bitDisplacement: - ea.value.l = address_[instruction.reg(index)].l + index_8bitdisplacement(); + ea.value.l = registers_[8 + instruction.reg(index)].l + index_8bitdisplacement(); ea.requires_fetch = true; break; @@ -265,13 +267,13 @@ void Executor::run_for_instructions(int count) { perform(instruction, operand_[0], operand_[1], status_, *this); -// TODO: is it worth holding registers as a single block to avoid conditional below? +// TODO: rephrase to avoid conditional below. #define store_operand(n) \ if(!effective_address_[n].requires_fetch) { \ if(instruction.mode(n) == AddressingMode::DataRegisterDirect) { \ - data_[instruction.reg(n)] = operand_[n]; \ + registers_[instruction.reg(n)] = operand_[n]; \ } else { \ - address_[instruction.reg(n)] = operand_[n]; \ + registers_[8 + instruction.reg(n)] = operand_[n]; \ } \ } else { \ write(instruction.size(), effective_address_[n].value.l, operand_[n]); \ @@ -291,15 +293,15 @@ typename Executor::Registers Executor::get Registers result; for(int c = 0; c < 8; c++) { - result.data[c] = data_[c].l; + result.data[c] = registers_[c].l; } for(int c = 0; c < 7; c++) { - result.address[c] = address_[c].l; + result.address[c] = registers_[8 + c].l; } result.status = status_.status(); result.program_counter = program_counter_.l; - stack_pointers_[status_.is_supervisor_] = address_[7]; + stack_pointers_[status_.is_supervisor_] = sp(); result.user_stack_pointer = stack_pointers_[0].l; result.supervisor_stack_pointer = stack_pointers_[1].l; @@ -309,17 +311,17 @@ typename Executor::Registers Executor::get template void Executor::set_state(const Registers &state) { for(int c = 0; c < 8; c++) { - data_[c].l = state.data[c]; + registers_[c].l = state.data[c]; } for(int c = 0; c < 7; c++) { - address_[c].l = state.address[c]; + registers_[8 + c].l = state.address[c]; } status_.set_status(state.status); program_counter_.l = state.program_counter; stack_pointers_[0].l = state.user_stack_pointer; stack_pointers_[1].l = state.supervisor_stack_pointer; - address_[7] = stack_pointers_[status_.is_supervisor_]; + sp() = stack_pointers_[status_.is_supervisor_]; } // MARK: - Flow Control. @@ -335,9 +337,9 @@ void Executor::raise_exception(int index) { did_update_status(); // Push status and the program counter at instruction start. - bus_handler_.template write(address_[7].l - 4, instruction_address_); - bus_handler_.template write(address_[7].l - 6, status); - address_[7].l -= 6; + bus_handler_.template write(sp().l - 4, instruction_address_); + bus_handler_.template write(sp().l - 6, status); + sp().l -= 6; // Fetch the new program counter. program_counter_.l = bus_handler_.template read(address); @@ -346,8 +348,8 @@ void Executor::raise_exception(int index) { template void Executor::did_update_status() { // Shuffle the stack pointers. - stack_pointers_[active_stack_pointer_] = address_[7]; - address_[7] = stack_pointers_[status_.is_supervisor_]; + stack_pointers_[active_stack_pointer_] = sp(); + sp() = stack_pointers_[status_.is_supervisor_]; active_stack_pointer_ = status_.is_supervisor_; } @@ -366,31 +368,31 @@ void Executor::add_pc(uint32_t offset) { template void Executor::bsr(uint32_t offset) { - address_[7].l -= 4; - bus_handler_.template write(address_[7].l, program_counter_.l); + sp().l -= 4; + bus_handler_.template write(sp().l, program_counter_.l); program_counter_.l = instruction_address_ + offset; } template void Executor::jsr(uint32_t address) { - address_[7].l -= 4; - bus_handler_.template write(address_[7].l, program_counter_.l); + sp().l -= 4; + bus_handler_.template write(sp().l, program_counter_.l); program_counter_.l = address; } template void Executor::link(uint32_t &address, uint32_t offset) { - address_[7].l -= 4; - bus_handler_.template write(address_[7].l, address); - address = address_[7].l; - address_[7].l += offset; + sp().l -= 4; + bus_handler_.template write(sp().l, address); + address = sp().l; + sp().l += offset; } template void Executor::unlink(uint32_t &address) { - address_[7].l = address; - address = bus_handler_.template read(address_[7].l); - address_[7].l += 4; + sp().l = address; + address = bus_handler_.template read(sp().l); + sp().l += 4; } template @@ -415,7 +417,7 @@ void Executor::movep(Preinstruction instruction, uint32_t sou bus_handler_.template write(address, uint8_t(reg)); } else { // Move memory to register. - uint32_t ® = data_[instruction.reg<1>()].l; + uint32_t ® = registers_[instruction.reg<1>()].l; uint32_t address = source; if constexpr (sizeof(IntT) == 4) { @@ -440,11 +442,16 @@ template void Executor::movem(Preinstruction instruction, uint32_t source, uint32_t dest) { if(instruction.mode<0>() == AddressingMode::DataRegisterDirect) { // Move registers to memory. + if(instruction.mode<1>() == AddressingMode::AddressRegisterIndirectWithPredecrement) { + } else { + } } else { // Move memory to registers. } } +#undef sp + } } diff --git a/OSBindings/Mac/Clock SignalTests/68000ComparativeTests.mm b/OSBindings/Mac/Clock SignalTests/68000ComparativeTests.mm index f3dd080c8..c96d92934 100644 --- a/OSBindings/Mac/Clock SignalTests/68000ComparativeTests.mm +++ b/OSBindings/Mac/Clock SignalTests/68000ComparativeTests.mm @@ -72,7 +72,7 @@ - (void)setUp { // To limit tests run to a subset of files and/or of tests, uncomment and fill in below. - _fileSet = [NSSet setWithArray:@[@"movem.json"]]; + _fileSet = [NSSet setWithArray:@[@"move.json"]]; // _testSet = [NSSet setWithArray:@[@"MOVE[A] 0148"]]; // _fileSet = [NSSet setWithArray:@[@"jmp_jsr.json"]]; // _testSet = [NSSet setWithArray:@[@"CHK 41a8"]];