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:
parent
0f5e0e17a4
commit
bcebb2e520
@ -1354,49 +1354,26 @@ void pushf(MemoryT &memory, RegistersT ®isters, 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 ®isters) {
|
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 ®isters, 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 ®isters, 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user