From bd0b62232f5eb87a1d789d371acee3e8215a4249 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Sun, 8 Oct 2023 21:41:36 -0400 Subject: [PATCH] Consider that displacements may always be signed. Down to 1 failure. --- InstructionSets/x86/Decoder.cpp | 18 ++++----- .../Implementation/PerformImplementation.hpp | 38 +++++++++++++++++-- OSBindings/Mac/Clock SignalTests/8088Tests.mm | 6 +-- 3 files changed, 46 insertions(+), 16 deletions(-) diff --git a/InstructionSets/x86/Decoder.cpp b/InstructionSets/x86/Decoder.cpp index a8c3f92d4..ee4a79598 100644 --- a/InstructionSets/x86/Decoder.cpp +++ b/InstructionSets/x86/Decoder.cpp @@ -1018,21 +1018,21 @@ std::pair::InstructionT> Decoder::decode(con // TODO: whether the displacement is signed appears to depend on the opcode. // Find an appropriate table. - if(!sign_extend_displacement_) { - switch(displacement_size_) { - case DataSize::None: displacement_ = 0; break; - case DataSize::Byte: displacement_ = decltype(displacement_)(uint8_t(inward_data_)); break; - case DataSize::Word: displacement_ = decltype(displacement_)(uint16_t(inward_data_)); break; - case DataSize::DWord: displacement_ = decltype(displacement_)(uint32_t(inward_data_)); break; - } - } else { +// if(!sign_extend_displacement_) { +// switch(displacement_size_) { +// case DataSize::None: displacement_ = 0; break; +// case DataSize::Byte: displacement_ = decltype(displacement_)(uint8_t(inward_data_)); break; +// case DataSize::Word: displacement_ = decltype(displacement_)(uint16_t(inward_data_)); break; +// case DataSize::DWord: displacement_ = decltype(displacement_)(uint32_t(inward_data_)); break; +// } +// } else { switch(displacement_size_) { case DataSize::None: displacement_ = 0; break; case DataSize::Byte: displacement_ = int8_t(inward_data_); break; case DataSize::Word: displacement_ = int16_t(inward_data_); break; case DataSize::DWord: displacement_ = int32_t(inward_data_); break; } - } +// } inward_data_ >>= bit_size(displacement_size_); // Use inequality of sizes as a test for necessary sign extension. diff --git a/InstructionSets/x86/Implementation/PerformImplementation.hpp b/InstructionSets/x86/Implementation/PerformImplementation.hpp index eefce4e96..9940caa37 100644 --- a/InstructionSets/x86/Implementation/PerformImplementation.hpp +++ b/InstructionSets/x86/Implementation/PerformImplementation.hpp @@ -203,7 +203,16 @@ void add(IntT &destination, IntT source, Status &status) { } template -typename DataSizeType::type *resolve(InstructionT &instruction, Source source, DataPointer pointer, RegistersT ®isters, MemoryT &memory, typename DataSizeType::type *none = nullptr) { +typename DataSizeType::type * +resolve( + InstructionT &instruction, + Source source, + DataPointer pointer, + RegistersT ®isters, + MemoryT &memory, + typename DataSizeType::type *none = nullptr, + typename DataSizeType::type *immediate = nullptr +) { // Rules: // // * if this is a memory access, set target_address and break; @@ -264,7 +273,9 @@ typename DataSizeType::type *resolve(InstructionT &instruction, Sourc case Source::FS: if constexpr (is_32bit(model) && data_size == DataSize::Word) return ®isters.fs(); else return nullptr; case Source::GS: if constexpr (is_32bit(model) && data_size == DataSize::Word) return ®isters.gs(); else return nullptr; - case Source::Immediate: // TODO (here the use of a pointer falls down?) + case Source::Immediate: + *immediate = instruction.operand(); + return immediate; case Source::None: return none; @@ -319,8 +330,27 @@ template < using AddressT = typename AddressT::type; // Establish source() and destination() shorthand to fetch data if necessary. - auto source = [&]() -> IntT& { return *resolve(instruction, instruction.source().template source(), instruction.source(), registers, memory); }; - auto destination = [&]() -> IntT& { return *resolve(instruction, instruction.destination().template source(), instruction.destination(), registers, memory); }; + IntT immediate; + auto source = [&]() -> IntT& { + return *resolve( + instruction, + instruction.source().template source(), + instruction.source(), + registers, + memory, + nullptr, + &immediate); + }; + auto destination = [&]() -> IntT& { + return *resolve( + instruction, + instruction.destination().template source(), + instruction.destination(), + registers, + memory, + nullptr, + &immediate); + }; // Guide to the below: // diff --git a/OSBindings/Mac/Clock SignalTests/8088Tests.mm b/OSBindings/Mac/Clock SignalTests/8088Tests.mm index c47a28109..0b208bd55 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/thomasharte/Projects/ProcessorTests/8088/v1"; +constexpr char TestSuiteHome[] = "/Users/tharte/Projects/ProcessorTests/8088/v1"; using Status = InstructionSet::x86::Status; struct Registers { @@ -142,7 +142,7 @@ struct Memory { // to a selector, they're just at an absolute location. template IntT &access(uint32_t address, Tag tag) { if(tags.find(address) == tags.end()) { -// printf("Access to unexpected RAM address"); + printf("Access to unexpected RAM address"); } tags[address] = tag; return *reinterpret_cast(&memory[address]); @@ -234,7 +234,7 @@ struct FailedExecution { NSString *path = [NSString stringWithUTF8String:TestSuiteHome]; NSSet *allowList = [NSSet setWithArray:@[ // ADC -// @"10.json.gz", @"11.json.gz", @"12.json.gz", @"13.json.gz", @"14.json.gz", @"15.json.gz", + @"10.json.gz", @"11.json.gz", @"12.json.gz", @"13.json.gz", @"14.json.gz", @"15.json.gz", // TO add: 80/2, 81/2, 83/2 // ADD