diff --git a/InstructionSets/x86/Instruction.cpp b/InstructionSets/x86/Instruction.cpp index 4fc91ebb4..403904890 100644 --- a/InstructionSets/x86/Instruction.cpp +++ b/InstructionSets/x86/Instruction.cpp @@ -142,6 +142,24 @@ std::string InstructionSet::x86::to_string(Operation operation, DataSize size) { } } +bool InstructionSet::x86::mnemonic_implies_data_size(Operation operation) { + switch(operation) { + default: return false; + + case Operation::CMPS: + case Operation::LODS: + case Operation::MOVS: + case Operation::SCAS: + case Operation::STOS: + return true; + } +} + +std::string InstructionSet::x86::to_string(DataSize size) { + constexpr char sizes[][6] = { "byte", "word", "dword", "?" }; + return sizes[static_cast(size)]; +} + std::string InstructionSet::x86::to_string(Source source, DataSize size) { switch(source) { case Source::eAX: { diff --git a/InstructionSets/x86/Instruction.hpp b/InstructionSets/x86/Instruction.hpp index 9808ded0e..8e771a472 100644 --- a/InstructionSets/x86/Instruction.hpp +++ b/InstructionSets/x86/Instruction.hpp @@ -399,6 +399,7 @@ constexpr int num_operands(Operation operation) { case Operation::DAA: case Operation::DAS: case Operation::CBW: case Operation::CWD: case Operation::INTO: + case Operation::PUSHF: case Operation::POPF: case Operation::Invalid: return 0; } @@ -419,6 +420,8 @@ constexpr int bit_size(DataSize size) { return (8 << int(size)) & 0x3f; } std::string to_string(Operation, DataSize); +std::string to_string(DataSize); +bool mnemonic_implies_data_size(Operation); enum class AddressSize: uint8_t { b16 = 0, diff --git a/OSBindings/Mac/Clock SignalTests/8088Tests.mm b/OSBindings/Mac/Clock SignalTests/8088Tests.mm index 87d74b433..4b8afafa5 100644 --- a/OSBindings/Mac/Clock SignalTests/8088Tests.mm +++ b/OSBindings/Mac/Clock SignalTests/8088Tests.mm @@ -131,32 +131,36 @@ constexpr char TestSuiteHome[] = "/Users/tharte/Projects/ProcessorTests/8088/v1" instruction.operation_size() == InstructionSet::x86::DataSize::Byte ? 2 : 4 ); + case Source::DirectAddress: 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) << ':'; + if(!InstructionSet::x86::mnemonic_implies_data_size(instruction.operation)) { + stream << InstructionSet::x86::to_string(instruction.operation_size()) << ' '; } + Source segment = instruction.data_segment(); + if(segment == Source::None) { + segment = pointer.default_segment(); + 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'; + if(source == Source::Indirect) { + stream << InstructionSet::x86::to_string(pointer.base(), data_size(instruction.address_size())); + stream << '+' << InstructionSet::x86::to_string(pointer.index(), data_size(instruction.address_size())); + if(instruction.offset()) { + stream << '+' << std::setfill('0') << std::setw(4) << std::uppercase << std::hex << instruction.offset() << 'h'; + } + } else { + stream << to_hex(instruction.operand(), 4); + } stream << ']'; return stream.str(); } - - case Source::DirectAddress: - return (std::stringstream() << - '[' << - to_hex(instruction.operand(), 4) << - ']' - ).str(); } return operand;