diff --git a/InstructionSets/x86/Implementation/PerformImplementation.hpp b/InstructionSets/x86/Implementation/PerformImplementation.hpp index cb214e35f..b0fdfd17d 100644 --- a/InstructionSets/x86/Implementation/PerformImplementation.hpp +++ b/InstructionSets/x86/Implementation/PerformImplementation.hpp @@ -55,36 +55,8 @@ uint32_t address( return address + *resolve(instruction, pointer.base(), pointer, registers, memory); } -template -uint32_t address( - InstructionT &instruction, - DataPointer pointer, - RegistersT ®isters, - MemoryT &memory -) { - switch(pointer.source()) { - default: return 0; - case Source::Indirect: return address(instruction, pointer, registers, memory); - case Source::IndirectNoBase: return address(instruction, pointer, registers, memory); - case Source::DirectAddress: return address(instruction, pointer, registers, memory); - } -} - -template -IntT *resolve( - InstructionT &instruction, - Source source, - DataPointer pointer, - RegistersT ®isters, - MemoryT &memory, - IntT *none, - IntT *immediate -) { - // Rules: - // - // * if this is a memory access, set target_address and break; - // * otherwise return the appropriate value. - uint32_t target_address; +template +IntT *register_(RegistersT ®isters) { switch(source) { case Source::eAX: // Slightly contorted if chain here and below: @@ -131,10 +103,63 @@ IntT *resolve( else if constexpr (std::is_same_v) { return ®isters.bh(); } else { return nullptr; } - case Source::ES: if constexpr (std::is_same_v) return ®isters.es(); else return nullptr; - case Source::CS: if constexpr (std::is_same_v) return ®isters.cs(); else return nullptr; - case Source::SS: if constexpr (std::is_same_v) return ®isters.ss(); else return nullptr; - case Source::DS: if constexpr (std::is_same_v) return ®isters.ds(); else return nullptr; + default: return nullptr; + } +} + +template +uint32_t address( + InstructionT &instruction, + DataPointer pointer, + RegistersT ®isters, + MemoryT &memory +) { + switch(pointer.source()) { + default: return 0; + case Source::eAX: return *register_(registers); + case Source::eCX: return *register_(registers); + case Source::eDX: return *register_(registers); + case Source::eBX: return *register_(registers); + case Source::eSPorAH: return *register_(registers); + case Source::eBPorCH: return *register_(registers); + case Source::eSIorDH: return *register_(registers); + case Source::eDIorBH: return *register_(registers); + case Source::Indirect: return address(instruction, pointer, registers, memory); + case Source::IndirectNoBase: return address(instruction, pointer, registers, memory); + case Source::DirectAddress: return address(instruction, pointer, registers, memory); + } +} + +template +IntT *resolve( + InstructionT &instruction, + Source source, + DataPointer pointer, + RegistersT ®isters, + MemoryT &memory, + IntT *none, + IntT *immediate +) { + // Rules: + // + // * if this is a memory access, set target_address and break; + // * otherwise return the appropriate value. + uint32_t target_address; + switch(source) { + case Source::eAX: return register_(registers); + case Source::eCX: return register_(registers); + case Source::eDX: return register_(registers); + case Source::eBX: return register_(registers); + case Source::eSPorAH: return register_(registers); + case Source::eBPorCH: return register_(registers); + case Source::eSIorDH: return register_(registers); + case Source::eDIorBH: return register_(registers); + + // Segment registers are always 16-bit. + case Source::ES: if constexpr (std::is_same_v) return ®isters.es(); else return nullptr; + case Source::CS: if constexpr (std::is_same_v) return ®isters.cs(); else return nullptr; + case Source::SS: if constexpr (std::is_same_v) return ®isters.ss(); else return nullptr; + case Source::DS: if constexpr (std::is_same_v) return ®isters.ds(); else return nullptr; // 16-bit models don't have FS and GS. case Source::FS: if constexpr (is_32bit(model) && std::is_same_v) return ®isters.fs(); else return nullptr; diff --git a/OSBindings/Mac/Clock SignalTests/8088Tests.mm b/OSBindings/Mac/Clock SignalTests/8088Tests.mm index aad5bb1ae..14562acf8 100644 --- a/OSBindings/Mac/Clock SignalTests/8088Tests.mm +++ b/OSBindings/Mac/Clock SignalTests/8088Tests.mm @@ -25,7 +25,7 @@ namespace { // The tests themselves are not duplicated in this repository; // provide their real path here. -constexpr char TestSuiteHome[] = "/Users/tharte/Projects/ProcessorTests/8088/v1"; +constexpr char TestSuiteHome[] = "/Users/thomasharte/Projects/ProcessorTests/8088/v1"; using Status = InstructionSet::x86::Status; struct Registers { @@ -497,6 +497,10 @@ struct FailedExecution { execution_support.status = initial_status; execution_support.registers = initial_registers; + if(decoded.second.operation != InstructionSet::x86::Operation::LEA) { + return; + } + // Execute instruction. // // TODO: enquire of the actual mechanism of repetition; if it were stateful as below then