diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2024-05-30 21:26:10 +0200 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2024-05-30 21:26:10 +0200 |
| commit | 7eb24ff51407562fe29fc1259cd3a8ce47f143e8 (patch) | |
| tree | 54abb8744d320aa639bbe692ff97d94c5b842cad /src | |
| parent | e367a2bcc95a8ad1f292a231bffe12a8d2dcea84 (diff) | |
| download | box64-7eb24ff51407562fe29fc1259cd3a8ce47f143e8.tar.gz box64-7eb24ff51407562fe29fc1259cd3a8ce47f143e8.zip | |
[ARM64_DYNBAREC] Added AVX.66.0F38 2C-2F opcodes
Diffstat (limited to 'src')
| -rw-r--r-- | src/dynarec/arm64/arm64_emitter.h | 2 | ||||
| -rw-r--r-- | src/dynarec/arm64/arm64_printer.c | 6 | ||||
| -rw-r--r-- | src/dynarec/arm64/dynarec_arm64_avx_66_0f38.c | 65 | ||||
| -rw-r--r-- | src/dynarec/arm64/dynarec_arm64_helper.h | 15 |
4 files changed, 87 insertions, 1 deletions
diff --git a/src/dynarec/arm64/arm64_emitter.h b/src/dynarec/arm64/arm64_emitter.h index 464693ba..9552f5de 100644 --- a/src/dynarec/arm64/arm64_emitter.h +++ b/src/dynarec/arm64/arm64_emitter.h @@ -1483,7 +1483,7 @@ int convert_bitmask(uint64_t bitmask); #define VUZP1Q_64(Rt, Rn, Rm) EMIT(UZP_gen(1, 0b11, Rm, 0, Rn, Rt)) #define VUZP2Q_64(Rt, Rn, Rm) EMIT(UZP_gen(1, 0b11, Rm, 1, Rn, Rt)) -#define BITBIF_gen(Q, opc2, Rm, Rn, Rd) ((Q)<<30 | 0b101110101<<21 | (Rm)<<16 | 0b000111<<10 | (Rn)<<4 | (Rd)) +#define BITBIF_gen(Q, opc2, Rm, Rn, Rd) ((Q)<<30 | 0b101110101<<21 | (Rm)<<16 | 0b000111<<10 | (Rn)<<5 | (Rd)) // Bitwise insert Vn in Vd if Vm is "0" #define VBIF(Vd, Vn,Vm) EMIT(BITBIF_gen(0, 0b11, Vm, Vn, Vd)) // Bitwise insert Vn in Vd if Vm is "0" diff --git a/src/dynarec/arm64/arm64_printer.c b/src/dynarec/arm64/arm64_printer.c index 8e975c63..98bbcc98 100644 --- a/src/dynarec/arm64/arm64_printer.c +++ b/src/dynarec/arm64/arm64_printer.c @@ -952,6 +952,12 @@ const char* arm64_print(uint32_t opcode, uintptr_t addr) snprintf(buff, sizeof(buff), "VMUL V%d.%s, V%d.%s, V%d.%s", Rd, Vd, Rn, Vd, Rm, Vd); return buff; } + // VBIT / VBIF + if(isMask(opcode, "0Q1011101o1mmmmm000111nnnnnddddd", &a)) { + char q = a.Q?'Q':'D'; + snprintf(buff, sizeof(buff), "VBI%c %c%d, %c%d, %c%d", a.o?'F':'T', q, Rd, q, Rn, q, Rm); + return buff; + } // CMP if(isMask(opcode, "0Q101110ff1mmmmm100011nnnnnddddd", &a)) { const char* Y[] = {"8B", "16B", "4H", "8H", "2S", "4S", "??", "2D"}; diff --git a/src/dynarec/arm64/dynarec_arm64_avx_66_0f38.c b/src/dynarec/arm64/dynarec_arm64_avx_66_0f38.c index 74e8a20c..14dfd263 100644 --- a/src/dynarec/arm64/dynarec_arm64_avx_66_0f38.c +++ b/src/dynarec/arm64/dynarec_arm64_avx_66_0f38.c @@ -79,6 +79,71 @@ uintptr_t dynarec64_AVX_66_0F38(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip } else YMM0(gd); break; + case 0x2C: + INST_NAME("VMASKMOVPS Gx, Vx, Ex"); + nextop = F8; + GETGX_empty_VXEX(v0, v2, v1, 0); + q0 = fpu_get_scratch(dyn, ninst); + // create mask + VSSHRQ_32(q0, v2, 31); + VANDQ(v0, v1, q0); + if(vex.l) { + GETGY_empty_VYEY(v0, v2, v1); + VSSHRQ_32(q0, v2, 31); + VANDQ(v0, v1, q0); + } else YMM0(gd); + break; + case 0x2D: + INST_NAME("VMASKMOVPD Gx, Vx, Ex"); + nextop = F8; + GETGX_empty_VXEX(v0, v2, v1, 0); + q0 = fpu_get_scratch(dyn, ninst); + // create mask + VSSHRQ_64(q0, v2, 63); + VANDQ(v0, v1, q0); + if(vex.l) { + GETGY_empty_VYEY(v0, v2, v1); + VSSHRQ_64(q0, v2, 63); + VANDQ(v0, v1, q0); + } else YMM0(gd); + break; + case 0x2E: + INST_NAME("VMASKMOVPS Ex, Gx, Vx"); + nextop = F8; + GETGXVXEX(v0, v2, v1, 0); + q0 = fpu_get_scratch(dyn, ninst); + // create mask + VSSHRQ_32(q0, v2, 31); + VBITQ(v1, v0, q0); + if(!MODREG) + VST128(v1, ed, fixedaddress); + if(vex.l) { + GETGYVYEY(v0, v2, v1); + VSSHRQ_32(q0, v2, 31); + VBITQ(v1, v0, q0); + if(!MODREG) + VST128(v1, ed, fixedaddress+16); + } + break; + case 0x2F: + INST_NAME("VMASKMOVPD Ex, Gx, Vx"); + nextop = F8; + GETGXVXEX(v0, v2, v1, 0); + q0 = fpu_get_scratch(dyn, ninst); + // create mask + VSSHRQ_64(q0, v2, 63); + VBITQ(v1, v0, q0); + if(!MODREG) + VST128(v1, ed, fixedaddress); + if(vex.l) { + GETGYVYEY(v0, v2, v1); + VSSHRQ_64(q0, v2, 63); + VBITQ(v1, v0, q0); + if(!MODREG) + VST128(v1, ed, fixedaddress+16); + } + break; + default: DEFAULT; } diff --git a/src/dynarec/arm64/dynarec_arm64_helper.h b/src/dynarec/arm64/dynarec_arm64_helper.h index 6349054b..e455acda 100644 --- a/src/dynarec/arm64/dynarec_arm64_helper.h +++ b/src/dynarec/arm64/dynarec_arm64_helper.h @@ -478,6 +478,12 @@ GETEX_Y(ex, 0, D); \ GETGX_empty(gx) +// Get EX and and non-writen VX and GX +#define GETGXVXEX(gx, vx, ex, D) \ + GETVX(vx, 0); \ + GETEX_Y(ex, 1, D); \ + GETGX(gx, 0) + // Get empty GY, and non-writen VY and EY #define GETGY_empty_VYEY(gy, vy, ey) \ vy = ymm_get_reg(dyn, ninst, x1, vex.v, 0, gd, (MODREG)?((nextop&7)+(rex.b<<3)):-1, -1); \ @@ -487,6 +493,15 @@ VLD128(ey, ed, fixedaddress+16); \ gy = ymm_get_reg_empty(dyn, ninst, x1, gd, vex.v, (MODREG)?((nextop&7)+(rex.b<<3)):-1, -1) +// Get EY and non-writen VY and GY +#define GETGYVYEY(gy, vy, ey) \ + vy = ymm_get_reg(dyn, ninst, x1, vex.v, 0, gd, (MODREG)?((nextop&7)+(rex.b<<3)):-1, -1); \ + if(MODREG) \ + ey = ymm_get_reg(dyn, ninst, x1, (nextop&7)+(rex.b<<3), 1, gd, vex.v, -1); \ + else \ + VLD128(ey, ed, fixedaddress+16); \ + gy = ymm_get_reg(dyn, ninst, x1, gd, 0, vex.v, (MODREG)?((nextop&7)+(rex.b<<3)):-1, -1) + // Get empty GY, and non-writen EY #define GETGY_empty_EY(gy, ey) \ if(MODREG) \ |