mirror of https://github.com/mgba-emu/mgba.git
ARM: Fix ALU reading PC after shifting
This commit is contained in:
parent
8b9cd78d0f
commit
27882fbded
1
CHANGES
1
CHANGES
|
@ -1,5 +1,6 @@
|
|||
0.9.0: (Future)
|
||||
Emulation fixes:
|
||||
- ARM: Fix ALU reading PC after shifting
|
||||
- GBA Memory: Misaligned SRAM writes are ignored
|
||||
Other fixes:
|
||||
- Qt: Only dynamically reset video scale if a game is running
|
||||
|
|
|
@ -302,7 +302,10 @@ ATTRIBUTE_NOINLINE static void _neutralS(struct ARMCore* cpu, int32_t d) {
|
|||
DEFINE_INSTRUCTION_ARM(NAME, \
|
||||
int rd = (opcode >> 12) & 0xF; \
|
||||
int rn = (opcode >> 16) & 0xF; \
|
||||
UNUSED(rn); \
|
||||
int32_t n = cpu->gprs[rn]; \
|
||||
if (UNLIKELY(rn == ARM_PC && (opcode & 0x02000010) == 0x00000010)) { \
|
||||
n += WORD_SIZE_ARM; \
|
||||
} \
|
||||
SHIFTER(cpu, opcode); \
|
||||
BODY; \
|
||||
S_BODY; \
|
||||
|
@ -465,58 +468,52 @@ ATTRIBUTE_NOINLINE static void _neutralS(struct ARMCore* cpu, int32_t d) {
|
|||
// Begin ALU definitions
|
||||
|
||||
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_S(n, cpu->shifterOperand, cpu->gprs[rd]),
|
||||
int32_t n = cpu->gprs[rn];
|
||||
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;)
|
||||
DEFINE_ALU_INSTRUCTION_ARM(AND, ARM_NEUTRAL_S(n, cpu->shifterOperand, cpu->gprs[rd]),
|
||||
cpu->gprs[rd] = n & cpu->shifterOperand;)
|
||||
|
||||
DEFINE_ALU_INSTRUCTION_ARM(BIC, ARM_NEUTRAL_S(cpu->gprs[rn], cpu->shifterOperand, cpu->gprs[rd]),
|
||||
cpu->gprs[rd] = cpu->gprs[rn] & ~cpu->shifterOperand;)
|
||||
DEFINE_ALU_INSTRUCTION_ARM(BIC, ARM_NEUTRAL_S(n, cpu->shifterOperand, cpu->gprs[rd]),
|
||||
cpu->gprs[rd] = n & ~cpu->shifterOperand;)
|
||||
|
||||
DEFINE_ALU_INSTRUCTION_S_ONLY_ARM(CMN, ARM_ADDITION_S(cpu->gprs[rn], cpu->shifterOperand, aluOut),
|
||||
int32_t aluOut = cpu->gprs[rn] + cpu->shifterOperand;)
|
||||
DEFINE_ALU_INSTRUCTION_S_ONLY_ARM(CMN, ARM_ADDITION_S(n, cpu->shifterOperand, aluOut),
|
||||
int32_t aluOut = n + cpu->shifterOperand;)
|
||||
|
||||
DEFINE_ALU_INSTRUCTION_S_ONLY_ARM(CMP, ARM_SUBTRACTION_S(cpu->gprs[rn], cpu->shifterOperand, aluOut),
|
||||
int32_t aluOut = cpu->gprs[rn] - cpu->shifterOperand;)
|
||||
DEFINE_ALU_INSTRUCTION_S_ONLY_ARM(CMP, ARM_SUBTRACTION_S(n, cpu->shifterOperand, aluOut),
|
||||
int32_t aluOut = n - cpu->shifterOperand;)
|
||||
|
||||
DEFINE_ALU_INSTRUCTION_ARM(EOR, ARM_NEUTRAL_S(cpu->gprs[rn], cpu->shifterOperand, cpu->gprs[rd]),
|
||||
cpu->gprs[rd] = cpu->gprs[rn] ^ cpu->shifterOperand;)
|
||||
DEFINE_ALU_INSTRUCTION_ARM(EOR, ARM_NEUTRAL_S(n, cpu->shifterOperand, cpu->gprs[rd]),
|
||||
cpu->gprs[rd] = n ^ cpu->shifterOperand;)
|
||||
|
||||
DEFINE_ALU_INSTRUCTION_ARM(MOV, ARM_NEUTRAL_S(cpu->gprs[rn], cpu->shifterOperand, cpu->gprs[rd]),
|
||||
DEFINE_ALU_INSTRUCTION_ARM(MOV, ARM_NEUTRAL_S(n, cpu->shifterOperand, cpu->gprs[rd]),
|
||||
cpu->gprs[rd] = cpu->shifterOperand;)
|
||||
|
||||
DEFINE_ALU_INSTRUCTION_ARM(MVN, ARM_NEUTRAL_S(cpu->gprs[rn], cpu->shifterOperand, cpu->gprs[rd]),
|
||||
DEFINE_ALU_INSTRUCTION_ARM(MVN, ARM_NEUTRAL_S(n, cpu->shifterOperand, cpu->gprs[rd]),
|
||||
cpu->gprs[rd] = ~cpu->shifterOperand;)
|
||||
|
||||
DEFINE_ALU_INSTRUCTION_ARM(ORR, ARM_NEUTRAL_S(cpu->gprs[rn], cpu->shifterOperand, cpu->gprs[rd]),
|
||||
cpu->gprs[rd] = cpu->gprs[rn] | cpu->shifterOperand;)
|
||||
DEFINE_ALU_INSTRUCTION_ARM(ORR, ARM_NEUTRAL_S(n, cpu->shifterOperand, cpu->gprs[rd]),
|
||||
cpu->gprs[rd] = n | cpu->shifterOperand;)
|
||||
|
||||
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], !cpu->cpsr.c),
|
||||
int32_t n = cpu->gprs[rn];
|
||||
cpu->gprs[rd] = cpu->shifterOperand - n - !cpu->cpsr.c;)
|
||||
|
||||
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 - !cpu->cpsr.c;)
|
||||
|
||||
DEFINE_ALU_INSTRUCTION_ARM(SUB, ARM_SUBTRACTION_S(n, cpu->shifterOperand, cpu->gprs[rd]),
|
||||
int32_t n = cpu->gprs[rn];
|
||||
cpu->gprs[rd] = n - cpu->shifterOperand;)
|
||||
|
||||
DEFINE_ALU_INSTRUCTION_S_ONLY_ARM(TEQ, ARM_NEUTRAL_S(cpu->gprs[rn], cpu->shifterOperand, aluOut),
|
||||
int32_t aluOut = cpu->gprs[rn] ^ cpu->shifterOperand;)
|
||||
DEFINE_ALU_INSTRUCTION_S_ONLY_ARM(TEQ, ARM_NEUTRAL_S(n, cpu->shifterOperand, aluOut),
|
||||
int32_t aluOut = n ^ cpu->shifterOperand;)
|
||||
|
||||
DEFINE_ALU_INSTRUCTION_S_ONLY_ARM(TST, ARM_NEUTRAL_S(cpu->gprs[rn], cpu->shifterOperand, aluOut),
|
||||
int32_t aluOut = cpu->gprs[rn] & cpu->shifterOperand;)
|
||||
DEFINE_ALU_INSTRUCTION_S_ONLY_ARM(TST, ARM_NEUTRAL_S(n, cpu->shifterOperand, aluOut),
|
||||
int32_t aluOut = n & cpu->shifterOperand;)
|
||||
|
||||
// End ALU definitions
|
||||
|
||||
|
|
Loading…
Reference in New Issue