diff options
| author | wannacu <76616478+wannacu@users.noreply.github.com> | 2025-02-13 20:07:36 +0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-02-13 13:07:36 +0100 |
| commit | 639466d45aa2d322e3bc770b7562f3385814e935 (patch) | |
| tree | 8c7586304068d1adc6dfe5ccd43c200c351fc670 /src | |
| parent | 95bdaf6eca65f3b45422c83abcf152c7022e6a26 (diff) | |
| download | box64-639466d45aa2d322e3bc770b7562f3385814e935.tar.gz box64-639466d45aa2d322e3bc770b7562f3385814e935.zip | |
[ARM64_DYNAREC] Added some BMI.0F38 opcodes (#2347)
* [ARM64_DYNAREC] Fixed BMI.0F38 F5 ocpode * [ARM64_DYNAREC] Added BMI.0F38 F3 /2,/3 ocpode * Added BMI.0F38 F7 opcode * Fixed emitter mistake about CSINVxw
Diffstat (limited to 'src')
| -rw-r--r-- | src/dynarec/arm64/arm64_emitter.h | 2 | ||||
| -rw-r--r-- | src/dynarec/arm64/dynarec_arm64_avx_0f38.c | 113 |
2 files changed, 113 insertions, 2 deletions
diff --git a/src/dynarec/arm64/arm64_emitter.h b/src/dynarec/arm64/arm64_emitter.h index f56a68dc..0ecfa33c 100644 --- a/src/dynarec/arm64/arm64_emitter.h +++ b/src/dynarec/arm64/arm64_emitter.h @@ -586,7 +586,7 @@ int convert_bitmask(uint64_t bitmask); #define CSINV_gen(sf, Rm, cond, Rn, Rd) ((sf)<<31 | 1<<30 | 0b11010100<<21 | (Rm)<<16 | (cond)<<12 | (Rn)<<5 | (Rd)) #define CSINVx(Rd, Rn, Rm, cond) EMIT(CSINV_gen(1, Rm, cond, Rn, Rd)) #define CSINVw(Rd, Rn, Rm, cond) EMIT(CSINV_gen(0, Rm, cond, Rn, Rd)) -#define CSINVxw(Rd, Rn, Rm, cond) EMIT(CSINV_gen(rex.w?, Rm, cond, Rn, Rd)) +#define CSINVxw(Rd, Rn, Rm, cond) EMIT(CSINV_gen(rex.w, Rm, cond, Rn, Rd)) #define CINVx(Rd, Rn, cond) CSINVx(Rd, Rn, Rn, invertCond(cond)) #define CINVw(Rd, Rn, cond) CSINVw(Rd, Rn, Rn, invertCond(cond)) #define CINVxw(Rd, Rn, cond) CSINVxw(Rd, Rn, Rn, invertCond(cond)) diff --git a/src/dynarec/arm64/dynarec_arm64_avx_0f38.c b/src/dynarec/arm64/dynarec_arm64_avx_0f38.c index bd0a1baf..c5a9baf5 100644 --- a/src/dynarec/arm64/dynarec_arm64_avx_0f38.c +++ b/src/dynarec/arm64/dynarec_arm64_avx_0f38.c @@ -137,6 +137,82 @@ uintptr_t dynarec64_AVX_0F38(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, i IFX(X_PF) BFCw(xFlags, F_PF, 1); } break; + + case 2: + INST_NAME("BLSMSK Vd, Ed"); + SETFLAGS(X_ALL, SF_SET); + GETED(0); + GETVD; + IFX(X_CF) { + TSTxw_REG(ed, ed); + CSETMw(x3, cEQ); + BFIw(xFlags, x3, F_CF, 1); + } + SUBxw_U12(x3, ed, 1); + need_tst = 0; + IFX(X_ZF) need_tst = 1; + IFXNATIVE(X_SF, NF_SF) need_tst = 1; + IFXNATIVE(X_OF, NF_VF) need_tst = 1; + EORxw_REG(vd, ed, x3); + if(need_tst) + TSTxw_REG(vd, vd); + IFX(X_ZF) { + IFNATIVE(NF_EQ) {} else { + CSETMw(x3, cEQ); + BFIw(xFlags, x3, F_ZF, 1); + } + } + IFX(X_SF) { + IFNATIVE(NF_SF) {} else { + LSRxw(x3, vd, rex.w?63:31); + BFIw(xFlags, x3, F_SF, 1); + } + } + IFX(X_OF) IFNATIVE(NF_VF) {} else {BFCw(xFlags, F_OF, 1);} + if (BOX64ENV(dynarec_test)) { + IFX(X_AF) BFCw(xFlags, F_AF, 1); + IFX(X_PF) BFCw(xFlags, F_PF, 1); + } + break; + + case 3: + INST_NAME("BLSI Vd, Ed"); + SETFLAGS(X_ALL, SF_SET); + GETED(0); + GETVD; + IFX(X_CF) { + TSTxw_REG(ed, ed); + CSETMw(x3, cEQ); + BFIw(xFlags, x3, F_CF, 1); + } + NEGxw_REG(x3, ed); + need_tst = 0; + IFX(X_ZF) need_tst = 1; + IFXNATIVE(X_SF, NF_SF) need_tst = 1; + IFXNATIVE(X_OF, NF_VF) need_tst = 1; + if(need_tst) + ANDSxw_REG(vd, ed, x3); + else + ANDxw_REG(vd, ed, x3); + IFX(X_ZF) { + IFNATIVE(NF_EQ) {} else { + CSETMw(x3, cEQ); + BFIw(xFlags, x3, F_ZF, 1); + } + } + IFX(X_SF) { + IFNATIVE(NF_SF) {} else { + LSRxw(x3, vd, rex.w?63:31); + BFIw(xFlags, x3, F_SF, 1); + } + } + IFX(X_OF) IFNATIVE(NF_VF) {} else {BFCw(xFlags, F_OF, 1);} + if (BOX64ENV(dynarec_test)) { + IFX(X_AF) BFCw(xFlags, F_AF, 1); + IFX(X_PF) BFCw(xFlags, F_PF, 1); + } + break; + default: DEFAULT; } @@ -151,7 +227,7 @@ uintptr_t dynarec64_AVX_0F38(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, i GETVD; UXTBw(x1, vd); CMPSw_U12(x1, rex.w?64:32); - CSETxw(x2, cPL); + CSETMxw(x2, cPL); IFX(F_CF) { BFIw(xFlags, x2, F_CF, 1); } @@ -184,6 +260,41 @@ uintptr_t dynarec64_AVX_0F38(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, i IFX(X_OF) IFNATIVE(NF_VF) {} else {BFCw(xFlags, F_OF, 1);} break; + case 0xF7: + INST_NAME("BEXTR Gd, Ed, Vd"); + nextop = F8; + SETFLAGS(X_ALL, SF_SET); + GETGD; + GETED(0); + GETVD; + MOV64xw(x1, 0); + UXTBw(x2, vd); // start + BFXILw(x3, vd, 8, 8); // length + TSTw_REG(x3, x3); + B_MARK(cEQ); + LSRxw_REG(x1, ed, x2); + CMPSw_U12(x3, rex.w?64:32); + B_MARK(cGE); + MOV32w(x2, rex.w?64:32); + SUBw_REG(x2, x2, x3); + LSLxw_REG(x1, x1, x2); + LSRxw_REG(x1, x1, x2); + TSTxw_REG(x1, x1); + MARK; + MOVxw_REG(gd, x1); + IFX(X_ZF) { + IFNATIVE(NF_EQ) {} else { + CSETw(x3, cEQ); + BFIw(xFlags, x3, F_ZF, 1); + } + } + IFX(X_AF) BFCw(xFlags, F_AF, 1); + IFX(X_PF) BFCw(xFlags, F_PF, 1); + IFX(X_CF) BFCw(xFlags, F_CF, 1); + IFX(X_OF) IFNATIVE(NF_VF) {} else {BFCw(xFlags, F_OF, 1);} + IFX(X_SF) IFNATIVE(NF_SF) {} else {BFCw(xFlags, F_SF, 1);} + break; + default: DEFAULT; } |