diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2023-11-23 18:19:59 +0100 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2023-11-23 18:19:59 +0100 |
| commit | ba80b40e9eb0412816d1270d57a0eb300844f476 (patch) | |
| tree | a01d511936211a31d0362e854e95734e45f2a3b4 /src | |
| parent | b0fe7ecf8c5590b35a5eadfd1f15a27e3e192464 (diff) | |
| download | box64-ba80b40e9eb0412816d1270d57a0eb300844f476.tar.gz box64-ba80b40e9eb0412816d1270d57a0eb300844f476.zip | |
[ARM64_DYNAREC] Some fixes and improvment to various opcodes
Diffstat (limited to 'src')
| -rw-r--r-- | src/dynarec/arm64/arm64_emitter.h | 1 | ||||
| -rw-r--r-- | src/dynarec/arm64/dynarec_arm64_00.c | 8 | ||||
| -rw-r--r-- | src/dynarec/arm64/dynarec_arm64_0f.c | 3 | ||||
| -rw-r--r-- | src/dynarec/arm64/dynarec_arm64_660f.c | 30 | ||||
| -rw-r--r-- | src/dynarec/arm64/dynarec_arm64_f0.c | 36 |
5 files changed, 31 insertions, 47 deletions
diff --git a/src/dynarec/arm64/arm64_emitter.h b/src/dynarec/arm64/arm64_emitter.h index 8a828d00..794a066b 100644 --- a/src/dynarec/arm64/arm64_emitter.h +++ b/src/dynarec/arm64/arm64_emitter.h @@ -2091,6 +2091,7 @@ #define STUMINH(Rs, Rn) EMIT(ATOMIC_gen(0b01, 0, 0, Rs, 0b111, Rn, 0b11111)) #define STUMINLH(Rs, Rn) EMIT(ATOMIC_gen(0b01, 0, 1, Rs, 0b111, Rn, 0b11111)) +// SWAPxx(Xs, Xt, Xn) : [Xn] => Xt, Xs => [Xn] #define SWAP_gen(size, A, R, Rs, Rn, Rt) ((size)<<30 | 0b111<<27 | (A)<<23 | (R)<<22 | 1<<21 | (Rs)<<16 | 1<<15 | (Rn)<<5 | (Rt)) #define SWPxw(Rs, Rt, Rn) EMIT(SWAP_gen(0b10+rex.w, 0, 0, Rs, Rn, Rt)) #define SWPAxw(Rs, Rt, Rn) EMIT(SWAP_gen(0b10+rex.w, 1, 0, Rs, Rn, Rt)) diff --git a/src/dynarec/arm64/dynarec_arm64_00.c b/src/dynarec/arm64/dynarec_arm64_00.c index 622269b9..2f05ee1f 100644 --- a/src/dynarec/arm64/dynarec_arm64_00.c +++ b/src/dynarec/arm64/dynarec_arm64_00.c @@ -1039,8 +1039,8 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin INST_NAME("(LOCK)XCHG Eb, Gb"); // Do the swap nextop = F8; + GETGB(x4); if(MODREG) { - GETGB(x4); if(rex.rex) { ed = xRAX+(nextop&7)+(rex.b<<3); eb1 = ed; @@ -1052,10 +1052,8 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin } UBFXw(x1, eb1, eb2, 8); // do the swap 14 -> ed, 1 -> gd - BFIx(gb1, x1, gb2, 8); BFIx(eb1, x4, eb2, 8); } else { - GETGB(x4); addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 0); if(arm64_atomics) { SWPALB(x4, x1, ed); @@ -1067,8 +1065,8 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin STLXRB(x3, x4, ed); CBNZx_MARKLOCK(x3); } - BFIx(gb1, x1, gb2, 8); } + BFIx(gb1, x1, gb2, 8); break; case 0x87: INST_NAME("(LOCK)XCHG Ed, Gd"); @@ -2088,7 +2086,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin SETFLAGS(X_ALL, SF_SET); // Hack to set flags in "don't care" state GETIP(ip); STORE_XEMU_CALL(xRIP); - CALL(native_priv, -1); + CALL(native_int, -1); LOAD_XEMU_CALL(xRIP); jump_to_epilog(dyn, 0, xRIP, ninst); *need_epilog = 0; diff --git a/src/dynarec/arm64/dynarec_arm64_0f.c b/src/dynarec/arm64/dynarec_arm64_0f.c index ae874bb0..87ca717f 100644 --- a/src/dynarec/arm64/dynarec_arm64_0f.c +++ b/src/dynarec/arm64/dynarec_arm64_0f.c @@ -1882,8 +1882,7 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin IFX(X_CF) { BFXILxw(xFlags, ed, u8, 1); // inject 1 bit from u8 to F_CF (i.e. pos 0) } - MOV32w(x4, 1); - BICxw_REG_LSL(ed, ed, x4, u8); + BFCxw(ed, u8, 1); if(wback) { STxw(ed, wback, fixedaddress); SMWRITE(); diff --git a/src/dynarec/arm64/dynarec_arm64_660f.c b/src/dynarec/arm64/dynarec_arm64_660f.c index 7e9d73a6..57ebe1f7 100644 --- a/src/dynarec/arm64/dynarec_arm64_660f.c +++ b/src/dynarec/arm64/dynarec_arm64_660f.c @@ -2272,8 +2272,6 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n ANDw_mask(x2, gd, 0, 0b000011); // mask=0x0f LSRw_REG(x1, ed, x2); BFIw(xFlags, x1, F_CF, 1); - ANDSw_mask(x1, x1, 0, 0); //mask=1 - B_NEXT(cEQ); MOV32w(x1, 1); LSLxw_REG(x1, x1, x2); BICx_REG(ed, ed, x1); @@ -2340,12 +2338,12 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n GETEW(x1, 1); u8 = F8; u8&=(rex.w?0x3f:0x0f); - 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 + IFX(X_CF) { + BFXILxw(xFlags, ed, u8, 1); // inject 1 bit from u8 to F_CF (i.e. pos 0) + } MOV32w(x4, 1); - ORRxw_REG_LSL(ed, ed, x4, u8); + BFIxw(ed, x4, u8, 1); EWBACK(x1); - MARK3; break; case 6: INST_NAME("BTR Ew, Ib"); @@ -2354,12 +2352,11 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n GETEW(x1, 1); u8 = F8; u8&=(rex.w?0x3f:0x0f); - 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); - BICxw_REG_LSL(ed, ed, x4, u8); + IFX(X_CF) { + BFXILxw(xFlags, ed, u8, 1); // inject 1 bit from u8 to F_CF (i.e. pos 0) + } + BFCxw(ed, u8, 1); EWBACK(x1); - MARK3; break; case 7: INST_NAME("BTC Ew, Ib"); @@ -2368,7 +2365,9 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n GETEW(x1, 1); u8 = F8; u8&=(rex.w?0x3f:0x0f); - BFXILxw(xFlags, ed, u8, 1); // inject 1 bit from u8 to F_CF (i.e. pos 0) + IFX(X_CF) { + BFXILxw(xFlags, ed, u8, 1); // inject 1 bit from u8 to F_CF (i.e. pos 0) + } MOV32w(x4, 1); EORxw_REG_LSL(ed, ed, x4, u8); EWBACK(x1); @@ -2396,9 +2395,10 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n ed = x4; } ANDw_mask(x2, gd, 0, 0b000011); // mask=0x0f - LSRw_REG(x1, ed, x2); - BFIw(xFlags, x1, F_CF, 1); - ANDw_mask(x1, x1, 0, 0); //mask=1 + IFX(X_CF) { + LSRw_REG(x1, ed, x2); + BFIw(xFlags, x1, F_CF, 1); + } MOV32w(x1, 1); LSLxw_REG(x1, x1, x2); EORx_REG(ed, ed, x1); diff --git a/src/dynarec/arm64/dynarec_arm64_f0.c b/src/dynarec/arm64/dynarec_arm64_f0.c index 8d435761..384b5772 100644 --- a/src/dynarec/arm64/dynarec_arm64_f0.c +++ b/src/dynarec/arm64/dynarec_arm64_f0.c @@ -399,7 +399,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); LSLw_REG(x4, x4, x2); - ORRw_REG(ed, ed, x4); + BICw_REG(ed, ed, x4); STLXRB(x4, ed, wback); CBNZw_MARKLOCK(x4); } @@ -446,10 +446,6 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin TBNZ_NEXT(xFlags, 0); // bit already set, jump to next instruction MOV32w(x4, 1); ORRxw_REG_LSL(ed, ed, x4, u8); - if(wback) { - STxw(ed, wback, fixedaddress); - SMWRITE(); - } } else { // Will fetch only 1 byte, to avoid alignment issue addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 0); @@ -461,17 +457,15 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin ed = x1; MARKLOCK; LDAXRB(ed, wback); - UBFXw(x4, ed, u8&7, 1); - BFIw(xFlags, x4, F_CF, 1); + BFXILw(xFlags, ed, u8&7, 1); // inject 1 bit from u8 to F_CF (i.e. pos 0) MOV32w(x4, 1); - LSLw_IMM(x4, x4, u8&7); - ORRw_REG(ed, ed, x4); + BFIw(ed, x4, u8&7, 1); STLXRB(x4, ed, wback); CBNZw_MARKLOCK(x4); } break; case 6: - INST_NAME("BTR Ed, Ib"); + INST_NAME("LOCK BTR Ed, Ib"); SETFLAGS(X_CF, SF_SUBSET); SET_DFNONE(x1); if(MODREG) { @@ -481,8 +475,7 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin u8&=(rex.w?0x3f:0x1f); BFXILxw(xFlags, ed, u8, 1); // inject 1 bit from u8 to F_CF (i.e. pos 0) TBZ_NEXT(xFlags, 0); // bit already clear, jump to next instruction - MOV32w(x4, 1); - BICxw_REG_LSL(ed, ed, x4, u8); + BFCxw(ed, u8, 1); } else { addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 0); u8 = F8; @@ -493,17 +486,14 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin ed = x1; MARKLOCK; LDAXRB(ed, wback); - UBFXw(x4, ed, u8&7, 1); - BFIw(xFlags, x4, F_CF, 1); - MOV32w(x4, 1); - LSLw_IMM(x4, x4, u8&7); - ORRw_REG(ed, ed, x4); + BFXILw(xFlags, ed, u8&7, 1); // inject 1 bit from u8 to F_CF (i.e. pos 0) + BFCw(ed, u8&7, 1); STLXRB(x4, ed, wback); CBNZw_MARKLOCK(x4); } break; case 7: - INST_NAME("BTC Ed, Ib"); + INST_NAME("LOCK BTC Ed, Ib"); SETFLAGS(X_CF, SF_SUBSET); SET_DFNONE(x1); if(MODREG) { @@ -514,10 +504,6 @@ uintptr_t dynarec64_F0(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) MOV32w(x4, 1); EORxw_REG_LSL(ed, ed, x4, u8); - if(wback) { - STxw(ed, wback, fixedaddress); - SMWRITE(); - } } else { addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 0); u8 = F8; @@ -528,9 +514,9 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin ed = x1; MARKLOCK; LDAXRB(ed, wback); - UBFXw(x4, ed, u8&7, 1); - BFIw(xFlags, x4, F_CF, 1); - BFCw(ed, u8&7, 1); + BFXILw(xFlags, ed, u8&7, 1); // inject 1 bit from u8 to F_CF (i.e. pos 0) + MOV32w(x4, 1); + EORw_REG_LSL(ed, ed, x4, u8&7); STLXRB(x4, ed, wback); CBNZw_MARKLOCK(x4); } |