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_00_2.c42
-rw-r--r--src/dynarec/rv64/dynarec_rv64_00_3.c5
-rw-r--r--src/dynarec/rv64/dynarec_rv64_0f.c45
-rw-r--r--src/dynarec/rv64/dynarec_rv64_660f.c28
-rw-r--r--src/dynarec/rv64/dynarec_rv64_f30f.c8
-rw-r--r--src/dynarec/rv64/dynarec_rv64_helper.h4
6 files changed, 126 insertions, 6 deletions
diff --git a/src/dynarec/rv64/dynarec_rv64_00_2.c b/src/dynarec/rv64/dynarec_rv64_00_2.c
index 6d626ba3..f7572790 100644
--- a/src/dynarec/rv64/dynarec_rv64_00_2.c
+++ b/src/dynarec/rv64/dynarec_rv64_00_2.c
@@ -504,6 +504,48 @@ uintptr_t dynarec64_00_2(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
                 ADD(xRDI, xRDI, x3);
             }
             break;
+        case 0xA6:
+            switch(rep) {
+            case 1:
+            case 2:
+                if(rep==1) {INST_NAME("REPNZ CMPSB");} else {INST_NAME("REPZ CMPSB");}
+                MAYSETFLAGS();
+                SETFLAGS(X_ALL, SF_SET_PENDING);
+                CBZ_NEXT(xRCX);
+                ANDI(x1, xFlags, 1<<F_DF);
+                BNEZ_MARK2(x1);
+                MARK;   // Part with DF==0
+                LBU(x1, xRSI, 0);
+                ADDI(xRSI, xRSI, 1);
+                LBU(x2, xRDI, 0);
+                ADDI(xRDI, xRDI, 1);
+                SUBI(xRCX, xRCX, 1);
+                if (rep==1) {BEQ_MARK3(x1, x2);} else {BNE_MARK3(x1, x2);}
+                BNEZ_MARK(xRCX);
+                B_MARK3_nocond;
+                MARK2;   // Part with DF==1
+                LBU(x1, xRSI, 0);
+                SUBI(xRSI, xRSI, 1);
+                LBU(x2, xRDI, 0);
+                SUBI(xRDI, xRDI, 1);
+                SUBI(xRCX, xRCX, 1);
+                if (rep==1) {BEQ_MARK3(x1, x2);} else {BNE_MARK3(x1, x2);}
+                BNEZ_MARK2(xRCX);
+                MARK3;  // end
+                emit_cmp8(dyn, ninst, x1, x2, x3, x4, x5, x6);
+                break;
+            default:
+                INST_NAME("CMPSB");
+                SETFLAGS(X_ALL, SF_SET_PENDING);
+                GETDIR(x3, x1, 1);
+                LBU(x1, xRSI, 0);
+                LBU(x2, xRDI, 0);
+                ADD(xRSI, xRSI, x3);
+                ADD(xRDI, xRDI, x3);
+                emit_cmp8(dyn, ninst, x1, x2, x3, x4, x5, x6);
+                break;
+            }
+            break;
         case 0xA8:
             INST_NAME("TEST AL, Ib");
             SETFLAGS(X_ALL, SF_SET_PENDING);
diff --git a/src/dynarec/rv64/dynarec_rv64_00_3.c b/src/dynarec/rv64/dynarec_rv64_00_3.c
index 70e73582..11b0ac5e 100644
--- a/src/dynarec/rv64/dynarec_rv64_00_3.c
+++ b/src/dynarec/rv64/dynarec_rv64_00_3.c
@@ -904,7 +904,10 @@ uintptr_t dynarec64_00_3(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
             SET_DFNONE();
             ORI(xFlags, xFlags, 1 << F_CF);
             break;
-
+        case 0xFC:
+            INST_NAME("CLD");
+            ANDI(xFlags, xFlags, ~(1<<F_CF));
+            break;
         case 0xFF:
             nextop = F8;
             switch((nextop>>3)&7) {
diff --git a/src/dynarec/rv64/dynarec_rv64_0f.c b/src/dynarec/rv64/dynarec_rv64_0f.c
index 3cded7b4..21895f48 100644
--- a/src/dynarec/rv64/dynarec_rv64_0f.c
+++ b/src/dynarec/rv64/dynarec_rv64_0f.c
@@ -136,7 +136,21 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
             if(!MODREG)
                 SMWRITE2();
             break;
-
+        case 0x12:
+            nextop = F8;
+            if(MODREG) {
+                INST_NAME("MOVHLPS Gx,Ex");
+                GETGX(x1);
+                GETEX(x2, 0);
+                LD(x3, wback, fixedaddress+8);
+                SD(x3, gback, 0);
+            } else {
+                INST_NAME("MOVLPS Gx,Ex");
+                GETEXSD(v0, 0);
+                GETGXSD_empty(v1);
+                FMVD(v1, v0);
+            }
+            break;
         case 0x14:
             INST_NAME("UNPCKLPS Gx,Ex");
             nextop = F8;
@@ -343,7 +357,21 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                 SSE_LOOP_Q(x3, x4, XOR(x3, x3, x4));
             }
             break;
-
+        case 0x58:
+            INST_NAME("ADDPS Gx, Ex");
+            nextop = F8;
+            GETGX(x1);
+            GETEX(x2, 0);
+            s0 = fpu_get_scratch(dyn);
+            s1 = fpu_get_scratch(dyn);
+            for(int i=0; i<4; ++i) {
+                // GX->f[i] += EX->f[i];
+                FLW(s0, wback, fixedaddress+i*4);
+                FLW(s1, gback, i*4);
+                FADDS(s1, s1, s0);
+                FSW(s1, gback, i*4);
+            }
+            break;
         case 0x5A:
             INST_NAME("CVTPS2PD Gx, Ex");
             nextop = F8;
@@ -358,7 +386,18 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
             FSD(s0, gback, 0);
             FSD(s1, gback, 8);
             break;
-
+        case 0x5B:
+            INST_NAME("CVTDQ2PS Gx, Ex");
+            nextop = F8;
+            GETGX(x1);
+            GETEX(x2, 0);
+            s0 = fpu_get_scratch(dyn);
+            for (int i=0; i<4; ++i) {
+                LW(x3, wback, fixedaddress+i*4);
+                FCVTSW(s0, x3, RD_RNE);
+                FSW(s0, gback, i*4);
+            }
+            break;
         case 0x77:
             INST_NAME("EMMS");
             // empty MMX, FPU now usable
diff --git a/src/dynarec/rv64/dynarec_rv64_660f.c b/src/dynarec/rv64/dynarec_rv64_660f.c
index 9c102d01..3cd22575 100644
--- a/src/dynarec/rv64/dynarec_rv64_660f.c
+++ b/src/dynarec/rv64/dynarec_rv64_660f.c
@@ -369,6 +369,34 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
             LWU(x3, x1, fixedaddress+0*4);
             SW(x3, x2, 1*4);
             break;
+        case 0x64:
+            INST_NAME("PCMPGTB Gx,Ex");
+            nextop = F8;
+            GETGX(x1);
+            GETEX(x2, 0);
+            for(int i=0; i<16; ++i) {
+                // GX->ub[i] = (GX->sb[i]>EX->sb[i])?0xFF:0x00;
+                LB(x3, wback, fixedaddress+i);
+                LB(x4, gback, i);
+                SLT(x3, x3, x4);
+                NEG(x3, x3);
+                SB(x3, gback, i);
+            }
+            break;
+        case 0x65:
+            INST_NAME("PCMPGTW Gx,Ex");
+            nextop = F8;
+            GETGX(x1);
+            GETEX(x2, 0);
+            for(int i=0; i<8; ++i) {
+                // GX->uw[i] = (GX->sw[i]>EX->sw[i])?0xFFFF:0x0000;
+                LH(x3, wback, fixedaddress+i*2);
+                LH(x4, gback, i*2);
+                SLT(x3, x3, x4);
+                NEG(x3, x3);
+                SH(x3, gback, i*2);
+            }
+            break;
         case 0x66:
             INST_NAME("PCMPGTD Gx,Ex");
             nextop = F8;
diff --git a/src/dynarec/rv64/dynarec_rv64_f30f.c b/src/dynarec/rv64/dynarec_rv64_f30f.c
index f90861bf..d1b51258 100644
--- a/src/dynarec/rv64/dynarec_rv64_f30f.c
+++ b/src/dynarec/rv64/dynarec_rv64_f30f.c
@@ -120,7 +120,13 @@ uintptr_t dynarec64_F30F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
                 }
             }
             break;
-
+        case 0x51:
+            INST_NAME("SQRTSS Gx, Ex");
+            nextop = F8;
+            GETEXSS(v0, 0);
+            GETGXSS_empty(v1);
+            FSQRTS(v1, v0);
+            break;
         case 0x58:
             INST_NAME("ADDSS Gx, Ex");
             nextop = F8;
diff --git a/src/dynarec/rv64/dynarec_rv64_helper.h b/src/dynarec/rv64/dynarec_rv64_helper.h
index 18e425e3..284767da 100644
--- a/src/dynarec/rv64/dynarec_rv64_helper.h
+++ b/src/dynarec/rv64/dynarec_rv64_helper.h
@@ -475,7 +475,7 @@
 #define BNEZ_MARK2(reg) BNE_MARK2(reg, xZR)
 // Branch to MARK2 if reg1<reg2 (use j64)
 #define BLT_MARK2(reg1, reg2) Bxx_gen(LT, MARK2, reg1,reg2)
-// Branch to MARK instruction unconditionnal (use j64)
+// Branch to MARK2 instruction unconditionnal (use j64)
 #define B_MARK2_nocond  Bxx_gen(__, MARK2, 0, 0)
 // Branch to MARK3 if reg1==reg2 (use j64)
 #define BEQ_MARK3(reg1, reg2) Bxx_gen(EQ, MARK3, reg1, reg2)
@@ -483,6 +483,8 @@
 #define BNE_MARK3(reg1, reg2) Bxx_gen(NE, MARK3, reg1, reg2)
 // Branch to MARK3 if reg1!=0 (use j64)
 #define BNEZ_MARK3(reg) BNE_MARK3(reg, xZR)
+// Branch to MARK3 instruction unconditionnal (use j64)
+#define B_MARK3_nocond  Bxx_gen(__, MARK3, 0, 0)
 // Branch to MARKLOCK if reg1!=reg2 (use j64)
 #define BNE_MARKLOCK(reg1, reg2) Bxx_gen(NE, MARKLOCK, reg1, reg2)
 // Branch to MARKLOCK if reg1!=0 (use j64)