1
0
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:
Thomas Harte 2023-10-05 17:12:38 -04:00
parent ada411c0d8
commit f411a961a3
5 changed files with 17 additions and 10 deletions

View File

@ -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 \
); \ ); \
} \ } \

View File

@ -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;
}; };

View File

@ -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) {

View File

@ -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) +

View File

@ -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]