1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-06-25 18:30:07 +00:00

Simplify flow slightly; uncover issues in CMPSW.

This commit is contained in:
Thomas Harte 2023-10-20 16:52:47 -04:00
parent efb854ddfa
commit a71db54212
2 changed files with 31 additions and 22 deletions

View File

@ -1395,31 +1395,20 @@ void repeat(const InstructionT &instruction, Status &status, RegistersT &registe
}
template <typename IntT, typename AddressT, typename InstructionT, typename MemoryT, typename RegistersT, typename FlowControllerT>
void cmps(const InstructionT &instruction, MemoryT &memory, RegistersT &registers, Status &status, FlowControllerT &flow_controller) {
void cmps(const InstructionT &instruction, AddressT &eSI, AddressT &eDI, MemoryT &memory, RegistersT &registers, Status &status, FlowControllerT &flow_controller) {
if(repetition_over<AddressT>(instruction, registers)) {
return;
}
Source source_segment = instruction.segment_override();
if(source_segment == Source::None) {
source_segment = Source::DS;
} else {
printf("");
}
if(source_segment == Source::None) source_segment = Source::DS;
if constexpr (std::is_same_v<AddressT, uint16_t>) {
IntT lhs = memory.template access<IntT>(source_segment, registers.si());
IntT rhs = memory.template access<IntT>(Source::ES, registers.di());
Primitive::sub<false, false>(lhs, rhs, status);
registers.si() += status.direction<AddressT>();
registers.di() += status.direction<AddressT>();
} else {
IntT lhs = memory.template access<IntT>(source_segment, registers.esi());
IntT rhs = memory.template access<IntT>(Source::ES, registers.edi());
Primitive::sub<false, false>(lhs, rhs, status);
registers.esi() += status.direction<AddressT>();
registers.edi() += status.direction<AddressT>();
}
IntT lhs = memory.template access<IntT>(source_segment, eSI);
const IntT rhs = memory.template access<IntT>(Source::ES, eDI);
eSI += status.direction<AddressT>();
eDI += status.direction<AddressT>();
Primitive::sub<false, false>(lhs, rhs, status);
repeat<AddressT>(instruction, status, registers, flow_controller);
}
@ -1443,7 +1432,7 @@ template <
[[maybe_unused]] IOT &io
) {
using IntT = typename DataSizeType<data_size>::type;
// using AddressT = typename AddressT<is_32bit(model)>::type;
using AddressT = uint16_t; // TODO.
// Establish source() and destination() shorthand to fetch data if necessary.
IntT immediate;
@ -1500,6 +1489,23 @@ template <
else if constexpr (data_size == DataSize::DWord) return registers.eax();
};
// For the string versions, evaluate to either SI and DI or ESI and EDI, depending on the address size.
// [TODO on the latter].
const auto eSI = [&]() -> AddressT& {
if constexpr (std::is_same_v<AddressT, uint16_t>) {
return registers.si();
} else {
return registers.esi();
}
};
const auto eDI = [&]() -> AddressT& {
if constexpr (std::is_same_v<AddressT, uint16_t>) {
return registers.di();
} else {
return registers.edi();
}
};
// Guide to the below:
//
// * use hard-coded register names where appropriate;
@ -1642,7 +1648,7 @@ template <
// TODO: don't assume address size below.
case Operation::CMPS:
Primitive::cmps<IntT, uint16_t>(instruction, memory, registers, status, flow_controller);
Primitive::cmps<IntT, uint16_t>(instruction, eSI(), eDI(), memory, registers, status, flow_controller);
break;
}

View File

@ -404,7 +404,7 @@ struct FailedExecution {
// TODO: LODS, MOVS, SCAS, STOS
*/
// CMPS
@"A6.json.gz", //@"A7.json.gz",
@"A6.json.gz", @"A7.json.gz",
/*
@"E0.json.gz", // LOOPNE
@"E1.json.gz", // LOOPE
@ -714,6 +714,9 @@ struct FailedExecution {
execution_support.registers = initial_registers;
// Execute instruction.
//
// TODO: enquire of the actual mechanism of repetition; if it were stateful as below then
// would it survive interrupts? So is it just IP adjustment?
execution_support.registers.ip_ += decoded.first;
do {
execution_support.flow_controller.begin_instruction();