diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_avx_0f.c | 67 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_avx_66_0f.c | 46 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_avx_f3_0f.c | 18 | ||||
| -rw-r--r-- | src/emu/x64runavx0f.c | 3 |
4 files changed, 131 insertions, 3 deletions
diff --git a/src/dynarec/rv64/dynarec_rv64_avx_0f.c b/src/dynarec/rv64/dynarec_rv64_avx_0f.c index 95b8972b..95207210 100644 --- a/src/dynarec/rv64/dynarec_rv64_avx_0f.c +++ b/src/dynarec/rv64/dynarec_rv64_avx_0f.c @@ -37,7 +37,7 @@ uintptr_t dynarec64_AVX_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, in int v0, v1, v2; int q0, q1, q2; int d0, d1, d2; - int s0; + int s0, s1; uint64_t tmp64u, u64; int64_t j64; int64_t fixedaddress, gdoffset, vxoffset, gyoffset; @@ -89,6 +89,71 @@ uintptr_t dynarec64_AVX_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, in SD(xZR, wback, fixedaddress + 8); } break; + case 0x2E: + // no special check... + case 0x2F: + if (opcode == 0x2F) { + INST_NAME("COMISS Gx, Ex"); + } else { + INST_NAME("UCOMISS Gx, Ex"); + } + SETFLAGS(X_ALL, SF_SET, NAT_FLAGS_NOFUSION); + SET_DFNONE(); + nextop = F8; + GETGXSS(d0); + GETEXSS(v0, 0); + CLEAR_FLAGS(); + // if isnan(d0) || isnan(v0) + IFX (X_ZF | X_PF | X_CF) { + FEQS(x3, d0, d0); + FEQS(x2, v0, v0); + AND(x2, x2, x3); + BNE_MARK(x2, xZR); + ORI(xFlags, xFlags, (1 << F_ZF) | (1 << F_PF) | (1 << F_CF)); + B_NEXT_nocond; + } + MARK; + // else if isless(d0, v0) + IFX (X_CF) { + FLTS(x2, d0, v0); + BEQ_MARK2(x2, xZR); + ORI(xFlags, xFlags, 1 << F_CF); + B_NEXT_nocond; + } + MARK2; + // else if d0 == v0 + IFX (X_ZF) { + FEQS(x2, d0, v0); + CBZ_NEXT(x2); + ORI(xFlags, xFlags, 1 << F_ZF); + } + break; + case 0x5A: + INST_NAME("VCVTPS2PD Gx, Ex"); + nextop = F8; + GETGX(); + GETGY(); + GETEX(x2, 0, vex.l ? 12 : 4); + s0 = fpu_get_scratch(dyn); + s1 = fpu_get_scratch(dyn); + FLW(s0, wback, fixedaddress); + FLW(s1, wback, fixedaddress + 4); + FCVTDS(s0, s0); + FCVTDS(s1, s1); + FSD(s0, gback, gdoffset + 0); + FSD(s1, gback, gdoffset + 8); + if (vex.l) { + FLW(s0, wback, fixedaddress + 8); + FLW(s1, wback, fixedaddress + 12); + FCVTDS(s0, s0); + FCVTDS(s1, s1); + FSD(s0, gyback, gyoffset + 0); + FSD(s1, gyback, gyoffset + 8); + } else { + FSD(xZR, gyback, gyoffset + 0); + FSD(xZR, gyback, gyoffset + 8); + } + break; default: DEFAULT; } diff --git a/src/dynarec/rv64/dynarec_rv64_avx_66_0f.c b/src/dynarec/rv64/dynarec_rv64_avx_66_0f.c index c0d177dc..e7389fc2 100644 --- a/src/dynarec/rv64/dynarec_rv64_avx_66_0f.c +++ b/src/dynarec/rv64/dynarec_rv64_avx_66_0f.c @@ -46,6 +46,27 @@ uintptr_t dynarec64_AVX_66_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, rex_t rex = vex.rex; switch (opcode) { + case 0x28: + INST_NAME("VMOVAPD Gx, Ex"); + nextop = F8; + GETEX(x2, 0, vex.l ? 24 : 8); + GETGX(); + GETGY(); + LD(x3, wback, fixedaddress); + SD(x3, gback, gdoffset); + LD(x3, wback, fixedaddress + 8); + SD(x3, gback, gdoffset + 8); + if (vex.l) { + GETEY(); + LD(x3, wback, fixedaddress); + SD(x3, gyback, gyoffset); + LD(x3, wback, fixedaddress + 8); + SD(x3, gyback, gyoffset + 8); + } else { + SD(xZR, gyback, gyoffset); + SD(xZR, gyback, gyoffset + 8); + } + break; case 0x6E: INST_NAME("VMOVD Gx, Ed"); nextop = F8; @@ -57,6 +78,31 @@ uintptr_t dynarec64_AVX_66_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, SD(xZR, gyback, gyoffset); SD(xZR, gyback, gyoffset + 8); break; + case 0x7E: + INST_NAME("VMOVD Ed, Gx"); + nextop = F8; + GETGX(); + ed = TO_NAT((nextop & 7) + (rex.b << 3)); + if (rex.w) { + if (MODREG) { + LD(ed, gback, gdoffset); + } else { + addr = geted(dyn, addr, ninst, nextop, &wback, x2, x3, &fixedaddress, rex, NULL, 1, 0); + LD(x3, gback, gdoffset); + SD(x3, wback, fixedaddress); + SMWRITE2(); + } + } else { + if (MODREG) { + LWU(ed, gback, gdoffset); + } else { + addr = geted(dyn, addr, ninst, nextop, &wback, x2, x3, &fixedaddress, rex, NULL, 1, 0); + LWU(x3, gback, gdoffset); + SW(x3, wback, fixedaddress); + SMWRITE2(); + } + } + break; default: DEFAULT; } diff --git a/src/dynarec/rv64/dynarec_rv64_avx_f3_0f.c b/src/dynarec/rv64/dynarec_rv64_avx_f3_0f.c index e96640a6..b3cfb048 100644 --- a/src/dynarec/rv64/dynarec_rv64_avx_f3_0f.c +++ b/src/dynarec/rv64/dynarec_rv64_avx_f3_0f.c @@ -87,6 +87,24 @@ uintptr_t dynarec64_AVX_F3_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, SD(xZR, wback, fixedaddress + 8); } break; + case 0x5A: + INST_NAME("VCVTSS2SD Gx, Vx, Ex"); + nextop = F8; + GETEX(x2, 0, 1); + GETGX(); + GETVX(); + GETGY(); + s0 = fpu_get_scratch(dyn); + FLW(s0, wback, fixedaddress); + FCVTDS(s0, s0); + FSD(s0, gback, gdoffset); + if (gd != vex.v) { + LD(x2, vback, vxoffset + 8); + SD(x2, gback, gdoffset + 8); + } + SD(xZR, gyback, gyoffset); + SD(xZR, gyback, gyoffset + 8); + break; default: DEFAULT; } diff --git a/src/emu/x64runavx0f.c b/src/emu/x64runavx0f.c index 9093de3c..6712386b 100644 --- a/src/emu/x64runavx0f.c +++ b/src/emu/x64runavx0f.c @@ -460,8 +460,7 @@ uintptr_t RunAVX_0F(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step) GETEX(0); GETGX; GETGY; - if(vex.l) { - GETEY; + if (vex.l) { GY->d[1] = EX->f[3]; GY->d[0] = EX->f[2]; } else |