mirror of
https://github.com/TomHarte/CLK.git
synced 2025-01-13 22:32:03 +00:00
Simplify flow slightly; uncover issues in CMPSW.
This commit is contained in:
parent
efb854ddfa
commit
a71db54212
@ -1395,31 +1395,20 @@ void repeat(const InstructionT &instruction, Status &status, RegistersT ®iste
|
||||
}
|
||||
|
||||
template <typename IntT, typename AddressT, typename InstructionT, typename MemoryT, typename RegistersT, typename FlowControllerT>
|
||||
void cmps(const InstructionT &instruction, MemoryT &memory, RegistersT ®isters, Status &status, FlowControllerT &flow_controller) {
|
||||
void cmps(const InstructionT &instruction, AddressT &eSI, AddressT &eDI, MemoryT &memory, RegistersT ®isters, 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;
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
|
Loading…
x
Reference in New Issue
Block a user