ARM: Slightly optimize CARRY check
Vicki Pfau vi@endrift.com
Sat, 28 Jan 2017 12:16:26 -0800
3 files changed,
28 insertions(+),
4 deletions(-)
M
include/mgba/internal/arm/isa-inlines.h
→
include/mgba/internal/arm/isa-inlines.h
@@ -31,7 +31,8 @@ #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_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_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))))
M
src/arm/isa-arm.c
→
src/arm/isa-arm.c
@@ -197,6 +197,19 @@ 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))) { \ + 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; \ + } + #define ARM_SUBTRACTION_S(M, N, D) \ if (rd == ARM_PC && _ARMModeHasSPSR(ARMPSRGetPriv(cpu->cpsr))) { \ cpu->cpsr = cpu->spsr; \@@ -240,7 +253,7 @@ { \
ARMPSR cpsr = 0; \ cpsr = ARMPSROrUnsafeN(cpsr, ARM_SIGN(DHI)); \ cpsr = ARMPSROrUnsafeZ(cpsr, !((DHI) | (DLO))); \ - cpu->cpsr = (cpu->cpsr & (0x3FFFFFFF)) | cpsr; \ + cpu->cpsr = (cpu->cpsr & (0x3FFFFFFF)) | cpsr; \ } #define ADDR_MODE_2_I_TEST (opcode & 0x00000F80)@@ -460,7 +473,7 @@ 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]), +DEFINE_ALU_INSTRUCTION_ARM(ADC, ARM_ADDITION_CARRY_S(n, cpu->shifterOperand, cpu->gprs[rd], ARMPSRGetC(cpu->cpsr)), int32_t n = cpu->gprs[rn]; cpu->gprs[rd] = n + cpu->shifterOperand + ARMPSRGetC(cpu->cpsr);)
M
src/arm/isa-thumb.c
→
src/arm/isa-thumb.c
@@ -21,6 +21,16 @@ 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; \ + } + #define THUMB_SUBTRACTION_S(M, N, D) \ { \ ARMPSR cpsr = 0; \@@ -207,7 +217,7 @@ 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_S(d, n, cpu->gprs[rd]);) + THUMB_ADDITION_CARRY_S(d, n, cpu->gprs[rd], ARMPSRGetC(cpu->cpsr));) DEFINE_DATA_FORM_5_INSTRUCTION_THUMB(SBC, int n = cpu->gprs[rn] + !ARMPSRIsC(cpu->cpsr);