Revert "ARM: Overhaul PSR access" This reverts commit 37f5feb713d5768f2bf5405e5a9db8765248efc2 and fixup commits.
jump to
@@ -173,12 +173,6 @@ } \
ATTRIBUTE_UNUSED static inline TYPE TYPE ## Fill ## FIELD (TYPE src) { \ return FILL_BITS(src, (START), (START) + (SIZE)); \ } \ - ATTRIBUTE_UNUSED static inline TYPE TYPE ## OrUnsafe ## FIELD (TYPE src, TYPE bits) { \ - return (src | ((bits) << (START))); \ - } \ - ATTRIBUTE_UNUSED static inline TYPE TYPE ## Or ## FIELD (TYPE src, TYPE bits) { \ - return (src | (((bits) << (START)) & MAKE_MASK(START, (START) + (SIZE)))); \ - } \ ATTRIBUTE_UNUSED static inline TYPE TYPE ## Set ## FIELD (TYPE src, TYPE bits) { \ return INS_BITS(src, (START), (START) + (SIZE), bits); \ } \
@@ -68,15 +68,33 @@ };
struct ARMCore; -DECL_BITFIELD(ARMPSR, uint32_t); -DECL_BITS(ARMPSR, Priv, 0, 5); -DECL_BIT(ARMPSR, T, 5); -DECL_BIT(ARMPSR, F, 6); -DECL_BIT(ARMPSR, I, 7); -DECL_BIT(ARMPSR, V, 28); -DECL_BIT(ARMPSR, C, 29); -DECL_BIT(ARMPSR, Z, 30); -DECL_BIT(ARMPSR, N, 31); +union PSR { + struct { +#if defined(__POWERPC__) || defined(__PPC__) + unsigned n : 1; + unsigned z : 1; + unsigned c : 1; + unsigned v : 1; + unsigned unused : 20; + unsigned i : 1; + unsigned f : 1; + unsigned t : 1; + unsigned priv : 5; +#else + unsigned priv : 5; + unsigned t : 1; + unsigned f : 1; + unsigned i : 1; + unsigned unused : 20; + unsigned v : 1; + unsigned c : 1; + unsigned z : 1; + unsigned n : 1; +#endif + }; + + int32_t packed; +}; struct ARMMemory { uint32_t (*load32)(struct ARMCore*, uint32_t address, int* cycleCounter);@@ -117,8 +135,8 @@ };
struct ARMCore { int32_t gprs[16]; - ARMPSR cpsr; - ARMPSR spsr; + union PSR cpsr; + union PSR spsr; int32_t cycles; int32_t nextEvent;
@@ -10,20 +10,20 @@ #include "macros.h"
#include "arm.h" -#define ARM_COND_EQ (ARMPSRIsZ(cpu->cpsr)) -#define ARM_COND_NE (!ARMPSRIsZ(cpu->cpsr)) -#define ARM_COND_CS (ARMPSRIsC(cpu->cpsr)) -#define ARM_COND_CC (!ARMPSRIsC(cpu->cpsr)) -#define ARM_COND_MI (ARMPSRIsN(cpu->cpsr)) -#define ARM_COND_PL (!ARMPSRIsN(cpu->cpsr)) -#define ARM_COND_VS (ARMPSRIsV(cpu->cpsr)) -#define ARM_COND_VC (!ARMPSRIsV(cpu->cpsr)) -#define ARM_COND_HI (ARMPSRIsC(cpu->cpsr) && !ARMPSRIsZ(cpu->cpsr)) -#define ARM_COND_LS (!ARMPSRIsC(cpu->cpsr) || ARMPSRIsZ(cpu->cpsr)) -#define ARM_COND_GE (!ARMPSRIsN(cpu->cpsr) == !ARMPSRIsV(cpu->cpsr)) -#define ARM_COND_LT (!ARMPSRIsN(cpu->cpsr) != !ARMPSRIsV(cpu->cpsr)) -#define ARM_COND_GT (!ARMPSRIsZ(cpu->cpsr) && !ARMPSRIsN(cpu->cpsr) == !ARMPSRIsV(cpu->cpsr)) -#define ARM_COND_LE (ARMPSRIsZ(cpu->cpsr) || !ARMPSRIsN(cpu->cpsr) != !ARMPSRIsV(cpu->cpsr)) +#define ARM_COND_EQ (cpu->cpsr.z) +#define ARM_COND_NE (!cpu->cpsr.z) +#define ARM_COND_CS (cpu->cpsr.c) +#define ARM_COND_CC (!cpu->cpsr.c) +#define ARM_COND_MI (cpu->cpsr.n) +#define ARM_COND_PL (!cpu->cpsr.n) +#define ARM_COND_VS (cpu->cpsr.v) +#define ARM_COND_VC (!cpu->cpsr.v) +#define ARM_COND_HI (cpu->cpsr.c && !cpu->cpsr.z) +#define ARM_COND_LS (!cpu->cpsr.c || cpu->cpsr.z) +#define ARM_COND_GE (!cpu->cpsr.n == !cpu->cpsr.v) +#define ARM_COND_LT (!cpu->cpsr.n != !cpu->cpsr.v) +#define ARM_COND_GT (!cpu->cpsr.z && !cpu->cpsr.n == !cpu->cpsr.v) +#define ARM_COND_LE (cpu->cpsr.z || !cpu->cpsr.n != !cpu->cpsr.v) #define ARM_COND_AL 1 #define ARM_SIGN(I) ((I) >> 31)@@ -31,8 +31,7 @@ #define ARM_SXT_8(I) (((int8_t) (I) << 24) >> 24)
#define ARM_SXT_16(I) (((int16_t) (I) << 16) >> 16) #define ARM_UXT_64(I) (uint64_t)(uint32_t) (I) -#define ARM_CARRY_FROM(M, N, D) (UINT_MAX - (uint32_t) (M) < (uint32_t) (N)) -#define ARM_CARRY_FROM_CARRY(M, N, D, C) (((uint32_t) (M) >> 31) + ((uint32_t) (N) >> 31) > ((uint32_t) (D) >> 31)) +#define ARM_CARRY_FROM(M, N, D) (((uint32_t) (M) >> 31) + ((uint32_t) (N) >> 31) > ((uint32_t) (D) >> 31)) #define ARM_BORROW_FROM(M, N, D) (((uint32_t) (M)) >= ((uint32_t) (N))) #define ARM_BORROW_FROM_CARRY(M, N, D, C) (ARM_UXT_64(M) >= (ARM_UXT_64(N)) + (uint64_t) (C)) #define ARM_V_ADDITION(M, N, D) (!(ARM_SIGN((M) ^ (N))) && (ARM_SIGN((M) ^ (D))) && (ARM_SIGN((N) ^ (D))))@@ -84,23 +83,24 @@
cpu->executionMode = executionMode; switch (executionMode) { case MODE_ARM: - cpu->cpsr = ARMPSRClearT(cpu->cpsr); + cpu->cpsr.t = 0; break; case MODE_THUMB: - cpu->cpsr = ARMPSRFillT(cpu->cpsr); + cpu->cpsr.t = 1; } cpu->nextEvent = cpu->cycles; } static inline void _ARMReadCPSR(struct ARMCore* cpu) { - _ARMSetMode(cpu, ARMPSRGetT(cpu->cpsr)); - ARMSetPrivilegeMode(cpu, ARMPSRGetPriv(cpu->cpsr)); + _ARMSetMode(cpu, cpu->cpsr.t); + ARMSetPrivilegeMode(cpu, cpu->cpsr.priv); cpu->irqh.readCPSR(cpu); } static inline uint32_t _ARMPCAddress(struct ARMCore* cpu) { int instructionLength; - if (ARMPSRIsT(cpu->cpsr)) { + enum ExecutionMode mode = cpu->cpsr.t; + if (mode == MODE_ARM) { instructionLength = WORD_SIZE_ARM; } else { instructionLength = WORD_SIZE_THUMB;
@@ -11,7 +11,6 @@
CXX_GUARD_START #include <mgba/core/core.h> -#include <mgba/internal/arm/arm.h> #include <mgba/internal/gba/gba.h> #include <mgba/internal/gb/serialize.h>@@ -238,8 +237,8 @@ uint32_t id;
struct { int32_t gprs[16]; - ARMPSR cpsr; - ARMPSR spsr; + union PSR cpsr; + union PSR spsr; int32_t cycles; int32_t nextEvent;
@@ -40,8 +40,8 @@ cpu->bankedRegisters[oldBank][1] = cpu->gprs[ARM_LR];
cpu->gprs[ARM_SP] = cpu->bankedRegisters[newBank][0]; cpu->gprs[ARM_LR] = cpu->bankedRegisters[newBank][1]; - cpu->bankedSPSRs[oldBank] = cpu->spsr; - cpu->spsr = cpu->bankedSPSRs[newBank]; + cpu->bankedSPSRs[oldBank] = cpu->spsr.packed; + cpu->spsr.packed = cpu->bankedSPSRs[newBank]; } cpu->privilegeMode = mode; }@@ -127,8 +127,8 @@ cpu->bankedSPSRs[i] = 0;
} cpu->privilegeMode = MODE_SYSTEM; - cpu->cpsr = MODE_SYSTEM; - cpu->spsr = 0; + cpu->cpsr.packed = MODE_SYSTEM; + cpu->spsr.packed = 0; cpu->shifterOperand = 0; cpu->shifterCarryOut = 0;@@ -147,10 +147,10 @@ cpu->irqh.reset(cpu);
} void ARMRaiseIRQ(struct ARMCore* cpu) { - if (ARMPSRIsI(cpu->cpsr)) { + if (cpu->cpsr.i) { return; } - ARMPSR cpsr = cpu->cpsr; + union PSR cpsr = cpu->cpsr; int instructionWidth; if (cpu->executionMode == MODE_THUMB) { instructionWidth = WORD_SIZE_THUMB;@@ -158,19 +158,19 @@ } else {
instructionWidth = WORD_SIZE_ARM; } ARMSetPrivilegeMode(cpu, MODE_IRQ); - cpu->cpsr = ARMPSRSetPriv(cpu->cpsr, MODE_IRQ); + cpu->cpsr.priv = MODE_IRQ; cpu->gprs[ARM_LR] = cpu->gprs[ARM_PC] - instructionWidth + WORD_SIZE_ARM; cpu->gprs[ARM_PC] = BASE_IRQ; int currentCycles = 0; ARM_WRITE_PC; _ARMSetMode(cpu, MODE_ARM); cpu->spsr = cpsr; - cpu->cpsr = ARMPSRFillI(cpu->cpsr); + cpu->cpsr.i = 1; cpu->cycles += currentCycles; } void ARMRaiseSWI(struct ARMCore* cpu) { - ARMPSR cpsr = cpu->cpsr; + union PSR cpsr = cpu->cpsr; int instructionWidth; if (cpu->executionMode == MODE_THUMB) { instructionWidth = WORD_SIZE_THUMB;@@ -178,19 +178,19 @@ } else {
instructionWidth = WORD_SIZE_ARM; } ARMSetPrivilegeMode(cpu, MODE_SUPERVISOR); - cpu->cpsr = ARMPSRSetPriv(cpu->cpsr, MODE_SUPERVISOR); + cpu->cpsr.priv = MODE_SUPERVISOR; cpu->gprs[ARM_LR] = cpu->gprs[ARM_PC] - instructionWidth; cpu->gprs[ARM_PC] = BASE_SWI; int currentCycles = 0; ARM_WRITE_PC; _ARMSetMode(cpu, MODE_ARM); cpu->spsr = cpsr; - cpu->cpsr = ARMPSRFillI(cpu->cpsr); + cpu->cpsr.i = 1; cpu->cycles += currentCycles; } void ARMRaiseUndefined(struct ARMCore* cpu) { - ARMPSR cpsr = cpu->cpsr; + union PSR cpsr = cpu->cpsr; int instructionWidth; if (cpu->executionMode == MODE_THUMB) { instructionWidth = WORD_SIZE_THUMB;@@ -198,14 +198,14 @@ } else {
instructionWidth = WORD_SIZE_ARM; } ARMSetPrivilegeMode(cpu, MODE_UNDEFINED); - cpu->cpsr = ARMPSRSetPriv(cpu->cpsr, MODE_UNDEFINED); + cpu->cpsr.priv = MODE_UNDEFINED; cpu->gprs[ARM_LR] = cpu->gprs[ARM_PC] - instructionWidth; cpu->gprs[ARM_PC] = BASE_UNDEF; int currentCycles = 0; ARM_WRITE_PC; _ARMSetMode(cpu, MODE_ARM); cpu->spsr = cpsr; - cpu->cpsr = ARMPSRFillI(cpu->cpsr); + cpu->cpsr.i = 1; cpu->cycles += currentCycles; }
@@ -37,15 +37,15 @@ { "w/r", _writeRegister, CLIDVParse, "Write a register" },
{ 0, 0, 0, 0 } }; -static inline void _printPSR(struct CLIDebuggerBackend* be, ARMPSR psr) { - be->printf(be, "%08X [%c%c%c%c%c%c%c]\n", psr, - ARMPSRIsN(psr) ? 'N' : '-', - ARMPSRIsZ(psr) ? 'Z' : '-', - ARMPSRIsC(psr) ? 'C' : '-', - ARMPSRIsV(psr) ? 'V' : '-', - ARMPSRIsI(psr) ? 'I' : '-', - ARMPSRIsF(psr) ? 'F' : '-', - ARMPSRIsT(psr) ? 'T' : '-'); +static inline void _printPSR(struct CLIDebuggerBackend* be, union PSR psr) { + be->printf(be, "%08X [%c%c%c%c%c%c%c]\n", psr.packed, + psr.n ? 'N' : '-', + psr.z ? 'Z' : '-', + psr.c ? 'C' : '-', + psr.v ? 'V' : '-', + psr.i ? 'I' : '-', + psr.f ? 'F' : '-', + psr.t ? 'T' : '-'); } static void _disassemble(struct CLIDebuggerSystem* debugger, struct CLIDebugVector* dv) {@@ -136,7 +136,7 @@ cpu->gprs[(r << 2) + 3]);
} _printPSR(be, cpu->cpsr); int instructionLength; - enum ExecutionMode mode = ARMPSRIsT(cpu->cpsr); + enum ExecutionMode mode = cpu->cpsr.t; if (mode == MODE_ARM) { instructionLength = WORD_SIZE_ARM; } else {@@ -196,11 +196,11 @@ if (strcmp(name, "pc") == 0) {
return cpu->gprs[ARM_PC]; } if (strcmp(name, "cpsr") == 0) { - return cpu->cpsr; + return cpu->cpsr.packed; } // TODO: test if mode has SPSR if (strcmp(name, "spsr") == 0) { - return cpu->spsr; + return cpu->spsr.packed; } if (name[0] == 'r' && name[1] >= '0' && name[1] <= '9') { int reg = atoi(&name[1]);
@@ -26,7 +26,7 @@
static void ARMDebuggerCheckBreakpoints(struct mDebuggerPlatform* d) { struct ARMDebugger* debugger = (struct ARMDebugger*) d; int instructionLength; - enum ExecutionMode mode = ARMPSRIsT(debugger->cpu->cpsr); + enum ExecutionMode mode = debugger->cpu->cpsr.t; if (mode == MODE_ARM) { instructionLength = WORD_SIZE_ARM; } else {
@@ -30,7 +30,7 @@ shiftVal += 4;
} if (!shift) { cpu->shifterOperand = shiftVal; - cpu->shifterCarryOut = ARMPSRGetC(cpu->cpsr); + cpu->shifterCarryOut = cpu->cpsr.c; } else if (shift < 32) { cpu->shifterOperand = shiftVal << shift; cpu->shifterCarryOut = (shiftVal >> (32 - shift)) & 1;@@ -45,7 +45,7 @@ } else {
int immediate = (opcode & 0x00000F80) >> 7; if (!immediate) { cpu->shifterOperand = cpu->gprs[rm]; - cpu->shifterCarryOut = ARMPSRGetC(cpu->cpsr); + cpu->shifterCarryOut = cpu->cpsr.c; } else { cpu->shifterOperand = cpu->gprs[rm] << immediate; cpu->shifterCarryOut = (cpu->gprs[rm] >> (32 - immediate)) & 1;@@ -69,7 +69,7 @@ shiftVal += 4;
} if (!shift) { cpu->shifterOperand = shiftVal; - cpu->shifterCarryOut = ARMPSRGetC(cpu->cpsr); + cpu->shifterCarryOut = cpu->cpsr.c; } else if (shift < 32) { cpu->shifterOperand = shiftVal >> shift; cpu->shifterCarryOut = (shiftVal >> (shift - 1)) & 1;@@ -108,7 +108,7 @@ shiftVal += 4;
} if (!shift) { cpu->shifterOperand = shiftVal; - cpu->shifterCarryOut = ARMPSRGetC(cpu->cpsr); + cpu->shifterCarryOut = cpu->cpsr.c; } else if (shift < 32) { cpu->shifterOperand = shiftVal >> shift; cpu->shifterCarryOut = (shiftVal >> (shift - 1)) & 1;@@ -148,7 +148,7 @@ }
int rotate = shift & 0x1F; if (!shift) { cpu->shifterOperand = shiftVal; - cpu->shifterCarryOut = ARMPSRGetC(cpu->cpsr); + cpu->shifterCarryOut = cpu->cpsr.c; } else if (rotate) { cpu->shifterOperand = ROR(shiftVal, rotate); cpu->shifterCarryOut = (shiftVal >> (rotate - 1)) & 1;@@ -163,7 +163,7 @@ cpu->shifterOperand = ROR(cpu->gprs[rm], immediate);
cpu->shifterCarryOut = (cpu->gprs[rm] >> (immediate - 1)) & 1; } else { // RRX - cpu->shifterOperand = (ARMPSRGetC(cpu->cpsr) << 31) | (((uint32_t) cpu->gprs[rm]) >> 1); + cpu->shifterOperand = (cpu->cpsr.c << 31) | (((uint32_t) cpu->gprs[rm]) >> 1); cpu->shifterCarryOut = cpu->gprs[rm] & 0x00000001; } }@@ -174,7 +174,7 @@ int rotate = (opcode & 0x00000F00) >> 7;
int immediate = opcode & 0x000000FF; if (!rotate) { cpu->shifterOperand = immediate; - cpu->shifterCarryOut = ARMPSRGetC(cpu->cpsr); + cpu->shifterCarryOut = cpu->cpsr.c; } else { cpu->shifterOperand = ROR(immediate, rotate); cpu->shifterCarryOut = ARM_SIGN(cpu->shifterOperand);@@ -185,76 +185,51 @@ // Instruction definitions
// Beware pre-processor antics #define ARM_ADDITION_S(M, N, D) \ - if (rd == ARM_PC && _ARMModeHasSPSR(ARMPSRGetPriv(cpu->cpsr))) { \ - cpu->cpsr = cpu->spsr; \ - _ARMReadCPSR(cpu); \ - } else { \ - ARMPSR cpsr = 0; \ - cpsr = ARMPSROrUnsafeN(cpsr, ARM_SIGN(D)); \ - cpsr = ARMPSROrUnsafeZ(cpsr, !(D)); \ - cpsr = ARMPSROrUnsafeC(cpsr, ARM_CARRY_FROM(M, N, D)); \ - cpsr = ARMPSROrUnsafeV(cpsr, ARM_V_ADDITION(M, N, D)); \ - cpu->cpsr = (cpu->cpsr & (0x0FFFFFFF)) | cpsr; \ - } - -#define ARM_ADDITION_CARRY_S(M, N, D, C) \ - if (rd == ARM_PC && _ARMModeHasSPSR(ARMPSRGetPriv(cpu->cpsr))) { \ + if (rd == ARM_PC && _ARMModeHasSPSR(cpu->cpsr.priv)) { \ cpu->cpsr = cpu->spsr; \ _ARMReadCPSR(cpu); \ } else { \ - ARMPSR cpsr = 0; \ - cpsr = ARMPSROrUnsafeN(cpsr, ARM_SIGN(D)); \ - cpsr = ARMPSROrUnsafeZ(cpsr, !(D)); \ - cpsr = ARMPSROrUnsafeC(cpsr, ARM_CARRY_FROM_CARRY(M, N, D, C)); \ - cpsr = ARMPSROrUnsafeV(cpsr, ARM_V_ADDITION(M, N, D)); \ - cpu->cpsr = (cpu->cpsr & (0x0FFFFFFF)) | cpsr; \ + cpu->cpsr.n = ARM_SIGN(D); \ + cpu->cpsr.z = !(D); \ + cpu->cpsr.c = ARM_CARRY_FROM(M, N, D); \ + cpu->cpsr.v = ARM_V_ADDITION(M, N, D); \ } #define ARM_SUBTRACTION_S(M, N, D) \ - if (rd == ARM_PC && _ARMModeHasSPSR(ARMPSRGetPriv(cpu->cpsr))) { \ + if (rd == ARM_PC && _ARMModeHasSPSR(cpu->cpsr.priv)) { \ cpu->cpsr = cpu->spsr; \ _ARMReadCPSR(cpu); \ } else { \ - ARMPSR cpsr = 0; \ - cpsr = ARMPSROrUnsafeN(cpsr, ARM_SIGN(D)); \ - cpsr = ARMPSROrUnsafeZ(cpsr, !(D)); \ - cpsr = ARMPSROrUnsafeC(cpsr, ARM_BORROW_FROM(M, N, D)); \ - cpsr = ARMPSROrUnsafeV(cpsr, ARM_V_SUBTRACTION(M, N, D)); \ - cpu->cpsr = (cpu->cpsr & (0x0FFFFFFF)) | cpsr; \ + cpu->cpsr.n = ARM_SIGN(D); \ + cpu->cpsr.z = !(D); \ + cpu->cpsr.c = ARM_BORROW_FROM(M, N, D); \ + cpu->cpsr.v = ARM_V_SUBTRACTION(M, N, D); \ } #define ARM_SUBTRACTION_CARRY_S(M, N, D, C) \ - if (rd == ARM_PC && _ARMModeHasSPSR(ARMPSRGetPriv(cpu->cpsr))) { \ + if (rd == ARM_PC && _ARMModeHasSPSR(cpu->cpsr.priv)) { \ cpu->cpsr = cpu->spsr; \ _ARMReadCPSR(cpu); \ } else { \ - ARMPSR cpsr = 0; \ - cpsr = ARMPSROrUnsafeN(cpsr, ARM_SIGN(D)); \ - cpsr = ARMPSROrUnsafeZ(cpsr, !(D)); \ - cpsr = ARMPSROrUnsafeC(cpsr, ARM_BORROW_FROM_CARRY(M, N, D, C)); \ - cpsr = ARMPSROrUnsafeV(cpsr, ARM_V_SUBTRACTION(M, N, D)); \ - cpu->cpsr = (cpu->cpsr & (0x0FFFFFFF)) | cpsr; \ + cpu->cpsr.n = ARM_SIGN(D); \ + cpu->cpsr.z = !(D); \ + cpu->cpsr.c = ARM_BORROW_FROM_CARRY(M, N, D, C); \ + cpu->cpsr.v = ARM_V_SUBTRACTION(M, N, D); \ } #define ARM_NEUTRAL_S(M, N, D) \ - if (rd == ARM_PC && _ARMModeHasSPSR(ARMPSRGetPriv(cpu->cpsr))) { \ + if (rd == ARM_PC && _ARMModeHasSPSR(cpu->cpsr.priv)) { \ cpu->cpsr = cpu->spsr; \ _ARMReadCPSR(cpu); \ } else { \ - ARMPSR cpsr = 0; \ - cpsr = ARMPSROrUnsafeN(cpsr, ARM_SIGN(D)); \ - cpsr = ARMPSROrUnsafeZ(cpsr, !(D)); \ - cpsr = ARMPSROrUnsafeC(cpsr, cpu->shifterCarryOut); \ - cpu->cpsr = (cpu->cpsr & (0x1FFFFFFF)) | cpsr; \ + cpu->cpsr.n = ARM_SIGN(D); \ + cpu->cpsr.z = !(D); \ + cpu->cpsr.c = cpu->shifterCarryOut; \ } #define ARM_NEUTRAL_HI_S(DLO, DHI) \ - { \ - ARMPSR cpsr = 0; \ - cpsr = ARMPSROrUnsafeN(cpsr, ARM_SIGN(DHI)); \ - cpsr = ARMPSROrUnsafeZ(cpsr, !((DHI) | (DLO))); \ - cpu->cpsr = (cpu->cpsr & (0x3FFFFFFF)) | cpsr; \ - } + cpu->cpsr.n = ARM_SIGN(DHI); \ + cpu->cpsr.z = !((DHI) | (DLO)); #define ADDR_MODE_2_I_TEST (opcode & 0x00000F80) #define ADDR_MODE_2_I ((opcode & 0x00000F80) >> 7)@@ -272,7 +247,7 @@
#define ADDR_MODE_2_LSL (cpu->gprs[rm] << ADDR_MODE_2_I) #define ADDR_MODE_2_LSR (ADDR_MODE_2_I_TEST ? ((uint32_t) cpu->gprs[rm]) >> ADDR_MODE_2_I : 0) #define ADDR_MODE_2_ASR (ADDR_MODE_2_I_TEST ? ((int32_t) cpu->gprs[rm]) >> ADDR_MODE_2_I : ((int32_t) cpu->gprs[rm]) >> 31) -#define ADDR_MODE_2_ROR (ADDR_MODE_2_I_TEST ? ROR(cpu->gprs[rm], ADDR_MODE_2_I) : (ARMPSRGetC(cpu->cpsr) << 31) | (((uint32_t) cpu->gprs[rm]) >> 1)) +#define ADDR_MODE_2_ROR (ADDR_MODE_2_I_TEST ? ROR(cpu->gprs[rm], ADDR_MODE_2_I) : (cpu->cpsr.c << 31) | (((uint32_t) cpu->gprs[rm]) >> 1)) #define ADDR_MODE_3_ADDRESS ADDR_MODE_2_ADDRESS #define ADDR_MODE_3_RN ADDR_MODE_2_RN@@ -473,9 +448,9 @@ DEFINE_ALU_INSTRUCTION_ARM(ADD, ARM_ADDITION_S(n, cpu->shifterOperand, cpu->gprs[rd]),
int32_t n = cpu->gprs[rn]; cpu->gprs[rd] = n + cpu->shifterOperand;) -DEFINE_ALU_INSTRUCTION_ARM(ADC, ARM_ADDITION_CARRY_S(n, cpu->shifterOperand, cpu->gprs[rd], ARMPSRGetC(cpu->cpsr)), +DEFINE_ALU_INSTRUCTION_ARM(ADC, ARM_ADDITION_S(n, cpu->shifterOperand, cpu->gprs[rd]), int32_t n = cpu->gprs[rn]; - cpu->gprs[rd] = n + cpu->shifterOperand + ARMPSRGetC(cpu->cpsr);) + cpu->gprs[rd] = n + cpu->shifterOperand + cpu->cpsr.c;) DEFINE_ALU_INSTRUCTION_ARM(AND, ARM_NEUTRAL_S(cpu->gprs[rn], cpu->shifterOperand, cpu->gprs[rd]), cpu->gprs[rd] = cpu->gprs[rn] & cpu->shifterOperand;)@@ -505,13 +480,13 @@ DEFINE_ALU_INSTRUCTION_ARM(RSB, ARM_SUBTRACTION_S(cpu->shifterOperand, n, cpu->gprs[rd]),
int32_t n = cpu->gprs[rn]; cpu->gprs[rd] = cpu->shifterOperand - n;) -DEFINE_ALU_INSTRUCTION_ARM(RSC, ARM_SUBTRACTION_CARRY_S(cpu->shifterOperand, n, cpu->gprs[rd], !ARMPSRIsC(cpu->cpsr)), +DEFINE_ALU_INSTRUCTION_ARM(RSC, ARM_SUBTRACTION_CARRY_S(cpu->shifterOperand, n, cpu->gprs[rd], !cpu->cpsr.c), int32_t n = cpu->gprs[rn]; - cpu->gprs[rd] = cpu->shifterOperand - n - !ARMPSRIsC(cpu->cpsr);) + cpu->gprs[rd] = cpu->shifterOperand - n - !cpu->cpsr.c;) -DEFINE_ALU_INSTRUCTION_ARM(SBC, ARM_SUBTRACTION_CARRY_S(n, cpu->shifterOperand, cpu->gprs[rd], !ARMPSRIsC(cpu->cpsr)), +DEFINE_ALU_INSTRUCTION_ARM(SBC, ARM_SUBTRACTION_CARRY_S(n, cpu->shifterOperand, cpu->gprs[rd], !cpu->cpsr.c), int32_t n = cpu->gprs[rn]; - cpu->gprs[rd] = n - cpu->shifterOperand - !ARMPSRIsC(cpu->cpsr);) + cpu->gprs[rd] = n - cpu->shifterOperand - !cpu->cpsr.c;) DEFINE_ALU_INSTRUCTION_ARM(SUB, ARM_SUBTRACTION_S(n, cpu->shifterOperand, cpu->gprs[rd]), int32_t n = cpu->gprs[rn];@@ -677,14 +652,14 @@ int f = opcode & 0x00080000;
int32_t operand = cpu->gprs[opcode & 0x0000000F]; int32_t mask = (c ? 0x000000FF : 0) | (f ? 0xFF000000 : 0); if (mask & PSR_USER_MASK) { - cpu->cpsr = (cpu->cpsr & ~PSR_USER_MASK) | (operand & PSR_USER_MASK); + cpu->cpsr.packed = (cpu->cpsr.packed & ~PSR_USER_MASK) | (operand & PSR_USER_MASK); } if (mask & PSR_STATE_MASK) { - cpu->cpsr = (cpu->cpsr & ~PSR_STATE_MASK) | (operand & PSR_STATE_MASK); + cpu->cpsr.packed = (cpu->cpsr.packed & ~PSR_STATE_MASK) | (operand & PSR_STATE_MASK); } if (cpu->privilegeMode != MODE_USER && (mask & PSR_PRIV_MASK)) { ARMSetPrivilegeMode(cpu, (enum PrivilegeMode) ((operand & 0x0000000F) | 0x00000010)); - cpu->cpsr = (cpu->cpsr & ~PSR_PRIV_MASK) | (operand & PSR_PRIV_MASK); + cpu->cpsr.packed = (cpu->cpsr.packed & ~PSR_PRIV_MASK) | (operand & PSR_PRIV_MASK); } _ARMReadCPSR(cpu); if (cpu->executionMode == MODE_THUMB) {@@ -701,15 +676,15 @@ int f = opcode & 0x00080000;
int32_t operand = cpu->gprs[opcode & 0x0000000F]; int32_t mask = (c ? 0x000000FF : 0) | (f ? 0xFF000000 : 0); mask &= PSR_USER_MASK | PSR_PRIV_MASK | PSR_STATE_MASK; - cpu->spsr = (cpu->spsr & ~mask) | (operand & mask) | 0x00000010;) + cpu->spsr.packed = (cpu->spsr.packed & ~mask) | (operand & mask) | 0x00000010;) DEFINE_INSTRUCTION_ARM(MRS, \ int rd = (opcode >> 12) & 0xF; \ - cpu->gprs[rd] = cpu->cpsr;) + cpu->gprs[rd] = cpu->cpsr.packed;) DEFINE_INSTRUCTION_ARM(MRSR, \ int rd = (opcode >> 12) & 0xF; \ - cpu->gprs[rd] = cpu->spsr;) + cpu->gprs[rd] = cpu->spsr.packed;) DEFINE_INSTRUCTION_ARM(MSRI, int c = opcode & 0x00010000;@@ -718,14 +693,14 @@ int rotate = (opcode & 0x00000F00) >> 7;
int32_t operand = ROR(opcode & 0x000000FF, rotate); int32_t mask = (c ? 0x000000FF : 0) | (f ? 0xFF000000 : 0); if (mask & PSR_USER_MASK) { - cpu->cpsr = (cpu->cpsr & ~PSR_USER_MASK) | (operand & PSR_USER_MASK); + cpu->cpsr.packed = (cpu->cpsr.packed & ~PSR_USER_MASK) | (operand & PSR_USER_MASK); } if (mask & PSR_STATE_MASK) { - cpu->cpsr = (cpu->cpsr & ~PSR_STATE_MASK) | (operand & PSR_STATE_MASK); + cpu->cpsr.packed = (cpu->cpsr.packed & ~PSR_STATE_MASK) | (operand & PSR_STATE_MASK); } if (cpu->privilegeMode != MODE_USER && (mask & PSR_PRIV_MASK)) { ARMSetPrivilegeMode(cpu, (enum PrivilegeMode) ((operand & 0x0000000F) | 0x00000010)); - cpu->cpsr = (cpu->cpsr & ~PSR_PRIV_MASK) | (operand & PSR_PRIV_MASK); + cpu->cpsr.packed = (cpu->cpsr.packed & ~PSR_PRIV_MASK) | (operand & PSR_PRIV_MASK); } _ARMReadCPSR(cpu); if (cpu->executionMode == MODE_THUMB) {@@ -743,7 +718,7 @@ int rotate = (opcode & 0x00000F00) >> 7;
int32_t operand = ROR(opcode & 0x000000FF, rotate); int32_t mask = (c ? 0x000000FF : 0) | (f ? 0xFF000000 : 0); mask &= PSR_USER_MASK | PSR_PRIV_MASK | PSR_STATE_MASK; - cpu->spsr = (cpu->spsr & ~mask) | (operand & mask) | 0x00000010;) + cpu->spsr.packed = (cpu->spsr.packed & ~mask) | (operand & mask) | 0x00000010;) DEFINE_INSTRUCTION_ARM(SWI, cpu->irqh.swi32(cpu, opcode & 0xFFFFFF))
@@ -12,42 +12,20 @@ // Instruction definitions
// Beware pre-processor insanity #define THUMB_ADDITION_S(M, N, D) \ - { \ - ARMPSR cpsr = 0; \ - cpsr = ARMPSROrUnsafeN(cpsr, ARM_SIGN(D)); \ - cpsr = ARMPSROrUnsafeZ(cpsr, !(D)); \ - cpsr = ARMPSROrUnsafeC(cpsr, ARM_CARRY_FROM(M, N, D)); \ - cpsr = ARMPSROrUnsafeV(cpsr, ARM_V_ADDITION(M, N, D)); \ - cpu->cpsr = (cpu->cpsr & (0x0FFFFFFF)) | cpsr; \ - } - -#define THUMB_ADDITION_CARRY_S(M, N, D, C) \ - { \ - ARMPSR cpsr = 0; \ - cpsr = ARMPSROrUnsafeN(cpsr, ARM_SIGN(D)); \ - cpsr = ARMPSROrUnsafeZ(cpsr, !(D)); \ - cpsr = ARMPSROrUnsafeC(cpsr, ARM_CARRY_FROM_CARRY(M, N, D, C)); \ - cpsr = ARMPSROrUnsafeV(cpsr, ARM_V_ADDITION(M, N, D)); \ - cpu->cpsr = (cpu->cpsr & (0x0FFFFFFF)) | cpsr; \ - } + cpu->cpsr.n = ARM_SIGN(D); \ + cpu->cpsr.z = !(D); \ + cpu->cpsr.c = ARM_CARRY_FROM(M, N, D); \ + cpu->cpsr.v = ARM_V_ADDITION(M, N, D); #define THUMB_SUBTRACTION_S(M, N, D) \ - { \ - ARMPSR cpsr = 0; \ - cpsr = ARMPSROrUnsafeN(cpsr, ARM_SIGN(D)); \ - cpsr = ARMPSROrUnsafeZ(cpsr, !(D)); \ - cpsr = ARMPSROrUnsafeC(cpsr, ARM_BORROW_FROM(M, N, D)); \ - cpsr = ARMPSROrUnsafeV(cpsr, ARM_V_SUBTRACTION(M, N, D)); \ - cpu->cpsr = (cpu->cpsr & (0x0FFFFFFF)) | cpsr; \ - } + cpu->cpsr.n = ARM_SIGN(D); \ + cpu->cpsr.z = !(D); \ + cpu->cpsr.c = ARM_BORROW_FROM(M, N, D); \ + cpu->cpsr.v = ARM_V_SUBTRACTION(M, N, D); #define THUMB_NEUTRAL_S(M, N, D) \ -{ \ - ARMPSR cpsr = 0; \ - cpsr = ARMPSROrUnsafeN(cpsr, ARM_SIGN(D)); \ - cpsr = ARMPSROrUnsafeZ(cpsr, !(D)); \ - cpu->cpsr = (cpu->cpsr & (0x3FFFFFFF)) | cpsr; \ - } + cpu->cpsr.n = ARM_SIGN(D); \ + cpu->cpsr.z = !(D); #define THUMB_ADDITION(D, M, N) \ int n = N; \@@ -87,31 +65,31 @@ DEFINE_IMMEDIATE_5_INSTRUCTION_THUMB(LSL1,
if (!immediate) { cpu->gprs[rd] = cpu->gprs[rm]; } else { - cpu->cpsr = ARMPSRSetC(cpu->cpsr, (cpu->gprs[rm] >> (32 - immediate)) & 1); + cpu->cpsr.c = (cpu->gprs[rm] >> (32 - immediate)) & 1; cpu->gprs[rd] = cpu->gprs[rm] << immediate; } THUMB_NEUTRAL_S( , , cpu->gprs[rd]);) DEFINE_IMMEDIATE_5_INSTRUCTION_THUMB(LSR1, if (!immediate) { - cpu->cpsr = ARMPSRSetC(cpu->cpsr, ARM_SIGN(cpu->gprs[rm])); + cpu->cpsr.c = ARM_SIGN(cpu->gprs[rm]); cpu->gprs[rd] = 0; } else { - cpu->cpsr = ARMPSRSetC(cpu->cpsr, (cpu->gprs[rm] >> (immediate - 1)) & 1); + cpu->cpsr.c = (cpu->gprs[rm] >> (immediate - 1)) & 1; cpu->gprs[rd] = ((uint32_t) cpu->gprs[rm]) >> immediate; } THUMB_NEUTRAL_S( , , cpu->gprs[rd]);) DEFINE_IMMEDIATE_5_INSTRUCTION_THUMB(ASR1, if (!immediate) { - cpu->cpsr = ARMPSRSetC(cpu->cpsr, ARM_SIGN(cpu->gprs[rm])); - if (ARMPSRIsC(cpu->cpsr)) { + cpu->cpsr.c = ARM_SIGN(cpu->gprs[rm]); + if (cpu->cpsr.c) { cpu->gprs[rd] = 0xFFFFFFFF; } else { cpu->gprs[rd] = 0; } } else { - cpu->cpsr = ARMPSRSetC(cpu->cpsr, (cpu->gprs[rm] >> (immediate - 1)) & 1); + cpu->cpsr.c = (cpu->gprs[rm] >> (immediate - 1)) & 1; cpu->gprs[rd] = cpu->gprs[rm] >> immediate; } THUMB_NEUTRAL_S( , , cpu->gprs[rd]);)@@ -166,13 +144,13 @@ DEFINE_DATA_FORM_5_INSTRUCTION_THUMB(LSL2,
int rs = cpu->gprs[rn] & 0xFF; if (rs) { if (rs < 32) { - cpu->cpsr = ARMPSRSetC(cpu->cpsr, (cpu->gprs[rd] >> (32 - rs)) & 1); + cpu->cpsr.c = (cpu->gprs[rd] >> (32 - rs)) & 1; cpu->gprs[rd] <<= rs; } else { if (rs > 32) { - cpu->cpsr = ARMPSRClearC(cpu->cpsr); + cpu->cpsr.c = 0; } else { - cpu->cpsr = ARMPSRSetC(cpu->cpsr, cpu->gprs[rd] & 0x00000001); + cpu->cpsr.c = cpu->gprs[rd] & 0x00000001; } cpu->gprs[rd] = 0; }@@ -183,13 +161,13 @@ DEFINE_DATA_FORM_5_INSTRUCTION_THUMB(LSR2,
int rs = cpu->gprs[rn] & 0xFF; if (rs) { if (rs < 32) { - cpu->cpsr = ARMPSRSetC(cpu->cpsr, (cpu->gprs[rd] >> (rs - 1)) & 1); + cpu->cpsr.c = (cpu->gprs[rd] >> (rs - 1)) & 1; cpu->gprs[rd] = (uint32_t) cpu->gprs[rd] >> rs; } else { if (rs > 32) { - cpu->cpsr = ARMPSRClearC(cpu->cpsr); + cpu->cpsr.c = 0; } else { - cpu->cpsr = ARMPSRSetC(cpu->cpsr, ARM_SIGN(cpu->gprs[rd])); + cpu->cpsr.c = ARM_SIGN(cpu->gprs[rd]); } cpu->gprs[rd] = 0; }@@ -200,11 +178,11 @@ DEFINE_DATA_FORM_5_INSTRUCTION_THUMB(ASR2,
int rs = cpu->gprs[rn] & 0xFF; if (rs) { if (rs < 32) { - cpu->cpsr = ARMPSRSetC(cpu->cpsr, (cpu->gprs[rd] >> (rs - 1)) & 1); + cpu->cpsr.c = (cpu->gprs[rd] >> (rs - 1)) & 1; cpu->gprs[rd] >>= rs; } else { - cpu->cpsr = ARMPSRSetC(cpu->cpsr, ARM_SIGN(cpu->gprs[rd])); - if (ARMPSRIsC(cpu->cpsr)) { + cpu->cpsr.c = ARM_SIGN(cpu->gprs[rd]); + if (cpu->cpsr.c) { cpu->gprs[rd] = 0xFFFFFFFF; } else { cpu->gprs[rd] = 0;@@ -216,11 +194,11 @@
DEFINE_DATA_FORM_5_INSTRUCTION_THUMB(ADC, int n = cpu->gprs[rn]; int d = cpu->gprs[rd]; - cpu->gprs[rd] = d + n + ARMPSRGetC(cpu->cpsr); - THUMB_ADDITION_CARRY_S(d, n, cpu->gprs[rd], ARMPSRGetC(cpu->cpsr));) + cpu->gprs[rd] = d + n + cpu->cpsr.c; + THUMB_ADDITION_S(d, n, cpu->gprs[rd]);) DEFINE_DATA_FORM_5_INSTRUCTION_THUMB(SBC, - int n = cpu->gprs[rn] + !ARMPSRIsC(cpu->cpsr); + int n = cpu->gprs[rn] + !cpu->cpsr.c; int d = cpu->gprs[rd]; cpu->gprs[rd] = d - n; THUMB_SUBTRACTION_S(d, n, cpu->gprs[rd]);)@@ -229,10 +207,10 @@ int rs = cpu->gprs[rn] & 0xFF;
if (rs) { int r4 = rs & 0x1F; if (r4 > 0) { - cpu->cpsr = ARMPSRSetC(cpu->cpsr, (cpu->gprs[rd] >> (r4 - 1)) & 1); + cpu->cpsr.c = (cpu->gprs[rd] >> (r4 - 1)) & 1; cpu->gprs[rd] = ROR(cpu->gprs[rd], r4); } else { - cpu->cpsr = ARMPSRSetC(cpu->cpsr, ARM_SIGN(cpu->gprs[rd])); + cpu->cpsr.c = ARM_SIGN(cpu->gprs[rd]); } } THUMB_NEUTRAL_S( , , cpu->gprs[rd]);)
@@ -325,7 +325,7 @@ for (r = 0; r < ARM_PC; ++r) {
_int2hex32(cpu->gprs[r], &stub->outgoing[i]); i += 8; } - _int2hex32(cpu->gprs[ARM_PC] - (ARMPSRIsT(cpu->cpsr) ? WORD_SIZE_THUMB : WORD_SIZE_ARM), &stub->outgoing[i]); + _int2hex32(cpu->gprs[ARM_PC] - (cpu->cpsr.t ? WORD_SIZE_THUMB : WORD_SIZE_ARM), &stub->outgoing[i]); i += 8; stub->outgoing[i] = 0;@@ -359,7 +359,7 @@ THUMB_WRITE_PC;
} } } else if (reg == 0x19) { - cpu->cpsr = value; + cpu->cpsr.packed = value; } else { stub->outgoing[0] = '\0'; _sendMessage(stub);@@ -379,7 +379,7 @@ uint32_t value;
if (reg < 0x10) { value = cpu->gprs[reg]; } else if (reg == 0x19) { - value = cpu->cpsr; + value = cpu->cpsr.packed; } else { stub->outgoing[0] = '\0'; _sendMessage(stub);
@@ -25,11 +25,11 @@
static void _SoftReset(struct GBA* gba) { struct ARMCore* cpu = gba->cpu; ARMSetPrivilegeMode(cpu, MODE_IRQ); - cpu->spsr = 0; + cpu->spsr.packed = 0; cpu->gprs[ARM_LR] = 0; cpu->gprs[ARM_SP] = SP_BASE_IRQ; ARMSetPrivilegeMode(cpu, MODE_SUPERVISOR); - cpu->spsr = 0; + cpu->spsr.packed = 0; cpu->gprs[ARM_LR] = 0; cpu->gprs[ARM_SP] = SP_BASE_SUPERVISOR; ARMSetPrivilegeMode(cpu, MODE_SYSTEM);
@@ -227,7 +227,7 @@ if (cpu->executionMode == MODE_THUMB) {
gba->bus |= cpu->prefetch[1] << 16; } - if (gba->springIRQ && !ARMPSRIsI(cpu->cpsr)) { + if (gba->springIRQ && !cpu->cpsr.i) { ARMRaiseIRQ(cpu); gba->springIRQ = 0; }
@@ -42,8 +42,8 @@ int i;
for (i = 0; i < 16; ++i) { STORE_32(gba->cpu->gprs[i], i * sizeof(state->cpu.gprs[0]), state->cpu.gprs); } - STORE_32(gba->cpu->cpsr, 0, &state->cpu.cpsr); - STORE_32(gba->cpu->spsr, 0, &state->cpu.spsr); + STORE_32(gba->cpu->cpsr.packed, 0, &state->cpu.cpsr.packed); + STORE_32(gba->cpu->spsr.packed, 0, &state->cpu.spsr.packed); STORE_32(gba->cpu->cycles, 0, &state->cpu.cycles); STORE_32(gba->cpu->nextEvent, 0, &state->cpu.nextEvent); for (i = 0; i < 6; ++i) {@@ -151,8 +151,8 @@ size_t i;
for (i = 0; i < 16; ++i) { LOAD_32(gba->cpu->gprs[i], i * sizeof(gba->cpu->gprs[0]), state->cpu.gprs); } - LOAD_32(gba->cpu->cpsr, 0, &state->cpu.cpsr); - LOAD_32(gba->cpu->spsr, 0, &state->cpu.spsr); + LOAD_32(gba->cpu->cpsr.packed, 0, &state->cpu.cpsr.packed); + LOAD_32(gba->cpu->spsr.packed, 0, &state->cpu.spsr.packed); LOAD_32(gba->cpu->cycles, 0, &state->cpu.cycles); LOAD_32(gba->cpu->nextEvent, 0, &state->cpu.nextEvent); for (i = 0; i < 6; ++i) {@@ -162,13 +162,13 @@ LOAD_32(gba->cpu->bankedRegisters[i][j], (i * 7 + j) * sizeof(gba->cpu->bankedRegisters[0][0]), state->cpu.bankedRegisters);
} LOAD_32(gba->cpu->bankedSPSRs[i], i * sizeof(gba->cpu->bankedSPSRs[0]), state->cpu.bankedSPSRs); } - gba->cpu->privilegeMode = ARMPSRGetPriv(gba->cpu->cpsr); + gba->cpu->privilegeMode = gba->cpu->cpsr.priv; gba->cpu->memory.setActiveRegion(gba->cpu, gba->cpu->gprs[ARM_PC]); if (state->biosPrefetch) { LOAD_32(gba->memory.biosPrefetch, 0, &state->biosPrefetch); } LOAD_32(gba->memory.lastPrefetchedPc, 0, &state->lastPrefetchedPc); - if (ARMPSRIsT(gba->cpu->cpsr)) { + if (gba->cpu->cpsr.t) { gba->cpu->executionMode = MODE_THUMB; if (state->cpuPrefetch[0] && state->cpuPrefetch[1]) { LOAD_32(gba->cpu->prefetch[0], 0, state->cpuPrefetch);