From ef5ee8cf947335833e3933099aa3715e0ba594b0 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Fri, 29 Sep 2023 14:57:08 -0400 Subject: [PATCH] Include missing context on JMP/CALL far. Zero failing tests amongst official opcodes. --- InstructionSets/x86/Decoder.cpp | 1 + InstructionSets/x86/Instruction.cpp | 5 ++--- InstructionSets/x86/Instruction.hpp | 4 ++-- OSBindings/Mac/Clock SignalTests/8088Tests.mm | 19 ++++++++++++------- 4 files changed, 17 insertions(+), 12 deletions(-) diff --git a/InstructionSets/x86/Decoder.cpp b/InstructionSets/x86/Decoder.cpp index cab0fa04b..20efb3a0d 100644 --- a/InstructionSets/x86/Decoder.cpp +++ b/InstructionSets/x86/Decoder.cpp @@ -95,6 +95,7 @@ std::pair::InstructionT> Decoder::decode(con SetOperation(Operation::op); \ phase_ = Phase::DisplacementOrOperand; \ operand_size_ = DataSize::Word; \ + destination_ = Source::Immediate; \ displacement_size_ = data_size(default_address_size_) /// Handles ENTER — a fixed three-byte operation. diff --git a/InstructionSets/x86/Instruction.cpp b/InstructionSets/x86/Instruction.cpp index 0f1bc62db..4b24ac47a 100644 --- a/InstructionSets/x86/Instruction.cpp +++ b/InstructionSets/x86/Instruction.cpp @@ -62,13 +62,13 @@ std::string InstructionSet::x86::to_string(Operation operation, DataSize size) { case Operation::CALLabs: return "call"; case Operation::CALLrel: return "call"; - case Operation::CALLfar: return "callf far"; + case Operation::CALLfar: return "callf"; case Operation::IRET: return "iret"; case Operation::RETfar: return "retf"; case Operation::RETnear: return "retn"; case Operation::JMPabs: return "jmp"; case Operation::JMPrel: return "jmp"; - case Operation::JMPfar: return "jmpf far"; + case Operation::JMPfar: return "jmpf"; case Operation::JCXZ: return "jcxz"; case Operation::INT: return "int"; case Operation::INTO: return "into"; @@ -155,7 +155,6 @@ bool InstructionSet::x86::mnemonic_implies_data_size(Operation operation) { case Operation::SCAS: case Operation::STOS: case Operation::JMPrel: - case Operation::JMPfar: case Operation::LEA: return true; } diff --git a/InstructionSets/x86/Instruction.hpp b/InstructionSets/x86/Instruction.hpp index 1467defcf..c70ef640b 100644 --- a/InstructionSets/x86/Instruction.hpp +++ b/InstructionSets/x86/Instruction.hpp @@ -94,7 +94,7 @@ enum class Operation: uint8_t { CALLabs, /// Relative call; see displacement(). CALLrel, - /// Far call; see the segment() and offset() fields. + /// Far call; if destination is Source::Immediate then see the segment() and offset() fields; otherwise take segment and offset by indirection. CALLfar, /// Return from interrupt. IRET, @@ -106,7 +106,7 @@ enum class Operation: uint8_t { JMPabs, /// Near jump with a relative destination. JMPrel, - /// Far jump to the indicated segment and offset. + /// Far jump; if destination is Source::Immediate then see the segment() and offset() fields; otherwise take segment and offset by indirection. JMPfar, /// Relative jump performed only if CX = 0; see the displacement. JCXZ, diff --git a/OSBindings/Mac/Clock SignalTests/8088Tests.mm b/OSBindings/Mac/Clock SignalTests/8088Tests.mm index 1efe32904..a023c10eb 100644 --- a/OSBindings/Mac/Clock SignalTests/8088Tests.mm +++ b/OSBindings/Mac/Clock SignalTests/8088Tests.mm @@ -146,9 +146,6 @@ std::string to_string( - (NSArray *)testFiles { NSString *path = [NSString stringWithUTF8String:TestSuiteHome]; NSSet *allowList = [NSSet setWithArray:@[ - // Failing CALL and JMP. -// @"FF.3.json.gz", -// @"FF.5.json.gz", ]]; // Unofficial opcodes; ignored for now. @@ -237,10 +234,18 @@ std::string to_string( case Operation::CALLfar: case Operation::JMPfar: { - operation += " 0x"; - operation += to_hex(instruction.segment(), 4, false); - operation += ":0x"; - operation += to_hex(instruction.offset(), 4, false); + switch(instruction.destination().source()) { + case Source::Immediate: + operation += " far 0x"; + operation += to_hex(instruction.segment(), 4, false); + operation += ":0x"; + operation += to_hex(instruction.offset(), 4, false); + break; + default: + operation += " "; + operation += to_string(instruction.destination(), instruction, offsetLength, immediateLength); + break; + } } break; case Operation::LDS: