about summary refs log tree commit diff stats
path: root/src/dynarec
diff options
context:
space:
mode:
Diffstat (limited to 'src/dynarec')
-rw-r--r--src/dynarec/arm64/dynarec_arm64_00.c35
-rw-r--r--src/dynarec/dynarec_native_functions.c7
-rw-r--r--src/dynarec/dynarec_native_functions.h1
3 files changed, 37 insertions, 6 deletions
diff --git a/src/dynarec/arm64/dynarec_arm64_00.c b/src/dynarec/arm64/dynarec_arm64_00.c
index 30fd5f6b..7785b84e 100644
--- a/src/dynarec/arm64/dynarec_arm64_00.c
+++ b/src/dynarec/arm64/dynarec_arm64_00.c
@@ -821,13 +821,36 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
             }
             break;
         case 0x62:
-            if(rex.is32bits) {
-                // BOUND here
-                DEFAULT;
+            INST_NAME("BOUND Gd, Ed");
+            nextop = F8;
+            if(rex.is32bits && MODREG) {
+                addr = geted(dyn, addr, ninst, nextop, &wback, x1, &fixedaddress, NULL, 0, 0, rex, NULL, 0, 0);
+                LDRxw_U12(x2, wback, 0);
+                LDRxw_U12(x3, wback, 4+(rex.w*4));
+                GETGD;
+                GETIP(ip);
+                CMPSxw_REG(gd, x2);
+                B_MARK(cLT);
+                CMPSxw_REG(gd, x3);
+                B_MARK(cGT);
+                B_NEXT_nocond;
+                MARK;
+                STORE_XEMU_CALL(xRIP);
+                CALL(native_br, -1);
+                LOAD_XEMU_CALL(xRIP);
             } else {
-                INST_NAME("BOUND Gd, Ed");
-                nextop = F8;
-                FAKEED;
+                if(BOX64DRENV(dynarec_safeflags)>1) {
+                    READFLAGS(X_PEND);
+                } else {
+                    SETFLAGS(X_ALL, SF_SET_NODF);    // Hack to set flags in "don't care" state
+                }
+                GETIP(ip);
+                STORE_XEMU_CALL(xRIP);
+                CALL(native_ud, -1);
+                LOAD_XEMU_CALL(xRIP);
+                jump_to_epilog(dyn, 0, xRIP, ninst);
+                *need_epilog = 0;
+                *ok = 0;
             }
             break;
         case 0x63:
diff --git a/src/dynarec/dynarec_native_functions.c b/src/dynarec/dynarec_native_functions.c
index bcf06e6a..c9a116e6 100644
--- a/src/dynarec/dynarec_native_functions.c
+++ b/src/dynarec/dynarec_native_functions.c
@@ -189,6 +189,13 @@ void native_ud(x64emu_t* emu)
     emit_signal(emu, SIGILL, (void*)R_RIP, 0);
 }
 
+void native_br(x64emu_t* emu)
+{
+    if(BOX64ENV(dynarec_test))
+        emu->test.test = 0;
+    emit_signal(emu, SIGSEGV, (void*)R_RIP, 0xb09d);
+}
+
 void native_priv(x64emu_t* emu)
 {
     emu->test.test = 0;
diff --git a/src/dynarec/dynarec_native_functions.h b/src/dynarec/dynarec_native_functions.h
index 1fad8ef1..ad8226e6 100644
--- a/src/dynarec/dynarec_native_functions.h
+++ b/src/dynarec/dynarec_native_functions.h
@@ -53,6 +53,7 @@ void native_pclmul_y(x64emu_t* emu, int gy, int vy, void* p, uint32_t u8);
 void native_clflush(x64emu_t* emu, void* p);
 
 void native_ud(x64emu_t* emu);
+void native_br(x64emu_t* emu);
 void native_priv(x64emu_t* emu);
 void native_singlestep(x64emu_t* emu);
 void native_int3(x64emu_t* emu);