mirror of
https://github.com/TomHarte/CLK.git
synced 2024-11-26 08:49:37 +00:00
Create a central location for avoiding segment conditionality.
This commit is contained in:
parent
ada411c0d8
commit
f411a961a3
@ -277,9 +277,9 @@ template <bool is_write, typename DataT> void DataPointerResolver<model, Registe
|
|||||||
|
|
||||||
case Source::DirectAddress:
|
case Source::DirectAddress:
|
||||||
if constexpr(is_write) {
|
if constexpr(is_write) {
|
||||||
memory.template write(instruction.data_segment(), instruction.displacement(), value);
|
memory.template write(instruction.segment_override(), instruction.displacement(), value);
|
||||||
} else {
|
} else {
|
||||||
value = memory.template read<DataT>(instruction.data_segment(), instruction.displacement());
|
value = memory.template read<DataT>(instruction.segment_override(), instruction.displacement());
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case Source::Immediate:
|
case Source::Immediate:
|
||||||
@ -295,13 +295,13 @@ template <bool is_write, typename DataT> void DataPointerResolver<model, Registe
|
|||||||
\
|
\
|
||||||
if constexpr (is_write) { \
|
if constexpr (is_write) { \
|
||||||
memory.template write( \
|
memory.template write( \
|
||||||
instruction.data_segment(), \
|
instruction.segment_override(), \
|
||||||
address, \
|
address, \
|
||||||
value \
|
value \
|
||||||
); \
|
); \
|
||||||
} else { \
|
} else { \
|
||||||
value = memory.template read<DataT>( \
|
value = memory.template read<DataT>( \
|
||||||
instruction.data_segment(), \
|
instruction.segment_override(), \
|
||||||
address \
|
address \
|
||||||
); \
|
); \
|
||||||
} \
|
} \
|
||||||
|
@ -281,7 +281,7 @@ template <
|
|||||||
|
|
||||||
// If execution has reached here then a memory fetch is required.
|
// If execution has reached here then a memory fetch is required.
|
||||||
// Do it and exit.
|
// Do it and exit.
|
||||||
segment = Source::DS; // TODO.
|
segment = source.segment(instruction.segment_override());
|
||||||
fetched_data = original_data = memory.template read<IntT>(segment, address);
|
fetched_data = original_data = memory.template read<IntT>(segment, address);
|
||||||
return fetched_data;
|
return fetched_data;
|
||||||
};
|
};
|
||||||
|
@ -383,7 +383,7 @@ std::string InstructionSet::x86::to_string(
|
|||||||
stream << InstructionSet::x86::to_string(operation_size) << ' ';
|
stream << InstructionSet::x86::to_string(operation_size) << ' ';
|
||||||
}
|
}
|
||||||
|
|
||||||
Source segment = instruction.data_segment();
|
Source segment = instruction.segment_override();
|
||||||
if(segment == Source::None) {
|
if(segment == Source::None) {
|
||||||
segment = pointer.default_segment();
|
segment = pointer.default_segment();
|
||||||
if(segment == Source::None) {
|
if(segment == Source::None) {
|
||||||
|
@ -625,6 +625,13 @@ class DataPointer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
constexpr Source segment(Source segment_override) const {
|
||||||
|
// TODO: remove conditionaluty here.
|
||||||
|
if(segment_override != Source::None) return segment_override;
|
||||||
|
if(const auto segment = default_segment(); segment != Source::None) return segment;
|
||||||
|
return Source::DS;
|
||||||
|
}
|
||||||
|
|
||||||
template <bool obscure_indirectNoBase = false> constexpr Source base() const {
|
template <bool obscure_indirectNoBase = false> constexpr Source base() const {
|
||||||
if constexpr (obscure_indirectNoBase) {
|
if constexpr (obscure_indirectNoBase) {
|
||||||
return (source_ <= Source::IndirectNoBase) ? Source::None : sib_.base();
|
return (source_ <= Source::IndirectNoBase) ? Source::None : sib_.base();
|
||||||
@ -766,7 +773,7 @@ template<bool is_32bit> class Instruction {
|
|||||||
/// On x86 a segment override cannot modify the segment used as a destination in string instructions,
|
/// On x86 a segment override cannot modify the segment used as a destination in string instructions,
|
||||||
/// or that used by stack instructions, but this function does not spend the time necessary to provide
|
/// or that used by stack instructions, but this function does not spend the time necessary to provide
|
||||||
/// the correct default for those.
|
/// the correct default for those.
|
||||||
Source data_segment() const {
|
Source segment_override() const {
|
||||||
if(!has_length_extension()) return Source::None;
|
if(!has_length_extension()) return Source::None;
|
||||||
return Source(
|
return Source(
|
||||||
int(Source::ES) +
|
int(Source::ES) +
|
||||||
|
@ -411,7 +411,7 @@ decode(const std::initializer_list<uint8_t> &stream, bool set_32_bit = false) {
|
|||||||
// add DWORD PTR [edi-0x42],0x9f683aa9
|
// add DWORD PTR [edi-0x42],0x9f683aa9
|
||||||
// lock jp 0xfffffff0 (from 0000000e)
|
// lock jp 0xfffffff0 (from 0000000e)
|
||||||
test(instructions[0], DataSize::DWord, Operation::INC, Source::eDX);
|
test(instructions[0], DataSize::DWord, Operation::INC, Source::eDX);
|
||||||
XCTAssertEqual(instructions[0].data_segment(), Source::CS);
|
XCTAssertEqual(instructions[0].segment_override(), Source::CS);
|
||||||
test(instructions[1], DataSize::Byte, Operation::OR, Source::Immediate, Source::eAX, 0x9);
|
test(instructions[1], DataSize::Byte, Operation::OR, Source::Immediate, Source::eAX, 0x9);
|
||||||
test(instructions[2], DataSize::DWord, Operation::ADD, Source::Immediate, ScaleIndexBase(Source::eDI), 0x9f683aa9, -0x42);
|
test(instructions[2], DataSize::DWord, Operation::ADD, Source::Immediate, ScaleIndexBase(Source::eDI), 0x9f683aa9, -0x42);
|
||||||
test(instructions[3], Operation::JP, 0, -30);
|
test(instructions[3], Operation::JP, 0, -30);
|
||||||
@ -422,7 +422,7 @@ decode(const std::initializer_list<uint8_t> &stream, bool set_32_bit = false) {
|
|||||||
// stos BYTE PTR es:[edi],al
|
// stos BYTE PTR es:[edi],al
|
||||||
// pusha
|
// pusha
|
||||||
test(instructions[4], DataSize::Byte, Operation::MOV, Source::Immediate, Source::AH, 0xc1);
|
test(instructions[4], DataSize::Byte, Operation::MOV, Source::Immediate, Source::AH, 0xc1);
|
||||||
XCTAssertEqual(instructions[4].data_segment(), Source::DS);
|
XCTAssertEqual(instructions[4].segment_override(), Source::DS);
|
||||||
test(instructions[5], DataSize::Word, Operation::POP, Source::None, Source::DS);
|
test(instructions[5], DataSize::Word, Operation::POP, Source::None, Source::DS);
|
||||||
test(instructions[6], DataSize::Byte, Operation::STOS);
|
test(instructions[6], DataSize::Byte, Operation::STOS);
|
||||||
test(instructions[7], Operation::PUSHA);
|
test(instructions[7], Operation::PUSHA);
|
||||||
@ -465,7 +465,7 @@ decode(const std::initializer_list<uint8_t> &stream, bool set_32_bit = false) {
|
|||||||
test(instructions[21], DataSize::Byte, Operation::XOR, Source::Immediate, Source::eAX, 0x45);
|
test(instructions[21], DataSize::Byte, Operation::XOR, Source::Immediate, Source::eAX, 0x45);
|
||||||
test(instructions[22], DataSize::DWord, Operation::LDS, ScaleIndexBase(Source::eCX), Source::eDX);
|
test(instructions[22], DataSize::DWord, Operation::LDS, ScaleIndexBase(Source::eCX), Source::eDX);
|
||||||
test(instructions[23], DataSize::Byte, Operation::MOV, Source::eAX, Source::DirectAddress, 0xe4dba6d3);
|
test(instructions[23], DataSize::Byte, Operation::MOV, Source::eAX, Source::DirectAddress, 0xe4dba6d3);
|
||||||
XCTAssertEqual(instructions[23].data_segment(), Source::DS);
|
XCTAssertEqual(instructions[23].segment_override(), Source::DS);
|
||||||
|
|
||||||
// pop ds
|
// pop ds
|
||||||
// movs DWORD PTR es:[edi],DWORD PTR ds:[esi]
|
// movs DWORD PTR es:[edi],DWORD PTR ds:[esi]
|
||||||
|
Loading…
Reference in New Issue
Block a user