about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/dynarec/rv64/dynarec_rv64_avx_0f.c67
-rw-r--r--src/dynarec/rv64/dynarec_rv64_avx_66_0f.c46
-rw-r--r--src/dynarec/rv64/dynarec_rv64_avx_f3_0f.c18
-rw-r--r--src/emu/x64runavx0f.c3
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