diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2023-08-04 12:09:49 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-08-04 12:09:49 +0200 |
| commit | 0f7b23148f614b23d58736b95337a5b8f6ecd638 (patch) | |
| tree | d390aaddb858f9f166f7cd296712519f586b6233 /src | |
| parent | 0edf24ae977d812386bf6bc0b5d41b7ab3900a05 (diff) | |
| parent | a46923e4949864da2f505b701bc4f0541b076481 (diff) | |
| download | box64-0f7b23148f614b23d58736b95337a5b8f6ecd638.tar.gz box64-0f7b23148f614b23d58736b95337a5b8f6ecd638.zip | |
Merge pull request #922 from wannacu/main
[ARM64_DYNAREC] Fixed BT/BTC/BTR/BTS opcodes
Diffstat (limited to 'src')
| -rw-r--r-- | src/dynarec/arm64/arm64_emitter.h | 15 | ||||
| -rw-r--r-- | src/dynarec/arm64/arm64_printer.c | 14 | ||||
| -rw-r--r-- | src/dynarec/arm64/dynarec_arm64_0f.c | 19 | ||||
| -rw-r--r-- | src/dynarec/arm64/dynarec_arm64_660f.c | 17 | ||||
| -rw-r--r-- | src/dynarec/arm64/dynarec_arm64_f0.c | 22 |
5 files changed, 55 insertions, 32 deletions
diff --git a/src/dynarec/arm64/arm64_emitter.h b/src/dynarec/arm64/arm64_emitter.h index 7ebc0208..98708b1a 100644 --- a/src/dynarec/arm64/arm64_emitter.h +++ b/src/dynarec/arm64/arm64_emitter.h @@ -537,6 +537,15 @@ #define EORx_REG_LSR(Rd, Rn, Rm, lsr) EMIT(LOGIC_REG_gen(1, 0b10, 0b01, 0, Rm, lsr, Rn, Rd)) #define EORw_REG_LSR(Rd, Rn, Rm, lsr) EMIT(LOGIC_REG_gen(0, 0b10, 0b01, 0, Rm, lsr, Rn, Rd)) #define EORxw_REG_LSR(Rd, Rn, Rm, lsr) EMIT(LOGIC_REG_gen(rex.w, 0b10, 0b01, 0, Rm, lsr, Rn, Rd)) +#define EONx_REG(Rd, Rn, Rm) EMIT(LOGIC_REG_gen(1, 0b10, 0b00, 1, Rm, 0, Rn, Rd)) +#define EONw_REG(Rd, Rn, Rm) EMIT(LOGIC_REG_gen(0, 0b10, 0b00, 1, Rm, 0, Rn, Rd)) +#define EONxw_REG(Rd, Rn, Rm) EMIT(LOGIC_REG_gen(rex.w, 0b10, 0b00, 1, Rm, 0, Rn, Rd)) +#define EONx_REG_LSL(Rd, Rn, Rm, lsl) EMIT(LOGIC_REG_gen(1, 0b10, 0b00, 1, Rm, lsl, Rn, Rd)) +#define EONw_REG_LSL(Rd, Rn, Rm, lsl) EMIT(LOGIC_REG_gen(0, 0b10, 0b00, 1, Rm, lsl, Rn, Rd)) +#define EONxw_REG_LSL(Rd, Rn, Rm, lsl) EMIT(LOGIC_REG_gen(rex.w, 0b10, 0b00, 1, Rm, lsl, Rn, Rd)) +#define EONx_REG_LSR(Rd, Rn, Rm, lsr) EMIT(LOGIC_REG_gen(1, 0b10, 0b01, 1, Rm, lsr, Rn, Rd)) +#define EONw_REG_LSR(Rd, Rn, Rm, lsr) EMIT(LOGIC_REG_gen(0, 0b10, 0b01, 1, Rm, lsr, Rn, Rd)) +#define EONxw_REG_LSR(Rd, Rn, Rm, lsr) EMIT(LOGIC_REG_gen(rex.w, 0b10, 0b01, 1, Rm, lsr, Rn, Rd)) #define MOVx_REG(Rd, Rm) ORRx_REG(Rd, xZR, Rm) #define MOVw_REG(Rd, Rm) ORRw_REG(Rd, xZR, Rm) #define MOVxw_REG(Rd, Rm) ORRxw_REG(Rd, xZR, Rm) @@ -563,6 +572,12 @@ #define BICx_REG BICx #define BICw_REG BICw #define BICxw_REG BICxw +#define BICx_REG_LSL(Rd, Rn, Rm, lsl) EMIT(LOGIC_REG_gen(1, 0b00, 0b00, 1, Rm, lsl, Rn, Rd)) +#define BICw_REG_LSL(Rd, Rn, Rm, lsl) EMIT(LOGIC_REG_gen(0, 0b00, 0b00, 1, Rm, lsl, Rn, Rd)) +#define BICxw_REG_LSL(Rd, Rn, Rm, lsl) EMIT(LOGIC_REG_gen(rex.w, 0b00, 0b00, 1, Rm, lsl, Rn, Rd)) +#define BICx_REG_LSR(Rd, Rn, Rm, lsl) EMIT(LOGIC_REG_gen(1, 0b00, 0b01, 1, Rm, lsl, Rn, Rd)) +#define BICw_REG_LSR(Rd, Rn, Rm, lsl) EMIT(LOGIC_REG_gen(0, 0b00, 0b01, 1, Rm, lsl, Rn, Rd)) +#define BICxw_REG_LSR(Rd, Rn, Rm, lsl) EMIT(LOGIC_REG_gen(rex.w, 0b00, 0b01, 1, Rm, lsl, Rn, Rd)) #define TSTx_REG(Rn, Rm) ANDSx_REG(xZR, Rn, Rm) #define TSTw_REG(Rn, Rm) ANDSw_REG(wZR, Rn, Rm) #define TSTxw_REG(Rn, Rm) ANDSxw_REG(xZR, Rn, Rm) diff --git a/src/dynarec/arm64/arm64_printer.c b/src/dynarec/arm64/arm64_printer.c index ead54a61..2c134dee 100644 --- a/src/dynarec/arm64/arm64_printer.c +++ b/src/dynarec/arm64/arm64_printer.c @@ -1107,7 +1107,19 @@ const char* arm64_print(uint32_t opcode, uintptr_t addr) snprintf(buff, sizeof(buff), "FSQRT %c%d, %c%d", s, Rd, s, Rn); return buff; } - + // FPRINTX + if(isMask(opcode, "0Q1011100f100001100110nnnnnddddd", &a)) { + char s = a.Q?'V':'D'; + char d = sf?'D':'S'; + int n = (a.Q && !sf)?4:2; + snprintf(buff, sizeof(buff), "VFRINTX %c%d.%d%c, %c%d.%d%c", s, Rd, n, d, s, Rn, n, d); + return buff; + } + if (isMask(opcode, "00011110ff100111010000nnnnnddddd", &a)) { + char s = (sf==0)?'S':((sf==1)?'D':'?'); + snprintf(buff, sizeof(buff), "FRINTX %c%d, %c%d", s, Rd, s, Rn); + return buff; + } // FRINTI if(isMask(opcode, "0Q1011101f100001100110nnnnnddddd", &a)) { char s = a.Q?'V':'D'; diff --git a/src/dynarec/arm64/dynarec_arm64_0f.c b/src/dynarec/arm64/dynarec_arm64_0f.c index 00aa61be..ea976365 100644 --- a/src/dynarec/arm64/dynarec_arm64_0f.c +++ b/src/dynarec/arm64/dynarec_arm64_0f.c @@ -1104,7 +1104,7 @@ 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); - ASRxw(x1, gd, 5+rex.w); // r1 = (gd>>5) + ASRx(x1, gd, 5+rex.w); // r1 = (gd>>5) ADDx_REG_LSL(x3, wback, x1, 2+rex.w); //(&ed)+=r1*4; LDxw(x1, x3, fixedaddress); ed = x1; @@ -1152,7 +1152,7 @@ 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); - ASRxw(x1, gd, 5+rex.w); // r1 = (gd>>5) + ASRx(x1, gd, 5+rex.w); // r1 = (gd>>5) ADDx_REG_LSL(x3, wback, x1, 2+rex.w); //(&ed)+=r1*4; LDxw(x1, x3, fixedaddress); ed = x1; @@ -1318,7 +1318,7 @@ 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); - ASRxw(x1, gd, 5+rex.w); // r1 = (gd>>5) + ASRx(x1, gd, 5+rex.w); // r1 = (gd>>5) ADDx_REG_LSL(x3, wback, x1, 2+rex.w); //(&ed)+=r1*4; LDxw(x1, x3, fixedaddress); ed = x1; @@ -1331,15 +1331,14 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin } LSRxw_REG(x4, ed, x2); if(rex.w) { - ANDSx_mask(x4, x4, 1, 0, 0); //mask=1 + ANDx_mask(x4, x4, 1, 0, 0); //mask=1 } else { - ANDSw_mask(x4, x4, 0, 0); //mask=1 + ANDw_mask(x4, x4, 0, 0); //mask=1 } BFIw(xFlags, x4, F_CF, 1); MOV32w(x4, 1); LSLxw_REG(x4, x4, x2); - EORxw_REG(x4, ed, x4); - CSELxw(ed, ed, x4, cEQ); + BICxw_REG(ed, ed, x4); if(wback) { STRxw_U12(ed, wback, fixedaddress); SMWRITE(); @@ -1418,7 +1417,7 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin BFXILxw(xFlags, ed, u8, 1); // inject 1 bit from u8 to F_CF (i.e. pos 0) TBNZ_MARK3(xFlags, 0); // bit already set, jump to next instruction MOV32w(x4, 1); - EORxw_REG_LSL(ed, ed, x4, u8); + ORRxw_REG_LSL(ed, ed, x4, u8); if(wback) { STxw(ed, wback, fixedaddress); SMWRITE(); @@ -1443,7 +1442,7 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin BFXILxw(xFlags, ed, u8, 1); // inject 1 bit from u8 to F_CF (i.e. pos 0) TBZ_MARK3(xFlags, 0); // bit already clear, jump to next instruction MOV32w(x4, 1); - EORxw_REG_LSL(ed, ed, x4, u8); + BICxw_REG_LSL(ed, ed, x4, u8); if(wback) { STxw(ed, wback, fixedaddress); SMWRITE(); @@ -1490,7 +1489,7 @@ 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); - ASRxw(x1, gd, 5+rex.w); // r1 = (gd>>5) + ASRx(x1, gd, 5+rex.w); // r1 = (gd>>5) ADDx_REG_LSL(x3, wback, x1, 2+rex.w); //(&ed)+=r1*4; LDxw(x1, x3, fixedaddress); ed = x1; diff --git a/src/dynarec/arm64/dynarec_arm64_660f.c b/src/dynarec/arm64/dynarec_arm64_660f.c index 509263fb..b4aa13fa 100644 --- a/src/dynarec/arm64/dynarec_arm64_660f.c +++ b/src/dynarec/arm64/dynarec_arm64_660f.c @@ -1756,7 +1756,7 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n } else { SMREAD(); addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, &unscaled, 0xfff<<2, (1<<2)-1, rex, NULL, 0, 0); - SBFXw(x1, gd, 4, 12); // r1 = (gw>>4) + SBFXx(x1, gd, 4, 12); // r1 = (gw>>4) ADDx_REG_LSL(x3, wback, x1, 1); //(&ed)+=r1*2; LDH(x1, x3, fixedaddress); ed = x1; @@ -1797,9 +1797,10 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n wback = 0; } else { addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, &unscaled, 0xfff<<2, (1<<2)-1, rex, NULL, 0, 0); - SBFXw(x4, gd, 4, 12); // r1 = (gw>>4) + SBFXx(x4, gd, 4, 12); // r1 = (gw>>4) ADDx_REG_LSL(x3, wback, x4, 1); //(&ed)+=r1*2; LDH(x4, x3, fixedaddress); + wback = x3; ed = x4; } ANDw_mask(x2, gd, 0, 0b000011); // mask=0x0f @@ -1809,7 +1810,7 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n B_NEXT(cNE); MOV32w(x1, 1); LSLxw_REG(x1, x1, x2); - EORx_REG(ed, ed, x1); + ORRx_REG(ed, ed, x1); if(wback) { STRH_U12(ed, wback, fixedaddress); } @@ -1859,7 +1860,7 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n } else { SMREAD(); addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, &unscaled, 0xfff<<2, (1<<2)-1, rex, NULL, 0, 0); - SBFXw(x4, gd, 4, 12); // r1 = (gw>>4) + SBFXx(x4, gd, 4, 12); // r1 = (gw>>4) ADDx_REG_LSL(x3, wback, x4, 1); //(&ed)+=r1*2; LDH(x4, x3, fixedaddress); wback = x3; @@ -1872,7 +1873,7 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n B_NEXT(cEQ); MOV32w(x1, 1); LSLxw_REG(x1, x1, x2); - EORx_REG(ed, ed, x1); + BICx_REG(ed, ed, x1); if(wback) { STH(ed, wback, fixedaddress); SMWRITE(); @@ -1939,7 +1940,7 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n BFXILxw(xFlags, ed, u8, 1); // inject 1 bit from u8 to F_CF (i.e. pos 0) TBNZ_MARK3(xFlags, 0); // bit already set, jump to next instruction MOV32w(x4, 1); - EORxw_REG_LSL(ed, ed, x4, u8); + ORRxw_REG_LSL(ed, ed, x4, u8); EWBACK(x1); MARK3; break; @@ -1953,7 +1954,7 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n BFXILxw(xFlags, ed, u8, 1); // inject 1 bit from u8 to F_CF (i.e. pos 0) TBZ_MARK3(xFlags, 0); // bit already clear, jump to next instruction MOV32w(x4, 1); - EORxw_REG_LSL(ed, ed, x4, u8); + BICxw_REG_LSL(ed, ed, x4, u8); EWBACK(x1); MARK3; break; @@ -1985,7 +1986,7 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n } else { SMREAD(); addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, &unscaled, 0xfff<<2, (1<<2)-1, rex, NULL, 0, 0); - SBFXw(x4, gd, 4, 12); // r1 = (gw>>4) + SBFXx(x4, gd, 4, 12); // r1 = (gw>>4) ADDx_REG_LSL(x3, wback, x4, 1); //(&ed)+=r1*2; LDH(x4, x3, fixedaddress); wback = x3; diff --git a/src/dynarec/arm64/dynarec_arm64_f0.c b/src/dynarec/arm64/dynarec_arm64_f0.c index 4a1421cc..da747204 100644 --- a/src/dynarec/arm64/dynarec_arm64_f0.c +++ b/src/dynarec/arm64/dynarec_arm64_f0.c @@ -173,8 +173,7 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin BFIw(xFlags, x4, F_CF, 1); MOV32w(x4, 1); LSLxw_REG(x4, x4, x2); - EORxw_REG(x4, ed, x4); - CSELxw(ed, ed, x4, cNE); + ORRxw_REG(ed, ed, x4); } else { // Will fetch only 1 byte, to avoid alignment issue if(rex.w) { @@ -191,12 +190,11 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin ed = x1; wback = x3; LSRw_REG(x4, ed, x2); - ANDSw_mask(x4, x4, 0, 0); //mask=1 + ANDw_mask(x4, x4, 0, 0); //mask=1 BFIw(xFlags, x4, F_CF, 1); MOV32w(x4, 1); LSLw_REG(x4, x4, x2); - EORw_REG(x4, ed, x4); - CSELw(ed, ed, x4, cNE); + ORRw_REG(ed, ed, x4); STLXRB(x4, ed, wback); CBNZw_MARKLOCK(x4); SMDMB(); @@ -322,15 +320,14 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin } LSRxw_REG(x4, ed, x2); if(rex.w) { - ANDSx_mask(x4, x4, 1, 0, 0); //mask=1 + ANDx_mask(x4, x4, 1, 0, 0); //mask=1 } else { - ANDSw_mask(x4, x4, 0, 0); //mask=1 + ANDw_mask(x4, x4, 0, 0); //mask=1 } BFIw(xFlags, x4, F_CF, 1); MOV32w(x4, 1); LSLxw_REG(x4, x4, x2); - EORxw_REG(x4, ed, x4); - CSELxw(ed, ed, x4, cEQ); + BICxw_REG(ed, ed, x4); } else { // Will fetch only 1 byte, to avoid alignment issue if(rex.w) { @@ -340,19 +337,18 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin } SMDMB(); addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 0); - ASRxw(x1, gd, 3); // r1 = (gd>>3) + ASRx(x1, gd, 3); // r1 = (gd>>3) ADDx_REG_LSL(x3, wback, x1, 0); //(&ed)+=r1; MARKLOCK; LDAXRB(x1, wback); ed = x1; wback = x3; LSRw_REG(x4, ed, x2); - ANDSw_mask(x4, x4, 0, 0); //mask=1 + ANDw_mask(x4, x4, 0, 0); //mask=1 BFIw(xFlags, x4, F_CF, 1); MOV32w(x4, 1); LSLw_REG(x4, x4, x2); - EORw_REG(x4, ed, x4); - CSELw(ed, ed, x4, cEQ); + ORRw_REG(ed, ed, x4); STLXRB(x4, ed, wback); CBNZw_MARKLOCK(x4); SMDMB(); |