about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--src/dynarec/arm64/dynarec_arm64_660f.c4
-rw-r--r--src/dynarec/rv64/dynarec_rv64_0f.c33
-rw-r--r--src/dynarec/rv64/dynarec_rv64_660f.c124
-rw-r--r--src/dynarec/rv64/dynarec_rv64_f20f.c31
-rw-r--r--src/emu/x64run660f.c4
5 files changed, 147 insertions, 49 deletions
diff --git a/src/dynarec/arm64/dynarec_arm64_660f.c b/src/dynarec/arm64/dynarec_arm64_660f.c
index a8625e23..c967374d 100644
--- a/src/dynarec/arm64/dynarec_arm64_660f.c
+++ b/src/dynarec/arm64/dynarec_arm64_660f.c
@@ -1006,7 +1006,7 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
                     VMOVeD(q0, 0, v1, 0);

                     break;

                 case 0x0C:

-                    INST_NAME("PBLENDPS Gx, Ex, Ib");

+                    INST_NAME("BLENDPS Gx, Ex, Ib");

                     nextop = F8;

                     GETGX(q0, 1);

                     GETEX(q1, 0, 1);

@@ -1021,7 +1021,7 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
                         }

                     break;

                 case 0x0D:

-                    INST_NAME("PBLENDPD Gx, Ex, Ib");

+                    INST_NAME("BLENDPD Gx, Ex, Ib");

                     nextop = F8;

                     GETGX(q0, 1);

                     GETEX(q1, 0, 1);

diff --git a/src/dynarec/rv64/dynarec_rv64_0f.c b/src/dynarec/rv64/dynarec_rv64_0f.c
index e3af9d94..0c691c05 100644
--- a/src/dynarec/rv64/dynarec_rv64_0f.c
+++ b/src/dynarec/rv64/dynarec_rv64_0f.c
@@ -66,21 +66,26 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
             if(MODREG) {
                 switch(nextop) {
                     case 0xD0:
-                        //TODO
-                        DEFAULT;
-                        /*INST_NAME("FAKE xgetbv");
-                        nextop = F8;
-                        addr = fakeed(dyn, addr, ninst, nextop);
-                        SETFLAGS(X_ALL, SF_SET_NODF); // Hack to set flags in "don't care" state
-                        GETIP(ip);
-                        STORE_XEMU_CALL(x3);
-                        CALL(native_ud, -1);
-                        LOAD_XEMU_CALL();
-                        jump_to_epilog(dyn, 0, xRIP, ninst);
-                        *need_epilog = 0;
-                        *ok = 0;*/
+                        INST_NAME("XGETBV");
+                        AND(x1, xRCX, xMASK);
+                        BEQZ_MARK(x1);
+                        UDF();
+                        MARK;
+                        MOV32w(xRAX, 0b111);
+                        MOV32w(xRDX, 0);
+                        break;
+                    case 0xE0:
+                    case 0xE1:
+                    case 0xE2:
+                    case 0xE3:
+                    case 0xE4:
+                    case 0xE5:
+                    case 0xE6:
+                    case 0xE7:
+                        INST_NAME("SMSW Ed");
+                        ed = xRAX + (nextop & 7) + (rex.b << 3);
+                        MOV32w(ed, (1 << 0) | (1 << 4)); // only PE and ET set...
                         break;
-
                     case 0xF9:
                         INST_NAME("RDTSCP");
                         NOTEST(x1);
diff --git a/src/dynarec/rv64/dynarec_rv64_660f.c b/src/dynarec/rv64/dynarec_rv64_660f.c
index 00c9c66c..8fb7734d 100644
--- a/src/dynarec/rv64/dynarec_rv64_660f.c
+++ b/src/dynarec/rv64/dynarec_rv64_660f.c
@@ -684,6 +684,13 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
                         SD(x3, gback, gdoffset + i * 8);
                     }
                     break;
+                case 0x29:
+                    INST_NAME("PCMPEQQ Gx, Ex"); // SSE4 opcode!
+                    nextop = F8;
+                    GETGX();
+                    GETEX(x2, 0, 8);
+                    SSE_LOOP_Q(x3, x4, XOR(x3, x3, x4); SNEZ(x3, x3); ADDI(x3, x3, -1));
+                    break;
                 case 0x2B:
                     INST_NAME("PACKUSDW Gx, Ex");
                     nextop = F8;
@@ -1055,37 +1062,6 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
         case 0x3A: // these are some more SSSE3+ opcodes
             opcode = F8;
             switch (opcode) {
-                case 0x0B:
-                    INST_NAME("ROUNDSD Gx, Ex, Ib");
-                    nextop = F8;
-                    GETEXSD(d0, 1);
-                    GETGXSD_empty(v0);
-                    d1 = fpu_get_scratch(dyn);
-                    v1 = fpu_get_scratch(dyn);
-                    u8 = F8;
-                    FEQD(x2, d0, d0);
-                    BNEZ_MARK(x2);
-                    if (v0 != d0) FMVD(v0, d0);
-                    B_NEXT_nocond;
-                    MARK; // d0 is not nan
-                    FABSD(v1, d0);
-                    MOV64x(x3, 1ULL << __DBL_MANT_DIG__);
-                    FCVTDL(d1, x3, RD_RTZ);
-                    FLTD(x3, v1, d1);
-                    BNEZ_MARK2(x3);
-                    if (v0 != d0) FMVD(v0, d0);
-                    B_NEXT_nocond;
-                    MARK2;
-                    if (u8 & 4) {
-                        u8 = sse_setround(dyn, ninst, x4, x2);
-                        FCVTLD(x5, d0, RD_DYN);
-                        FCVTDL(v0, x5, RD_RTZ);
-                        x87_restoreround(dyn, ninst, u8);
-                    } else {
-                        FCVTLD(x5, d0, round_round[u8 & 3]);
-                        FCVTDL(v0, x5, RD_RTZ);
-                    }
-                    break;
                 case 0x09:
                     INST_NAME("ROUNDPD Gx, Ex, Ib");
                     nextop = F8;
@@ -1142,6 +1118,80 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
                     MARK2;
                     FSD(d0, gback, gdoffset + 8);
                     break;
+                case 0x0A:
+                    INST_NAME("ROUNDSS Gx, Ex, Ib");
+                    nextop = F8;
+                    GETEXSS(d0, 1);
+                    GETGXSS_empty(v0);
+                    d1 = fpu_get_scratch(dyn);
+                    v1 = fpu_get_scratch(dyn);
+                    u8 = F8;
+                    FEQS(x2, d0, d0);
+                    BNEZ_MARK(x2);
+                    if (v0 != d0) FMVS(v0, d0);
+                    B_NEXT_nocond;
+                    MARK; // d0 is not nan
+                    FABSS(v1, d0);
+                    MOV64x(x3, 1ULL << __FLT_MANT_DIG__);
+                    FCVTSW(d1, x3, RD_RTZ);
+                    FLTS(x3, v1, d1);
+                    BNEZ_MARK2(x3);
+                    if (v0 != d0) FMVS(v0, d0);
+                    B_NEXT_nocond;
+                    MARK2;
+                    if (u8 & 4) {
+                        u8 = sse_setround(dyn, ninst, x4, x2);
+                        FCVTWS(x5, d0, RD_DYN);
+                        FCVTSW(v0, x5, RD_RTZ);
+                        x87_restoreround(dyn, ninst, u8);
+                    } else {
+                        FCVTWS(x5, d0, round_round[u8 & 3]);
+                        FCVTSW(v0, x5, RD_RTZ);
+                    }
+                    break;
+                case 0x0B:
+                    INST_NAME("ROUNDSD Gx, Ex, Ib");
+                    nextop = F8;
+                    GETEXSD(d0, 1);
+                    GETGXSD_empty(v0);
+                    d1 = fpu_get_scratch(dyn);
+                    v1 = fpu_get_scratch(dyn);
+                    u8 = F8;
+                    FEQD(x2, d0, d0);
+                    BNEZ_MARK(x2);
+                    if (v0 != d0) FMVD(v0, d0);
+                    B_NEXT_nocond;
+                    MARK; // d0 is not nan
+                    FABSD(v1, d0);
+                    MOV64x(x3, 1ULL << __DBL_MANT_DIG__);
+                    FCVTDL(d1, x3, RD_RTZ);
+                    FLTD(x3, v1, d1);
+                    BNEZ_MARK2(x3);
+                    if (v0 != d0) FMVD(v0, d0);
+                    B_NEXT_nocond;
+                    MARK2;
+                    if (u8 & 4) {
+                        u8 = sse_setround(dyn, ninst, x4, x2);
+                        FCVTLD(x5, d0, RD_DYN);
+                        FCVTDL(v0, x5, RD_RTZ);
+                        x87_restoreround(dyn, ninst, u8);
+                    } else {
+                        FCVTLD(x5, d0, round_round[u8 & 3]);
+                        FCVTDL(v0, x5, RD_RTZ);
+                    }
+                    break;
+                case 0x0C:
+                    INST_NAME("BLENDPS Gx, Ex, Ib");
+                    nextop = F8;
+                    GETGX();
+                    GETEX(x2, 1, 12);
+                    u8 = F8 & 0b1111;
+                    for (int i = 0; i < 4; ++i)
+                        if (u8 & (1 << i)) {
+                            LWU(x1, wback, fixedaddress + i * 4);
+                            SW(x1, gback, gdoffset + i * 4);
+                        }
+                    break;
                 case 0x0E:
                     INST_NAME("PBLENDW Gx, Ex, Ib");
                     nextop = F8;
@@ -1265,6 +1315,18 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
                         SMWRITE2();
                     }
                     break;
+                case 0x17:
+                    INST_NAME("EXTRACTPS Ew, Gx, Ib");
+                    nextop = F8;
+                    GETGX();
+                    GETED(1);
+                    u8 = F8;
+                    LWU(ed, gback, gdoffset + 4 * (u8 & 3));
+                    if (wback) {
+                        SW(ed, wback, fixedaddress);
+                        SMWRITE2();
+                    }
+                    break;
                 case 0x20:
                     INST_NAME("PINSRB Gx, ED, Ib");
                     nextop = F8;
diff --git a/src/dynarec/rv64/dynarec_rv64_f20f.c b/src/dynarec/rv64/dynarec_rv64_f20f.c
index a7942c7e..73fea164 100644
--- a/src/dynarec/rv64/dynarec_rv64_f20f.c
+++ b/src/dynarec/rv64/dynarec_rv64_f20f.c
@@ -416,6 +416,37 @@ uintptr_t dynarec64_F20F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
             NEG(x2, x2);
             FMVDX(d0, x2);
             break;
+        case 0xD0:
+            INST_NAME("ADDSUBPS Gx, Ex");
+            nextop = F8;
+            GETGX();
+            GETEX(x2, 0, 12);
+            d0 = fpu_get_scratch(dyn);
+            d1 = fpu_get_scratch(dyn);
+            // GX->f[0] -= EX->f[0];
+            FLW(d0, wback, fixedaddress + 0);
+            FLW(d1, gback, gdoffset + 0);
+            FSUBS(d1, d1, d0);
+            FSW(d1, gback, gdoffset + 0);
+
+            // GX->f[1] += EX->f[1];
+            FLW(d0, wback, fixedaddress + 4);
+            FLW(d1, gback, gdoffset + 4);
+            FADDS(d1, d1, d0);
+            FSW(d1, gback, gdoffset + 4);
+
+            // GX->f[2] -= EX->f[2];
+            FLW(d0, wback, fixedaddress + 8);
+            FLW(d1, gback, gdoffset + 8);
+            FSUBS(d1, d1, d0);
+            FSW(d1, gback, gdoffset + 8);
+
+            // GX->f[3] += EX->f[3];
+            FLW(d0, wback, fixedaddress + 12);
+            FLW(d1, gback, gdoffset + 12);
+            FADDS(d1, d1, d0);
+            FSW(d1, gback, gdoffset + 12);
+            break;
         case 0xE6:
             INST_NAME("CVTPD2DQ Gx, Ex");
             nextop = F8;
diff --git a/src/emu/x64run660f.c b/src/emu/x64run660f.c
index 84ed4e25..35fd6eab 100644
--- a/src/emu/x64run660f.c
+++ b/src/emu/x64run660f.c
@@ -966,7 +966,7 @@ uintptr_t Run660F(x64emu_t *emu, rex_t rex, uintptr_t addr)
                 }

                 break;

 

-            case 0x0C:  /* PBLENDPS Gx, Ex, Ib */

+            case 0x0C: /* BLENDPS Gx, Ex, Ib */

                 nextop = F8;

                 GETEX(1);

                 GETGX;

@@ -976,7 +976,7 @@ uintptr_t Run660F(x64emu_t *emu, rex_t rex, uintptr_t addr)
                         GX->ud[i] = EX->ud[i];

                 }

                 break;

-            case 0x0D:  /* PBLENDPD Gx, Ex, Ib */

+            case 0x0D: /* BLENDPD Gx, Ex, Ib */

                 nextop = F8;

                 GETEX(1);

                 GETGX;