about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorYang Liu <numbksco@gmail.com>2024-02-29 23:11:52 +0800
committerGitHub <noreply@github.com>2024-02-29 16:11:52 +0100
commitda1ac7beee6c1710329f6794a27a8b1296d649ce (patch)
tree08bd507f0f04dcd5b4e0da39c30441e36cab270c /src
parent28b79626d9c77abb63b1d3212bbbd7dfa2e96687 (diff)
downloadbox64-da1ac7beee6c1710329f6794a27a8b1296d649ce.tar.gz
box64-da1ac7beee6c1710329f6794a27a8b1296d649ce.zip
[LA64_DYNAREC] Added basic LBT support, setup xMASK (#1302)
* [LA64] Added basic LBT support, setup xMASK

* [CI] Run tests without LBT
Diffstat (limited to 'src')
-rw-r--r--src/dynarec/la64/dynarec_la64_emit_math.c25
-rw-r--r--src/dynarec/la64/dynarec_la64_helper.c3
-rw-r--r--src/dynarec/la64/la64_emitter.h8
-rw-r--r--src/dynarec/la64/la64_prolog.S3
-rw-r--r--src/include/debug.h2
-rw-r--r--src/main.c10
6 files changed, 37 insertions, 14 deletions
diff --git a/src/dynarec/la64/dynarec_la64_emit_math.c b/src/dynarec/la64/dynarec_la64_emit_math.c
index 9fe6ce2f..45e09758 100644
--- a/src/dynarec/la64/dynarec_la64_emit_math.c
+++ b/src/dynarec/la64/dynarec_la64_emit_math.c
@@ -40,6 +40,21 @@ void emit_add32(dynarec_la64_t* dyn, int ninst, rex_t rex, int s1, int s2, int s
     {
         SET_DFNONE();
     }
+
+    if (la64_lbt) {
+        IFX(X_ALL) {
+            X64_ADD_WU(s1, s2);
+            X64_GET_EFLAGS(s3, X_ALL);
+            ORI(xFlags, xFlags, s3);
+        }
+        ADDxw(s1, s1, s2);
+        if (!rex.w) ZEROUP(s1);
+
+        IFX(X_PEND)
+            SDxw(s1, xEmu, offsetof(x64emu_t, res));
+        return;
+    }
+
     IFX(X_CF)
     {
         if (rex.w) {
@@ -68,17 +83,11 @@ void emit_add32(dynarec_la64_t* dyn, int ninst, rex_t rex, int s1, int s2, int s
         AND(s4, s1, s2); // s4 = op1 & op2
     }
 
-    if (rex.w)
-        ADD_D(s1, s1, s2);
-    else
-        ADD_W(s1, s1, s2);
+    ADDxw(s1, s1, s2);
 
     IFX(X_PEND)
     {
-        if (rex.w)
-            ST_D(s1, xEmu, offsetof(x64emu_t, res));
-        else
-            ST_W(s1, xEmu, offsetof(x64emu_t, res));
+        SDxw(s1, xEmu, offsetof(x64emu_t, res));
     }
     IFX(X_AF | X_OF)
     {
diff --git a/src/dynarec/la64/dynarec_la64_helper.c b/src/dynarec/la64/dynarec_la64_helper.c
index 0d3a8dd3..5ab4e320 100644
--- a/src/dynarec/la64/dynarec_la64_helper.c
+++ b/src/dynarec/la64/dynarec_la64_helper.c
@@ -444,6 +444,9 @@ void call_c(dynarec_la64_t* dyn, int ninst, void* fnc, int reg, int ret, int sav
             LD_D(xRIP, xEmu, offsetof(x64emu_t, ip));
 #undef GO
     }
+    // regenerate mask
+    ADDI_W(xMASK, xZR, -1);
+    LU32I_D(xMASK, 0);
 
     fpu_popcache(dyn, ninst, reg, 0);
     if (saveflags) {
diff --git a/src/dynarec/la64/la64_emitter.h b/src/dynarec/la64/la64_emitter.h
index 2717a4b2..5e826734 100644
--- a/src/dynarec/la64/la64_emitter.h
+++ b/src/dynarec/la64/la64_emitter.h
@@ -80,6 +80,8 @@ f24-f31  fs0-fs7   Static registers                Callee
 #define x4      8
 #define x5      9
 #define x6      10
+// used to clear the upper 32bits
+#define xMASK   11
 // 32bits version of scratch
 #define w1      x1
 #define w2      x2
@@ -104,11 +106,7 @@ f24-f31  fs0-fs7   Static registers                Callee
 #define SPLIT12(A) ((A) & 0xfff)
 
 // ZERO the upper part
-#define ZEROUP(r)               \
-    do {                        \
-        MOV32w(x2, 0xffffffff); \
-        AND(r, r, x2);          \
-    } while (0);
+#define ZEROUP(r) AND(r, r, xMASK);
 
 // Standard formats
 #define type_4R(opc, ra, rk, rj, rd)     ((opc) << 20 | (ra) << 15 | (rk) << 10 | (rj) << 5 | (rd))
diff --git a/src/dynarec/la64/la64_prolog.S b/src/dynarec/la64/la64_prolog.S
index b1dd3450..354e5518 100644
--- a/src/dynarec/la64/la64_prolog.S
+++ b/src/dynarec/la64/la64_prolog.S
@@ -56,5 +56,8 @@ la64_prolog:
     st.d   $r11, $sp, -16
     st.d   $r0,  $sp, -8
     addi.d $sp,  $sp, -16
+    // setup xMASK
+    addi.w  $r11, $r0, -1
+    lu32i.d $r4, 0
     //jump to function
     jirl   $r0,  $a1, 0
diff --git a/src/include/debug.h b/src/include/debug.h
index 0f0526f7..2c5746a0 100644
--- a/src/include/debug.h
+++ b/src/include/debug.h
@@ -60,6 +60,8 @@ extern int rv64_xtheadmempair;
 extern int rv64_xtheadfmemidx;
 extern int rv64_xtheadmac;
 extern int rv64_xtheadfmv;
+#elif defined(LA64)
+extern int la64_lbt;
 #endif
 #endif
 extern int box64_libcef;
diff --git a/src/main.c b/src/main.c
index bf628181..9450bfa4 100644
--- a/src/main.c
+++ b/src/main.c
@@ -106,6 +106,8 @@ int rv64_xtheadmempair = 0;
 int rv64_xtheadfmemidx = 0;
 int rv64_xtheadmac = 0;
 int rv64_xtheadfmv = 0;
+#elif defined(LA64)
+int la64_lbt = 0;
 #endif
 #else   //DYNAREC
 int box64_dynarec = 0;
@@ -444,9 +446,15 @@ HWCAP2_ECV
         printf_log(LOG_INFO, " AFP");
 #elif defined(LA64)
     printf_log(LOG_INFO, "Dynarec for LoongArch");
+    char *p = getenv("BOX64_DYNAREC_LA64NOEXT");
+    if(p == NULL || p[0] == '0') {
+        // We don't bother to detect it, it's there.
+        la64_lbt = 1;
+    }
 #elif defined(RV64)
     void RV64_Detect_Function();
-    if(!getenv("BOX64_DYNAREC_RV64NOEXT"))
+    char *p = getenv("BOX64_DYNAREC_RV64NOEXT");
+    if(p == NULL || p[0] == '0')
         RV64_Detect_Function();
     printf_log(LOG_INFO, "Dynarec for RISC-V ");
     printf_log(LOG_INFO, "With extension: I M A F D C");