about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--src/dynarec/arm64/dynarec_arm64_00.c81
-rw-r--r--src/dynarec/arm64/dynarec_arm64_0f.c46
-rw-r--r--src/dynarec/arm64/dynarec_arm64_66.c2
-rw-r--r--src/dynarec/arm64/dynarec_arm64_emit_shift.c97
-rw-r--r--src/dynarec/arm64/dynarec_arm64_helper.c2
-rw-r--r--src/dynarec/dynarec_native_functions.c11
-rw-r--r--src/dynarec/dynarec_native_functions.h2
7 files changed, 193 insertions, 48 deletions
diff --git a/src/dynarec/arm64/dynarec_arm64_00.c b/src/dynarec/arm64/dynarec_arm64_00.c
index aa5f4461..a0177a3a 100644
--- a/src/dynarec/arm64/dynarec_arm64_00.c
+++ b/src/dynarec/arm64/dynarec_arm64_00.c
@@ -1802,8 +1802,9 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                 case 4:
                 case 6:
                     INST_NAME("SHL Eb, Ib");
-                    if(geted_ib(dyn, addr, ninst, nextop)&0x1f) {
-                        SETFLAGS(X_ALL, SF_SET_PENDING);    // some flags are left undefined
+                    u8 = geted_ib(dyn, addr, ninst, nextop)&0x1f;
+                    if(u8) {
+                        SETFLAGS(X_CF|X_PF|X_AF|X_ZF|X_SF|((u8==1)?X_OF:0), (u8==1)?SF_SET_PENDING:SF_SUBSET_PENDING);
                         GETEB(x1, 1);
                         u8 = (F8)&0x1f;
                         emit_shl8c(dyn, ninst, ed, u8, x4, x5);
@@ -1815,8 +1816,9 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     break;
                 case 5:
                     INST_NAME("SHR Eb, Ib");
-                    if(geted_ib(dyn, addr, ninst, nextop)&0x1f) {
-                        SETFLAGS(X_ALL, SF_SET_PENDING);
+                    u8 = geted_ib(dyn, addr, ninst, nextop)&0x1f;
+                    if(u8) {
+                        SETFLAGS(X_CF|X_PF|X_AF|X_ZF|X_SF|((u8==1)?X_OF:0), (u8==1)?SF_SET_PENDING:SF_SUBSET_PENDING);
                         GETEB(x1, 1);
                         u8 = (F8)&0x1f;
                         emit_shr8c(dyn, ninst, ed, u8, x4, x5);
@@ -1828,8 +1830,9 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     break;
                 case 7:
                     INST_NAME("SAR Eb, Ib");
-                    if(geted_ib(dyn, addr, ninst, nextop)&0x1f) {
-                        SETFLAGS(X_ALL, SF_SET_PENDING);
+                    u8 = geted_ib(dyn, addr, ninst, nextop)&0x1f;
+                    if(u8) {
+                        SETFLAGS(X_CF|X_PF|X_AF|X_ZF|X_SF|((u8==1)?X_OF:0), (u8==1)?SF_SET_PENDING:SF_SUBSET_PENDING);
                         GETSEB(x1, 1);
                         u8 = (F8)&0x1f;
                         emit_sar8c(dyn, ninst, ed, u8, x4, x5);
@@ -1846,8 +1849,9 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
             switch((nextop>>3)&7) {
                 case 0:
                     INST_NAME("ROL Ed, Ib");
-                    if(geted_ib(dyn, addr, ninst, nextop)&(0x1f+(rex.w*0x20))) {
-                        SETFLAGS(X_OF|X_CF, SF_SUBSET_PENDING);
+                    u8 = geted_ib(dyn, addr, ninst, nextop)&(0x1f+(rex.w*0x20));
+                    if(u8) {
+                        SETFLAGS(X_CF|((u8==1)?X_OF:0), SF_SUBSET_PENDING);
                         GETED(1);
                         u8 = (F8)&(rex.w?0x3f:0x1f);
                         emit_rol32c(dyn, ninst, rex, ed, u8, x3, x4);
@@ -1859,8 +1863,9 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     break;
                 case 1:
                     INST_NAME("ROR Ed, Ib");
-                    if(geted_ib(dyn, addr, ninst, nextop)&(0x1f+(rex.w*0x20))) {
-                        SETFLAGS(X_OF|X_CF, SF_SUBSET_PENDING);
+                    u8 = geted_ib(dyn, addr, ninst, nextop)&(0x1f+(rex.w*0x20));
+                    if(u8) {
+                        SETFLAGS(X_CF|((u8==1)?X_OF:0), SF_SUBSET_PENDING);
                         GETED(1);
                         u8 = (F8)&(rex.w?0x3f:0x1f);
                         emit_ror32c(dyn, ninst, rex, ed, u8, x3, x4);
@@ -1895,8 +1900,9 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                 case 4:
                 case 6:
                     INST_NAME("SHL Ed, Ib");
-                    if(geted_ib(dyn, addr, ninst, nextop)&(0x1f+(rex.w*0x20))) {
-                        SETFLAGS(X_ALL, SF_SET_PENDING);    // some flags are left undefined
+                    u8 = geted_ib(dyn, addr, ninst, nextop)&(0x1f+(rex.w*0x20));
+                    if(u8) {
+                        SETFLAGS(X_CF|X_PF|X_AF|X_ZF|X_SF|((u8==1)?X_OF:0), (u8==1)?SF_SET_PENDING:SF_SUBSET_PENDING);
                         GETED(1);
                         u8 = (F8)&(rex.w?0x3f:0x1f);
                         emit_shl32c(dyn, ninst, rex, ed, u8, x3, x4);
@@ -1908,8 +1914,9 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     break;
                 case 5:
                     INST_NAME("SHR Ed, Ib");
-                    if(geted_ib(dyn, addr, ninst, nextop)&(0x1f+(rex.w*0x20))) {
-                        SETFLAGS(X_ALL, SF_SET_PENDING);    // some flags are left undefined
+                    u8 = geted_ib(dyn, addr, ninst, nextop)&(0x1f+(rex.w*0x20));
+                    if(u8) {
+                        SETFLAGS(X_CF|X_PF|X_AF|X_ZF|X_SF|((u8==1)?X_OF:0), (u8==1)?SF_SET_PENDING:SF_SUBSET_PENDING);
                         GETED(1);
                         u8 = (F8)&(rex.w?0x3f:0x1f);
                         emit_shr32c(dyn, ninst, rex, ed, u8, x3, x4);
@@ -1921,8 +1928,9 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     break;
                 case 7:
                     INST_NAME("SAR Ed, Ib");
-                    if(geted_ib(dyn, addr, ninst, nextop)&(0x1f+(rex.w*0x20))) {
-                        SETFLAGS(X_ALL, SF_SET_PENDING);    // some flags are left undefined
+                    u8 = geted_ib(dyn, addr, ninst, nextop)&(0x1f+(rex.w*0x20));
+                    if(u8) {
+                        SETFLAGS(X_CF|X_PF|X_AF|X_ZF|X_SF|((u8==1)?X_OF:0), (u8==1)?SF_SET_PENDING:SF_SUBSET_PENDING);
                         GETED(1);
                         u8 = (F8)&(rex.w?0x3f:0x1f);
                         emit_sar32c(dyn, ninst, rex, ed, u8, x3, x4);
@@ -2063,13 +2071,16 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                 #if 1
                 INST_NAME("INT 3");
                 // check if TRAP signal is handled
-                LDRx_U12(x1, xEmu, offsetof(x64emu_t, context));
+                TABLE64(x1, (uintptr_t)my_context);
                 MOV32w(x2, offsetof(box64context_t, signals[SIGTRAP]));
                 LDRx_REG(x3, x1, x2);
+                //LDRx_U12(x3, x1, offsetof(box64context_t, signals[SIGTRAP]));
                 CMPSx_U12(x3, 0);
-                B_NEXT(cNE);
-                MOV32w(x1, SIGTRAP);
-                CALL_(raise, -1, 0);
+                B_NEXT(cEQ);
+                GETIP(ip);
+                STORE_XEMU_CALL(xRIP);
+                CALL(native_int3, -1);
+                LOAD_XEMU_CALL(xRIP);
                 break;
                 #else
                 DEFAULT;
@@ -2957,16 +2968,28 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     if(!rex.w) {
                         SET_DFNONE(x2);
                         GETED(0);
-                        MOVw_REG(x3, xRAX);
-                        ORRx_REG_LSL(x3, x3, xRDX, 32);
-                        if(MODREG) {
-                            MOVw_REG(x4, ed);
-                            ed = x4;
+                        if(ninst && (nextop==0xF0)
+                           && dyn->insts[ninst-1].x64.addr
+                           && *(uint8_t*)(dyn->insts[ninst-1].x64.addr)==0xB8
+                           && *(uint32_t*)(dyn->insts[ninst-1].x64.addr+1)==0) {
+                            // hack for some protection that check a divide by zero actualy trigger a divide by zero exception
+                            MESSAGE(LOG_INFO, "Divide by 0 hack\n");
+                            GETIP(ip);
+                            STORE_XEMU_CALL(xRIP);
+                            CALL(native_div0, -1);
+                            LOAD_XEMU_CALL(xRIP);
+                        } else {
+                            MOVw_REG(x3, xRAX);
+                            ORRx_REG_LSL(x3, x3, xRDX, 32);
+                            if(MODREG) {
+                                MOVw_REG(x4, ed);
+                                ed = x4;
+                            }
+                            UDIVx(x2, x3, ed);
+                            MSUBx(x4, x2, ed, xRAX);
+                            MOVw_REG(xRAX, x2);
+                            MOVw_REG(xRDX, x4);
                         }
-                        UDIVx(x2, x3, ed);
-                        MSUBx(x4, x2, ed, xRAX);
-                        MOVw_REG(xRAX, x2);
-                        MOVw_REG(xRDX, x4);
                     } else {
                         if(ninst
                            && dyn->insts[ninst-1].x64.addr
diff --git a/src/dynarec/arm64/dynarec_arm64_0f.c b/src/dynarec/arm64/dynarec_arm64_0f.c
index 87ca717f..3ef67695 100644
--- a/src/dynarec/arm64/dynarec_arm64_0f.c
+++ b/src/dynarec/arm64/dynarec_arm64_0f.c
@@ -1719,7 +1719,7 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
             break;

         case 0xAF:

             INST_NAME("IMUL Gd, Ed");

-            SETFLAGS(X_ALL, SF_PENDING);

+            SETFLAGS(X_ALL, SF_SET_PENDING);

             nextop = F8;

             GETGD;

             GETED(0);

@@ -1728,9 +1728,20 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                 UFLAG_IF {

                     SMULH(x3, gd, ed);

                     MULx(gd, gd, ed);

-                    UFLAG_OP1(x3);

-                    UFLAG_RES(gd);

-                    UFLAG_DF(x3, d_imul64);

+                    IFX(X_PEND) {

+                        UFLAG_OP1(x3);

+                        UFLAG_RES(gd);

+                        UFLAG_DF(x4, d_imul64);

+                    } else IFX(X_CF|X_OF) {

+                        SET_DFNONE(x4);

+                    }

+                    IFX(X_CF|X_OF) {

+                        ASRx(x4, gd, 63);

+                        CMPSx_REG(x3, x4);

+                        CSETw(x3, cNE);

+                        BFIw(xFlags, x3, F_CF, 1);

+                        BFIw(xFlags, x3, F_OF, 1);

+                    }

                 } else {

                     MULxw(gd, gd, ed);

                 }

@@ -1738,11 +1749,30 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                 // 32bits imul

                 UFLAG_IF {

                     SMULL(gd, gd, ed);

-                    UFLAG_RES(gd);

-                    LSRx(x3, gd, 32);

-                    UFLAG_OP1(x3);

+                    IFX(X_PEND) {

+                        UFLAG_RES(gd);

+                        LSRx(x3, gd, 32);

+                        UFLAG_OP1(x3);

+                        UFLAG_DF(x4, d_imul32);

+                    } else IFX(X_CF|X_OF) {

+                        SET_DFNONE(x4);

+                    }

+                    IFX(X_CF|X_OF) {

+                        ASRx(x3, gd, 31);

+                        ASRw(x4, gd, 31);

+                        CMPSw_REG(x3, x4);

+                        CSETw(x3, cNE);

+                        BFIw(xFlags, x3, F_CF, 1);

+                        BFIw(xFlags, x3, F_OF, 1);

+                    }

+                    if(box64_dynarec_test) {

+                        // to avoid noise during test

+                        BFCw(xFlags, F_AF, 1);

+                        BFCw(xFlags, F_PF, 1);

+                        BFCw(xFlags, F_ZF, 1);

+                        BFCw(xFlags, F_SF, 1);

+                    }

                     MOVw_REG(gd, gd);

-                    UFLAG_DF(x3, d_imul32);

                 } else {

                     MULxw(gd, gd, ed);

                 }

diff --git a/src/dynarec/arm64/dynarec_arm64_66.c b/src/dynarec/arm64/dynarec_arm64_66.c
index e8540776..6d77a3c0 100644
--- a/src/dynarec/arm64/dynarec_arm64_66.c
+++ b/src/dynarec/arm64/dynarec_arm64_66.c
@@ -373,7 +373,7 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
             if(rex.is32bits) {

                 INST_NAME("PUSH reg");

                 gd = xRAX+(opcode&0x07);

-                if (gd == xRSP) {

+                if (gd==xRSP) {

                     MOVw_REG(x1, xRSP);

                     PUSH1_16(x1);

                 } else {

diff --git a/src/dynarec/arm64/dynarec_arm64_emit_shift.c b/src/dynarec/arm64/dynarec_arm64_emit_shift.c
index 778583b4..24f16979 100644
--- a/src/dynarec/arm64/dynarec_arm64_emit_shift.c
+++ b/src/dynarec/arm64/dynarec_arm64_emit_shift.c
@@ -70,6 +70,10 @@ void emit_shl32(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, int s2, int s3
             CSELw(s4, s4, wZR, cEQ);
             BFIw(xFlags, s4, F_OF, 1);
     }
+    if(box64_dynarec_test)
+        IFX(X_AF) {
+            BFCw(xFlags, F_AF, 1);
+        }
     IFX(X_PF) {
         emit_pf(dyn, ninst, s1, s3, s4);
     }
@@ -122,6 +126,10 @@ void emit_shl32c(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, uint32_t c, i
             BFCw(xFlags, F_OF, 1);
         }
     }
+    if(box64_dynarec_test)
+        IFX(X_AF) {
+            BFCw(xFlags, F_AF, 1);
+        }
     IFX(X_PF) {
         emit_pf(dyn, ninst, s1, s3, s4);
     }
@@ -165,6 +173,10 @@ void emit_shr32(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, int s2, int s3
         LSRxw(s4, s1, (rex.w)?63:31);
         BFIx(xFlags, s4, F_SF, 1);
     }
+    if(box64_dynarec_test)
+        IFX(X_AF) {
+            BFCw(xFlags, F_AF, 1);
+        }
     IFX(X_PF) {
         emit_pf(dyn, ninst, s1, s3, s4);
     }
@@ -214,6 +226,10 @@ void emit_shr32c(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, uint32_t c, i
         LSRxw(s4, s1, (rex.w)?63:31);
         BFIx(xFlags, s4, F_SF, 1);
     }
+    if(box64_dynarec_test)
+        IFX(X_AF) {
+            BFCw(xFlags, F_AF, 1);
+        }
     IFX(X_PF) {
         emit_pf(dyn, ninst, s1, s3, s4);
     }
@@ -257,6 +273,10 @@ void emit_sar32c(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, uint32_t c, i
         if(c==1) {
             BFCw(xFlags, F_OF, 1);
     }
+    if(box64_dynarec_test)
+        IFX(X_AF) {
+            BFCw(xFlags, F_AF, 1);
+        }
     IFX(X_PF) {
         emit_pf(dyn, ninst, s1, s3, s4);
     }
@@ -294,6 +314,10 @@ void emit_shl8(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4)
             CSELw(s4, s4, wZR, cEQ);
             BFIw(xFlags, s4, F_OF, 1);
     }
+    if(box64_dynarec_test)
+        IFX(X_AF) {
+            BFCw(xFlags, F_AF, 1);
+        }
     IFX(X_PF) {
         emit_pf(dyn, ninst, s1, s3, s4);
     }
@@ -331,6 +355,9 @@ void emit_shl8c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int s
                 BFCw(xFlags, F_OF, 1);
             }
         }
+        if(box64_dynarec_test) IFX(X_AF) {
+            BFCw(xFlags, F_AF, 1);
+        }
         IFX(X_PF) {
             emit_pf(dyn, ninst, s1, s3, s4);
         }
@@ -346,6 +373,9 @@ void emit_shl8c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int s
         IFX(X_SF) {
             BFCw(xFlags, F_SF, 1);
         }
+        if(box64_dynarec_test) IFX(X_AF) {
+            BFCw(xFlags, F_AF, 1);
+        }
         IFX(X_PF | X_ZF) {
             MOV32w(s3, 1);
             IFX(X_ZF) {
@@ -388,6 +418,10 @@ void emit_shr8(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4)
         STRB_U12(s1, xEmu, offsetof(x64emu_t, res));
     }
     COMP_ZFSF(s1, 8)
+    if(box64_dynarec_test)
+        IFX(X_AF) {
+            BFCw(xFlags, F_AF, 1);
+        }
     IFX(X_PF) {
         emit_pf(dyn, ninst, s1, s3, s4);
     }
@@ -425,6 +459,10 @@ void emit_shr8c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int s
         STRB_U12(s1, xEmu, offsetof(x64emu_t, res));
     }
     COMP_ZFSF(s1, 8)
+    if(box64_dynarec_test)
+        IFX(X_AF) {
+            BFCw(xFlags, F_AF, 1);
+        }
     IFX(X_PF) {
         emit_pf(dyn, ninst, s1, s3, s4);
     }
@@ -455,6 +493,10 @@ void emit_sar8(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4)
         Bcond(cNE, 4+4);
             BFCw(xFlags, F_OF, 1);
     }
+    if(box64_dynarec_test)
+        IFX(X_AF) {
+            BFCw(xFlags, F_AF, 1);
+        }
     IFX(X_PF) {
         emit_pf(dyn, ninst, s1, s3, s4);
     }
@@ -473,7 +515,7 @@ void emit_sar8c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int s
     } else IFX(X_ALL) {
         SET_DFNONE(s4);
     }
-    IFX(X_CF) {
+    if(c<8) IFX(X_CF) {
         ASRw(s3, s1, c-1);
         BFIw(xFlags, s3, 0, 1);
     }
@@ -481,14 +523,28 @@ void emit_sar8c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int s
     IFX(X_PEND) {
         STRB_U12(s1, xEmu, offsetof(x64emu_t, res));
     }
-    COMP_ZFSF(s1, 8)
-    IFX(X_OF)
-        if(c==1) {
-            BFCw(xFlags, F_OF, 1);
-    }
-    IFX(X_PF) {
-        emit_pf(dyn, ninst, s1, s3, s4);
-    }
+    if(c<8) {
+        COMP_ZFSF(s1, 8)
+        IFX(X_OF)
+            if(c==1) {
+                BFCw(xFlags, F_OF, 1);
+        }
+        IFX(X_PF) {
+            emit_pf(dyn, ninst, s1, s3, s4);
+        }
+    } else {
+        LSRw(s3, s1, 7);
+        BFIw(xFlags, s3, F_CF, 1);
+        BFIw(wFlags, s3, F_SF, 1);
+        EORw_mask(s3, s3, 0, 0);    //1
+        BFIw(xFlags, s3, F_ZF, 1);
+        MOV32w(s3, 1);
+        BFIw(xFlags, s3, F_PF, 1);
+    }
+    if(box64_dynarec_test)
+        IFX(X_AF) {
+            BFCw(xFlags, F_AF, 1);
+        }
 }
 
 // emit SHL16 instruction, from s1 , shift s2, store result in s1 using s3 and s4 as scratch. s3 can be same as s2
@@ -519,6 +575,10 @@ void emit_shl16(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4)
             CSELw(s4, s4, wZR, cEQ);
             BFIw(xFlags, s4, F_OF, 1);
     }
+    if(box64_dynarec_test)
+        IFX(X_AF) {
+            BFCw(xFlags, F_AF, 1);
+        }
     IFX(X_PF) {
         emit_pf(dyn, ninst, s1, s3, s4);
     }
@@ -557,6 +617,9 @@ void emit_shl16c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int
                 BFCw(xFlags, F_OF, 1);
             }
         }
+        if(box64_dynarec_test) IFX(X_AF) {
+            BFCw(xFlags, F_AF, 1);
+        }
         IFX(X_PF) {
             emit_pf(dyn, ninst, s1, s3, s4);
         }
@@ -610,6 +673,10 @@ void emit_shr16(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4)
         STRH_U12(s1, xEmu, offsetof(x64emu_t, res));
     }
     COMP_ZFSF(s1, 16)
+    if(box64_dynarec_test)
+        IFX(X_AF) {
+            BFCw(xFlags, F_AF, 1);
+        }
     IFX(X_PF) {
         emit_pf(dyn, ninst, s1, s3, s4);
     }
@@ -647,6 +714,10 @@ void emit_shr16c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int
         STRH_U12(s1, xEmu, offsetof(x64emu_t, res));
     }
     COMP_ZFSF(s1, 16)
+    if(box64_dynarec_test)
+        IFX(X_AF) {
+            BFCw(xFlags, F_AF, 1);
+        }
     IFX(X_PF) {
         emit_pf(dyn, ninst, s1, s3, s4);
     }
@@ -677,6 +748,10 @@ void emit_sar16(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4)
         Bcond(cNE, 4+4);
             BFCw(xFlags, F_OF, 1);
     }
+    if(box64_dynarec_test)
+        IFX(X_AF) {
+            BFCw(xFlags, F_AF, 1);
+        }
     IFX(X_PF) {
         emit_pf(dyn, ninst, s1, s3, s4);
     }
@@ -708,6 +783,10 @@ void emit_sar16c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int
         if(c==1) {
             BFCw(xFlags, F_OF, 1);
     }
+    if(box64_dynarec_test)
+        IFX(X_AF) {
+            BFCw(xFlags, F_AF, 1);
+        }
     IFX(X_PF) {
         emit_pf(dyn, ninst, s1, s3, s4);
     }
diff --git a/src/dynarec/arm64/dynarec_arm64_helper.c b/src/dynarec/arm64/dynarec_arm64_helper.c
index ab49bc1e..8fbfbc73 100644
--- a/src/dynarec/arm64/dynarec_arm64_helper.c
+++ b/src/dynarec/arm64/dynarec_arm64_helper.c
@@ -2099,7 +2099,7 @@ void emit_pf(dynarec_arm_t* dyn, int ninst, int s1, int s3, int s4)
     // PF: (((emu->x64emu_parity_tab[(res) / 32] >> ((res) % 32)) & 1) == 0)
     ANDw_mask(s3, s1, 0b011011, 0b000010); // mask=0xE0
     LSRw(s3, s3, 5);
-    MOV64x(s4, (uintptr_t)GetParityTab());
+    TABLE64(s4, (uintptr_t)GetParityTab());
     LDRw_REG_LSL2(s4, s4, s3);
     ANDw_mask(s3, s1, 0, 0b000100); //0x1f
     LSRw_REG(s4, s4, s3);
diff --git a/src/dynarec/dynarec_native_functions.c b/src/dynarec/dynarec_native_functions.c
index 94a6f521..07dad6bf 100644
--- a/src/dynarec/dynarec_native_functions.c
+++ b/src/dynarec/dynarec_native_functions.c
@@ -186,6 +186,17 @@ void native_singlestep(x64emu_t* emu)
     emit_signal(emu, SIGTRAP, (void*)R_RIP, 1);
 }
 
+void native_int3(x64emu_t* emu)
+{
+    emit_signal(emu, SIGTRAP, (void*)R_RIP, 128);
+}
+
+void native_div0(x64emu_t* emu)
+{
+    emu->test.test = 0;
+    emit_div0(emu,  (void*)R_RIP, 0);
+}
+
 void native_fsave(x64emu_t* emu, uint8_t* ed)
 {
     fpu_savenv(emu, (char*)ed, 0);
diff --git a/src/dynarec/dynarec_native_functions.h b/src/dynarec/dynarec_native_functions.h
index 06585c4e..6e7fc46d 100644
--- a/src/dynarec/dynarec_native_functions.h
+++ b/src/dynarec/dynarec_native_functions.h
@@ -46,7 +46,9 @@ void native_clflush(x64emu_t* emu, void* p);
 void native_ud(x64emu_t* emu);
 void native_priv(x64emu_t* emu);
 void native_singlestep(x64emu_t* emu);
+void native_int3(x64emu_t* emu);
 void native_int(x64emu_t* emu, int num);
+void native_div0(x64emu_t* emu);
 
 // Caches transformation (for loops) // Specific, need to be written par backend
 int CacheNeedsTransform(dynarec_native_t* dyn, int i1);