1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-11-19 23:32:28 +00:00

Further reduce repetition overhead.

This commit is contained in:
Thomas Harte 2023-10-20 17:08:11 -04:00
parent 0f5e0e17a4
commit bcebb2e520

View File

@ -1354,49 +1354,26 @@ void pushf(MemoryT &memory, RegistersT &registers, Status &status) {
push<uint16_t>(value, memory, registers); push<uint16_t>(value, memory, registers);
} }
template <typename AddressT, typename InstructionT, typename RegistersT> template <typename AddressT, typename InstructionT>
bool repetition_over(const InstructionT &instruction, RegistersT &registers) { bool repetition_over(const InstructionT &instruction, AddressT &eCX) {
if(instruction.repetition() == Repetition::None) { return instruction.repetition() != Repetition::None && !eCX;
return false;
}
if constexpr (std::is_same_v<AddressT, uint16_t>) {
return !registers.cx();
} else {
return !registers.ecx();
}
} }
template <typename AddressT, typename InstructionT, typename RegistersT, typename FlowControllerT> template <typename AddressT, typename InstructionT, typename FlowControllerT>
void repeat(const InstructionT &instruction, Status &status, RegistersT &registers, FlowControllerT &flow_controller) { void repeat(const InstructionT &instruction, Status &status, AddressT &eCX, FlowControllerT &flow_controller) {
if(instruction.repetition() == Repetition::None) { if(
instruction.repetition() == Repetition::None ||
!(--eCX) ||
(instruction.repetition() == Repetition::RepNE) == status.flag<Flag::Zero>()
) {
return; return;
} }
bool count_exhausted = false;
if constexpr (std::is_same_v<AddressT, uint16_t>) {
count_exhausted = !(--registers.cx());
} else {
count_exhausted = !(--registers.ecx());
}
if(count_exhausted) {
return;
}
const bool zero = status.flag<Flag::Zero>();
if(instruction.repetition() == Repetition::RepE && !zero) {
return;
} else if(instruction.repetition() == Repetition::RepNE && zero) {
return;
}
flow_controller.repeat_last(); flow_controller.repeat_last();
} }
template <typename IntT, typename AddressT, typename InstructionT, typename MemoryT, typename RegistersT, typename FlowControllerT> template <typename IntT, typename AddressT, typename InstructionT, typename MemoryT, typename FlowControllerT>
void cmps(const InstructionT &instruction, AddressT &eSI, AddressT &eDI, MemoryT &memory, RegistersT &registers, Status &status, FlowControllerT &flow_controller) { void cmps(const InstructionT &instruction, AddressT &eCX, AddressT &eSI, AddressT &eDI, MemoryT &memory, Status &status, FlowControllerT &flow_controller) {
if(repetition_over<AddressT>(instruction, registers)) { if(repetition_over<AddressT>(instruction, eCX)) {
return; return;
} }
@ -1410,7 +1387,7 @@ void cmps(const InstructionT &instruction, AddressT &eSI, AddressT &eDI, MemoryT
Primitive::sub<false, false>(lhs, rhs, status); Primitive::sub<false, false>(lhs, rhs, status);
repeat<AddressT>(instruction, status, registers, flow_controller); repeat<AddressT>(instruction, status, eCX, flow_controller);
} }
} }
@ -1630,7 +1607,7 @@ template <
case Operation::XCHG: Primitive::xchg(destination(), source()); return; case Operation::XCHG: Primitive::xchg(destination(), source()); return;
case Operation::SALC: Primitive::salc(registers.al(), status); return; case Operation::SALC: Primitive::salc(registers.al(), status); return;
case Operation::SETMO: case Operation::SETMO:
if constexpr (model == Model::i8086) { if constexpr (model == Model::i8086) {
Primitive::setmo(destination(), status); Primitive::setmo(destination(), status);
@ -1654,7 +1631,7 @@ template <
case Operation::PUSHF: Primitive::pushf(memory, registers, status); break; case Operation::PUSHF: Primitive::pushf(memory, registers, status); break;
case Operation::CMPS: case Operation::CMPS:
Primitive::cmps<IntT, AddressT>(instruction, eSI(), eDI(), memory, registers, status, flow_controller); Primitive::cmps<IntT, AddressT>(instruction, eCX(), eSI(), eDI(), memory, status, flow_controller);
break; break;
} }