From 79b126e6bb0436d1130e7ea2a1d762012636cc44 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Fri, 10 Nov 2023 22:11:52 -0500 Subject: [PATCH] Add route for tracking segment register changes. --- .../Implementation/PerformImplementation.hpp | 14 ++++++++++-- InstructionSets/x86/Instruction.hpp | 5 ++++- OSBindings/Mac/Clock SignalTests/8088Tests.mm | 22 +++++++++++++------ 3 files changed, 31 insertions(+), 10 deletions(-) diff --git a/InstructionSets/x86/Implementation/PerformImplementation.hpp b/InstructionSets/x86/Implementation/PerformImplementation.hpp index 1808366e4..26b42b168 100644 --- a/InstructionSets/x86/Implementation/PerformImplementation.hpp +++ b/InstructionSets/x86/Implementation/PerformImplementation.hpp @@ -253,7 +253,12 @@ template < return; case Operation::LEA: Primitive::lea(instruction, destination_w(), context); return; - case Operation::MOV: Primitive::mov(destination_w(), source_r()); break; + case Operation::MOV: + Primitive::mov(destination_w(), source_r()); + if constexpr (std::is_same_v) { + context.registers.did_update(instruction.destination.source()); + } + break; case Operation::JO: jcc(context.flags.template condition()); return; case Operation::JNO: jcc(!context.flags.template condition()); return; @@ -319,7 +324,12 @@ template < case Operation::XLAT: Primitive::xlat(instruction, context); return; - case Operation::POP: destination_w() = Primitive::pop(context); break; + case Operation::POP: + destination_w() = Primitive::pop(context); + if constexpr (std::is_same_v) { + context.registers.did_update(instruction.destination.source()); + } + break; case Operation::PUSH: Primitive::push(source_rmw(), context); // PUSH SP modifies SP before pushing it; // hence PUSH is sometimes read-modify-write. diff --git a/InstructionSets/x86/Instruction.hpp b/InstructionSets/x86/Instruction.hpp index 589e6d330..4fc19a297 100644 --- a/InstructionSets/x86/Instruction.hpp +++ b/InstructionSets/x86/Instruction.hpp @@ -444,7 +444,7 @@ enum class Source: uint8_t { T0 = 0, T1 = 1, T2 = 2, T3 = 3, T4 = 4, T5 = 5, T6 = 6, T7 = 7, D0 = 0, D1 = 1, D2 = 2, D3 = 3, D4 = 4, D5 = 5, D6 = 6, D7 = 7, - // Selectors. + // Segment registers. ES, CS, SS, DS, FS, GS, /// @c None can be treated as a source that produces 0 when encountered; @@ -473,6 +473,9 @@ enum class Source: uint8_t { constexpr bool is_register(Source source) { return source < Source::None; } +constexpr bool is_segment_register(Source source) { + return is_register(source) && source >= Source::ES; +} enum class Repetition: uint8_t { None, RepE, RepNE, Rep, diff --git a/OSBindings/Mac/Clock SignalTests/8088Tests.mm b/OSBindings/Mac/Clock SignalTests/8088Tests.mm index 0310acab2..0bd7a64c6 100644 --- a/OSBindings/Mac/Clock SignalTests/8088Tests.mm +++ b/OSBindings/Mac/Clock SignalTests/8088Tests.mm @@ -68,6 +68,7 @@ struct Registers { uint16_t &di() { return di_; } uint16_t es_, cs_, ds_, ss_; + uint32_t es_base_, cs_base_, ds_base_, ss_base_; uint16_t ip_; uint16_t &ip() { return ip_; } @@ -77,6 +78,17 @@ struct Registers { uint16_t &ds() { return ds_; } uint16_t &ss() { return ss_; } + using Source = InstructionSet::x86::Source; + void did_update(Source segment) { + switch(segment) { + default: break; + case Source::ES: es_base_ = es_ << 4; break; + case Source::CS: cs_base_ = cs_ << 4; break; + case Source::DS: ds_base_ = ds_ << 4; break; + case Source::SS: ss_base_ = ss_ << 4; break; + } + } + bool operator ==(const Registers &rhs) const { return ax_.full == rhs.ax_.full && @@ -395,9 +407,9 @@ struct FailedExecution { NSString *path = [NSString stringWithUTF8String:TestSuiteHome]; NSSet *allowList = [NSSet setWithArray:@[ // Current execution failures, albeit all permitted: - @"D4.json.gz", // AAM - @"F6.7.json.gz", // IDIV byte - @"F7.7.json.gz", // IDIV word +// @"D4.json.gz", // AAM +// @"F6.7.json.gz", // IDIV byte +// @"F7.7.json.gz", // IDIV word ]]; NSSet *ignoreList = nil; @@ -694,10 +706,6 @@ struct FailedExecution { failure_list = &permitted_failures; } - if(failure_list == &execution_failures) { - printf("Fail: %d\n", int(decoded.second.operation())); - } - // Record a failure. FailedExecution failure; failure.instruction = decoded.second;