1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-06-01 22:41:32 +00:00

Trust tests on immediate-opcode ROR 0; limit shift by register.

This commit is contained in:
Thomas Harte 2024-03-10 23:38:31 -04:00
parent 336292bc49
commit 830d70d3aa
2 changed files with 19 additions and 20 deletions

View File

@ -52,6 +52,10 @@ struct Executor {
registers_.pc(4) :
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
// shift amount of 0.
if(!shift_amount) {
@ -98,6 +102,12 @@ struct Executor {
operand2 = fields.immediate();
if(fields.rotate()) {
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 {
operand2 = decode_shift<true, shift_sets_carry>(fields, rotate_carry, shift_by_register ? 8 : 4);

View File

@ -383,22 +383,6 @@ struct MemoryLedger {
uint32_t r15_mask = 0xffff'ffff;
bool ignore_test = false;
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:
// adds lr, r0, pc
// The test set comes from an ARM that doesn't multiplex flags
@ -407,6 +391,11 @@ struct MemoryLedger {
regs[15] &= 0x03ff'fffc;
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;
}
@ -429,10 +418,10 @@ struct MemoryLedger {
if(ignore_test) {
continue;
}
if(instruction == 0xe33ef000 && test_count == 1) {
printf("");
}
//
// if(instruction == 0x03110002 && test_count == 5) {
// printf("");
// }
execute(instruction, *test);
NSMutableString *error = nil;