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:
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
|
// 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;
|
||||||
}
|
}
|
||||||
|
@ -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_)
|
||||||
);
|
);
|
||||||
|
@ -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;
|
||||||
|
@ -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),
|
||||||
|
@ -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);
|
||||||
|
Loading…
Reference in New Issue
Block a user