about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--src/dynarec/la64/dynarec_la64_66.c12
-rw-r--r--src/libtools/signals.c25
-rw-r--r--src/os/hostext_linux.c13
3 files changed, 48 insertions, 2 deletions
diff --git a/src/dynarec/la64/dynarec_la64_66.c b/src/dynarec/la64/dynarec_la64_66.c
index 95ef995d..90ad5a11 100644
--- a/src/dynarec/la64/dynarec_la64_66.c
+++ b/src/dynarec/la64/dynarec_la64_66.c
@@ -8,6 +8,7 @@
 #include "box64cpu.h"
 #include "emu/x64emu_private.h"
 #include "la64_emitter.h"
+#include "la64_mapping.h"
 #include "x64emu.h"
 #include "box64stack.h"
 #include "callback.h"
@@ -699,6 +700,17 @@ uintptr_t dynarec64_66(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                 ADD_D(xRDI, xRDI, x3);
             }
             break;
+        case 0xAD:
+            if (rep) {
+                DEFAULT;
+            } else {
+                INST_NAME("LODSW");
+                GETDIR(x1, x2, 2);
+                LD_HU(x2, xRSI, 0);
+                ADD_D(xRSI, xRSI, x1);
+                BSTRINSz(xRAX, x2, 15, 0);
+            }
+            break;
         case 0xAF:
             switch (rep) {
                 case 1:
diff --git a/src/libtools/signals.c b/src/libtools/signals.c
index fcf7e7e9..72cd7591 100644
--- a/src/libtools/signals.c
+++ b/src/libtools/signals.c
@@ -354,7 +354,30 @@ void copyUCTXreg2Emu(x64emu_t* emu, ucontext_t* p, uintptr_t ip) {
     GO(R15);
     #undef GO
     emu->ip.q[0] = ip;
-    emu->eflags.x64 = CONTEXT_REG(p, xFlags);
+#ifdef LA64
+    // TODO: move to ADJUST_ARCH
+    if (cpuext.lbt) {
+        struct lbt_context* lbt_ctx = NULL;
+        struct sctx_info* info = (struct sctx_info*)p->uc_mcontext.__extcontext;
+        while (info->magic && !lbt_ctx) {
+            if (info->magic == LBT_CTX_MAGIC)
+                lbt_ctx = (struct lbt_context*)((uintptr_t)info + sizeof(struct sctx_info));
+            else
+                info = (struct sctx_info*)((uintptr_t)info + info->size);
+        }
+
+        if (lbt_ctx) {
+            uint64_t scratch = 0;
+            uint64_t flags = CONTEXT_REG(p, xFlags) & ~0b100011010101;
+            flags = flags | (lbt_ctx->eflags & 0b100011010101);
+            emu->eflags.x64 = flags;
+        } else {
+            printf_log(LOG_NONE, "Are you on a non-LBT kernel? Use BOX64_DYNAREC_LA64NOEXT=lbt to prevent Box64 from using it.\n");
+            emu->eflags.x64 = CONTEXT_REG(p, xFlags);
+        }
+    } else
+#endif
+        emu->eflags.x64 = CONTEXT_REG(p, xFlags);
 #endif
 }
 
diff --git a/src/os/hostext_linux.c b/src/os/hostext_linux.c
index c202a33f..531f7b85 100644
--- a/src/os/hostext_linux.c
+++ b/src/os/hostext_linux.c
@@ -185,7 +185,7 @@ int DetectHostCpuFeatures(void)
     #endif
 #elif defined(LA64)
     char* p = GetEnv("BOX64_DYNAREC_LA64NOEXT");
-    if(p == NULL || p[0] == '0') {
+    if (p == NULL || p[0] != '1') {
         uint32_t cpucfg2 = 0, idx = 2;
         asm volatile("cpucfg %0, %1" : "=r"(cpucfg2) : "r"(idx));
         if (((cpucfg2 >> 6) & 0b11) != 3) return 0; // LSX/LASX must present
@@ -195,6 +195,17 @@ int DetectHostCpuFeatures(void)
         cpuext.lam_bh = (cpucfg2 >> 27) & 0b1;
         cpuext.lamcas = (cpucfg2 >> 28) & 0b1;
         cpuext.scq = (cpucfg2 >> 30) & 0b1;
+        if (p) {
+            p = strtok(p, ",");
+            while (p) {
+                if (!strcasecmp(p, "lbt")) cpuext.lbt = 0;
+                if (!strcasecmp(p, "frecipe")) cpuext.frecipe = 0;
+                if (!strcasecmp(p, "lam_bh")) cpuext.lam_bh = 0;
+                if (!strcasecmp(p, "lamcas")) cpuext.lamcas = 0;
+                if (!strcasecmp(p, "scq")) cpuext.scq = 0;
+                p = strtok(NULL, ",");
+            }
+        }
     }
 #elif defined(RV64)
     // private env. variable for the developer ;)