about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorYang Liu <liuyang22@iscas.ac.cn>2023-11-25 01:24:02 +0800
committerGitHub <noreply@github.com>2023-11-24 18:24:02 +0100
commit4969b8c2526fb3db392eee8eeee54cb18de1d555 (patch)
treee6360c473643956ff8deb238bc76473d4f7df474 /src
parent239ef8951d3a3620becbf1e2382cc5559aa66ffb (diff)
downloadbox64-4969b8c2526fb3db392eee8eeee54cb18de1d555.tar.gz
box64-4969b8c2526fb3db392eee8eeee54cb18de1d555.zip
[DYNAREC_RV64] Added more opcode for minipad2.exe (#1081)
* [DYNAREC_RV64] Added D1 /2 RCL opcode

* [DYNAREC_RV64] Added DA /6 FIDIV opcode

* [DYNAREC_RV64] Added DF /6 FBSTP opcode
Diffstat (limited to 'src')
-rw-r--r--src/dynarec/rv64/dynarec_rv64_00_3.c14
-rw-r--r--src/dynarec/rv64/dynarec_rv64_da.c120
-rw-r--r--src/dynarec/rv64/dynarec_rv64_df.c10
-rw-r--r--src/dynarec/rv64/dynarec_rv64_helper.h2
4 files changed, 143 insertions, 3 deletions
diff --git a/src/dynarec/rv64/dynarec_rv64_00_3.c b/src/dynarec/rv64/dynarec_rv64_00_3.c
index ddc78d67..9cdedfe7 100644
--- a/src/dynarec/rv64/dynarec_rv64_00_3.c
+++ b/src/dynarec/rv64/dynarec_rv64_00_3.c
@@ -503,6 +503,16 @@ uintptr_t dynarec64_00_3(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
                     WBACK;
                     if(!wback && !rex.w) ZEROUP(ed);
                     break;
+                case 2:
+                    INST_NAME("RCL Ed, 1");
+                    MESSAGE("LOG_DUMP", "Need optimization\n");
+                    READFLAGS(X_CF);
+                    SETFLAGS(X_OF|X_CF, SF_SET);
+                    MOV32w(x2, 1);
+                    GETEDW(x4, x1, 0);
+                    CALL_(rex.w ? ((void*)rcl64) : ((void*)rcl32), ed, x4);
+                    WBACK;
+                    break;
                 case 3:
                     INST_NAME("RCR Ed, 1");
                     MESSAGE(LOG_DUMP, "Need Optimization\n");
@@ -604,7 +614,9 @@ uintptr_t dynarec64_00_3(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
         case 0xD9:
             addr = dynarec64_D9(dyn, addr, ip, ninst, rex, rep, ok, need_epilog);
             break;
-
+        case 0xDA:
+            addr = dynarec64_DA(dyn, addr, ip, ninst, rex, rep, ok, need_epilog);
+            break;
         case 0xDB:
             addr = dynarec64_DB(dyn, addr, ip, ninst, rex, rep, ok, need_epilog);
             break;
diff --git a/src/dynarec/rv64/dynarec_rv64_da.c b/src/dynarec/rv64/dynarec_rv64_da.c
new file mode 100644
index 00000000..99cdef91
--- /dev/null
+++ b/src/dynarec/rv64/dynarec_rv64_da.c
@@ -0,0 +1,120 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <stddef.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_DA(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog)
+{
+    uint8_t nextop = F8;
+    int64_t j64;
+    uint8_t ed;
+    uint8_t wback;
+    int v1, v2;
+    int d0;
+    int s0;
+    int64_t fixedaddress;
+    int unscaled;
+
+    MAYUSE(s0);
+    MAYUSE(d0);
+    MAYUSE(v2);
+    MAYUSE(v1);
+    MAYUSE(ed);
+    MAYUSE(j64);
+
+    switch (nextop) {
+        case 0xC0:
+        case 0xC1:
+        case 0xC2:
+        case 0xC3:
+        case 0xC4:
+        case 0xC5:
+        case 0xC6:
+        case 0xC7:
+            DEFAULT;
+            break;
+        case 0xC8:
+        case 0xC9:
+        case 0xCA:
+        case 0xCB:
+        case 0xCC:
+        case 0xCD:
+        case 0xCE:
+        case 0xCF:
+            DEFAULT;
+            break;
+        case 0xD0:
+        case 0xD1:
+        case 0xD2:
+        case 0xD3:
+        case 0xD4:
+        case 0xD5:
+        case 0xD6:
+        case 0xD7:
+            DEFAULT;
+            break;
+        case 0xD8:
+        case 0xD9:
+        case 0xDA:
+        case 0xDB:
+        case 0xDC:
+        case 0xDD:
+        case 0xDE:
+        case 0xDF:
+            DEFAULT;
+            break;
+        case 0xE9:
+            DEFAULT;
+            break;
+
+        case 0xE4:
+        case 0xF0:
+        case 0xF1:
+        case 0xF4:
+        case 0xF5:
+        case 0xF6:
+        case 0xF7:
+        case 0xF8:
+        case 0xF9:
+        case 0xFD:
+            DEFAULT;
+            break;
+
+        default:
+            switch ((nextop >> 3) & 7) {
+                case 6:
+                    INST_NAME("FIDIV ST0, Ed");
+                    v1 = x87_get_st(dyn, ninst, x1, x2, 0, EXT_CACHE_ST_D);
+                    v2 = fpu_get_scratch(dyn);
+                    addr = geted(dyn, addr, ninst, nextop, &ed, x2, x1, &fixedaddress, rex, NULL, 1, 0);
+                    LW(x1, ed, fixedaddress);
+                    FCVTDW(v2, x1, RD_RNE);
+                    FDIVD(v1, v1, v2);
+                    break;
+                default:
+                    DEFAULT;
+                    break;
+            }
+    }
+    return addr;
+}
diff --git a/src/dynarec/rv64/dynarec_rv64_df.c b/src/dynarec/rv64/dynarec_rv64_df.c
index de3d9568..a2f66677 100644
--- a/src/dynarec/rv64/dynarec_rv64_df.c
+++ b/src/dynarec/rv64/dynarec_rv64_df.c
@@ -46,7 +46,7 @@ uintptr_t dynarec64_DF(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
 
         case 0xE0:
             INST_NAME("FNSTSW AX");
-            LHU(x2, xEmu, offsetof(x64emu_t, top));
+            LWU(x2, xEmu, offsetof(x64emu_t, top));
             LHU(x1, xEmu, offsetof(x64emu_t, sw));
             MOV32w(x3, 0b1100011111111111); // mask
             AND(x1, x1, x3);
@@ -193,6 +193,14 @@ uintptr_t dynarec64_DF(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                         FSD(v1, x5, 0);  // ref
                     }
                     break;
+                case 6:
+                    INST_NAME("FBSTP tbytes, ST0");
+                    x87_forget(dyn, ninst, x1, x2, 0);
+                    addr = geted(dyn, addr, ninst, nextop, &ed, x1, x2, &fixedaddress, rex, NULL, 0, 0);
+                    if (ed != x1) { MV(x1, ed); }
+                    CALL(fpu_fbst, -1);
+                    X87_POP_OR_FAIL(dyn, ninst, x3);
+                    break;
                 case 7:
                     INST_NAME("FISTP i64, ST0");
                     v1 = x87_get_st(dyn, ninst, x1, x2, 0, EXT_CACHE_ST_D);
diff --git a/src/dynarec/rv64/dynarec_rv64_helper.h b/src/dynarec/rv64/dynarec_rv64_helper.h
index 195f0b5f..12881835 100644
--- a/src/dynarec/rv64/dynarec_rv64_helper.h
+++ b/src/dynarec/rv64/dynarec_rv64_helper.h
@@ -1388,7 +1388,7 @@ uintptr_t dynarec64_67(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
 uintptr_t dynarec64_67_32(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_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);
 uintptr_t dynarec64_DC(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_DD(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog);