1
0
mirror of https://github.com/TomHarte/CLK.git synced 2025-04-09 00:37:27 +00:00

Add Repetition::Rep to unify repeat logic.

This commit is contained in:
Thomas Harte 2023-10-27 16:27:24 -04:00
parent 66cee41b99
commit f9d1a4dd8f
3 changed files with 23 additions and 30 deletions

View File

@ -1381,26 +1381,19 @@ bool repetition_over(const AddressT &eCX) {
}
template <typename AddressT, Repetition repetition, typename FlowControllerT>
void repeat_ene(Status &status, AddressT &eCX, FlowControllerT &flow_controller) {
if(
repetition == Repetition::None || // No repetition => stop.
!(--eCX) || // [e]cx is zero after being decremented => stop.
(repetition == Repetition::RepNE) == status.flag<Flag::Zero>()
// repe and !zero, or repne and zero => stop.
) {
return;
}
flow_controller.repeat_last();
}
template <typename AddressT, Repetition repetition, typename FlowControllerT>
void repeat(AddressT &eCX, FlowControllerT &flow_controller) {
void repeat([[maybe_unused]] Status &status, AddressT &eCX, FlowControllerT &flow_controller) {
if(
repetition == Repetition::None || // No repetition => stop.
!(--eCX) // [e]cx is zero after being decremented => stop.
) {
return;
}
if constexpr (repetition != Repetition::Rep) {
// If this is RepE or RepNE, also test the zero flag.
if((repetition == Repetition::RepNE) == status.flag<Flag::Zero>()) {
return;
}
}
flow_controller.repeat_last();
}
@ -1417,7 +1410,7 @@ void cmps(const InstructionT &instruction, AddressT &eCX, AddressT &eSI, Address
Primitive::sub<false, false>(lhs, rhs, status);
repeat_ene<AddressT, repetition>(status, eCX, flow_controller);
repeat<AddressT, repetition>(status, eCX, flow_controller);
}
template <typename IntT, typename AddressT, Repetition repetition, typename MemoryT, typename FlowControllerT>
@ -1431,7 +1424,7 @@ void scas(AddressT &eCX, AddressT &eDI, IntT &eAX, MemoryT &memory, Status &stat
Primitive::sub<false, false>(eAX, rhs, status);
repeat_ene<AddressT, repetition>(status, eCX, flow_controller);
repeat<AddressT, repetition>(status, eCX, flow_controller);
}
template <typename IntT, typename AddressT, Repetition repetition, typename InstructionT, typename MemoryT, typename FlowControllerT>
@ -1443,7 +1436,7 @@ void lods(const InstructionT &instruction, AddressT &eCX, AddressT &eSI, IntT &e
eAX = memory.template access<IntT>(instruction.data_segment(), eSI);
eSI += status.direction<AddressT>() * sizeof(IntT);
repeat<AddressT, repetition>(eCX, flow_controller);
repeat<AddressT, repetition>(status, eCX, flow_controller);
}
template <typename IntT, typename AddressT, Repetition repetition, typename InstructionT, typename MemoryT, typename FlowControllerT>
@ -1457,7 +1450,7 @@ void movs(const InstructionT &instruction, AddressT &eCX, AddressT &eSI, Address
eSI += status.direction<AddressT>() * sizeof(IntT);
eDI += status.direction<AddressT>() * sizeof(IntT);
repeat<AddressT, repetition>(eCX, flow_controller);
repeat<AddressT, repetition>(status, eCX, flow_controller);
}
template <typename IntT, typename AddressT, Repetition repetition, typename MemoryT, typename FlowControllerT>
@ -1469,7 +1462,7 @@ void stos(AddressT &eCX, AddressT &eDI, IntT &eAX, MemoryT &memory, Status &stat
memory.template access<IntT>(Source::ES, eDI) = eAX;
eDI += status.direction<AddressT>() * sizeof(IntT);
repeat<AddressT, repetition>(eCX, flow_controller);
repeat<AddressT, repetition>(status, eCX, flow_controller);
}
template <typename IntT, typename AddressT, Repetition repetition, typename InstructionT, typename MemoryT, typename IOT, typename FlowControllerT>
@ -1481,7 +1474,7 @@ void outs(const InstructionT &instruction, AddressT &eCX, uint16_t port, Address
io.template out<IntT>(port, memory.template access<IntT>(instruction.data_segment(), eSI));
eSI += status.direction<AddressT>() * sizeof(IntT);
repeat<AddressT, repetition>(eCX, flow_controller);
repeat<AddressT, repetition>(status, eCX, flow_controller);
}
template <typename IntT, typename AddressT, Repetition repetition, typename MemoryT, typename IOT, typename FlowControllerT>
@ -1493,7 +1486,7 @@ void ins(AddressT &eCX, uint16_t port, AddressT &eDI, MemoryT &memory, IOT &io,
memory.template access<IntT>(Source::ES, eDI) = io.template in<IntT>(port);
eDI += status.direction<AddressT>() * sizeof(IntT);
repeat<AddressT, repetition>(eCX, flow_controller);
repeat<AddressT, repetition>(status, eCX, flow_controller);
}
template <typename IntT, typename IOT>
@ -1782,35 +1775,35 @@ template <
Primitive::lods<IntT, AddressT, Repetition::None>(instruction, eCX(), eSI(), pair_low(), memory, status, flow_controller);
break;
case Operation::LODS_REP:
Primitive::lods<IntT, AddressT, Repetition::RepE>(instruction, eCX(), eSI(), pair_low(), memory, status, flow_controller);
Primitive::lods<IntT, AddressT, Repetition::Rep>(instruction, eCX(), eSI(), pair_low(), memory, status, flow_controller);
break;
case Operation::MOVS:
Primitive::movs<IntT, AddressT, Repetition::None>(instruction, eCX(), eSI(), eDI(), memory, status, flow_controller);
break;
case Operation::MOVS_REP:
Primitive::movs<IntT, AddressT, Repetition::RepE>(instruction, eCX(), eSI(), eDI(), memory, status, flow_controller);
Primitive::movs<IntT, AddressT, Repetition::Rep>(instruction, eCX(), eSI(), eDI(), memory, status, flow_controller);
break;
case Operation::STOS:
Primitive::stos<IntT, AddressT, Repetition::None>(eCX(), eDI(), pair_low(), memory, status, flow_controller);
break;
case Operation::STOS_REP:
Primitive::stos<IntT, AddressT, Repetition::RepE>(eCX(), eDI(), pair_low(), memory, status, flow_controller);
Primitive::stos<IntT, AddressT, Repetition::Rep>(eCX(), eDI(), pair_low(), memory, status, flow_controller);
break;
case Operation::OUTS:
Primitive::outs<IntT, AddressT, Repetition::None>(instruction, eCX(), registers.dx(), eSI(), memory, io, status, flow_controller);
break;
case Operation::OUTS_REP:
Primitive::outs<IntT, AddressT, Repetition::RepE>(instruction, eCX(), registers.dx(), eSI(), memory, io, status, flow_controller);
Primitive::outs<IntT, AddressT, Repetition::Rep>(instruction, eCX(), registers.dx(), eSI(), memory, io, status, flow_controller);
break;
case Operation::INS:
Primitive::ins<IntT, AddressT, Repetition::None>(eCX(), registers.dx(), eDI(), memory, io, status, flow_controller);
break;
case Operation::INS_REP:
Primitive::ins<IntT, AddressT, Repetition::RepE>(eCX(), registers.dx(), eDI(), memory, io, status, flow_controller);
Primitive::ins<IntT, AddressT, Repetition::Rep>(eCX(), registers.dx(), eDI(), memory, io, status, flow_controller);
break;
}

View File

@ -398,7 +398,7 @@ std::string InstructionSet::x86::to_string(
}
const bool is_negative = Numeric::top_bit<decltype(value)>() & value;
const uint64_t abs_value = std::abs(int16_t(value)); // TODO: don't assume 16-bit.
const uint64_t abs_value = uint64_t(std::abs(int16_t(value))); // TODO: don't assume 16-bit.
stream << (is_negative ? '-' : '+') << std::uppercase << std::hex << abs_value << 'h';
};

View File

@ -470,7 +470,7 @@ enum class Source: uint8_t {
};
enum class Repetition: uint8_t {
None, RepE, RepNE
None, RepE, RepNE, Rep,
};
/// @returns @c true if @c operation supports repetition mode @c repetition; @c false otherwise.
@ -491,16 +491,16 @@ constexpr Operation rep_operation(Operation operation, Repetition repetition) {
case Operation::CMPS:
switch(repetition) {
default:
case Repetition::None: return Operation::CMPS;
default:
case Repetition::RepE: return Operation::CMPS_REPE;
case Repetition::RepNE: return Operation::CMPS_REPNE;
}
case Operation::SCAS:
switch(repetition) {
default:
case Repetition::None: return Operation::SCAS;
default:
case Repetition::RepE: return Operation::SCAS_REPE;
case Repetition::RepNE: return Operation::SCAS_REPNE;
}