about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorYang Liu <numbksco@gmail.com>2024-03-01 02:33:36 +0800
committerGitHub <noreply@github.com>2024-02-29 19:33:36 +0100
commitc58adce8f60c4fb8b00ed0cedcc4a69f0dc973ff (patch)
tree0aa1dfe235a770dd44171045820ca60d320a558d
parent92532b0fd1c14aefbd82aed93a04ce5b11e5abf7 (diff)
downloadbox64-c58adce8f60c4fb8b00ed0cedcc4a69f0dc973ff.tar.gz
box64-c58adce8f60c4fb8b00ed0cedcc4a69f0dc973ff.zip
[LA64_DYNAREC] Added 1 more opcode and more fixes (#1305)
* Fixed printer name mapping

* Fixed emit_sub32c

* Remove a useless macro

* Added 85 TEST opcode
-rw-r--r--CMakeLists.txt1
-rw-r--r--src/dynarec/la64/dynarec_la64_00.c10
-rw-r--r--src/dynarec/la64/dynarec_la64_emit_math.c2
-rw-r--r--src/dynarec/la64/dynarec_la64_emit_tests.c70
-rw-r--r--src/dynarec/la64/dynarec_la64_helper.h6
-rw-r--r--src/dynarec/la64/la64_emitter.h2
-rw-r--r--src/dynarec/la64/la64_printer.c2
7 files changed, 88 insertions, 5 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 6179d5fa..9068fc5e 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -835,6 +835,7 @@ if(LARCH64_DYNAREC)
 
     set(DYNAREC_PASS
     "${BOX64_ROOT}/src/dynarec/la64/dynarec_la64_helper.c"
+    "${BOX64_ROOT}/src/dynarec/la64/dynarec_la64_emit_tests.c"
     "${BOX64_ROOT}/src/dynarec/la64/dynarec_la64_emit_math.c"
     "${BOX64_ROOT}/src/dynarec/la64/dynarec_la64_00.c"
     )
diff --git a/src/dynarec/la64/dynarec_la64_00.c b/src/dynarec/la64/dynarec_la64_00.c
index bcfd9e7b..268c89ac 100644
--- a/src/dynarec/la64/dynarec_la64_00.c
+++ b/src/dynarec/la64/dynarec_la64_00.c
@@ -193,6 +193,14 @@ uintptr_t dynarec64_00(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                     DEFAULT;
             }
             break;
+        case 0x85:
+            INST_NAME("TEST Ed, Gd");
+            SETFLAGS(X_ALL, SF_SET_PENDING);
+            nextop = F8;
+            GETGD;
+            GETED(0);
+            emit_test32(dyn, ninst, rex, ed, gd, x3, x4, x5);
+            break;
         case 0x89:
             INST_NAME("MOV Ed, Gd");
             nextop = F8;
@@ -214,7 +222,7 @@ uintptr_t dynarec64_00(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
             nextop=F8;
             GETGD;
             if(MODREG) {
-                MVxw(gd, xRAX + TO_LA64((nextop&7) + (rex.b<<3)));
+                MVxw(gd, TO_LA64((nextop&7) + (rex.b<<3)));
             } else {
                 addr = geted(dyn, addr, ninst, nextop, &ed, x2, x1, &fixedaddress, rex, &lock, 1, 0);
                 SMREADLOCK(lock);
diff --git a/src/dynarec/la64/dynarec_la64_emit_math.c b/src/dynarec/la64/dynarec_la64_emit_math.c
index b3db124c..9543d5f1 100644
--- a/src/dynarec/la64/dynarec_la64_emit_math.c
+++ b/src/dynarec/la64/dynarec_la64_emit_math.c
@@ -549,8 +549,8 @@ void emit_sub32c(dynarec_la64_t* dyn, int ninst, rex_t rex, int s1, int64_t c, i
     }
 
     if (la64_lbt) {
+        IFX(X_PEND) {} else {MOV64xw(s2, c);}
         IFX(X_ALL) {
-            IFX(X_PEND) {} else {MOV64xw(s2, c);}
             X64_SUB_WU(s1, s2);
             X64_GET_EFLAGS(s3, X_ALL);
             ORI(xFlags, xFlags, s3);
diff --git a/src/dynarec/la64/dynarec_la64_emit_tests.c b/src/dynarec/la64/dynarec_la64_emit_tests.c
new file mode 100644
index 00000000..f7e1938e
--- /dev/null
+++ b/src/dynarec/la64/dynarec_la64_emit_tests.c
@@ -0,0 +1,70 @@
+#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 "la64_printer.h"
+#include "dynarec_la64_private.h"
+#include "dynarec_la64_functions.h"
+#include "dynarec_la64_helper.h"
+
+
+// emit TEST32 instruction, from test s1, s2, using s3 and s4 as scratch
+void emit_test32(dynarec_la64_t* dyn, int ninst, rex_t rex, int s1, int s2, int s3, int s4, int s5)
+{
+    CLEAR_FLAGS();
+    IFX_PENDOR0 {
+        SET_DF(s3, rex.w?d_tst64:d_tst32);
+    } else {
+        SET_DFNONE();
+    }
+
+    if (la64_lbt) {
+        IFX(X_ALL) {
+            if (rex.w) X64_AND_D(s1, s2); else X64_AND_W(s1, s2);
+            X64_GET_EFLAGS(s3, X_ALL);
+            ORI(xFlags, xFlags, s3);
+        }
+
+        AND(s3, s1, s2);
+
+        IFX_PENDOR0 {
+            SDxw(s3, xEmu, offsetof(x64emu_t, res));
+        }
+        return;
+    }
+
+    AND(s3, s1, s2); // res = s1 & s2
+
+    IFX_PENDOR0 {
+        SDxw(s3, xEmu, offsetof(x64emu_t, res));
+    }
+    IFX(X_SF | X_ZF) {
+        if (!rex.w) ZEROUP(s3);
+    }
+    IFX(X_SF) {
+        SRLI_D(s4, s3, rex.w?63:31);
+        BEQZ(s4, 8);
+        ORI(xFlags, xFlags, 1 << F_SF);
+    }
+    IFX(X_ZF) {
+        BNEZ(s3, 8);
+        ORI(xFlags, xFlags, 1 << F_ZF);
+    }
+    IFX(X_PF) {
+        emit_pf(dyn, ninst, s3, s4, s5);
+    }
+}
\ 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 5306814d..76f71d32 100644
--- a/src/dynarec/la64/dynarec_la64_helper.h
+++ b/src/dynarec/la64/dynarec_la64_helper.h
@@ -212,6 +212,10 @@
 #define GETMARKLOCK dyn->insts[ninst].marklock
 
 #define IFX(A) if ((dyn->insts[ninst].x64.gen_flags & (A)))
+#define IFX_PENDOR0 if ((dyn->insts[ninst].x64.gen_flags & (X_PEND) || !dyn->insts[ninst].x64.gen_flags))
+#define IFXX(A)     if ((dyn->insts[ninst].x64.gen_flags == (A)))
+#define IFX2X(A, B) if ((dyn->insts[ninst].x64.gen_flags == (A) || dyn->insts[ninst].x64.gen_flags == (B) || dyn->insts[ninst].x64.gen_flags == ((A) | (B))))
+#define IFXN(A, B)  if ((dyn->insts[ninst].x64.gen_flags & (A) && !(dyn->insts[ninst].x64.gen_flags & (B))))
 
 #define STORE_REG(A) ST_D(x##A, xEmu, offsetof(x64emu_t, regs[_##A]))
 #define LOAD_REG(A)  LD_D(x##A, xEmu, offsetof(x64emu_t, regs[_##A]))
@@ -376,6 +380,7 @@ void* la64_next(x64emu_t* emu, uintptr_t addr);
 #define jump_to_epilog STEPNAME(jump_to_epilog)
 #define jump_to_next   STEPNAME(jump_to_next)
 #define call_c         STEPNAME(call_c)
+#define emit_test32    STEPNAME(emit_test32)
 #define emit_add32     STEPNAME(emit_add32)
 #define emit_add32c    STEPNAME(emit_add32c)
 #define emit_add8      STEPNAME(emit_add8)
@@ -405,6 +410,7 @@ uintptr_t geted32(dynarec_la64_t* dyn, uintptr_t addr, int ninst, uint8_t nextop
 void jump_to_epilog(dynarec_la64_t* dyn, uintptr_t ip, int reg, int ninst);
 void jump_to_next(dynarec_la64_t* dyn, uintptr_t ip, int reg, int ninst, int is32bits);
 void call_c(dynarec_la64_t* dyn, int ninst, void* fnc, int reg, int ret, int saveflags, int save_reg);
+void emit_test32(dynarec_la64_t* dyn, int ninst, rex_t rex, int s1, int s2, int s3, int s4, int s5);
 void emit_add32(dynarec_la64_t* dyn, int ninst, rex_t rex, int s1, int s2, int s3, int s4, int s5);
 void emit_add32c(dynarec_la64_t* dyn, int ninst, rex_t rex, int s1, int64_t c, int s2, int s3, int s4, int s5);
 void emit_add8(dynarec_la64_t* dyn, int ninst, int s1, int s2, int s3, int s4);
diff --git a/src/dynarec/la64/la64_emitter.h b/src/dynarec/la64/la64_emitter.h
index 6adcdf7f..656607f4 100644
--- a/src/dynarec/la64/la64_emitter.h
+++ b/src/dynarec/la64/la64_emitter.h
@@ -53,8 +53,6 @@ f24-f31  fs0-fs7   Static registers                Callee
 #define xRIP    20
 // function to move from x86 regs number to LA64 reg number
 #define TO_LA64(A) (((A)>7)?((A)+15):((A)+12))
-// function to move from LA64 regs number to x86 reg number
-#define FROM_LA64(A) (((A)>22)?((A)-15):((A)-12))
 // 32bits version
 #define wEAX    xRAX
 #define wECX    xRCX
diff --git a/src/dynarec/la64/la64_printer.c b/src/dynarec/la64/la64_printer.c
index 5e1231bd..277921dd 100644
--- a/src/dynarec/la64/la64_printer.c
+++ b/src/dynarec/la64/la64_printer.c
@@ -6,7 +6,7 @@
 #include "la64_printer.h"
 #include "debug.h"
 
-static const char* Xt[] = {"xZR", "r1", "r2", "sp", "xEmu", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "xRAX", "xRCX", "xRDX", "xRBX", "xRSP", "xRBP", "xRSI", "xRDI", "xR8", "r21", "xR9", "xR10", "xR11", "xR12", "xR13", "xR14", "xR15", "xFlags", "xRIP", "r31"};
+static const char* Xt[] = {"xZR", "r1", "r2", "sp", "xEmu", "x1_r5", "x2_r6", "x3_r7", "x4_r8", "x5_r9", "x6_r10", "xMASK_r11", "xRAX_r12", "xRCX_r13", "xRDX_r14", "xRBX_r15", "xRSP_r16", "xRBP_r17", "xRSI_r18", "xRDI_r19", "xRIP_r20", "r21", "r22", "xR8_r23", "xR9_r24", "xR10_r25", "xR11_r26", "xR12_r27", "xR13_r28", "xR14_r29", "xR15_r30", "xFlags_r31"};
 
 typedef struct la64_print_s {
     int d, j, k, a;