diff options
Diffstat (limited to 'src/dynarec')
| -rw-r--r-- | src/dynarec/arm64/dynarec_arm64_avx_66_0f.c | 149 | ||||
| -rw-r--r-- | src/dynarec/arm64/dynarec_arm64_helper.h | 13 |
2 files changed, 162 insertions, 0 deletions
diff --git a/src/dynarec/arm64/dynarec_arm64_avx_66_0f.c b/src/dynarec/arm64/dynarec_arm64_avx_66_0f.c index bb23bba8..871fefd7 100644 --- a/src/dynarec/arm64/dynarec_arm64_avx_66_0f.c +++ b/src/dynarec/arm64/dynarec_arm64_avx_66_0f.c @@ -359,6 +359,70 @@ uintptr_t dynarec64_AVX_66_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, if(!vex.l) YMM0(gd); break; + case 0x72: + nextop = F8; + switch((nextop>>3)&7) { + case 2: + INST_NAME("VPSRLD Vx, Ex, Ib"); + for(int l=0; l<1+vex.l; ++l) { + if(!l) { + GETVX_empty_EX(v0, v1, 1); + u8 = F8; + } else { + GETVY_empty_EY(v0, v1); + } + if(u8) { + if (u8>31) { + VEORQ(v0, v0, v0); + } else if(u8) { + VSHRQ_32(v0, v1, u8); + } + } else if(v0!=v1) + VMOVQ(v0, v1); + } + if(!vex.l) YMM0(vex.v); + break; + case 4: + INST_NAME("VPSRAD Vx, Ex, Ib"); + for(int l=0; l<1+vex.l; ++l) { + if(!l) { + GETVX_empty_EX(v0, v1, 1); + u8 = F8; + } else { + GETVY_empty_EY(v0, v1); + } + if(u8>31) u8=31; + if(u8) { + VSSHRQ_32(v0, v1, u8); + } else if(v0!=v1) + VMOVQ(v0, v1); + } + if(!vex.l) YMM0(vex.v); + break; + case 6: + INST_NAME("VPSLLD Vx, Ex, Ib"); + for(int l=0; l<1+vex.l; ++l) { + if(!l) { + GETVX_empty_EX(v0, v1, 1); + u8 = F8; + } else { + GETVY_empty_EY(v0, v1); + } + if(u8) { + if (u8>31) { + VEORQ(v0, v0, v0); + } else { + VSHLQ_32(v0, v1, u8); + } + } else if(v0!=v1) + VMOVQ(v0, v1); + } + if(!vex.l) YMM0(vex.v); + break; + default: + DEFAULT; + } + break; case 0x73: nextop = F8; switch((nextop>>3)&7) { @@ -455,6 +519,28 @@ uintptr_t dynarec64_AVX_66_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, } break; + case 0x7F: + INST_NAME("MOVDQA Ex,Gx"); + nextop = F8; + GETGX(v0, 0); + if(MODREG) { + v1 = sse_get_reg(dyn, ninst, x1, (nextop&7)+(rex.b<<3), 1); + VMOVQ(v1, v0); + if(vex.l) { + GETGYEY(v1, v0); + VMOVQ(v1, v0); + } + } else { + addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, NULL, 0xffe<<4, 15, rex, NULL, 0, 0); + VSTR128_U12(v0, ed, fixedaddress); + if(vex.l) { + GETGY(v0, 0, -1, -1, -1); + VSTR128_U12(v0, ed, fixedaddress+16); + } + SMWRITE2(); + } + break; + case 0xD8: INST_NAME("VPSUBUSB Gx, Vx, Ex"); nextop = F8; @@ -686,6 +772,69 @@ uintptr_t dynarec64_AVX_66_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, } if(!vex.l) YMM0(gd); break; + case 0xF8: + INST_NAME("VPSUBB Gx, Vx, Ex"); + nextop = F8; + for(int l=0; l<1+vex.l; ++l) { + if(!l) { GETGX_empty_VXEX(v0, v2, v1, 0); } else { GETGY_empty_VYEY(v0, v2, v1); } + VSUBQ_8(v0, v2, v1); + } + if(!vex.l) YMM0(gd); + break; + case 0xF9: + INST_NAME("VPSUBW Gx, Vx, Ex"); + nextop = F8; + for(int l=0; l<1+vex.l; ++l) { + if(!l) { GETGX_empty_VXEX(v0, v2, v1, 0); } else { GETGY_empty_VYEY(v0, v2, v1); } + VSUBQ_16(v0, v2, v1); + } + if(!vex.l) YMM0(gd); + break; + case 0xFA: + INST_NAME("VPSUBD Gx, Vx, Ex"); + nextop = F8; + for(int l=0; l<1+vex.l; ++l) { + if(!l) { GETGX_empty_VXEX(v0, v2, v1, 0); } else { GETGY_empty_VYEY(v0, v2, v1); } + VSUBQ_32(v0, v2, v1); + } + if(!vex.l) YMM0(gd); + break; + case 0xFB: + INST_NAME("VPSUBQ Gx, Vx, Ex"); + nextop = F8; + for(int l=0; l<1+vex.l; ++l) { + if(!l) { GETGX_empty_VXEX(v0, v2, v1, 0); } else { GETGY_empty_VYEY(v0, v2, v1); } + VSUBQ_64(v0, v2, v1); + } + if(!vex.l) YMM0(gd); + break; + case 0xFC: + INST_NAME("VPADDB Gx, Vx, Ex"); + nextop = F8; + for(int l=0; l<1+vex.l; ++l) { + if(!l) { GETGX_empty_VXEX(v0, v2, v1, 0); } else { GETGY_empty_VYEY(v0, v2, v1); } + VADDQ_8(v0, v2, v1); + } + if(!vex.l) YMM0(gd); + break; + case 0xFD: + INST_NAME("VPADDW Gx, Vx, Ex"); + nextop = F8; + for(int l=0; l<1+vex.l; ++l) { + if(!l) { GETGX_empty_VXEX(v0, v2, v1, 0); } else { GETGY_empty_VYEY(v0, v2, v1); } + VADDQ_16(v0, v2, v1); + } + if(!vex.l) YMM0(gd); + break; + case 0xFE: + INST_NAME("VPADDD Gx, Vx, Ex"); + nextop = F8; + for(int l=0; l<1+vex.l; ++l) { + if(!l) { GETGX_empty_VXEX(v0, v2, v1, 0); } else { GETGY_empty_VYEY(v0, v2, v1); } + VADDQ_32(v0, v2, v1); + } + if(!vex.l) YMM0(gd); + break; default: DEFAULT; diff --git a/src/dynarec/arm64/dynarec_arm64_helper.h b/src/dynarec/arm64/dynarec_arm64_helper.h index 872a86fb..8d7c09cc 100644 --- a/src/dynarec/arm64/dynarec_arm64_helper.h +++ b/src/dynarec/arm64/dynarec_arm64_helper.h @@ -459,6 +459,11 @@ #define GETVX_empty(a) \ a = sse_get_reg_empty(dyn, ninst, x1, vex.v) +// Get empty VX, and non-writen EX +#define GETVX_empty_EX(vx, ex, D) \ + GETEX_Y(ex, 0, D); \ + GETVX_empty(vx) + #define GETGY_VY(a, w1, b, w2, k1, k2) \ if(w2) b = ymm_get_reg(dyn, ninst, x1, vex.v, w2, gd, k1, k2); \ a = ymm_get_reg(dyn, ninst, x1, gd, w1, vex.v, k1, k2); \ @@ -509,6 +514,14 @@ 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 EY and non-writen GY +#define GETGYEY(gy, ey) \ + if(MODREG) \ + ey = ymm_get_reg(dyn, ninst, x1, (nextop&7)+(rex.b<<3), 1, gd, -1, -1); \ + else \ + VLD128(ey, ed, fixedaddress+16); \ + gy = ymm_get_reg(dyn, ninst, x1, gd, 0, (MODREG)?((nextop&7)+(rex.b<<3)):-1, -1, -1) + // Get empty GY, and non-writen EY #define GETGY_empty_EY(gy, ey) \ if(MODREG) \ |