From 83850d7596484e3c1d0c5ee6dcef9d39491c5de3 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Thu, 2 Nov 2023 16:55:38 -0400 Subject: [PATCH 1/2] Commute: Status -> Flags as per usual x86 naming. --- InstructionSets/x86/{Status.hpp => Flags.hpp} | 48 ++-- .../Implementation/PerformImplementation.hpp | 268 +++++++++--------- InstructionSets/x86/Perform.hpp | 4 +- .../Clock Signal.xcodeproj/project.pbxproj | 6 +- OSBindings/Mac/Clock SignalTests/8088Tests.mm | 67 ++--- 5 files changed, 197 insertions(+), 196 deletions(-) rename InstructionSets/x86/{Status.hpp => Flags.hpp} (82%) diff --git a/InstructionSets/x86/Status.hpp b/InstructionSets/x86/Flags.hpp similarity index 82% rename from InstructionSets/x86/Status.hpp rename to InstructionSets/x86/Flags.hpp index 9e6f77ffc..599dd3203 100644 --- a/InstructionSets/x86/Status.hpp +++ b/InstructionSets/x86/Flags.hpp @@ -1,19 +1,19 @@ // -// Status.hpp +// Flags.hpp // Clock Signal // // Created by Thomas Harte on 05/10/2023. // Copyright © 2023 Thomas Harte. All rights reserved. // -#ifndef InstructionSets_x86_Status_hpp -#define InstructionSets_x86_Status_hpp +#ifndef InstructionSets_x86_Flags_hpp +#define InstructionSets_x86_Flags_hpp #include "../../Numeric/Carry.hpp" namespace InstructionSet::x86 { -namespace ConditionCode { +namespace FlagValue { // // Standard flags. @@ -77,7 +77,7 @@ enum class Condition { LessOrEqual }; -class Status { +class Flags { public: using FlagT = uint32_t; @@ -156,33 +156,33 @@ class Status { // Complete value get and set. void set(uint16_t value) { - set_from(value & ConditionCode::Carry); - set_from(value & ConditionCode::AuxiliaryCarry); - set_from(value & ConditionCode::Overflow); - set_from(value & ConditionCode::Trap); - set_from(value & ConditionCode::Interrupt); - set_from(value & ConditionCode::Direction); + set_from(value & FlagValue::Carry); + set_from(value & FlagValue::AuxiliaryCarry); + set_from(value & FlagValue::Overflow); + set_from(value & FlagValue::Trap); + set_from(value & FlagValue::Interrupt); + set_from(value & FlagValue::Direction); set_from(value); - set_from((~value) & ConditionCode::Zero); - set_from((~value) & ConditionCode::Parity); + set_from((~value) & FlagValue::Zero); + set_from((~value) & FlagValue::Parity); } uint16_t get() const { return 0xf002 | - (flag() ? ConditionCode::Carry : 0) | - (flag() ? ConditionCode::AuxiliaryCarry : 0) | - (flag() ? ConditionCode::Sign : 0) | - (flag() ? ConditionCode::Overflow : 0) | - (flag() ? ConditionCode::Trap : 0) | - (flag() ? ConditionCode::Interrupt : 0) | - (flag() ? ConditionCode::Direction : 0) | - (flag() ? ConditionCode::Zero : 0) | + (flag() ? FlagValue::Carry : 0) | + (flag() ? FlagValue::AuxiliaryCarry : 0) | + (flag() ? FlagValue::Sign : 0) | + (flag() ? FlagValue::Overflow : 0) | + (flag() ? FlagValue::Trap : 0) | + (flag() ? FlagValue::Interrupt : 0) | + (flag() ? FlagValue::Direction : 0) | + (flag() ? FlagValue::Zero : 0) | - (flag() ? 0 : ConditionCode::Parity); + (flag() ? 0 : FlagValue::Parity); } std::string to_string() const { @@ -204,7 +204,7 @@ class Status { return result; } - bool operator ==(const Status &rhs) const { + bool operator ==(const Flags &rhs) const { return get() == rhs.get(); } @@ -230,4 +230,4 @@ class Status { } -#endif /* InstructionSets_x86_Status_hpp */ +#endif /* InstructionSets_x86_Flags_hpp */ diff --git a/InstructionSets/x86/Implementation/PerformImplementation.hpp b/InstructionSets/x86/Implementation/PerformImplementation.hpp index 3f84adc73..e8b0234aa 100644 --- a/InstructionSets/x86/Implementation/PerformImplementation.hpp +++ b/InstructionSets/x86/Implementation/PerformImplementation.hpp @@ -236,12 +236,12 @@ void aaa(CPU::RegisterPair16 &ax, ContextT &context) { // P. 313 The AF and CF flags are set to 1 if the adjustment results in a decimal carry; otherwise they are cleared to 0. The OF, SF, ZF, and PF flags are undefined. */ - if((ax.halves.low & 0x0f) > 9 || context.status.template flag()) { + if((ax.halves.low & 0x0f) > 9 || context.flags.template flag()) { ax.halves.low += 6; ++ax.halves.high; - context.status.template set_from(1); + context.flags.template set_from(1); } else { - context.status.template set_from(0); + context.flags.template set_from(0); } ax.halves.low &= 0x0f; } @@ -260,7 +260,7 @@ void aad(CPU::RegisterPair16 &ax, uint8_t imm, ContextT &context) { */ ax.halves.low = ax.halves.low + (ax.halves.high * imm); ax.halves.high = 0; - context.status.template set_from(ax.halves.low); + context.flags.template set_from(ax.halves.low); } template @@ -284,7 +284,7 @@ void aam(CPU::RegisterPair16 &ax, uint8_t imm, ContextT &context) { ax.halves.high = ax.halves.low / imm; ax.halves.low = ax.halves.low % imm; - context.status.template set_from(ax.halves.low); + context.flags.template set_from(ax.halves.low); } template @@ -306,12 +306,12 @@ void aas(CPU::RegisterPair16 &ax, ContextT &context) { The AF and CF flags are set to 1 if there is a decimal borrow; otherwise, they are cleared to 0. The OF, SF, ZF, and PF flags are undefined. */ - if((ax.halves.low & 0x0f) > 9 || context.status.template flag()) { + if((ax.halves.low & 0x0f) > 9 || context.flags.template flag()) { ax.halves.low -= 6; --ax.halves.high; - context.status.template set_from(1); + context.flags.template set_from(1); } else { - context.status.template set_from(0); + context.flags.template set_from(0); } ax.halves.low &= 0x0f; } @@ -347,25 +347,25 @@ void daa(uint8_t &al, ContextT &context) { The SF, ZF, and PF flags are set according to the result. The OF flag is undefined. */ const uint8_t old_al = al; - const auto old_carry = context.status.template flag(); - context.status.template set_from(0); + const auto old_carry = context.flags.template flag(); + context.flags.template set_from(0); - if((al & 0x0f) > 0x09 || context.status.template flag()) { - context.status.template set_from(old_carry | (al > 0xf9)); + if((al & 0x0f) > 0x09 || context.flags.template flag()) { + context.flags.template set_from(old_carry | (al > 0xf9)); al += 0x06; - context.status.template set_from(1); + context.flags.template set_from(1); } else { - context.status.template set_from(0); + context.flags.template set_from(0); } if(old_al > 0x99 || old_carry) { al += 0x60; - context.status.template set_from(1); + context.flags.template set_from(1); } else { - context.status.template set_from(0); + context.flags.template set_from(0); } - context.status.template set_from(al); + context.flags.template set_from(al); } template @@ -399,25 +399,25 @@ void das(uint8_t &al, ContextT &context) { The SF, ZF, and PF flags are set according to the result. The OF flag is undefined. */ const uint8_t old_al = al; - const auto old_carry = context.status.template flag(); - context.status.template set_from(0); + const auto old_carry = context.flags.template flag(); + context.flags.template set_from(0); - if((al & 0x0f) > 0x09 || context.status.template flag()) { - context.status.template set_from(old_carry | (al < 0x06)); + if((al & 0x0f) > 0x09 || context.flags.template flag()) { + context.flags.template set_from(old_carry | (al < 0x06)); al -= 0x06; - context.status.template set_from(1); + context.flags.template set_from(1); } else { - context.status.template set_from(0); + context.flags.template set_from(0); } if(old_al > 0x99 || old_carry) { al -= 0x60; - context.status.template set_from(1); + context.flags.template set_from(1); } else { - context.status.template set_from(0); + context.flags.template set_from(0); } - context.status.template set_from(al); + context.flags.template set_from(al); } template @@ -428,16 +428,16 @@ void add(IntT &destination, IntT source, ContextT &context) { /* The OF, SF, ZF, AF, CF, and PF flags are set according to the result. */ - const IntT result = destination + source + (with_carry ? context.status.template carry_bit() : 0); + const IntT result = destination + source + (with_carry ? context.flags.template carry_bit() : 0); - context.status.template set_from( + context.flags.template set_from( Numeric::carried_out() - 1>(destination, source, result)); - context.status.template set_from( + context.flags.template set_from( Numeric::carried_in<4>(destination, source, result)); - context.status.template set_from( + context.flags.template set_from( Numeric::overflow(destination, source, result)); - context.status.template set_from(result); + context.flags.template set_from(result); destination = result; } @@ -450,16 +450,16 @@ void sub(IntT &destination, IntT source, ContextT &context) { /* The OF, SF, ZF, AF, CF, and PF flags are set according to the result. */ - const IntT result = destination - source - (with_borrow ? context.status.template carry_bit() : 0); + const IntT result = destination - source - (with_borrow ? context.flags.template carry_bit() : 0); - context.status.template set_from( + context.flags.template set_from( Numeric::carried_out() - 1>(destination, source, result)); - context.status.template set_from( + context.flags.template set_from( Numeric::carried_in<4>(destination, source, result)); - context.status.template set_from( + context.flags.template set_from( Numeric::overflow(destination, source, result)); - context.status.template set_from(result); + context.flags.template set_from(result); if constexpr (write_back) { destination = result; @@ -486,8 +486,8 @@ void test(IntT &destination, IntT source, ContextT &context) { */ const IntT result = destination & source; - context.status.template set_from(0); - context.status.template set_from(result); + context.flags.template set_from(0); + context.flags.template set_from(result); } template @@ -519,7 +519,7 @@ void mul(IntT &destination_high, IntT &destination_low, IntT source, ContextT &c */ destination_high = (destination_low * source) >> (8 * sizeof(IntT)); destination_low *= source; - context.status.template set_from(destination_high); + context.flags.template set_from(destination_high); } template @@ -554,7 +554,7 @@ void imul(IntT &destination_high, IntT &destination_low, IntT source, ContextT & destination_low = IntT(sIntT(destination_low) * sIntT(source)); const auto sign_extension = (destination_low & Numeric::top_bit()) ? IntT(~0) : 0; - context.status.template set_from(destination_high != sign_extension); + context.flags.template set_from(destination_high != sign_extension); } template @@ -681,9 +681,9 @@ void inc(IntT &destination, ContextT &context) { */ ++destination; - context.status.template set_from(destination == Numeric::top_bit()); - context.status.template set_from(((destination - 1) ^ destination) & 0x10); - context.status.template set_from(destination); + context.flags.template set_from(destination == Numeric::top_bit()); + context.flags.template set_from(((destination - 1) ^ destination) & 0x10); + context.flags.template set_from(destination); } template @@ -716,7 +716,7 @@ void loop(IntT &counter, OffsetT displacement, ContextT &context) { template void loope(IntT &counter, OffsetT displacement, ContextT &context) { --counter; - if(counter && context.status.template flag()) { + if(counter && context.flags.template flag()) { context.flow_controller.jump(context.registers.ip() + displacement); } } @@ -724,7 +724,7 @@ void loope(IntT &counter, OffsetT displacement, ContextT &context) { template void loopne(IntT &counter, OffsetT displacement, ContextT &context) { --counter; - if(counter && !context.status.template flag()) { + if(counter && !context.flags.template flag()) { context.flow_controller.jump(context.registers.ip() + displacement); } } @@ -738,12 +738,12 @@ void dec(IntT &destination, ContextT &context) { The CF flag is not affected. The OF, SF, ZF, AF, and PF flags are set according to the result. */ - context.status.template set_from(destination == Numeric::top_bit()); + context.flags.template set_from(destination == Numeric::top_bit()); --destination; - context.status.template set_from(destination); - context.status.template set_from(((destination + 1) ^ destination) & 0x10); + context.flags.template set_from(destination); + context.flags.template set_from(((destination + 1) ^ destination) & 0x10); } template @@ -757,8 +757,8 @@ void and_(IntT &destination, IntT source, ContextT &context) { */ destination &= source; - context.status.template set_from(0); - context.status.template set_from(destination); + context.flags.template set_from(0); + context.flags.template set_from(destination); } template @@ -772,8 +772,8 @@ void or_(IntT &destination, IntT source, ContextT &context) { */ destination |= source; - context.status.template set_from(0); - context.status.template set_from(destination); + context.flags.template set_from(0); + context.flags.template set_from(destination); } template @@ -787,8 +787,8 @@ void xor_(IntT &destination, IntT source, ContextT &context) { */ destination ^= source; - context.status.template set_from(0); - context.status.template set_from(destination); + context.flags.template set_from(0); + context.flags.template set_from(destination); } template @@ -804,13 +804,13 @@ void neg(IntT &destination, ContextT &context) { The CF flag cleared to 0 if the source operand is 0; otherwise it is set to 1. The OF, SF, ZF, AF, and PF flags are set according to the result. */ - context.status.template set_from(Numeric::carried_in<4>(IntT(0), destination, IntT(-destination))); + context.flags.template set_from(Numeric::carried_in<4>(IntT(0), destination, IntT(-destination))); destination = -destination; - context.status.template set_from(destination); - context.status.template set_from(destination == Numeric::top_bit()); - context.status.template set_from(destination); + context.flags.template set_from(destination); + context.flags.template set_from(destination == Numeric::top_bit()); + context.flags.template set_from(destination); } template @@ -915,7 +915,7 @@ void iret(ContextT &context) { context.memory.preauthorise_stack_read(sizeof(uint16_t) * 3); const auto ip = pop(context); const auto cs = pop(context); - context.status.set(pop(context)); + context.flags.set(pop(context)); context.flow_controller.jump(cs, ip); } @@ -984,7 +984,7 @@ void mov(IntT &destination, IntT source) { template void into(ContextT &context) { - if(context.status.template flag()) { + if(context.flags.template flag()) { interrupt(Interrupt::OnOverflow, context); } } @@ -994,11 +994,11 @@ void sahf(uint8_t &ah, ContextT &context) { /* EFLAGS(SF:ZF:0:AF:0:PF:1:CF) ← AH; */ - context.status.template set_from(ah); - context.status.template set_from(!(ah & 0x40)); - context.status.template set_from(ah & 0x10); - context.status.template set_from(!(ah & 0x04)); - context.status.template set_from(ah & 0x01); + context.flags.template set_from(ah); + context.flags.template set_from(!(ah & 0x40)); + context.flags.template set_from(ah & 0x10); + context.flags.template set_from(!(ah & 0x04)); + context.flags.template set_from(ah & 0x01); } template @@ -1007,12 +1007,12 @@ void lahf(uint8_t &ah, ContextT &context) { AH ← EFLAGS(SF:ZF:0:AF:0:PF:1:CF); */ ah = - (context.status.template flag() ? 0x80 : 0x00) | - (context.status.template flag() ? 0x40 : 0x00) | - (context.status.template flag() ? 0x10 : 0x00) | - (context.status.template flag() ? 0x00 : 0x04) | + (context.flags.template flag() ? 0x80 : 0x00) | + (context.flags.template flag() ? 0x40 : 0x00) | + (context.flags.template flag() ? 0x10 : 0x00) | + (context.flags.template flag() ? 0x00 : 0x04) | 0x02 | - (context.status.template flag() ? 0x01 : 0x00); + (context.flags.template flag() ? 0x01 : 0x00); } template @@ -1034,32 +1034,32 @@ void cwd(IntT &dx, IntT ax) { // TODO: changes to the interrupt flag do quite a lot more in protected mode. template -void clc(ContextT &context) { context.status.template set_from(0); } +void clc(ContextT &context) { context.flags.template set_from(0); } template -void cld(ContextT &context) { context.status.template set_from(0); } +void cld(ContextT &context) { context.flags.template set_from(0); } template -void cli(ContextT &context) { context.status.template set_from(0); } +void cli(ContextT &context) { context.flags.template set_from(0); } template -void stc(ContextT &context) { context.status.template set_from(1); } +void stc(ContextT &context) { context.flags.template set_from(1); } template -void std(ContextT &context) { context.status.template set_from(1); } +void std(ContextT &context) { context.flags.template set_from(1); } template -void sti(ContextT &context) { context.status.template set_from(1); } +void sti(ContextT &context) { context.flags.template set_from(1); } template void cmc(ContextT &context) { - context.status.template set_from(!context.status.template flag()); + context.flags.template set_from(!context.flags.template flag()); } template void salc(uint8_t &al, ContextT &context) { - al = context.status.template flag() ? 0xff : 0x00; + al = context.flags.template flag() ? 0xff : 0x00; } template void setmo(IntT &destination, ContextT &context) { destination = ~0; - context.status.template set_from(0); - context.status.template set_from(destination); + context.flags.template set_from(0); + context.flags.template set_from(destination); } template @@ -1094,7 +1094,7 @@ void rcl(IntT &destination, uint8_t count, ContextT &context) { it is undefined for multi-bit rotates. The SF, ZF, AF, and PF flags are not affected. */ const auto temp_count = count % (Numeric::bit_size() + 1); - auto carry = context.status.template carry_bit(); + auto carry = context.flags.template carry_bit(); switch(temp_count) { case 0: break; case Numeric::bit_size(): { @@ -1112,8 +1112,8 @@ void rcl(IntT &destination, uint8_t count, ContextT &context) { } break; } - context.status.template set_from(carry); - context.status.template set_from( + context.flags.template set_from(carry); + context.flags.template set_from( ((destination >> (Numeric::bit_size() - 1)) & 1) ^ carry ); } @@ -1134,8 +1134,8 @@ void rcr(IntT &destination, uint8_t count, ContextT &context) { tempCOUNT ← tempCOUNT – 1; OD; */ - auto carry = context.status.template carry_bit(); - context.status.template set_from( + auto carry = context.flags.template carry_bit(); + context.flags.template set_from( ((destination >> (Numeric::bit_size() - 1)) & 1) ^ carry ); @@ -1157,7 +1157,7 @@ void rcr(IntT &destination, uint8_t count, ContextT &context) { } break; } - context.status.template set_from(carry); + context.flags.template set_from(carry); } template @@ -1201,8 +1201,8 @@ void rol(IntT &destination, uint8_t count, ContextT &context) { (destination >> (Numeric::bit_size() - temp_count)); } - context.status.template set_from(destination & 1); - context.status.template set_from( + context.flags.template set_from(destination & 1); + context.flags.template set_from( ((destination >> (Numeric::bit_size() - 1)) ^ destination) & 1 ); } @@ -1248,8 +1248,8 @@ void ror(IntT &destination, uint8_t count, ContextT &context) { (destination << (Numeric::bit_size() - temp_count)); } - context.status.template set_from(destination & Numeric::top_bit()); - context.status.template set_from( + context.flags.template set_from(destination & Numeric::top_bit()); + context.flags.template set_from( (destination ^ (destination << 1)) & Numeric::top_bit() ); } @@ -1315,26 +1315,26 @@ void sal(IntT &destination, uint8_t count, ContextT &context) { switch(count) { case 0: return; case Numeric::bit_size(): - context.status.template set_from(destination & 1); + context.flags.template set_from(destination & 1); destination = 0; break; default: if(count > Numeric::bit_size()) { - context.status.template set_from(0); + context.flags.template set_from(0); destination = 0; } else { const auto mask = (Numeric::top_bit() >> (count - 1)); - context.status.template set_from( + context.flags.template set_from( destination & mask ); - context.status.template set_from( + context.flags.template set_from( (destination ^ (destination << 1)) & mask ); destination <<= count; } break; } - context.status.template set_from(destination); + context.flags.template set_from(destination); } template @@ -1346,14 +1346,14 @@ void sar(IntT &destination, uint8_t count, ContextT &context) { const IntT sign = Numeric::top_bit() & destination; if(count >= Numeric::bit_size()) { destination = sign ? IntT(~0) : IntT(0); - context.status.template set_from(sign); + context.flags.template set_from(sign); } else { const IntT mask = 1 << (count - 1); - context.status.template set_from(destination & mask); + context.flags.template set_from(destination & mask); destination = (destination >> count) | (sign ? ~(IntT(~0) >> count) : 0); } - context.status.template set_from(0); - context.status.template set_from(destination); + context.flags.template set_from(0); + context.flags.template set_from(destination); } template @@ -1362,29 +1362,29 @@ void shr(IntT &destination, uint8_t count, ContextT &context) { return; } - context.status.template set_from(Numeric::top_bit() & destination); + context.flags.template set_from(Numeric::top_bit() & destination); if(count == Numeric::bit_size()) { - context.status.template set_from(Numeric::top_bit() & destination); + context.flags.template set_from(Numeric::top_bit() & destination); destination = 0; } else if(count > Numeric::bit_size()) { - context.status.template set_from(0); + context.flags.template set_from(0); destination = 0; } else { const IntT mask = 1 << (count - 1); - context.status.template set_from(destination & mask); + context.flags.template set_from(destination & mask); destination >>= count; } - context.status.template set_from(destination); + context.flags.template set_from(destination); } template void popf(ContextT &context) { - context.status.set(pop(context)); + context.flags.set(pop(context)); } template void pushf(ContextT &context) { - uint16_t value = context.status.get(); + uint16_t value = context.flags.get(); push(value, context); } @@ -1403,7 +1403,7 @@ void repeat(AddressT &eCX, ContextT &context) { } if constexpr (repetition != Repetition::Rep) { // If this is RepE or RepNE, also test the zero flag. - if((repetition == Repetition::RepNE) == context.status.template flag()) { + if((repetition == Repetition::RepNE) == context.flags.template flag()) { return; } } @@ -1418,8 +1418,8 @@ void cmps(const InstructionT &instruction, AddressT &eCX, AddressT &eSI, Address IntT lhs = context.memory.template access(instruction.data_segment(), eSI); const IntT rhs = context.memory.template access(Source::ES, eDI); - eSI += context.status.template direction() * sizeof(IntT); - eDI += context.status.template direction() * sizeof(IntT); + eSI += context.flags.template direction() * sizeof(IntT); + eDI += context.flags.template direction() * sizeof(IntT); Primitive::sub(lhs, rhs, context); @@ -1433,7 +1433,7 @@ void scas(AddressT &eCX, AddressT &eDI, IntT &eAX, ContextT &context) { } const IntT rhs = context.memory.template access(Source::ES, eDI); - eDI += context.status.template direction() * sizeof(IntT); + eDI += context.flags.template direction() * sizeof(IntT); Primitive::sub(eAX, rhs, context); @@ -1447,7 +1447,7 @@ void lods(const InstructionT &instruction, AddressT &eCX, AddressT &eSI, IntT &e } eAX = context.memory.template access(instruction.data_segment(), eSI); - eSI += context.status.template direction() * sizeof(IntT); + eSI += context.flags.template direction() * sizeof(IntT); repeat(eCX, context); } @@ -1461,8 +1461,8 @@ void movs(const InstructionT &instruction, AddressT &eCX, AddressT &eSI, Address context.memory.template access(Source::ES, eDI) = context.memory.template access(instruction.data_segment(), eSI); - eSI += context.status.template direction() * sizeof(IntT); - eDI += context.status.template direction() * sizeof(IntT); + eSI += context.flags.template direction() * sizeof(IntT); + eDI += context.flags.template direction() * sizeof(IntT); repeat(eCX, context); } @@ -1474,7 +1474,7 @@ void stos(AddressT &eCX, AddressT &eDI, IntT &eAX, ContextT &context) { } context.memory.template access(Source::ES, eDI) = eAX; - eDI += context.status.template direction() * sizeof(IntT); + eDI += context.flags.template direction() * sizeof(IntT); repeat(eCX, context); } @@ -1489,7 +1489,7 @@ void outs(const InstructionT &instruction, AddressT &eCX, uint16_t port, Address port, context.memory.template access(instruction.data_segment(), eSI) ); - eSI += context.status.template direction() * sizeof(IntT); + eSI += context.flags.template direction() * sizeof(IntT); repeat(eCX, context); } @@ -1501,7 +1501,7 @@ void ins(AddressT &eCX, uint16_t port, AddressT &eDI, ContextT &context) { } context.memory.template access(Source::ES, eDI) = context.io.template in(port); - eDI += context.status.template direction() * sizeof(IntT); + eDI += context.flags.template direction() * sizeof(IntT); repeat(eCX, context); } @@ -1722,22 +1722,22 @@ template < case Operation::LEA: Primitive::lea(instruction, destination_w(), context); return; case Operation::MOV: Primitive::mov(destination_w(), source_r()); break; - case Operation::JO: jcc(context.status.template condition()); return; - case Operation::JNO: jcc(!context.status.template condition()); return; - case Operation::JB: jcc(context.status.template condition()); return; - case Operation::JNB: jcc(!context.status.template condition()); return; - case Operation::JZ: jcc(context.status.template condition()); return; - case Operation::JNZ: jcc(!context.status.template condition()); return; - case Operation::JBE: jcc(context.status.template condition()); return; - case Operation::JNBE: jcc(!context.status.template condition()); return; - case Operation::JS: jcc(context.status.template condition()); return; - case Operation::JNS: jcc(!context.status.template condition()); return; - case Operation::JP: jcc(!context.status.template condition()); return; - case Operation::JNP: jcc(context.status.template condition()); return; - case Operation::JL: jcc(context.status.template condition()); return; - case Operation::JNL: jcc(!context.status.template condition()); return; - case Operation::JLE: jcc(context.status.template condition()); return; - case Operation::JNLE: jcc(!context.status.template condition()); return; + case Operation::JO: jcc(context.flags.template condition()); return; + case Operation::JNO: jcc(!context.flags.template condition()); return; + case Operation::JB: jcc(context.flags.template condition()); return; + case Operation::JNB: jcc(!context.flags.template condition()); return; + case Operation::JZ: jcc(context.flags.template condition()); return; + case Operation::JNZ: jcc(!context.flags.template condition()); return; + case Operation::JBE: jcc(context.flags.template condition()); return; + case Operation::JNBE: jcc(!context.flags.template condition()); return; + case Operation::JS: jcc(context.flags.template condition()); return; + case Operation::JNS: jcc(!context.flags.template condition()); return; + case Operation::JP: jcc(!context.flags.template condition()); return; + case Operation::JNP: jcc(context.flags.template condition()); return; + case Operation::JL: jcc(context.flags.template condition()); return; + case Operation::JNL: jcc(!context.flags.template condition()); return; + case Operation::JLE: jcc(context.flags.template condition()); return; + case Operation::JNLE: jcc(!context.flags.template condition()); return; case Operation::RCL: Primitive::rcl(destination_rmw(), shift_count(), context); break; case Operation::RCR: Primitive::rcr(destination_rmw(), shift_count(), context); break; @@ -1923,9 +1923,9 @@ template < const uint16_t ip = context.memory.template access(address); const uint16_t cs = context.memory.template access(address + 2); - auto flags = context.status.get(); + auto flags = context.flags.get(); Primitive::push(flags, context); - context.status.template set_from(0); + context.flags.template set_from(0); // Push CS and IP. Primitive::push(context.registers.cs(), context); diff --git a/InstructionSets/x86/Perform.hpp b/InstructionSets/x86/Perform.hpp index b72b7cf58..2b61a100b 100644 --- a/InstructionSets/x86/Perform.hpp +++ b/InstructionSets/x86/Perform.hpp @@ -11,7 +11,7 @@ #include "Instruction.hpp" #include "Model.hpp" -#include "Status.hpp" +#include "Flags.hpp" namespace InstructionSet::x86 { @@ -44,7 +44,7 @@ template < typename IOT > struct ExecutionContext { FlowControllerT flow_controller; - Status status; + Flags flags; RegistersT registers; MemoryT memory; IOT io; diff --git a/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj b/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj index a19ee3205..5f01c2ea3 100644 --- a/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj +++ b/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj @@ -1125,7 +1125,7 @@ /* Begin PBXFileReference section */ 423BDC492AB24699008E37B6 /* 8088Tests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = 8088Tests.mm; sourceTree = ""; }; - 42437B342ACF02A9006DFED1 /* Status.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Status.hpp; sourceTree = ""; }; + 42437B342ACF02A9006DFED1 /* Flags.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Flags.hpp; sourceTree = ""; }; 42437B352ACF0AA2006DFED1 /* Perform.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Perform.hpp; sourceTree = ""; }; 42437B382ACF2798006DFED1 /* PerformImplementation.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = PerformImplementation.hpp; sourceTree = ""; }; 42437B392AD07465006DFED1 /* Interrupts.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Interrupts.hpp; sourceTree = ""; }; @@ -4999,11 +4999,11 @@ 4B69DEB52AB79E4F0055B217 /* Instruction.cpp */, 4BEDA3B825B25563000C2DBD /* Decoder.hpp */, 4BEDA3DB25B2588F000C2DBD /* Instruction.hpp */, + 42437B392AD07465006DFED1 /* Interrupts.hpp */, 4BE3C69527CBC540000EAD28 /* Model.hpp */, 42437B352ACF0AA2006DFED1 /* Perform.hpp */, - 42437B342ACF02A9006DFED1 /* Status.hpp */, + 42437B342ACF02A9006DFED1 /* Flags.hpp */, 42437B372ACF2798006DFED1 /* Implementation */, - 42437B392AD07465006DFED1 /* Interrupts.hpp */, ); path = x86; sourceTree = ""; diff --git a/OSBindings/Mac/Clock SignalTests/8088Tests.mm b/OSBindings/Mac/Clock SignalTests/8088Tests.mm index f5621db6c..2e61e651e 100644 --- a/OSBindings/Mac/Clock SignalTests/8088Tests.mm +++ b/OSBindings/Mac/Clock SignalTests/8088Tests.mm @@ -21,6 +21,7 @@ #include "../../../InstructionSets/x86/Decoder.hpp" #include "../../../InstructionSets/x86/Perform.hpp" +#include "../../../InstructionSets/x86/Flags.hpp" #include "../../../Numeric/RegisterSizes.hpp" namespace { @@ -29,7 +30,7 @@ namespace { // provide their real path here. constexpr char TestSuiteHome[] = "/Users/tharte/Projects/ProcessorTests/8088/v1"; -using Status = InstructionSet::x86::Status; +using Flags = InstructionSet::x86::Flags; struct Registers { CPU::RegisterPair16 ax_; uint8_t &al() { return ax_.halves.low; } @@ -287,8 +288,8 @@ struct IO { }; class FlowController { public: - FlowController(Memory &memory, Registers ®isters, Status &status) : - memory_(memory), registers_(registers), status_(status) {} + FlowController(Memory &memory, Registers ®isters, Flags &flags) : + memory_(memory), registers_(registers), flags_(flags) {} // Requirements for perform. void jump(uint16_t address) { @@ -318,19 +319,19 @@ class FlowController { private: Memory &memory_; Registers ®isters_; - Status &status_; + Flags &flags_; bool should_repeat_ = false; }; struct ExecutionSupport { - InstructionSet::x86::Status status; + Flags flags; Registers registers; Memory memory; FlowController flow_controller; IO io; static constexpr auto model = InstructionSet::x86::Model::i8086; - ExecutionSupport(): memory(registers), flow_controller(memory, registers, status) {} + ExecutionSupport(): memory(registers), flow_controller(memory, registers, flags) {} void clear() { memory.clear(); @@ -494,7 +495,7 @@ struct FailedExecution { return isEqual; } -- (void)populate:(Registers &)registers status:(InstructionSet::x86::Status &)status value:(NSDictionary *)value { +- (void)populate:(Registers &)registers flags:(Flags &)flags value:(NSDictionary *)value { registers.ax_.full = [value[@"ax"] intValue]; registers.bx_.full = [value[@"bx"] intValue]; registers.cx_.full = [value[@"cx"] intValue]; @@ -510,25 +511,25 @@ struct FailedExecution { registers.ss_ = [value[@"ss"] intValue]; registers.ip_ = [value[@"ip"] intValue]; - const uint16_t flags = [value[@"flags"] intValue]; - status.set(flags); + const uint16_t flags_value = [value[@"flags"] intValue]; + flags.set(flags_value); // Apply a quick test of flag packing/unpacking. constexpr auto defined_flags = static_cast( - InstructionSet::x86::ConditionCode::Carry | - InstructionSet::x86::ConditionCode::Parity | - InstructionSet::x86::ConditionCode::AuxiliaryCarry | - InstructionSet::x86::ConditionCode::Zero | - InstructionSet::x86::ConditionCode::Sign | - InstructionSet::x86::ConditionCode::Trap | - InstructionSet::x86::ConditionCode::Interrupt | - InstructionSet::x86::ConditionCode::Direction | - InstructionSet::x86::ConditionCode::Overflow + InstructionSet::x86::FlagValue::Carry | + InstructionSet::x86::FlagValue::Parity | + InstructionSet::x86::FlagValue::AuxiliaryCarry | + InstructionSet::x86::FlagValue::Zero | + InstructionSet::x86::FlagValue::Sign | + InstructionSet::x86::FlagValue::Trap | + InstructionSet::x86::FlagValue::Interrupt | + InstructionSet::x86::FlagValue::Direction | + InstructionSet::x86::FlagValue::Overflow ); - XCTAssert((status.get() & defined_flags) == (flags & defined_flags), - "Set status of %04x was returned as %04x", - flags & defined_flags, - (status.get() & defined_flags) + XCTAssert((flags.get() & defined_flags) == (flags_value & defined_flags), + "Set flags of %04x was returned as %04x", + flags_value & defined_flags, + (flags.get() & defined_flags) ); } @@ -544,7 +545,7 @@ struct FailedExecution { NSDictionary *const final_state = test[@"final"]; // Apply initial state. - InstructionSet::x86::Status initial_status; + Flags initial_flags; for(NSArray *ram in initial_state[@"ram"]) { execution_support.memory.seed([ram[0] intValue], [ram[1] intValue]); } @@ -552,8 +553,8 @@ struct FailedExecution { execution_support.memory.touch([ram[0] intValue]); } Registers initial_registers; - [self populate:initial_registers status:initial_status value:initial_state[@"regs"]]; - execution_support.status = initial_status; + [self populate:initial_registers flags:initial_flags value:initial_state[@"regs"]]; + execution_support.flags = initial_flags; execution_support.registers = initial_registers; // Execute instruction. @@ -571,7 +572,7 @@ struct FailedExecution { // Compare final state. Registers intended_registers; - InstructionSet::x86::Status intended_status; + InstructionSet::x86::Flags intended_flags; bool ramEqual = true; int mask_position = 0; @@ -602,21 +603,21 @@ struct FailedExecution { break; } - [self populate:intended_registers status:intended_status value:final_state[@"regs"]]; + [self populate:intended_registers flags:intended_flags value:final_state[@"regs"]]; const bool registersEqual = intended_registers == execution_support.registers; - const bool statusEqual = (intended_status.get() & flags_mask) == (execution_support.status.get() & flags_mask); + const bool flagsEqual = (intended_flags.get() & flags_mask) == (execution_support.flags.get() & flags_mask); - if(!statusEqual || !registersEqual || !ramEqual) { + if(!flagsEqual || !registersEqual || !ramEqual) { FailedExecution failure; failure.instruction = decoded.second; failure.test_name = std::string([test[@"name"] UTF8String]); NSMutableArray *reasons = [[NSMutableArray alloc] init]; - if(!statusEqual) { - Status difference; - difference.set((intended_status.get() ^ execution_support.status.get()) & flags_mask); + if(!flagsEqual) { + Flags difference; + difference.set((intended_flags.get() ^ execution_support.flags.get()) & flags_mask); [reasons addObject: - [NSString stringWithFormat:@"status differs; errors in %s", + [NSString stringWithFormat:@"flags differs; errors in %s", difference.to_string().c_str()]]; } if(!registersEqual) { From ebdf10525c779a4ac621a0972c9aca871f459958 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Thu, 2 Nov 2023 17:00:22 -0400 Subject: [PATCH 2/2] Fix parameter case. --- .../x86/Implementation/PerformImplementation.hpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/InstructionSets/x86/Implementation/PerformImplementation.hpp b/InstructionSets/x86/Implementation/PerformImplementation.hpp index e8b0234aa..0971685c4 100644 --- a/InstructionSets/x86/Implementation/PerformImplementation.hpp +++ b/InstructionSets/x86/Implementation/PerformImplementation.hpp @@ -191,18 +191,18 @@ namespace Primitive { // The below takes a reference in order properly to handle PUSH SP, // which should place the value of SP after the push onto the stack. -template +template void push(IntT &value, ContextT &context) { context.registers.sp_ -= sizeof(IntT); - context.memory.template access( + context.memory.template access( Source::SS, context.registers.sp_) = value; context.memory.template write_back(); } -template +template IntT pop(ContextT &context) { - const auto value = context.memory.template access( + const auto value = context.memory.template access( Source::SS, context.registers.sp_); context.registers.sp_ += sizeof(IntT);