1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-06-25 18:30:07 +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:
if constexpr(is_write) {
memory.template write(instruction.data_segment(), instruction.displacement(), value);
memory.template write(instruction.segment_override(), instruction.displacement(), value);
} else {
value = memory.template read<DataT>(instruction.data_segment(), instruction.displacement());
value = memory.template read<DataT>(instruction.segment_override(), instruction.displacement());
}
break;
case Source::Immediate:
@ -295,13 +295,13 @@ template <bool is_write, typename DataT> void DataPointerResolver<model, Registe
\
if constexpr (is_write) { \
memory.template write( \
instruction.data_segment(), \
instruction.segment_override(), \
address, \
value \
); \
} else { \
value = memory.template read<DataT>( \
instruction.data_segment(), \
instruction.segment_override(), \
address \
); \
} \

View File

@ -281,7 +281,7 @@ template <
// If execution has reached here then a memory fetch is required.
// Do it and exit.
segment = Source::DS; // TODO.
segment = source.segment(instruction.segment_override());
fetched_data = original_data = memory.template read<IntT>(segment, address);
return fetched_data;
};

View File

@ -383,7 +383,7 @@ std::string InstructionSet::x86::to_string(
stream << InstructionSet::x86::to_string(operation_size) << ' ';
}
Source segment = instruction.data_segment();
Source segment = instruction.segment_override();
if(segment == Source::None) {
segment = pointer.default_segment();
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 {
if constexpr (obscure_indirectNoBase) {
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,
/// or that used by stack instructions, but this function does not spend the time necessary to provide
/// the correct default for those.
Source data_segment() const {
Source segment_override() const {
if(!has_length_extension()) return Source::None;
return Source(
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
// lock jp 0xfffffff0 (from 0000000e)
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[2], DataSize::DWord, Operation::ADD, Source::Immediate, ScaleIndexBase(Source::eDI), 0x9f683aa9, -0x42);
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
// pusha
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[6], DataSize::Byte, Operation::STOS);
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[22], DataSize::DWord, Operation::LDS, ScaleIndexBase(Source::eCX), Source::eDX);
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
// movs DWORD PTR es:[edi],DWORD PTR ds:[esi]