about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--src/dynarec/rv64/dynarec_rv64_f30f.c35
-rw-r--r--src/dynarec/rv64/dynarec_rv64_helper.h26
-rw-r--r--src/dynarec/rv64/rv64_emitter.h18
3 files changed, 78 insertions, 1 deletions
diff --git a/src/dynarec/rv64/dynarec_rv64_f30f.c b/src/dynarec/rv64/dynarec_rv64_f30f.c
index 4aa1a12b..c50196e0 100644
--- a/src/dynarec/rv64/dynarec_rv64_f30f.c
+++ b/src/dynarec/rv64/dynarec_rv64_f30f.c
@@ -85,6 +85,41 @@ uintptr_t dynarec64_F30F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
             nextop = F8;
             FAKEED;
             break;
+
+        case 0x2A:
+            INST_NAME("CVTSI2SS Gx, Ed");
+            nextop = F8;
+            GETGXSS(v0);
+            GETED(0);
+            if(rex.w) {
+                FCVTSL(v0, ed);
+            } else {
+                FCVTSW(v0, ed);
+            }
+            break;
+
+        case 0x58:
+            INST_NAME("ADDSS Gx, Ex");
+            nextop = F8;
+            GETGXSS(v0);
+            GETEXSS(d0, 0);
+            FADDS(v0, v0, d0);
+            break;
+        case 0x59:
+            INST_NAME("MULSS Gx, Ex");
+            nextop = F8;
+            GETGXSS(v0);
+            GETEXSS(d0, 0);
+            FMULS(v0, v0, d0);
+            break;
+        case 0x5A:
+            INST_NAME("CVTSS2SD Gx, Ex");
+            nextop = F8;
+            GETEXSS(v1, 0);
+            GETGXSD_empty(v0);
+            FCVTDS(v0, v1);
+            break;
+
         default:
             DEFAULT;
     }
diff --git a/src/dynarec/rv64/dynarec_rv64_helper.h b/src/dynarec/rv64/dynarec_rv64_helper.h
index 17247fb7..986b5ac8 100644
--- a/src/dynarec/rv64/dynarec_rv64_helper.h
+++ b/src/dynarec/rv64/dynarec_rv64_helper.h
@@ -272,6 +272,32 @@
 // Generic get GD, but reg value in gd (R_RAX is not added)
 #define GETG        gd = ((nextop&0x38)>>3)+(rex.r<<3)
 
+// Get GX as a Single (might use x1)
+#define GETGXSS(a)                      \
+    gd = ((nextop&0x38)>>3)+(rex.r<<3); \
+    a = sse_get_reg(dyn, ninst, x1, gd, 1)
+
+// Get GX as a Double (might use x1)
+#define GETGXSD(a)                      \
+    gd = ((nextop&0x38)>>3)+(rex.r<<3); \
+    a = sse_get_reg(dyn, ninst, x1, gd, 0)
+
+// Get GX as a Double (might use x1), no fetching old value
+#define GETGXSD_empty(a)                \
+    gd = ((nextop&0x38)>>3)+(rex.r<<3); \
+    a = sse_get_reg_empty(dyn, ninst, x1, gd, 0)
+
+// Get Ex as a single, not a quad (warning, x1 get used, x2 might too)
+#define GETEXSS(a, D)                                                                                   \
+    if(MODREG) {                                                                                        \
+        a = sse_get_reg(dyn, ninst, x1, (nextop&7)+(rex.b<<3), 1);                                      \
+    } else {                                                                                            \
+        SMREAD();                                                                                       \
+        a = fpu_get_scratch(dyn);                                                                       \
+        addr = geted(dyn, addr, ninst, nextop, &ed, x1, x2, &fixedaddress, rex, NULL, 1, D);            \
+        FLW(a, ed, fixedaddress);                                                                       \
+    }
+
 // CALL will use x6 for the call address. Return value can be put in ret (unless ret is -1)
 // R0 will not be pushed/popd if ret is -2
 #define CALL(F, ret) call_c(dyn, ninst, F, x6, ret, 1, 0)
diff --git a/src/dynarec/rv64/rv64_emitter.h b/src/dynarec/rv64/rv64_emitter.h
index 242f27ee..cda28da2 100644
--- a/src/dynarec/rv64/rv64_emitter.h
+++ b/src/dynarec/rv64/rv64_emitter.h
@@ -383,7 +383,15 @@ f28–31  ft8–11  FP temporaries                  Caller
 // Move to Single
 #define FMVWX(frd, rs1)             EMIT(R_type(0b1111000, 0b00000, rs1, 0b000, frd, 0b1010011))
 // Convert from signed 32bits to Single
-#define FCVTSW(frd, rs1)             EMIT(R_type(0b1101000, 0b00000, rs1, 0b000, frd, 0b1010011))
+#define FCVTSW(frd, rs1)            EMIT(R_type(0b1101000, 0b00000, rs1, 0b000, frd, 0b1010011))
+
+#define FADDS(frd, frs1, frs2)      EMIT(R_type(0b0000000, frs2, frs1, 0b000, frd, 0b1010011))
+#define FSUBS(frd, frs1, frs2)      EMIT(R_type(0b0000100, frs2, frs1, 0b000, frd, 0b1010011))
+#define FMULS(frd, frs1, frs2)      EMIT(R_type(0b0001000, frs2, frs1, 0b000, frd, 0b1010011))
+#define FDIVS(frd, frs1, frs2)      EMIT(R_type(0b0001100, frs2, frs1, 0b000, frd, 0b1010011))
+#define FSQRTS(frd, frs1)           EMIT(R_type(0b0101100, 0b00000, frs1, 0b000, frd, 0b1010011))
+#define FMINS(frd, frs1, frs2)      EMIT(R_type(0b0010100, frs2, frs1, 0b000, frd, 0b1010011))
+#define FMAXS(frd, frs1, frs2)      EMIT(R_type(0b0010100, frs2, frs1, 0b001, frd, 0b1010011))
 
 // RV64F
 // Convert from signed 64bits to Single
@@ -414,6 +422,14 @@ f28–31  ft8–11  FP temporaries                  Caller
 // Convert from signed 32bits to Double
 #define FCVTDW(frd, rs1)             EMIT(R_type(0b1101001, 0b00000, rs1, 0b000, frd, 0b1010011))
 
+#define FADDD(frd, frs1, frs2)      EMIT(R_type(0b0000001, frs2, frs1, 0b000, frd, 0b1010011))
+#define FSUBD(frd, frs1, frs2)      EMIT(R_type(0b0000101, frs2, frs1, 0b000, frd, 0b1010011))
+#define FMULD(frd, frs1, frs2)      EMIT(R_type(0b0001001, frs2, frs1, 0b000, frd, 0b1010011))
+#define FDIVD(frd, frs1, frs2)      EMIT(R_type(0b0001101, frs2, frs1, 0b000, frd, 0b1010011))
+#define FSQRTD(frd, frs1)           EMIT(R_type(0b0101101, 0b00000, frs1, 0b000, frd, 0b1010011))
+#define FMIND(frd, frs1, frs2)      EMIT(R_type(0b0010101, frs2, frs1, 0b000, frd, 0b1010011))
+#define FMAXD(frd, frs1, frs2)      EMIT(R_type(0b0010101, frs2, frs1, 0b001, frd, 0b1010011))
+
 //RV64D
 // Move from Double
 #define FMVXD(rd, frs1)             EMIT(R_type(0b1110001, 0b00000, frs1, 0b000, rd, 0b1010011))