diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/dynarec/arm64/arm64_emitter.h | 1 | ||||
| -rw-r--r-- | src/dynarec/arm64/dynarec_arm64_0f.c | 20 |
2 files changed, 13 insertions, 8 deletions
diff --git a/src/dynarec/arm64/arm64_emitter.h b/src/dynarec/arm64/arm64_emitter.h index 6d787a9a..51bcaced 100644 --- a/src/dynarec/arm64/arm64_emitter.h +++ b/src/dynarec/arm64/arm64_emitter.h @@ -180,6 +180,7 @@ int convert_bitmask(uint64_t bitmask); #define ADDx_REG(Rd, Rn, Rm) EMIT(ADDSUB_REG_gen(1, 0, 0, 0b00, Rm, 0, Rn, Rd)) #define ADDSx_REG(Rd, Rn, Rm) FEMIT(ADDSUB_REG_gen(1, 0, 1, 0b00, Rm, 0, Rn, Rd)) #define ADDx_REG_LSL(Rd, Rn, Rm, lsl) EMIT(ADDSUB_REG_gen(1, 0, 0, 0b00, Rm, lsl, Rn, Rd)) +#define ADDz_REG_LSL(Rd, Rn, Rm, lsl) EMIT(ADDSUB_REG_gen(rex.is32bits?0:1, 0, 0, 0b00, Rm, lsl, Rn, Rd)) #define ADDw_REG(Rd, Rn, Rm) EMIT(ADDSUB_REG_gen(0, 0, 0, 0b00, Rm, 0, Rn, Rd)) #define ADDSw_REG(Rd, Rn, Rm) FEMIT(ADDSUB_REG_gen(0, 0, 1, 0b00, Rm, 0, Rn, Rd)) #define ADDw_REG_LSL(Rd, Rn, Rm, lsl) EMIT(ADDSUB_REG_gen(0, 0, 0, 0b00, Rm, lsl, Rn, Rd)) diff --git a/src/dynarec/arm64/dynarec_arm64_0f.c b/src/dynarec/arm64/dynarec_arm64_0f.c index 82a98fe0..d7ea133d 100644 --- a/src/dynarec/arm64/dynarec_arm64_0f.c +++ b/src/dynarec/arm64/dynarec_arm64_0f.c @@ -1639,8 +1639,9 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin } else { SMREAD(); addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, &unscaled, 0xfff<<(2+rex.w), (1<<(2+rex.w))-1, rex, NULL, 0, 0); - ASRx(x1, gd, 5+rex.w); // r1 = (gd>>5) - ADDx_REG_LSL(x3, wback, x1, 2+rex.w); //(&ed)+=r1*4; + ASRxw(x1, gd, 5+rex.w); // r1 = (gd>>5) + if(!rex.w && !rex.is32bits) {SXTWx(x1, x1);} + ADDz_REG_LSL(x3, wback, x1, 2+rex.w); //(&ed)+=r1*4; LDxw(x1, x3, fixedaddress); ed = x1; } @@ -1712,8 +1713,9 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin } else { SMREAD(); addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, &unscaled, 0xfff<<(2+rex.w), (1<<(2+rex.w))-1, rex, NULL, 0, 0); - ASRx(x1, gd, 5+rex.w); // r1 = (gd>>5) - ADDx_REG_LSL(x3, wback, x1, 2+rex.w); //(&ed)+=r1*4; + ASRxw(x1, gd, 5+rex.w); // r1 = (gd>>5) + if(!rex.w && !rex.is32bits) {SXTWx(x1, x1);} + ADDz_REG_LSL(x3, wback, x1, 2+rex.w); //(&ed)+=r1*4; LDxw(x1, x3, fixedaddress); ed = x1; wback = x3; @@ -1951,8 +1953,9 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin } else { SMREAD(); addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, &unscaled, 0xfff<<(2+rex.w), (1<<(2+rex.w))-1, rex, NULL, 0, 0); - ASRx(x1, gd, 5+rex.w); // r1 = (gd>>5) - ADDx_REG_LSL(x3, wback, x1, 2+rex.w); //(&ed)+=r1*4; + ASRxw(x1, gd, 5+rex.w); // r1 = (gd>>5) + if(!rex.w && !rex.is32bits) {SXTWx(x1, x1);} + ADDz_REG_LSL(x3, wback, x1, 2+rex.w); //(&ed)+=r1*4; LDxw(x1, x3, fixedaddress); ed = x1; wback = x3; @@ -2119,8 +2122,9 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin } else { SMREAD(); addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, &unscaled, 0xfff<<(2+rex.w), (1<<(2+rex.w))-1, rex, NULL, 0, 0); - ASRx(x1, gd, 5+rex.w); // r1 = (gd>>5) - ADDx_REG_LSL(x3, wback, x1, 2+rex.w); //(&ed)+=r1*4; + ASRxw(x1, gd, 5+rex.w); // r1 = (gd>>5) + if(!rex.w && !rex.is32bits) {SXTWx(x1, x1);} + ADDz_REG_LSL(x3, wback, x1, 2+rex.w); //(&ed)+=r1*4; LDxw(x1, x3, fixedaddress); ed = x1; wback = x3; |