mirror of
https://github.com/TomHarte/CLK.git
synced 2024-11-22 12:33:29 +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:
parent
5e7a142ff1
commit
8ee62b4789
@ -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;
|
||||
}
|
||||
|
@ -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_)
|
||||
);
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
@ -572,10 +577,13 @@ template<bool is_32bit> class Instruction {
|
||||
size_t packing_size() const { return sizeof(*this); /* TODO */ }
|
||||
|
||||
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_; }
|
||||
Source data_segment() const {
|
||||
DataPointer destination() const { return DataPointer(Source((sources_ >> 6) & 0x3f), sib_); }
|
||||
bool lock() const { return sources_ & 0x8000; }
|
||||
|
||||
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),
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user