about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-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
-rw-r--r--src/emu/x64run.c9
-rw-r--r--src/libtools/signals.c7
5 files changed, 50 insertions, 9 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);
diff --git a/src/emu/x64run.c b/src/emu/x64run.c
index 49600889..0fd35d2d 100644
--- a/src/emu/x64run.c
+++ b/src/emu/x64run.c
@@ -432,9 +432,12 @@ x64emurun:
             }
             break;
         case 0x62:                  /* BOUND Gd, Ed */
-            if(rex.is32bits) {
-                nextop = F8;
-                FAKEED(0);
+            nextop = F8;
+            if(rex.is32bits && MODREG) {
+                GETGD;
+                int* bounds = (int*)GETEA(0);
+                if(bounds[0]<GD->dword[0] || bounds[1]>GD->dword[0])
+                    emit_signal(emu, SIGSEGV, (void*)R_RIP, 0xb09d);
             } else {
                 unimp = 1;
                 goto fini;
diff --git a/src/libtools/signals.c b/src/libtools/signals.c
index e87b1c34..b424cee0 100644
--- a/src/libtools/signals.c
+++ b/src/libtools/signals.c
@@ -1241,6 +1241,10 @@ void my_sigactionhandler_oldcode_64(x64emu_t* emu, int32_t sig, int simple, sigi
                 sigcontext->uc_mcontext.gregs[X64_TRAPNO] = 14;
                 if(!mmapped) info2->si_code = 1;
                 info2->si_errno = 0;
+            } else if (info->si_errno==0xb09d) {
+                sigcontext->uc_mcontext.gregs[X64_ERR] = 0;
+                sigcontext->uc_mcontext.gregs[X64_TRAPNO] = 5;
+                info2->si_errno = 0;
             }else {
                 sigcontext->uc_mcontext.gregs[X64_ERR] = 0x14|((sysmapped && !(real_prot&PROT_READ))?0:1);
                 sigcontext->uc_mcontext.gregs[X64_TRAPNO] = 14;
@@ -2088,6 +2092,9 @@ void emit_signal(x64emu_t* emu, int sig, void* addr, int code)
     } else if(sig==SIGSEGV && code==0xecec) {
         info.si_errno = 0xecec;
         info.si_code = SEGV_ACCERR;
+    } else if (sig==SIGSEGV && code==0xb09d) {
+        info.si_errno = 0xb09d;
+        info.si_code = 0;
     }
     info.si_addr = addr;
     const char* x64name = NULL;