about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorxctan <xctan@cirno.icu>2023-03-27 16:00:39 +0800
committerGitHub <noreply@github.com>2023-03-27 10:00:39 +0200
commitcca1fd6f1987acc5fe7180a3925bbe8b1f34ccd0 (patch)
treee89709c3c7f47d02ff0a7bde36e19102adcaee67 /src
parent4fb126635c153b9bda9992e9d9d6483a0ca230f3 (diff)
downloadbox64-cca1fd6f1987acc5fe7180a3925bbe8b1f34ccd0.tar.gz
box64-cca1fd6f1987acc5fe7180a3925bbe8b1f34ccd0.zip
[RV64_DYNAREC] Added D8 /0 FADD opcode (#642)
* [RV64_DYNAREC] Fix broken x87_get_cache()

* [RV64_DYNAREC] Added D8 /0 FADD opcode
Diffstat (limited to 'src')
-rw-r--r--src/dynarec/rv64/dynarec_rv64_00.c3
-rw-r--r--src/dynarec/rv64/dynarec_rv64_d8.c83
-rw-r--r--src/dynarec/rv64/dynarec_rv64_helper.c1
-rw-r--r--src/dynarec/rv64/dynarec_rv64_helper.h2
-rw-r--r--src/dynarec/rv64/rv64_emitter.h12
5 files changed, 100 insertions, 1 deletions
diff --git a/src/dynarec/rv64/dynarec_rv64_00.c b/src/dynarec/rv64/dynarec_rv64_00.c
index 004707a1..e6bfe91f 100644
--- a/src/dynarec/rv64/dynarec_rv64_00.c
+++ b/src/dynarec/rv64/dynarec_rv64_00.c
@@ -1433,6 +1433,9 @@ uintptr_t dynarec64_00(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
             }
             break;
 
+        case 0xD8:
+            addr = dynarec64_D8(dyn, addr, ip, ninst, rex, rep, ok, need_epilog);
+            break;
         case 0xD9:
             addr = dynarec64_D9(dyn, addr, ip, ninst, rex, rep, ok, need_epilog);
             break;
diff --git a/src/dynarec/rv64/dynarec_rv64_d8.c b/src/dynarec/rv64/dynarec_rv64_d8.c
new file mode 100644
index 00000000..6525245d
--- /dev/null
+++ b/src/dynarec/rv64/dynarec_rv64_d8.c
@@ -0,0 +1,83 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <pthread.h>
+#include <errno.h>
+
+#include "debug.h"
+#include "box64context.h"
+#include "dynarec.h"
+#include "emu/x64emu_private.h"
+#include "emu/x64run_private.h"
+#include "x64run.h"
+#include "x64emu.h"
+#include "box64stack.h"
+#include "callback.h"
+#include "emu/x64run_private.h"
+#include "x64trace.h"
+#include "emu/x87emu_private.h"
+#include "dynarec_native.h"
+
+#include "rv64_printer.h"
+#include "dynarec_rv64_private.h"
+#include "dynarec_rv64_helper.h"
+#include "dynarec_rv64_functions.h"
+
+
+uintptr_t dynarec64_D8(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog)
+{
+    (void)ip; (void)rep; (void)need_epilog;
+
+    uint8_t nextop = F8;
+    uint8_t ed;
+    uint8_t wback, wb1;
+    uint8_t u8;
+    int64_t fixedaddress;
+    int unscaled;
+    int v1, v2;
+    int s0;
+    int i1, i2, i3;
+
+    MAYUSE(s0);
+    MAYUSE(v2);
+    MAYUSE(v1);
+
+    switch(nextop) {
+        case 0xC0 ... 0xC7:
+            DEFAULT;
+        case 0xC8 ... 0xCF:
+            DEFAULT;
+        case 0xD0 ... 0xD7:
+            DEFAULT;
+        case 0xD8 ... 0xDF:
+            DEFAULT;
+        case 0xE0 ... 0xE7:
+            DEFAULT;
+        case 0xE8 ... 0xEF:
+            DEFAULT;
+        case 0xF0 ... 0xF7:
+            DEFAULT;
+        case 0xF8 ... 0xFF:
+            DEFAULT;
+
+        default:
+            switch((nextop>>3)&7) {
+                case 0:
+                    INST_NAME("FADD ST0, float[ED]");
+                    v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_ST0);
+                    s0 = fpu_get_scratch(dyn);
+                    addr = geted(dyn, addr, ninst, nextop, &ed, x2, x1, &fixedaddress, rex, NULL, 1, 0);
+                    FLW(s0, ed, fixedaddress);
+                    if(ST_IS_F(0)) {
+                        FADDS(v1, v1, s0);
+                    } else {
+                        FCVTDS(s0, s0);
+                        FADDD(v1, v1, s0);
+                    }
+                    break;
+                default:
+                    DEFAULT;
+            }
+    }
+    return addr;
+}
diff --git a/src/dynarec/rv64/dynarec_rv64_helper.c b/src/dynarec/rv64/dynarec_rv64_helper.c
index f6d576ad..4f074b09 100644
--- a/src/dynarec/rv64/dynarec_rv64_helper.c
+++ b/src/dynarec/rv64/dynarec_rv64_helper.c
@@ -806,6 +806,7 @@ int x87_get_cache(dynarec_rv64_t* dyn, int ninst, int populate, int s1, int s2,
             ADDI(s2, s2, a);
             ANDI(s2, s2, 7);
         }
+        SLLI(s2, s2, 3);
         ADD(s1, xEmu, s2);
         FLD(dyn->e.x87reg[ret], s1, offsetof(x64emu_t, x87));
     }
diff --git a/src/dynarec/rv64/dynarec_rv64_helper.h b/src/dynarec/rv64/dynarec_rv64_helper.h
index a21fa5c0..dad8cde4 100644
--- a/src/dynarec/rv64/dynarec_rv64_helper.h
+++ b/src/dynarec/rv64/dynarec_rv64_helper.h
@@ -980,7 +980,7 @@ uintptr_t dynarec64_64(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
 //uintptr_t dynarec64_65(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep,int* ok, int* need_epilog);
 uintptr_t dynarec64_66(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog);
 //uintptr_t dynarec64_67(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog);
-//uintptr_t dynarec64_D8(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog);
+uintptr_t dynarec64_D8(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog);
 uintptr_t dynarec64_D9(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog);
 //uintptr_t dynarec64_DA(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog);
 uintptr_t dynarec64_DB(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog);
diff --git a/src/dynarec/rv64/rv64_emitter.h b/src/dynarec/rv64/rv64_emitter.h
index 391c4a3d..1f1b9035 100644
--- a/src/dynarec/rv64/rv64_emitter.h
+++ b/src/dynarec/rv64/rv64_emitter.h
@@ -397,6 +397,12 @@ f28–31  ft8–11  FP temporaries                  Caller
 // RV64F
 // Convert from signed 64bits to Single
 #define FCVTSL(frd, rs1)             EMIT(R_type(0b1101000, 0b00010, rs1, 0b000, frd, 0b1010011))
+// Convert from unsigned 64bits to Single
+#define FCVTSLU(frd, rs1)            EMIT(R_type(0b1101000, 0b00011, rs1, 0b000, frd, 0b1010011))
+// Convert from Single to signed 64bits
+#define FCVTLS(rd, frs1)            EMIT(R_type(0b1100000, 0b00010, frs1, 0b000, rd, 0b1010011))
+// Convert from Single to unsigned 64bits
+#define FCVTLUS(rd, frs1)           EMIT(R_type(0b1100000, 0b00011, frs1, 0b000, rd, 0b1010011))
 
 
 // RV32D
@@ -438,5 +444,11 @@ f28–31  ft8–11  FP temporaries                  Caller
 #define FMVDX(frd, rs1)             EMIT(R_type(0b1111001, 0b00000, rs1, 0b000, frd, 0b1010011))
 // Convert from signed 64bits to Double
 #define FCVTDL(frd, rs1)             EMIT(R_type(0b1101001, 0b00010, rs1, 0b000, frd, 0b1010011))
+// Convert from unsigned 64bits to Double
+#define FCVTDLU(frd, rs1)           EMIT(R_type(0b1101001, 0b00011, rs1, 0b000, frd, 0b1010011))
+// Convert from Double to signed 64bits
+#define FCVTLD(rd, frs1)            EMIT(R_type(0b1100001, 0b00010, frs1, 0b000, rd, 0b1010011))
+// Convert from Double to unsigned 64bits
+#define FCVTLUD(rd, frs1)           EMIT(R_type(0b1100001, 0b00011, frs1, 0b000, rd, 0b1010011))
 
 #endif //__RV64_EMITTER_H__