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:
parent
66cee41b99
commit
f9d1a4dd8f
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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';
|
||||
};
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user