From 9f63db991c3b39f960a45da0d318837f6c9bd5b7 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Fri, 22 Sep 2023 11:07:09 -0400 Subject: [PATCH] Capture default segments, fix base/index confusion. --- InstructionSets/x86/Decoder.cpp | 19 ++++++------- InstructionSets/x86/Instruction.hpp | 16 +++++++++++ OSBindings/Mac/Clock SignalTests/8088Tests.mm | 27 +++++++++++++------ 3 files changed, 43 insertions(+), 19 deletions(-) diff --git a/InstructionSets/x86/Decoder.cpp b/InstructionSets/x86/Decoder.cpp index 46bd274a3..d1d41184a 100644 --- a/InstructionSets/x86/Decoder.cpp +++ b/InstructionSets/x86/Decoder.cpp @@ -663,19 +663,16 @@ std::pair::InstructionT> Decoder::decode(con // Classic 16-bit decoding: mode picks a displacement size, // and a few fixed index+base pairs are defined. constexpr ScaleIndexBase rm_table[8] = { - ScaleIndexBase(0, Source::eBX, Source::eSI), - ScaleIndexBase(0, Source::eBX, Source::eDI), - ScaleIndexBase(0, Source::eBP, Source::eSI), - ScaleIndexBase(0, Source::eBP, Source::eDI), - ScaleIndexBase(0, Source::None, Source::eSI), - ScaleIndexBase(0, Source::None, Source::eDI), - ScaleIndexBase(0, Source::None, Source::eBP), - ScaleIndexBase(0, Source::None, Source::eBX), + ScaleIndexBase(0, Source::eSI, Source::eBX), + ScaleIndexBase(0, Source::eDI, Source::eBX), + ScaleIndexBase(0, Source::eSI, Source::eBP), + ScaleIndexBase(0, Source::eDI, Source::eBP), + ScaleIndexBase(0, Source::eSI, Source::None), + ScaleIndexBase(0, Source::eDI, Source::None), + ScaleIndexBase(0, Source::eBP, Source::None), + ScaleIndexBase(0, Source::eBX, Source::None), }; - // TODO: unless overridden, BP and SP are always relative to ss; SI to ds; DI to es. - // Capture that. - sib_ = rm_table[rm]; } } diff --git a/InstructionSets/x86/Instruction.hpp b/InstructionSets/x86/Instruction.hpp index 13fbf22b3..9808ded0e 100644 --- a/InstructionSets/x86/Instruction.hpp +++ b/InstructionSets/x86/Instruction.hpp @@ -623,6 +623,22 @@ class DataPointer { return sib_.index(); } + /// @returns The default segment to use for this access. + constexpr Source default_segment() const { + switch(source_) { + default: return Source::None; + + case Source::Indirect: + case Source::IndirectNoBase: + switch(base()) { + default: return Source::DS; + case Source::eBP: + case Source::eSP: return Source::SS; + case Source::eDI: return Source::ES; + } + } + } + template constexpr Source base() const { if constexpr (obscure_indirectNoBase) { return (source_ <= Source::IndirectNoBase) ? Source::None : sib_.base(); diff --git a/OSBindings/Mac/Clock SignalTests/8088Tests.mm b/OSBindings/Mac/Clock SignalTests/8088Tests.mm index 3678630d8..87d74b433 100644 --- a/OSBindings/Mac/Clock SignalTests/8088Tests.mm +++ b/OSBindings/Mac/Clock SignalTests/8088Tests.mm @@ -131,14 +131,25 @@ constexpr char TestSuiteHome[] = "/Users/tharte/Projects/ProcessorTests/8088/v1" instruction.operation_size() == InstructionSet::x86::DataSize::Byte ? 2 : 4 ); - case Source::Indirect: - return (std::stringstream() << - '[' << - InstructionSet::x86::to_string(pointer.index(), data_size(instruction.address_size())) << '+' << - InstructionSet::x86::to_string(pointer.base(), data_size(instruction.address_size())) << '+' << - std::setfill('0') << std::setw(4) << std::uppercase << std::hex << instruction.offset() << 'h' << - ']' - ).str(); + case Source::Indirect: { + std::stringstream stream; + + Source segment = Source::None; + switch(instruction.data_segment()) { + default: segment = instruction.data_segment(); break; + case Source::None: segment = pointer.default_segment(); break; + } + if(segment != Source::None && segment != Source::DS) { + stream << InstructionSet::x86::to_string(segment, InstructionSet::x86::DataSize::None) << ':'; + } + + stream << '['; + stream << InstructionSet::x86::to_string(pointer.base(), data_size(instruction.address_size())) << '+'; + stream << InstructionSet::x86::to_string(pointer.index(), data_size(instruction.address_size())) << '+'; + stream << std::setfill('0') << std::setw(4) << std::uppercase << std::hex << instruction.offset() << 'h'; + stream << ']'; + return stream.str(); + } case Source::DirectAddress: return (std::stringstream() <<