mirror of
https://github.com/TomHarte/CLK.git
synced 2025-02-20 14:29:11 +00:00
Add remaining acceptable error cases.
This commit is contained in:
parent
ed3922e458
commit
e78e5c8101
@ -470,6 +470,9 @@ enum class Source: uint8_t {
|
||||
/// getter is used).
|
||||
IndirectNoBase = Indirect - 1,
|
||||
};
|
||||
constexpr bool is_register(Source source) {
|
||||
return source < Source::None;
|
||||
}
|
||||
|
||||
enum class Repetition: uint8_t {
|
||||
None, RepE, RepNE, Rep,
|
||||
|
@ -658,11 +658,10 @@ struct FailedExecution {
|
||||
failure_list = &permitted_failures;
|
||||
}
|
||||
|
||||
// IDIV_REP has a couple of cases...
|
||||
// IDIV_REP: for reasons I don't understand, sometimes the test set doesn't increment
|
||||
// the IP across a REP_IDIV. I don't think (?) this correlates to real 8086 behaviour.
|
||||
// More research required, but for now I'm not treating this as a roadblock.
|
||||
if(decoded.second.operation() == Operation::IDIV_REP) {
|
||||
// For reasons I don't understand, sometimes the test set doesn't increment the IP
|
||||
// across a REP_IDIV. I don't think (?) this correlates to real 8086 behaviour.
|
||||
// More research required, but for now I'm not treating this as a roadblock.
|
||||
Registers advanced_registers = intended_registers;
|
||||
advanced_registers.ip_ += decoded.first;
|
||||
if(advanced_registers == execution_support.registers && ramEqual && flagsEqual) {
|
||||
@ -670,6 +669,35 @@ struct FailedExecution {
|
||||
}
|
||||
}
|
||||
|
||||
// IDIV[_REP] byte: the test cases sometimes throw even when I can't see why they should,
|
||||
// and other x86 emulations also don't throw. I guess — guess! — an 8086-specific oddity
|
||||
// deviates from the x86 average here. So I'm also permitting these for now.
|
||||
if(
|
||||
decoded.second.operation_size() == InstructionSet::x86::DataSize::Byte &&
|
||||
(decoded.second.operation() == Operation::IDIV_REP || decoded.second.operation() == Operation::IDIV)
|
||||
) {
|
||||
if(intended_registers.sp() == execution_support.registers.sp() - 6) {
|
||||
Registers non_exception_registers = intended_registers;
|
||||
non_exception_registers.ip() = execution_support.registers.ip();
|
||||
non_exception_registers.sp() = execution_support.registers.sp();
|
||||
non_exception_registers.ax() = execution_support.registers.ax();
|
||||
non_exception_registers.cs() = execution_support.registers.cs();
|
||||
|
||||
if(non_exception_registers == execution_support.registers) {
|
||||
failure_list = &permitted_failures;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// LEA from a register is undefined behaviour and throws on processors beyond the 8086.
|
||||
if(decoded.second.operation() == Operation::LEA && InstructionSet::x86::is_register(decoded.second.source().source())) {
|
||||
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