From 6dd5628dd6f6a908c144ff80e61bfe12b008ac97 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Wed, 25 Oct 2023 11:21:11 -0400 Subject: [PATCH] Provide full pair for string conversion. --- InstructionSets/x86/Instruction.cpp | 68 +++++++++---------- InstructionSets/x86/Instruction.hpp | 2 +- OSBindings/Mac/Clock SignalTests/8088Tests.mm | 14 ++-- 3 files changed, 42 insertions(+), 42 deletions(-) diff --git a/InstructionSets/x86/Instruction.cpp b/InstructionSets/x86/Instruction.cpp index 008dbfa08..da4a40107 100644 --- a/InstructionSets/x86/Instruction.cpp +++ b/InstructionSets/x86/Instruction.cpp @@ -432,7 +432,7 @@ std::string InstructionSet::x86::to_string( template std::string InstructionSet::x86::to_string( - Instruction instruction, + std::pair> instruction, Model model, int offset_length, int immediate_length @@ -440,7 +440,7 @@ std::string InstructionSet::x86::to_string( std::string operation; // Add segment override, if any, ahead of some operations that won't otherwise print it. - switch(instruction.operation) { + switch(instruction.second.operation) { default: break; case Operation::CMPS: @@ -448,7 +448,7 @@ std::string InstructionSet::x86::to_string( case Operation::STOS: case Operation::LODS: case Operation::MOVS: - switch(instruction.segment_override()) { + switch(instruction.second.segment_override()) { default: break; case Source::ES: operation += "es "; break; case Source::CS: operation += "cs "; break; @@ -461,10 +461,10 @@ std::string InstructionSet::x86::to_string( } // Add a repetition prefix; it'll be one of 'rep', 'repe' or 'repne'. - switch(instruction.repetition()) { + switch(instruction.second.repetition()) { case Repetition::None: break; case Repetition::RepE: - switch(instruction.operation) { + switch(instruction.second.operation) { case Operation::CMPS: case Operation::SCAS: operation += "repe "; @@ -476,7 +476,7 @@ std::string InstructionSet::x86::to_string( } break; case Repetition::RepNE: - switch(instruction.operation) { + switch(instruction.second.operation) { case Operation::CMPS: case Operation::SCAS: operation += "repne "; @@ -490,38 +490,38 @@ std::string InstructionSet::x86::to_string( } // Add operation itself. - operation += to_string(instruction.operation, instruction.operation_size(), model); + operation += to_string(instruction.second.operation, instruction.second.operation_size(), model); operation += " "; // Deal with a few special cases up front. - switch(instruction.operation) { + switch(instruction.second.operation) { default: { - const int operands = max_displayed_operands(instruction.operation); - const bool displacement = has_displacement(instruction.operation); - const bool print_first = operands > 1 && instruction.destination().source() != Source::None; + const int operands = max_displayed_operands(instruction.second.operation); + const bool displacement = has_displacement(instruction.second.operation); + const bool print_first = operands > 1 && instruction.second.destination().source() != Source::None; if(print_first) { - operation += to_string(instruction.destination(), instruction, offset_length, immediate_length); + operation += to_string(instruction.second.destination(), instruction.second, offset_length, immediate_length); } - if(operands > 0 && instruction.source().source() != Source::None) { + if(operands > 0 && instruction.second.source().source() != Source::None) { if(print_first) operation += ", "; - operation += to_string(instruction.source(), instruction, offset_length, immediate_length); + operation += to_string(instruction.second.source(), instruction.second, offset_length, immediate_length); } if(displacement) { - operation += to_hex(instruction.displacement(), offset_length); + operation += to_hex(instruction.second.displacement(), offset_length); } } break; case Operation::CALLfar: case Operation::JMPfar: { - switch(instruction.destination().source()) { + switch(instruction.second.destination().source()) { case Source::Immediate: - operation += to_hex(instruction.segment(), 4, false); + operation += to_hex(instruction.second.segment(), 4, false); operation += "h:"; - operation += to_hex(instruction.offset(), 4, false); + operation += to_hex(instruction.second.offset(), 4, false); operation += "h"; break; default: - operation += to_string(instruction.destination(), instruction, offset_length, immediate_length); + operation += to_string(instruction.second.destination(), instruction.second, offset_length, immediate_length); break; } } break; @@ -529,35 +529,35 @@ std::string InstructionSet::x86::to_string( case Operation::LDS: case Operation::LES: // The test set labels the pointer type as dword, which I guess is technically accurate. // A full 32 bits will be loaded from that address in 16-bit mode. - operation += to_string(instruction.destination(), instruction, offset_length, immediate_length); + operation += to_string(instruction.second.destination(), instruction.second, offset_length, immediate_length); operation += ", "; - operation += to_string(instruction.source(), instruction, offset_length, immediate_length, InstructionSet::x86::DataSize::DWord); + operation += to_string(instruction.second.source(), instruction.second, offset_length, immediate_length, InstructionSet::x86::DataSize::DWord); break; case Operation::IN: - operation += to_string(instruction.destination(), instruction, offset_length, immediate_length); + operation += to_string(instruction.second.destination(), instruction.second, offset_length, immediate_length); operation += ", "; - switch(instruction.source().source()) { + switch(instruction.second.source().source()) { case Source::DirectAddress: - operation += to_hex(uint8_t(instruction.offset())); + operation += to_hex(uint8_t(instruction.second.offset())); break; default: - operation += to_string(instruction.source(), instruction, offset_length, immediate_length, InstructionSet::x86::DataSize::Word); + operation += to_string(instruction.second.source(), instruction.second, offset_length, immediate_length, InstructionSet::x86::DataSize::Word); break; } break; case Operation::OUT: - switch(instruction.destination().source()) { + switch(instruction.second.destination().source()) { case Source::DirectAddress: - operation += to_hex(uint8_t(instruction.offset())); + operation += to_hex(uint8_t(instruction.second.offset())); break; default: - operation += to_string(instruction.destination(), instruction, offset_length, immediate_length, InstructionSet::x86::DataSize::Word); + operation += to_string(instruction.second.destination(), instruction.second, offset_length, immediate_length, InstructionSet::x86::DataSize::Word); break; } operation += ", "; - operation += to_string(instruction.source(), instruction, offset_length, immediate_length); + operation += to_string(instruction.second.source(), instruction.second, offset_length, immediate_length); break; // Rolls and shifts list eCX as a source on the understanding that everyone knows that rolls and shifts @@ -567,18 +567,18 @@ std::string InstructionSet::x86::to_string( case Operation::SAL: case Operation::SAR: case Operation::SHR: case Operation::SETMO: case Operation::SETMOC: - operation += to_string(instruction.destination(), instruction, offset_length, immediate_length); - switch(instruction.source().source()) { + operation += to_string(instruction.second.destination(), instruction.second, offset_length, immediate_length); + switch(instruction.second.source().source()) { case Source::None: break; case Source::eCX: operation += ", cl"; break; case Source::Immediate: // Providing an immediate operand of 1 is a little future-proofing by the decoder; the '1' // is actually implicit on a real 8088. So omit it. - if(instruction.operand() == 1) break; + if(instruction.second.operand() == 1) break; [[fallthrough]]; default: operation += ", "; - operation += to_string(instruction.source(), instruction, offset_length, immediate_length); + operation += to_string(instruction.second.source(), instruction.second, offset_length, immediate_length); break; } break; @@ -597,7 +597,7 @@ std::string InstructionSet::x86::to_string( //); template std::string InstructionSet::x86::to_string( - Instruction instruction, + std::pair> instruction, Model model, int offset_length, int immediate_length diff --git a/InstructionSets/x86/Instruction.hpp b/InstructionSets/x86/Instruction.hpp index 9f8b4995b..87e5ff358 100644 --- a/InstructionSets/x86/Instruction.hpp +++ b/InstructionSets/x86/Instruction.hpp @@ -929,7 +929,7 @@ std::string to_string( /// If @c immediate_length is '2' or '4', truncates any printed immediate value to 2 or 4 digits if it is compatible with being that length. template std::string to_string( - Instruction instruction, + std::pair> instruction, Model model, int offset_length = 0, int immediate_length = 0); diff --git a/OSBindings/Mac/Clock SignalTests/8088Tests.mm b/OSBindings/Mac/Clock SignalTests/8088Tests.mm index e27e8a67b..28bee7fb8 100644 --- a/OSBindings/Mac/Clock SignalTests/8088Tests.mm +++ b/OSBindings/Mac/Clock SignalTests/8088Tests.mm @@ -398,7 +398,7 @@ struct FailedExecution { return [NSJSONSerialization JSONObjectWithData:[NSData dataWithContentsOfGZippedFile:path] options:0 error:nil]; } -- (NSString *)toString:(const InstructionSet::x86::Instruction &)instruction offsetLength:(int)offsetLength immediateLength:(int)immediateLength { +- (NSString *)toString:(const std::pair> &)instruction offsetLength:(int)offsetLength immediateLength:(int)immediateLength { const auto operation = to_string(instruction, InstructionSet::x86::Model::i8086, offsetLength, immediateLength); return [[NSString stringWithUTF8String:operation.c_str()] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]; } @@ -445,12 +445,12 @@ struct FailedExecution { // The decoder doesn't preserve the original offset length, which makes no functional difference but // does affect the way that offsets are printed in the test set. NSSet *decodings = [NSSet setWithObjects: - [self toString:decoded.second offsetLength:4 immediateLength:4], - [self toString:decoded.second offsetLength:2 immediateLength:4], - [self toString:decoded.second offsetLength:0 immediateLength:4], - [self toString:decoded.second offsetLength:4 immediateLength:2], - [self toString:decoded.second offsetLength:2 immediateLength:2], - [self toString:decoded.second offsetLength:0 immediateLength:2], + [self toString:decoded offsetLength:4 immediateLength:4], + [self toString:decoded offsetLength:2 immediateLength:4], + [self toString:decoded offsetLength:0 immediateLength:4], + [self toString:decoded offsetLength:4 immediateLength:2], + [self toString:decoded offsetLength:2 immediateLength:2], + [self toString:decoded offsetLength:0 immediateLength:2], nil]; auto compare_decoding = [&](NSString *name) -> bool {