chore: don't write to CPSR + swap with SPSR at the same time

This commit is contained in:
Rekai Nyangadzayi Musuka 2022-10-21 05:13:07 -03:00
parent ecbfe67b27
commit dd4bb4ff03
1 changed files with 39 additions and 52 deletions

View File

@ -75,27 +75,25 @@ pub fn dataProcessing(comptime I: bool, comptime S: bool, comptime kind: u4) Ins
0x8, 0x9, 0xA, 0xB => {}, // Test Operations 0x8, 0x9, 0xA, 0xB => {}, // Test Operations
else => { else => {
cpu.r[rd] = result; cpu.r[rd] = result;
if (rd == 0xF) cpu.pipe.reload(u32, cpu); if (rd == 0xF) {
if (S) cpu.setCpsr(cpu.spsr.raw);
cpu.pipe.reload(u32, cpu);
}
}, },
} }
// Write Flags // Write Flags
switch (kind) { switch (kind) {
0x0, 0x1, 0xC, 0xD, 0xE, 0xF => { 0x0, 0x1, 0xC, 0xD, 0xE, 0xF => if (S and rd != 0xF) {
// Logic Operation Flags // Logic Operation Flags
if (S) {
if (rd == 0xF) {
cpu.setCpsr(cpu.spsr.raw);
} else {
cpu.cpsr.n.write(result >> 31 & 1 == 1); cpu.cpsr.n.write(result >> 31 & 1 == 1);
cpu.cpsr.z.write(result == 0); cpu.cpsr.z.write(result == 0);
// C set by Barrel Shifter, V is unaffected // C set by Barrel Shifter, V is unaffected
}
}
}, },
0x2, 0x3 => { 0x2, 0x3 => if (S and rd != 0xF) {
// SUB, RSB Flags // SUB, RSB Flags
if (S) {
cpu.cpsr.n.write(result >> 31 & 1 == 1); cpu.cpsr.n.write(result >> 31 & 1 == 1);
cpu.cpsr.z.write(result == 0); cpu.cpsr.z.write(result == 0);
@ -108,24 +106,16 @@ pub fn dataProcessing(comptime I: bool, comptime S: bool, comptime kind: u4) Ins
cpu.cpsr.c.write(op1 <= op2); cpu.cpsr.c.write(op1 <= op2);
cpu.cpsr.v.write(((op2 ^ result) & (~op1 ^ result)) >> 31 & 1 == 1); cpu.cpsr.v.write(((op2 ^ result) & (~op1 ^ result)) >> 31 & 1 == 1);
} }
if (rd == 0xF) cpu.setCpsr(cpu.spsr.raw);
}
}, },
0x4, 0x5 => { 0x4, 0x5 => if (S and rd != 0xF) {
// ADD, ADC Flags // ADD, ADC Flags
if (S) {
cpu.cpsr.n.write(result >> 31 & 1 == 1); cpu.cpsr.n.write(result >> 31 & 1 == 1);
cpu.cpsr.z.write(result == 0); cpu.cpsr.z.write(result == 0);
cpu.cpsr.c.write(didOverflow); cpu.cpsr.c.write(didOverflow);
cpu.cpsr.v.write(((op1 ^ result) & (op2 ^ result)) >> 31 & 1 == 1); cpu.cpsr.v.write(((op1 ^ result) & (op2 ^ result)) >> 31 & 1 == 1);
if (rd == 0xF) cpu.setCpsr(cpu.spsr.raw);
}
}, },
0x6, 0x7 => { 0x6, 0x7 => if (S and rd != 0xF) {
// SBC, RSC Flags // SBC, RSC Flags
if (S) {
cpu.cpsr.n.write(result >> 31 & 1 == 1); cpu.cpsr.n.write(result >> 31 & 1 == 1);
cpu.cpsr.z.write(result == 0); cpu.cpsr.z.write(result == 0);
@ -140,9 +130,6 @@ pub fn dataProcessing(comptime I: bool, comptime S: bool, comptime kind: u4) Ins
cpu.cpsr.c.write(subtrahend <= op2); cpu.cpsr.c.write(subtrahend <= op2);
cpu.cpsr.v.write(((op2 ^ result) & (~op1 ^ result)) >> 31 & 1 == 1); cpu.cpsr.v.write(((op2 ^ result) & (~op1 ^ result)) >> 31 & 1 == 1);
} }
if (rd == 0xF) cpu.setCpsr(cpu.spsr.raw);
}
}, },
0x8, 0x9, 0xA, 0xB => { 0x8, 0x9, 0xA, 0xB => {
// Test Operation Flags // Test Operation Flags