about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorYang Liu <numbksco@gmail.com>2024-03-03 01:26:07 +0800
committerGitHub <noreply@github.com>2024-03-02 18:26:07 +0100
commitebaedca7084932d1d101614dd20dd534804f867e (patch)
tree64586ebe0cd5f8ee5c6bfbafc6366472655d9120 /src
parenta86f5972398dcebcfd718fccc1a956d7045c503b (diff)
downloadbox64-ebaedca7084932d1d101614dd20dd534804f867e.tar.gz
box64-ebaedca7084932d1d101614dd20dd534804f867e.zip
[LA64_DYNAREC] Added more opcodes (#1313)
* [LA64_DYNAREC] Added F30F 1E NOP opcode

* [LA64_DYNAREC] Added E9/EB JMP opcodes
Diffstat (limited to 'src')
-rw-r--r--src/dynarec/la64/dynarec_la64_00.c38
-rw-r--r--src/dynarec/la64/dynarec_la64_f30f.c60
-rw-r--r--src/dynarec/la64/dynarec_la64_helper.h11
3 files changed, 108 insertions, 1 deletions
diff --git a/src/dynarec/la64/dynarec_la64_00.c b/src/dynarec/la64/dynarec_la64_00.c
index 7a5eb0f6..9616a1e1 100644
--- a/src/dynarec/la64/dynarec_la64_00.c
+++ b/src/dynarec/la64/dynarec_la64_00.c
@@ -103,6 +103,15 @@ uintptr_t dynarec64_00(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
             i64 = F32S;
             emit_add32c(dyn, ninst, rex, xRAX, i64, x3, x4, x5, x6);
             break;
+        case 0x0F:
+            switch (rep) {
+                case 2:
+                    addr = dynarec64_F30F(dyn, addr, ip, ninst, rex, ok, need_epilog);
+                    break;
+                default:
+                    DEFAULT;
+            }
+            break;
         case 0x28:
             INST_NAME("SUB Eb, Gb");
             SETFLAGS(X_ALL, SF_SET_PENDING);
@@ -364,6 +373,35 @@ uintptr_t dynarec64_00(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                 }
             }
             break;
+        case 0xE9:
+        case 0xEB:
+            BARRIER(BARRIER_MAYBE);
+            if (opcode == 0xE9) {
+                INST_NAME("JMP Id");
+                i32 = F32S;
+            } else {
+                INST_NAME("JMP Ib");
+                i32 = F8S;
+            }
+            JUMP((uintptr_t)getAlternate((void*)(addr + i32)), 0);
+            if (dyn->insts[ninst].x64.jmp_insts == -1) {
+                // out of the block
+                fpu_purgecache(dyn, ninst, 1, x1, x2, x3);
+                jump_to_next(dyn, (uintptr_t)getAlternate((void*)(addr + i32)), 0, ninst, rex.is32bits);
+            } else {
+                // inside the block
+                CacheTransform(dyn, ninst, CHECK_CACHE(), x1, x2, x3);
+                tmp = dyn->insts[dyn->insts[ninst].x64.jmp_insts].address - (dyn->native_size);
+                MESSAGE(1, "Jump to %d / 0x%x\n", tmp, tmp);
+                if (tmp == 4) {
+                    NOP();
+                } else {
+                    B(tmp);
+                }
+            }
+            *need_epilog = 0;
+            *ok = 0;
+            break;
         case 0xFF:
             nextop = F8;
             switch ((nextop >> 3) & 7) {
diff --git a/src/dynarec/la64/dynarec_la64_f30f.c b/src/dynarec/la64/dynarec_la64_f30f.c
new file mode 100644
index 00000000..107e5f38
--- /dev/null
+++ b/src/dynarec/la64/dynarec_la64_f30f.c
@@ -0,0 +1,60 @@
+#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 "dynarec_native.h"
+#include "bitutils.h"
+
+#include "la64_printer.h"
+#include "dynarec_la64_private.h"
+#include "dynarec_la64_functions.h"
+#include "dynarec_la64_helper.h"
+
+uintptr_t dynarec64_F30F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int* ok, int* need_epilog)
+{
+    (void)ip;
+    (void)need_epilog;
+
+    uint8_t opcode = F8;
+    uint8_t nextop, u8;
+    uint8_t gd, ed;
+    uint8_t wback, gback;
+    uint64_t u64;
+    int v0, v1;
+    int q0, q1;
+    int d0, d1;
+    int64_t fixedaddress, gdoffset;
+    int unscaled;
+    int64_t j64;
+
+    MAYUSE(d0);
+    MAYUSE(d1);
+    MAYUSE(q0);
+    MAYUSE(q1);
+    MAYUSE(v0);
+    MAYUSE(v1);
+    MAYUSE(j64);
+
+    switch (opcode) {
+        case 0x1E:
+            INST_NAME("NOP / ENDBR32 / ENDBR64");
+            nextop = F8;
+            FAKEED;
+            break;
+        default:
+            DEFAULT;
+    }
+    return addr;
+}
\ No newline at end of file
diff --git a/src/dynarec/la64/dynarec_la64_helper.h b/src/dynarec/la64/dynarec_la64_helper.h
index 9bd7ef04..e1088ec9 100644
--- a/src/dynarec/la64/dynarec_la64_helper.h
+++ b/src/dynarec/la64/dynarec_la64_helper.h
@@ -107,6 +107,13 @@
         ed = x1;                                                                                \
     }
 
+// FAKEED like GETED, but doesn't get anything
+#define FAKEED                                   \
+    if (!MODREG) {                               \
+        addr = fakeed(dyn, addr, ninst, nextop); \
+    }
+
+
 // Write back ed in wback (if wback not 0)
 #define WBACK                              \
     if (wback) {                           \
@@ -432,7 +439,8 @@ void* la64_next(x64emu_t* emu, uintptr_t addr);
 
 #define native_pass STEPNAME(native_pass)
 
-#define dynarec64_00 STEPNAME(dynarec64_00)
+#define dynarec64_00   STEPNAME(dynarec64_00)
+#define dynarec64_F30F STEPNAME(dynarec64_F30F)
 
 #define geted               STEPNAME(geted)
 #define geted32             STEPNAME(geted32)
@@ -519,6 +527,7 @@ void CacheTransform(dynarec_la64_t* dyn, int ninst, int cacheupd, int s1, int s2
 #endif
 
 uintptr_t dynarec64_00(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog);
+uintptr_t dynarec64_F30F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int* ok, int* need_epilog);
 
 #if STEP < 3
 #define PASS3(A)