mirror of
https://github.com/TomHarte/CLK.git
synced 2025-08-09 05:25:01 +00:00
Trust tests on immediate-opcode ROR 0; limit shift by register.
This commit is contained in:
@@ -52,6 +52,10 @@ struct Executor {
|
|||||||
registers_.pc(4) :
|
registers_.pc(4) :
|
||||||
registers_[fields.shift_register()];
|
registers_[fields.shift_register()];
|
||||||
|
|
||||||
|
// "The amount by which the register should be shifted may be contained in
|
||||||
|
// ... **the bottom byte** of another register".
|
||||||
|
shift_amount &= 0xff;
|
||||||
|
|
||||||
// A register shift amount of 0 has a different meaning than an in-instruction
|
// A register shift amount of 0 has a different meaning than an in-instruction
|
||||||
// shift amount of 0.
|
// shift amount of 0.
|
||||||
if(!shift_amount) {
|
if(!shift_amount) {
|
||||||
@@ -98,6 +102,12 @@ struct Executor {
|
|||||||
operand2 = fields.immediate();
|
operand2 = fields.immediate();
|
||||||
if(fields.rotate()) {
|
if(fields.rotate()) {
|
||||||
shift<ShiftType::RotateRight, shift_sets_carry>(operand2, fields.rotate(), rotate_carry);
|
shift<ShiftType::RotateRight, shift_sets_carry>(operand2, fields.rotate(), rotate_carry);
|
||||||
|
} else {
|
||||||
|
// This is possibly clarified by later data sheets; take carry as if a rotate by 32
|
||||||
|
// had occurred.
|
||||||
|
if constexpr (shift_sets_carry) {
|
||||||
|
rotate_carry = operand2 & 0x8000'0000;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
operand2 = decode_shift<true, shift_sets_carry>(fields, rotate_carry, shift_by_register ? 8 : 4);
|
operand2 = decode_shift<true, shift_sets_carry>(fields, rotate_carry, shift_by_register ? 8 : 4);
|
||||||
|
@@ -383,22 +383,6 @@ struct MemoryLedger {
|
|||||||
uint32_t r15_mask = 0xffff'ffff;
|
uint32_t r15_mask = 0xffff'ffff;
|
||||||
bool ignore_test = false;
|
bool ignore_test = false;
|
||||||
switch(instruction) {
|
switch(instruction) {
|
||||||
case 0x03110002:
|
|
||||||
// tsteq r1, #2; per my reading this is LSL#0 so the original
|
|
||||||
// carry value should be preserved. The test set doesn't seem
|
|
||||||
// to agree. Until I can reconcile them, don't test carry.
|
|
||||||
r15_mask &= ~ConditionCode::Carry;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 0x11800215:
|
|
||||||
// orrne r0, r0, r5, lsl r2
|
|
||||||
// The test set applies the rule 'lsl r2 % 32' whereas the data
|
|
||||||
// sheet specifically says for a shift-by-register that
|
|
||||||
// "LSL by more than 32 has result zero, carry out zero" so I think
|
|
||||||
// the test set is adrift on the following:
|
|
||||||
ignore_test = regs[2] >= 32;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 0xe090e00f:
|
case 0xe090e00f:
|
||||||
// adds lr, r0, pc
|
// adds lr, r0, pc
|
||||||
// The test set comes from an ARM that doesn't multiplex flags
|
// The test set comes from an ARM that doesn't multiplex flags
|
||||||
@@ -407,6 +391,11 @@ struct MemoryLedger {
|
|||||||
regs[15] &= 0x03ff'fffc;
|
regs[15] &= 0x03ff'fffc;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
// TODO:
|
||||||
|
// * adds to R15: e090f00e, e090f00f; possibly to do with non-multiplexing original?
|
||||||
|
// * movs to PC: e1b0f00e; as above?
|
||||||
|
// * some test set teqs — e33ff3c3, e33ff343, e33ef000 — seem to advance the PC twice?
|
||||||
|
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -429,10 +418,10 @@ struct MemoryLedger {
|
|||||||
if(ignore_test) {
|
if(ignore_test) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
//
|
||||||
if(instruction == 0xe33ef000 && test_count == 1) {
|
// if(instruction == 0x03110002 && test_count == 5) {
|
||||||
printf("");
|
// printf("");
|
||||||
}
|
// }
|
||||||
|
|
||||||
execute(instruction, *test);
|
execute(instruction, *test);
|
||||||
NSMutableString *error = nil;
|
NSMutableString *error = nil;
|
||||||
|
Reference in New Issue
Block a user