1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-11-26 08:49:37 +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
// within Instruction.
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();
return address;
}

View File

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

View File

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

View File

@ -321,11 +321,16 @@ enum class Operation: uint8_t {
LODSD,
};
enum class Size: uint8_t {
enum class DataSize: uint8_t {
Implied = 0,
Byte = 1,
Word = 2,
DWord = 4,
DWord = 3,
};
enum class AddressSize: uint8_t {
b16 = 0,
b32 = 1,
};
enum class Source: uint8_t {
@ -563,7 +568,7 @@ template<bool is_32bit> class Instruction {
// Fields yet to be properly incorporated...
ScaleIndexBase sib_;
bool address_size_ = false;
AddressSize address_size_ = AddressSize::b16;
public:
/// @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 destination() const { return DataPointer(Source((sources_ >> 6) & 0x3f), sib_); }
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 {
const auto segment_override = Source((sources_ >> 12) & 7);
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); }
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.
uint16_t segment() const { return uint16_t(operand_); }
@ -600,10 +608,10 @@ template<bool is_32bit> class Instruction {
Source destination,
ScaleIndexBase sib,
bool lock,
bool address_size,
AddressSize address_size,
Source segment_override,
Repetition repetition,
Size operation_size,
DataSize operation_size,
DisplacementT displacement,
ImmediateT operand) noexcept :
operation(operation),

View File

@ -20,13 +20,13 @@ using Operation = InstructionSet::x86::Operation;
using Instruction = InstructionSet::x86::Instruction<false>;
using Model = InstructionSet::x86::Model;
using Source = InstructionSet::x86::Source;
using Size = InstructionSet::x86::Size;
using Size = InstructionSet::x86::DataSize;
using ScaleIndexBase = InstructionSet::x86::ScaleIndexBase;
// MARK: - Specific instruction asserts.
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);
}
@ -39,7 +39,7 @@ template <typename InstructionT> void test(
std::optional<typename InstructionT::ImmediateT> operand = 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);
XCTAssert(instruction.source() == source);
if(destination) XCTAssert(instruction.destination() == *destination);