mirror of
https://github.com/TomHarte/CLK.git
synced 2025-02-16 18:30:32 +00:00
Add route for tracking segment register changes.
This commit is contained in:
parent
a230274306
commit
79b126e6bb
@ -253,7 +253,12 @@ template <
|
||||
return;
|
||||
|
||||
case Operation::LEA: Primitive::lea<IntT>(instruction, destination_w(), context); return;
|
||||
case Operation::MOV: Primitive::mov<IntT>(destination_w(), source_r()); break;
|
||||
case Operation::MOV:
|
||||
Primitive::mov<IntT>(destination_w(), source_r());
|
||||
if constexpr (std::is_same_v<IntT, uint16_t>) {
|
||||
context.registers.did_update(instruction.destination.source());
|
||||
}
|
||||
break;
|
||||
|
||||
case Operation::JO: jcc(context.flags.template condition<Condition::Overflow>()); return;
|
||||
case Operation::JNO: jcc(!context.flags.template condition<Condition::Overflow>()); return;
|
||||
@ -319,7 +324,12 @@ template <
|
||||
|
||||
case Operation::XLAT: Primitive::xlat<AddressT>(instruction, context); return;
|
||||
|
||||
case Operation::POP: destination_w() = Primitive::pop<IntT, false>(context); break;
|
||||
case Operation::POP:
|
||||
destination_w() = Primitive::pop<IntT, false>(context);
|
||||
if constexpr (std::is_same_v<IntT, uint16_t>) {
|
||||
context.registers.did_update(instruction.destination.source());
|
||||
}
|
||||
break;
|
||||
case Operation::PUSH:
|
||||
Primitive::push<IntT, false>(source_rmw(), context); // PUSH SP modifies SP before pushing it;
|
||||
// hence PUSH is sometimes read-modify-write.
|
||||
|
@ -444,7 +444,7 @@ enum class Source: uint8_t {
|
||||
T0 = 0, T1 = 1, T2 = 2, T3 = 3, T4 = 4, T5 = 5, T6 = 6, T7 = 7,
|
||||
D0 = 0, D1 = 1, D2 = 2, D3 = 3, D4 = 4, D5 = 5, D6 = 6, D7 = 7,
|
||||
|
||||
// Selectors.
|
||||
// Segment registers.
|
||||
ES, CS, SS, DS, FS, GS,
|
||||
|
||||
/// @c None can be treated as a source that produces 0 when encountered;
|
||||
@ -473,6 +473,9 @@ enum class Source: uint8_t {
|
||||
constexpr bool is_register(Source source) {
|
||||
return source < Source::None;
|
||||
}
|
||||
constexpr bool is_segment_register(Source source) {
|
||||
return is_register(source) && source >= Source::ES;
|
||||
}
|
||||
|
||||
enum class Repetition: uint8_t {
|
||||
None, RepE, RepNE, Rep,
|
||||
|
@ -68,6 +68,7 @@ struct Registers {
|
||||
uint16_t &di() { return di_; }
|
||||
|
||||
uint16_t es_, cs_, ds_, ss_;
|
||||
uint32_t es_base_, cs_base_, ds_base_, ss_base_;
|
||||
|
||||
uint16_t ip_;
|
||||
uint16_t &ip() { return ip_; }
|
||||
@ -77,6 +78,17 @@ struct Registers {
|
||||
uint16_t &ds() { return ds_; }
|
||||
uint16_t &ss() { return ss_; }
|
||||
|
||||
using Source = InstructionSet::x86::Source;
|
||||
void did_update(Source segment) {
|
||||
switch(segment) {
|
||||
default: break;
|
||||
case Source::ES: es_base_ = es_ << 4; break;
|
||||
case Source::CS: cs_base_ = cs_ << 4; break;
|
||||
case Source::DS: ds_base_ = ds_ << 4; break;
|
||||
case Source::SS: ss_base_ = ss_ << 4; break;
|
||||
}
|
||||
}
|
||||
|
||||
bool operator ==(const Registers &rhs) const {
|
||||
return
|
||||
ax_.full == rhs.ax_.full &&
|
||||
@ -395,9 +407,9 @@ struct FailedExecution {
|
||||
NSString *path = [NSString stringWithUTF8String:TestSuiteHome];
|
||||
NSSet *allowList = [NSSet setWithArray:@[
|
||||
// Current execution failures, albeit all permitted:
|
||||
@"D4.json.gz", // AAM
|
||||
@"F6.7.json.gz", // IDIV byte
|
||||
@"F7.7.json.gz", // IDIV word
|
||||
// @"D4.json.gz", // AAM
|
||||
// @"F6.7.json.gz", // IDIV byte
|
||||
// @"F7.7.json.gz", // IDIV word
|
||||
]];
|
||||
|
||||
NSSet *ignoreList = nil;
|
||||
@ -694,10 +706,6 @@ struct FailedExecution {
|
||||
failure_list = &permitted_failures;
|
||||
}
|
||||
|
||||
if(failure_list == &execution_failures) {
|
||||
printf("Fail: %d\n", int(decoded.second.operation()));
|
||||
}
|
||||
|
||||
// Record a failure.
|
||||
FailedExecution failure;
|
||||
failure.instruction = decoded.second;
|
||||
|
Loading…
x
Reference in New Issue
Block a user