mirror of https://github.com/mgba-emu/mgba.git
ARM7: Fix flags on SBC/RSC
This commit is contained in:
parent
62076d885c
commit
feb5ad2260
1
CHANGES
1
CHANGES
|
@ -24,6 +24,7 @@ Bugfixes:
|
|||
- Util: Fix socket bind addresses
|
||||
- All: Fix instruction tables getting zeroed when linking sometimes
|
||||
- SDL: Fix SDL 1.2 build
|
||||
- ARM7: Fix flags on SBC/RSC
|
||||
Misc:
|
||||
- GBA: Slightly optimize GBAProcessEvents
|
||||
- Qt: Add preset for DualShock 4
|
||||
|
|
|
@ -184,8 +184,6 @@ static inline void _immediate(struct ARMCore* cpu, uint32_t opcode) {
|
|||
// Instruction definitions
|
||||
// Beware pre-processor antics
|
||||
|
||||
#define NO_EXTEND64(V) (uint64_t)(uint32_t) (V)
|
||||
|
||||
#define ARM_ADDITION_S(M, N, D) \
|
||||
if (rd == ARM_PC && _ARMModeHasSPSR(cpu->cpsr.priv)) { \
|
||||
cpu->cpsr = cpu->spsr; \
|
||||
|
@ -208,6 +206,17 @@ static inline void _immediate(struct ARMCore* cpu, uint32_t opcode) {
|
|||
cpu->cpsr.v = ARM_V_SUBTRACTION(M, N, D); \
|
||||
}
|
||||
|
||||
#define ARM_SUBTRACTION_CARRY_S(M, N, D, C) \
|
||||
if (rd == ARM_PC && _ARMModeHasSPSR(cpu->cpsr.priv)) { \
|
||||
cpu->cpsr = cpu->spsr; \
|
||||
_ARMReadCPSR(cpu); \
|
||||
} else { \
|
||||
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(cpu->cpsr.priv)) { \
|
||||
cpu->cpsr = cpu->spsr; \
|
||||
|
@ -454,14 +463,13 @@ DEFINE_ALU_INSTRUCTION_ARM(RSB, ARM_SUBTRACTION_S(cpu->shifterOperand, n, cpu->g
|
|||
int32_t n = cpu->gprs[rn];
|
||||
cpu->gprs[rd] = cpu->shifterOperand - n;)
|
||||
|
||||
DEFINE_ALU_INSTRUCTION_ARM(RSC, ARM_SUBTRACTION_S(cpu->shifterOperand, n, cpu->gprs[rd]),
|
||||
int32_t n = cpu->gprs[rn] + !cpu->cpsr.c;
|
||||
cpu->gprs[rd] = cpu->shifterOperand - n;)
|
||||
|
||||
DEFINE_ALU_INSTRUCTION_ARM(SBC, ARM_SUBTRACTION_S(n, shifterOperand, cpu->gprs[rd]),
|
||||
DEFINE_ALU_INSTRUCTION_ARM(RSC, ARM_SUBTRACTION_CARRY_S(cpu->shifterOperand, n, cpu->gprs[rd], !cpu->cpsr.c),
|
||||
int32_t n = cpu->gprs[rn];
|
||||
int32_t shifterOperand = cpu->shifterOperand + !cpu->cpsr.c;
|
||||
cpu->gprs[rd] = n - shifterOperand;)
|
||||
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];
|
||||
|
@ -495,7 +503,7 @@ DEFINE_MULTIPLY_INSTRUCTION_ARM(SMULL,
|
|||
ARM_NEUTRAL_HI_S(cpu->gprs[rd], cpu->gprs[rdHi]))
|
||||
|
||||
DEFINE_MULTIPLY_INSTRUCTION_ARM(UMLAL,
|
||||
uint64_t d = NO_EXTEND64(cpu->gprs[rm]) * NO_EXTEND64(cpu->gprs[rs]);
|
||||
uint64_t d = ARM_UXT_64(cpu->gprs[rm]) * ARM_UXT_64(cpu->gprs[rs]);
|
||||
int32_t dm = cpu->gprs[rd];
|
||||
int32_t dn = d;
|
||||
cpu->gprs[rd] = dm + dn;
|
||||
|
@ -503,7 +511,7 @@ DEFINE_MULTIPLY_INSTRUCTION_ARM(UMLAL,
|
|||
ARM_NEUTRAL_HI_S(cpu->gprs[rd], cpu->gprs[rdHi]))
|
||||
|
||||
DEFINE_MULTIPLY_INSTRUCTION_ARM(UMULL,
|
||||
uint64_t d = NO_EXTEND64(cpu->gprs[rm]) * NO_EXTEND64(cpu->gprs[rs]);
|
||||
uint64_t d = ARM_UXT_64(cpu->gprs[rm]) * ARM_UXT_64(cpu->gprs[rs]);
|
||||
cpu->gprs[rd] = d;
|
||||
cpu->gprs[rdHi] = d >> 32;,
|
||||
ARM_NEUTRAL_HI_S(cpu->gprs[rd], cpu->gprs[rdHi]))
|
||||
|
|
|
@ -29,9 +29,11 @@
|
|||
#define ARM_SIGN(I) ((I) >> 31)
|
||||
#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) (((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))))
|
||||
#define ARM_V_SUBTRACTION(M, N, D) ((ARM_SIGN((M) ^ (N))) && (ARM_SIGN((M) ^ (D))))
|
||||
|
||||
|
|
Loading…
Reference in New Issue