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_660f.c16
-rw-r--r--src/dynarec/rv64/dynarec_rv64_db.c2
-rw-r--r--src/dynarec/rv64/dynarec_rv64_f20f.c31
-rw-r--r--src/dynarec/rv64/rv64_emitter.h2
4 files changed, 47 insertions, 4 deletions
diff --git a/src/dynarec/rv64/dynarec_rv64_660f.c b/src/dynarec/rv64/dynarec_rv64_660f.c
index 3e084330..bac50efc 100644
--- a/src/dynarec/rv64/dynarec_rv64_660f.c
+++ b/src/dynarec/rv64/dynarec_rv64_660f.c
@@ -161,6 +161,22 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
             SD(x3, gback, 0);
             SD(x4, gback, 8);
             break;
+        case 0x70: // TODO: Optimize this!
+            INST_NAME("PSHUFD Gx,Ex,Ib");
+            nextop = F8;
+            GETGX(x1);
+            GETEX(x2, 1);
+            u8 = F8;
+            i32 = -1;
+            for (int i=0; i<4; ++i) {
+                int32_t idx = (u8>>(i*2))&3;
+                if (idx!=i32) {
+                    LWU(x4, wback, fixedaddress+idx*4);
+                    i32 = idx;
+                }
+                SW(x4, gback, i*4);
+            }
+            break;
         case 0x72:
             nextop = F8;
             switch((nextop>>3)&7) {
diff --git a/src/dynarec/rv64/dynarec_rv64_db.c b/src/dynarec/rv64/dynarec_rv64_db.c
index 1bc42f1e..95e350c0 100644
--- a/src/dynarec/rv64/dynarec_rv64_db.c
+++ b/src/dynarec/rv64/dynarec_rv64_db.c
@@ -179,7 +179,7 @@ uintptr_t dynarec64_DB(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                     v1 = x87_do_push(dyn, ninst, x1, EXT_CACHE_ST_D);
                     addr = geted(dyn, addr, ninst, nextop, &ed, x2, x1, &fixedaddress, rex, NULL, 1, 0);
                     LW(x1, ed, fixedaddress);
-                    FCVTDW(v1, x1);    // i32 -> double
+                    FCVTDW(v1, x1, RD_RNE);    // i32 -> double
                     break;
                 case 1:
                     INST_NAME("FISTTP Ed, ST0");
diff --git a/src/dynarec/rv64/dynarec_rv64_f20f.c b/src/dynarec/rv64/dynarec_rv64_f20f.c
index 27e77a87..ef181e97 100644
--- a/src/dynarec/rv64/dynarec_rv64_f20f.c
+++ b/src/dynarec/rv64/dynarec_rv64_f20f.c
@@ -79,7 +79,17 @@ uintptr_t dynarec64_F20F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
                 SMWRITE2();
             }
             break;
-
+        case 0x2A:
+            INST_NAME("CVTSI2SD Gx, Ed");
+            nextop = F8;
+            GETGXSD(v0);
+            GETED(0);
+            if(rex.w) {
+                FCVTDL(v0, ed, RD_RNE);
+            } else {
+                FCVTDW(v0, ed, RD_RNE);
+            }
+            break;
         case 0x38:  // these are some more SSSE4.2+ opcodes
             opcode = F8;
             switch(opcode) {
@@ -124,7 +134,24 @@ uintptr_t dynarec64_F20F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
             GETEXSD(v1, 0);
             FSUBD(v0, v0, v1);
             break;
-
+        case 0x5E:
+            INST_NAME("DIVSD Gx, Ex");
+            nextop = F8;
+            GETGXSD(v0);
+            GETEXSD(v1, 0);
+            if(!box64_dynarec_fastnan) {
+                FEQD(x3, v0, v0);
+                FEQD(x4, v1, v1);
+            }
+            FDIVD(v0, v0, v1);
+            if(!box64_dynarec_fastnan) {
+                AND(x3, x3, x4);
+                CBZ_NEXT(x3);
+                FEQD(x3, v0, v0);
+                CBNZ_NEXT(x3);
+                FNEGD(v0, v0);
+            }
+            break;
         case 0xC2:
             INST_NAME("CMPSD Gx, Ex, Ib");
             nextop = F8;
diff --git a/src/dynarec/rv64/rv64_emitter.h b/src/dynarec/rv64/rv64_emitter.h
index 3e2bcbd6..73955b1c 100644
--- a/src/dynarec/rv64/rv64_emitter.h
+++ b/src/dynarec/rv64/rv64_emitter.h
@@ -469,7 +469,7 @@ f28–31  ft8–11  FP temporaries                  Caller
 // |rs1| => rd
 #define FABSD(rd, rs1)              FSGNJXD(rd, rs1, rs1)
 // Convert from signed 32bits to Double
-#define FCVTDW(frd, rs1)             EMIT(R_type(0b1101001, 0b00000, rs1, 0b000, frd, 0b1010011))
+#define FCVTDW(frd, rs1, rm)        EMIT(R_type(0b1101001, 0b00000, rs1, rm, frd, 0b1010011))
 
 #define FEQD(rd, frs1, frs2)        EMIT(R_type(0b1010001, frs2, frs1, 0b010, rd, 0b1010011))
 #define FLTD(rd, frs1, frs2)        EMIT(R_type(0b1010001, frs2, frs1, 0b001, rd, 0b1010011))