1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-11-26 23:52:26 +00:00

Simplify address size semantics.

Since it'll no longer be a mode-dependant toggle, but a fully-retained value.
This commit is contained in:
Thomas Harte 2022-03-01 17:29:26 -05:00
parent 5e7a142ff1
commit 8ee62b4789
5 changed files with 29 additions and 21 deletions

View File

@ -245,7 +245,7 @@ uint32_t DataPointerResolver<model, RegistersT, MemoryT>::effective_address(
// fields and to help to explore the best breakdown of storage // fields and to help to explore the best breakdown of storage
// within Instruction. // within Instruction.
constexpr uint32_t memory_masks[] = {0x0000'ffff, 0xffff'ffff}; constexpr uint32_t memory_masks[] = {0x0000'ffff, 0xffff'ffff};
const uint32_t memory_mask = memory_masks[instruction.address_size_is_32()]; const uint32_t memory_mask = memory_masks[int(instruction.address_size())];
address = (address & memory_mask) + (base & memory_mask) + instruction.displacement(); address = (address & memory_mask) + (base & memory_mask) + instruction.displacement();
return address; return address;
} }

View File

@ -179,10 +179,10 @@ std::pair<int, typename Decoder<model>::InstructionT> Decoder<model>::decode(con
RequiresMin(i80286); RequiresMin(i80286);
MemRegReg(ARPL, MemReg_Reg, 2); MemRegReg(ARPL, MemReg_Reg, 2);
break; break;
case 0x67: // case 0x67:
RequiresMin(i80386); // RequiresMin(i80386);
address_size_ = true; // address_size_ = true;
break; // break;
case 0x6c: // INSB case 0x6c: // INSB
RequiresMin(i80186); RequiresMin(i80186);
Complete(INS, None, None, 1); Complete(INS, None, None, 1);
@ -710,7 +710,7 @@ std::pair<int, typename Decoder<model>::InstructionT> Decoder<model>::decode(con
address_size_, address_size_,
segment_override_, segment_override_,
repetition_, repetition_,
Size(operation_size_), DataSize(operation_size_),
displacement_, displacement_,
operand_) operand_)
); );

View File

@ -148,7 +148,7 @@ template <Model model> class Decoder {
// Prefix capture fields. // Prefix capture fields.
Repetition repetition_ = Repetition::None; Repetition repetition_ = Repetition::None;
bool lock_ = false; bool lock_ = false;
bool address_size_ = false; AddressSize address_size_ = AddressSize::b16;
Source segment_override_ = Source::None; Source segment_override_ = Source::None;
/// Resets size capture and all fields with default values. /// Resets size capture and all fields with default values.
@ -157,7 +157,7 @@ template <Model model> class Decoder {
displacement_size_ = operand_size_ = 0; displacement_size_ = operand_size_ = 0;
displacement_ = operand_ = 0; displacement_ = operand_ = 0;
lock_ = false; lock_ = false;
address_size_ = false; address_size_ = AddressSize::b16;
segment_override_ = Source::None; segment_override_ = Source::None;
repetition_ = Repetition::None; repetition_ = Repetition::None;
phase_ = Phase::Instruction; phase_ = Phase::Instruction;

View File

@ -321,11 +321,16 @@ enum class Operation: uint8_t {
LODSD, LODSD,
}; };
enum class Size: uint8_t { enum class DataSize: uint8_t {
Implied = 0, Implied = 0,
Byte = 1, Byte = 1,
Word = 2, Word = 2,
DWord = 4, DWord = 3,
};
enum class AddressSize: uint8_t {
b16 = 0,
b32 = 1,
}; };
enum class Source: uint8_t { enum class Source: uint8_t {
@ -563,7 +568,7 @@ template<bool is_32bit> class Instruction {
// Fields yet to be properly incorporated... // Fields yet to be properly incorporated...
ScaleIndexBase sib_; ScaleIndexBase sib_;
bool address_size_ = false; AddressSize address_size_ = AddressSize::b16;
public: public:
/// @returns The number of bytes used for meaningful content within this class. A receiver must use at least @c sizeof(Instruction) bytes /// @returns The number of bytes used for meaningful content within this class. A receiver must use at least @c sizeof(Instruction) bytes
@ -574,7 +579,10 @@ template<bool is_32bit> class Instruction {
DataPointer source() const { return DataPointer(Source(sources_ & 0x3f), sib_); } DataPointer source() const { return DataPointer(Source(sources_ & 0x3f), sib_); }
DataPointer destination() const { return DataPointer(Source((sources_ >> 6) & 0x3f), sib_); } DataPointer destination() const { return DataPointer(Source((sources_ >> 6) & 0x3f), sib_); }
bool lock() const { return sources_ & 0x8000; } bool lock() const { return sources_ & 0x8000; }
bool address_size_is_32() const { return address_size_; }
AddressSize address_size() const {
return AddressSize(address_size_);
}
Source data_segment() const { Source data_segment() const {
const auto segment_override = Source((sources_ >> 12) & 7); const auto segment_override = Source((sources_ >> 12) & 7);
if(segment_override != Source::None) return segment_override; if(segment_override != Source::None) return segment_override;
@ -584,7 +592,7 @@ template<bool is_32bit> class Instruction {
} }
Repetition repetition() const { return Repetition(repetition_size_ & 3); } Repetition repetition() const { return Repetition(repetition_size_ & 3); }
Size operation_size() const { return Size(repetition_size_ >> 2); } DataSize operation_size() const { return DataSize(repetition_size_ >> 2); }
// TODO: confirm whether far call for some reason makes these 32-bit in protected mode. // TODO: confirm whether far call for some reason makes these 32-bit in protected mode.
uint16_t segment() const { return uint16_t(operand_); } uint16_t segment() const { return uint16_t(operand_); }
@ -600,10 +608,10 @@ template<bool is_32bit> class Instruction {
Source destination, Source destination,
ScaleIndexBase sib, ScaleIndexBase sib,
bool lock, bool lock,
bool address_size, AddressSize address_size,
Source segment_override, Source segment_override,
Repetition repetition, Repetition repetition,
Size operation_size, DataSize operation_size,
DisplacementT displacement, DisplacementT displacement,
ImmediateT operand) noexcept : ImmediateT operand) noexcept :
operation(operation), operation(operation),

View File

@ -20,13 +20,13 @@ using Operation = InstructionSet::x86::Operation;
using Instruction = InstructionSet::x86::Instruction<false>; using Instruction = InstructionSet::x86::Instruction<false>;
using Model = InstructionSet::x86::Model; using Model = InstructionSet::x86::Model;
using Source = InstructionSet::x86::Source; using Source = InstructionSet::x86::Source;
using Size = InstructionSet::x86::Size; using Size = InstructionSet::x86::DataSize;
using ScaleIndexBase = InstructionSet::x86::ScaleIndexBase; using ScaleIndexBase = InstructionSet::x86::ScaleIndexBase;
// MARK: - Specific instruction asserts. // MARK: - Specific instruction asserts.
template <typename InstructionT> void test(const InstructionT &instruction, int size, Operation operation) { template <typename InstructionT> void test(const InstructionT &instruction, int size, Operation operation) {
XCTAssertEqual(instruction.operation_size(), InstructionSet::x86::Size(size)); XCTAssertEqual(instruction.operation_size(), InstructionSet::x86::DataSize(size));
XCTAssertEqual(instruction.operation, operation); XCTAssertEqual(instruction.operation, operation);
} }
@ -39,7 +39,7 @@ template <typename InstructionT> void test(
std::optional<typename InstructionT::ImmediateT> operand = std::nullopt, std::optional<typename InstructionT::ImmediateT> operand = std::nullopt,
std::optional<typename InstructionT::DisplacementT> displacement = std::nullopt) { std::optional<typename InstructionT::DisplacementT> displacement = std::nullopt) {
XCTAssertEqual(instruction.operation_size(), InstructionSet::x86::Size(size)); XCTAssertEqual(instruction.operation_size(), InstructionSet::x86::DataSize(size));
XCTAssertEqual(instruction.operation, operation); XCTAssertEqual(instruction.operation, operation);
XCTAssert(instruction.source() == source); XCTAssert(instruction.source() == source);
if(destination) XCTAssert(instruction.destination() == *destination); if(destination) XCTAssert(instruction.destination() == *destination);