about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2025-10-14 09:23:15 +0200
committerptitSeb <sebastien.chev@gmail.com>2025-10-14 09:23:15 +0200
commitf5a64f93b60b98a7e76af9c8e85fc81e6ef109b4 (patch)
treeb8d1763c9ac3a1d2809307e10d00cbcb462c8baf
parent6732546e605c6ce6cd088ee0b61fdc1960a440fa (diff)
downloadbox64-f5a64f93b60b98a7e76af9c8e85fc81e6ef109b4.tar.gz
box64-f5a64f93b60b98a7e76af9c8e85fc81e6ef109b4.zip
[ARM64_DYNAREC] Better handling for invalid opcodes
-rw-r--r--src/dynarec/arm64/dynarec_arm64_00.c223
-rw-r--r--src/dynarec/arm64/dynarec_arm64_64.c129
-rw-r--r--src/dynarec/arm64/dynarec_arm64_66.c91
-rw-r--r--src/dynarec/arm64/dynarec_arm64_66f0.c247
-rw-r--r--src/dynarec/arm64/dynarec_arm64_67.c80
-rw-r--r--src/dynarec/arm64/dynarec_arm64_6764_32.c26
-rw-r--r--src/dynarec/arm64/dynarec_arm64_f0.c927
7 files changed, 842 insertions, 881 deletions
diff --git a/src/dynarec/arm64/dynarec_arm64_00.c b/src/dynarec/arm64/dynarec_arm64_00.c
index bcf25b21..4b150f03 100644
--- a/src/dynarec/arm64/dynarec_arm64_00.c
+++ b/src/dynarec/arm64/dynarec_arm64_00.c
@@ -952,17 +952,17 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
             }
             break;
         case 0x62:
-            INST_NAME("BOUND Gd, Ed");
             nextop = F8;
-            if(rex.is32bits && MODREG) {
+            if(rex.is32bits && !MODREG) {
+                INST_NAME("BOUND Gd, Ed");
                 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));
+                LDRxw_U12(x3, wback, 4);
                 GETGD;
                 GETIP(ip);
-                CMPSxw_REG(gd, x2);
+                CMPSw_REG(gd, x2);
                 B_MARK(cLT);
-                CMPSxw_REG(gd, x3);
+                CMPSw_REG(gd, x3);
                 B_MARK(cGT);
                 B_NEXT_nocond;
                 MARK;
@@ -970,17 +970,15 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                 CALL_S(const_native_br, -1);
                 LOAD_XEMU_CALL(xRIP);
             } else {
+                INST_NAME("Illegal 62");
                 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_S(const_native_ud, -1);
-                LOAD_XEMU_CALL(xRIP);
-                jump_to_epilog(dyn, 0, xRIP, ninst);
-                *need_epilog = 0;
+                UDF(0);
+                *need_epilog = 1;
                 *ok = 0;
             }
             break;
@@ -1234,8 +1232,11 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
 
         case 0x82:
             if(!rex.is32bits) {
-                DEFAULT;
-                return ip;
+                INST_NAME("Invalid 82");
+                UDF(0);
+                *need_epilog = 1;
+                *ok = 0;
+                return addr;
             }
             // fallthru
         case 0x80:
@@ -1635,18 +1636,25 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
             }
             break;
         case 0x8C:
-            INST_NAME("MOV Ed, Seg");
             nextop=F8;
             u8 = (nextop&0x38)>>3;
-            if (MODREG) {
-                gd = TO_NAT((nextop & 7) + (rex.b << 3));
-                LDRH_U12(gd, xEmu, offsetof(x64emu_t, segs[u8]));
-                UXTHw(gd, gd);
+            if(u8>5) {
+                INST_NAME("Invalid MOV Ed, Seg");
+                UDF(0);
+                *need_epilog = 1;
+                *ok = 0;
             } else {
-                LDRH_U12(x3, xEmu, offsetof(x64emu_t, segs[u8]));
-                addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, &unscaled, 0xfff<<1, 1, rex, NULL, 0, 0);
-                STH(x3, wback, fixedaddress);
-                SMWRITE2();
+                INST_NAME("MOV Ed, Seg");
+                if (MODREG) {
+                    gd = TO_NAT((nextop & 7) + (rex.b << 3));
+                    LDRH_U12(gd, xEmu, offsetof(x64emu_t, segs[u8]));
+                    UXTHw(gd, gd);
+                } else {
+                    LDRH_U12(x3, xEmu, offsetof(x64emu_t, segs[u8]));
+                    addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, &unscaled, 0xfff<<1, 1, rex, NULL, 0, 0);
+                    STH(x3, wback, fixedaddress);
+                    SMWRITE2();
+                }
             }
             break;
         case 0x8D:
@@ -1666,31 +1674,50 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
             }
             break;
         case 0x8E:
-            INST_NAME("MOV Seg,Ew");
             nextop = F8;
             u8 = (nextop&0x38)>>3;
-            if (MODREG) {
-                ed = TO_NAT((nextop & 7) + (rex.b << 3));
+            if((u8>5) || (u8==1)) {
+                INST_NAME("Invalid MOV Seg,Ed");
+                UDF(0);
+                *need_epilog = 1;
+                *ok = 0;
             } else {
-                SMREAD();
-                addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, &unscaled, 0xfff<<1, 1, rex, NULL, 0, 0);
-                LDH(x1, wback, fixedaddress);
-                ed = x1;
+                INST_NAME("MOV Seg,Ed");
+                if (MODREG) {
+                    ed = TO_NAT((nextop & 7) + (rex.b << 3));
+                } else {
+                    SMREAD();
+                    addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, &unscaled, 0xfff<<1, 1, rex, NULL, 0, 0);
+                    LDH(x1, wback, fixedaddress);
+                    ed = x1;
+                }
+                STRH_U12(ed, xEmu, offsetof(x64emu_t, segs[u8]));
+                STRw_U12(wZR, xEmu, offsetof(x64emu_t, segs_serial[u8]));
             }
-            STRH_U12(ed, xEmu, offsetof(x64emu_t, segs[u8]));
-            STRw_U12(wZR, xEmu, offsetof(x64emu_t, segs_serial[u8]));
             break;
         case 0x8F:
-            INST_NAME("POP Ed");
             nextop = F8;
-            SMREAD();
-            if(MODREG) {
-                POP1z(TO_NAT((nextop & 7) + (rex.b << 3)));
-            } else {
-                POP1z(x2); // so this can handle POP [ESP] and maybe some variant too
-                addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, &unscaled, 0xfff<<(2+rex.is32bits), (1<<(2+rex.is32bits))-1, rex, NULL, 0, 0);
-                STz(x2, ed, fixedaddress);
-                SMWRITE();
+            switch((nextop>>3)&7) {
+                case 0:
+                    INST_NAME("POP Ed");
+                    SMREAD();
+                    if(MODREG) {
+                        POP1z(TO_NAT((nextop & 7) + (rex.b << 3)));
+                    } else {
+                        POP1z(x2); // so this can handle POP [ESP] and maybe some variant too
+                        addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, &unscaled, 0xfff<<(2+rex.is32bits), (1<<(2+rex.is32bits))-1, rex, NULL, 0, 0);
+                        STz(x2, ed, fixedaddress);
+                        SMWRITE();
+                    }
+                    break;
+                case 3:
+                    INST_NAME("Invalid 8F /3");
+                    UDF(0);
+                    *need_epilog = 1;
+                    *ok = 0;
+                    break;
+                default:
+                    DEFAULT;
             }
             break;
         case 0x90:
@@ -2598,65 +2625,77 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
             }
             break;
         case 0xC6:
-            INST_NAME("MOV Eb, Ib");
             nextop=F8;
-            if(MODREG) {   // reg <= u8
-                u8 = F8;
-                if(!rex.rex) {
-                    ed = (nextop&7);
-                    eb1 = TO_NAT(ed & 3); // Ax, Cx, Dx or Bx
-                    eb2 = (ed&4)>>2;    // L or H
-                } else {
-                    eb1 = TO_NAT((nextop & 7) + (rex.b << 3));
-                    eb2 = 0;
-                }
-                MOV32w(x3, u8);
-                BFIx(eb1, x3, eb2*8, 8);
-            } else {                    // mem <= u8
-                addr = geted(dyn, addr, ninst, nextop, &wback, x1, &fixedaddress, &unscaled, 0xfff, 0, rex, &lock, 0, 1);
-                u8 = F8;
-                if(u8) {
-                    MOV32w(x3, u8);
-                    ed = x3;
-                } else
-                    ed = xZR;
-                STB(ed, wback, fixedaddress);
-                SMWRITELOCK(lock);
+            switch((nextop>>3)&7) {
+                case 0:
+                    INST_NAME("MOV Eb, Ib");
+                    if(MODREG) {   // reg <= u8
+                        u8 = F8;
+                        if(!rex.rex) {
+                            ed = (nextop&7);
+                            eb1 = TO_NAT(ed & 3); // Ax, Cx, Dx or Bx
+                            eb2 = (ed&4)>>2;    // L or H
+                        } else {
+                            eb1 = TO_NAT((nextop & 7) + (rex.b << 3));
+                            eb2 = 0;
+                        }
+                        MOV32w(x3, u8);
+                        BFIx(eb1, x3, eb2*8, 8);
+                    } else {                    // mem <= u8
+                        addr = geted(dyn, addr, ninst, nextop, &wback, x1, &fixedaddress, &unscaled, 0xfff, 0, rex, &lock, 0, 1);
+                        u8 = F8;
+                        if(u8) {
+                            MOV32w(x3, u8);
+                            ed = x3;
+                        } else
+                            ed = xZR;
+                        STB(ed, wback, fixedaddress);
+                        SMWRITELOCK(lock);
+                    }
+                    break;
+                default:
+                    DEFAULT;
             }
             break;
         case 0xC7:
-            INST_NAME("MOV Ed, Id");
             nextop=F8;
-            if(MODREG) {   // reg <= i32
-                i64 = F32S;
-                ed = TO_NAT((nextop & 7) + (rex.b << 3));
-                MOV64xw(ed, i64);
-            } else {                    // mem <= i32
-                IF_UNALIGNED(ip) {
-                    MESSAGE(LOG_DEBUG, "\tUnaligned path");
-                    addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, &lock, 0, 4);
-                    i64 = F32S;
-                    if(i64) {
-                        MOV64xw(x3, i64);
-                        ed = x3;
-                    } else
-                        ed = xZR;
-                    for(int i=0; i<(1<<(2+rex.w)); ++i) {
-                        STURB_I9(ed, wback, i);
-                        if(ed!=xZR)
-                            RORxw(ed, ed, 8);
+            switch((nextop>>3)&7) {
+                case 0:
+                    INST_NAME("MOV Ed, Id");
+                    if(MODREG) {   // reg <= i32
+                        i64 = F32S;
+                        ed = TO_NAT((nextop & 7) + (rex.b << 3));
+                        MOV64xw(ed, i64);
+                    } else {                    // mem <= i32
+                        IF_UNALIGNED(ip) {
+                            MESSAGE(LOG_DEBUG, "\tUnaligned path");
+                            addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, &lock, 0, 4);
+                            i64 = F32S;
+                            if(i64) {
+                                MOV64xw(x3, i64);
+                                ed = x3;
+                            } else
+                                ed = xZR;
+                            for(int i=0; i<(1<<(2+rex.w)); ++i) {
+                                STURB_I9(ed, wback, i);
+                                if(ed!=xZR)
+                                    RORxw(ed, ed, 8);
+                            }
+                        } else {
+                            addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, &unscaled, 0xfff<<(2+rex.w), (1<<(2+rex.w))-1, rex, &lock, 0, 4);
+                            i64 = F32S;
+                            if(i64) {
+                                MOV64xw(x3, i64);
+                                ed = x3;
+                            } else
+                                ed = xZR;
+                            STxw(ed, wback, fixedaddress);
+                        }
+                        SMWRITELOCK(lock);
                     }
-                } else {
-                    addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, &unscaled, 0xfff<<(2+rex.w), (1<<(2+rex.w))-1, rex, &lock, 0, 4);
-                    i64 = F32S;
-                    if(i64) {
-                        MOV64xw(x3, i64);
-                        ed = x3;
-                    } else
-                        ed = xZR;
-                    STxw(ed, wback, fixedaddress);
-                }
-                SMWRITELOCK(lock);
+                    break;
+                default:
+                    DEFAULT;
             }
             break;
         case 0xC8:
diff --git a/src/dynarec/arm64/dynarec_arm64_64.c b/src/dynarec/arm64/dynarec_arm64_64.c
index 494accda..a00edf07 100644
--- a/src/dynarec/arm64/dynarec_arm64_64.c
+++ b/src/dynarec/arm64/dynarec_arm64_64.c
@@ -991,34 +991,47 @@ uintptr_t dynarec64_64(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
             nextop = F8;
             grab_segdata(dyn, addr, ninst, x4, seg, (MODREG));
             u8 = (nextop&0x38)>>3;
-            if (MODREG) {
-                ed = TO_NAT((nextop & 7) + (rex.b << 3));
+            if((u8>5) || (u8==1)) {
+                INST_NAME("Invalid MOV Seg,Ew");
+                UDF(0);
+                *need_epilog = 1;
+                *ok = 0;
             } else {
-                SMREAD();
-                addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, NULL, 0, 0);
-                LDRH_REGz(x1, x4, wback);
-                ed = x1;
+                if (MODREG) {
+                    ed = TO_NAT((nextop & 7) + (rex.b << 3));
+                } else {
+                    SMREAD();
+                    addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, NULL, 0, 0);
+                    LDRH_REGz(x1, x4, wback);
+                    ed = x1;
+                }
+                STRH_U12(ed, xEmu, offsetof(x64emu_t, segs[u8]));
+                STRw_U12(wZR, xEmu, offsetof(x64emu_t, segs_serial[u8]));
             }
-            STRH_U12(ed, xEmu, offsetof(x64emu_t, segs[u8]));
-            STRw_U12(wZR, xEmu, offsetof(x64emu_t, segs_serial[u8]));
             break;
         case 0x8F:
-            INST_NAME("POP FS:Ed");
             nextop = F8;
             grab_segdata(dyn, addr, ninst, x4, seg, (MODREG));
-            if(MODREG) {
-                POP1z(TO_NAT((nextop & 7) + (rex.b << 3)));
-            } else {
-                POP1z(x2); // so this can handle POP [ESP] and maybe some variant too
-                addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, &unscaled, 0, 0, rex, NULL, 0, 0);
-                if(ed==xRSP) {
-                    STRz_REGz(x2, x4, ed);
-                } else {
-                    // complicated to just allow a segfault that can be recovered correctly
-                    SUBz_U12(xRSP, xRSP, rex.is32bits?4:8);
-                    STRz_REGz(x2, x4, ed);
-                    ADDz_U12(xRSP, xRSP, rex.is32bits?4:8);
-                }
+            switch((nextop>>3)&7) {
+                case 0:
+                    INST_NAME("POP FS:Ed");
+                    if(MODREG) {
+                        POP1z(TO_NAT((nextop & 7) + (rex.b << 3)));
+                    } else {
+                        POP1z(x2); // so this can handle POP [ESP] and maybe some variant too
+                        addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, &unscaled, 0, 0, rex, NULL, 0, 0);
+                        if(ed==xRSP) {
+                            STRz_REGz(x2, x4, ed);
+                        } else {
+                            // complicated to just allow a segfault that can be recovered correctly
+                            SUBz_U12(xRSP, xRSP, rex.is32bits?4:8);
+                            STRz_REGz(x2, x4, ed);
+                            ADDz_U12(xRSP, xRSP, rex.is32bits?4:8);
+                        }
+                    }
+                    break;
+                default:
+                    DEFAULT;
             }
             break;
         case 0x90:
@@ -1083,43 +1096,55 @@ uintptr_t dynarec64_64(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
             break;
 
         case 0xC6:
-            INST_NAME("MOV Seg:Eb, Ib");
             nextop=F8;
             grab_segdata(dyn, addr, ninst, x4, seg, (MODREG));
-            if(MODREG) {   // reg <= u8
-                u8 = F8;
-                if(!rex.rex) {
-                    ed = (nextop&7);
-                    eb1 = TO_NAT(ed & 3); // Ax, Cx, Dx or Bx
-                    eb2 = (ed&4)>>2;    // L or H
-                } else {
-                    eb1 = TO_NAT((nextop & 7) + (rex.b << 3));
-                    eb2 = 0;
-                }
-                MOV32w(x3, u8);
-                BFIx(eb1, x3, eb2*8, 8);
-            } else {                    // mem <= u8
-                addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, NULL, 0, 0, rex, NULL, 0, 1);
-                u8 = F8;
-                MOV32w(x3, u8);
-                STRB_REGz(x3, x4, ed);
-                SMWRITE2();
+            switch((nextop>>3)&7) {
+                case 0:
+                    INST_NAME("MOV Seg:Eb, Ib");
+                    if(MODREG) {   // reg <= u8
+                        u8 = F8;
+                        if(!rex.rex) {
+                            ed = (nextop&7);
+                            eb1 = TO_NAT(ed & 3); // Ax, Cx, Dx or Bx
+                            eb2 = (ed&4)>>2;    // L or H
+                        } else {
+                            eb1 = TO_NAT((nextop & 7) + (rex.b << 3));
+                            eb2 = 0;
+                        }
+                        MOV32w(x3, u8);
+                        BFIx(eb1, x3, eb2*8, 8);
+                    } else {                    // mem <= u8
+                        addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, NULL, 0, 0, rex, NULL, 0, 1);
+                        u8 = F8;
+                        MOV32w(x3, u8);
+                        STRB_REGz(x3, x4, ed);
+                        SMWRITE2();
+                    }
+                    break;
+                default:
+                    DEFAULT;
             }
             break;
         case 0xC7:
-            INST_NAME("MOV Seg:Ed, Id");
             nextop=F8;
             grab_segdata(dyn, addr, ninst, x4, seg, (MODREG));
-            if(MODREG) {   // reg <= i32
-                i64 = F32S;
-                ed = TO_NAT((nextop & 7) + (rex.b << 3));
-                MOV64xw(ed, i64);
-            } else {                    // mem <= i32
-                addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, NULL, 0, 0, rex, NULL, 0, 4);
-                i64 = F32S;
-                MOV64xw(x3, i64);
-                STRxw_REGz(x3, x4, ed);
-                SMWRITE2();
+            switch((nextop>>3)&7) {
+                case 0:
+                    INST_NAME("MOV Seg:Ed, Id");
+                    if(MODREG) {   // reg <= i32
+                        i64 = F32S;
+                        ed = TO_NAT((nextop & 7) + (rex.b << 3));
+                        MOV64xw(ed, i64);
+                    } else {                    // mem <= i32
+                        addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, NULL, 0, 0, rex, NULL, 0, 4);
+                        i64 = F32S;
+                        MOV64xw(x3, i64);
+                        STRxw_REGz(x3, x4, ed);
+                        SMWRITE2();
+                    }
+                    break;
+                default:
+                    DEFAULT;
             }
             break;
 
diff --git a/src/dynarec/arm64/dynarec_arm64_66.c b/src/dynarec/arm64/dynarec_arm64_66.c
index 1e1daeaf..c26e0f0d 100644
--- a/src/dynarec/arm64/dynarec_arm64_66.c
+++ b/src/dynarec/arm64/dynarec_arm64_66.c
@@ -717,28 +717,41 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
             INST_NAME("MOV Seg,Ew");

             nextop = F8;

             u8 = (nextop&0x38)>>3;

-            if (MODREG) {

-                ed = TO_NAT((nextop & 7) + (rex.b << 3));

+            if((u8>5) || (u8==1)) {

+                INST_NAME("Invalid MOV Seg,Ew");

+                UDF(0);

+                *need_epilog = 1;

+                *ok = 0;

             } else {

-                SMREAD();

-                addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, &unscaled, 0xfff<<1, 1, rex, NULL, 0, 0);

-                LDH(x1, wback, fixedaddress);

-                ed = x1;

+                if (MODREG) {

+                    ed = TO_NAT((nextop & 7) + (rex.b << 3));

+                } else {

+                    SMREAD();

+                    addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, &unscaled, 0xfff<<1, 1, rex, NULL, 0, 0);

+                    LDH(x1, wback, fixedaddress);

+                    ed = x1;

+                }

+                STRH_U12(ed, xEmu, offsetof(x64emu_t, segs[u8]));

+                STRw_U12(wZR, xEmu, offsetof(x64emu_t, segs_serial[u8]));

             }

-            STRH_U12(ed, xEmu, offsetof(x64emu_t, segs[u8]));

-            STRw_U12(wZR, xEmu, offsetof(x64emu_t, segs_serial[u8]));

             break;

         case 0x8F:

-            INST_NAME("POP Ew");

             nextop = F8;

-            POP1_16(x1);

-            if (MODREG) {

-                wback = TO_NAT((nextop & 7) + (rex.b << 3));

-                BFIz(wback, x1, 0, 16);

-            } else {

-                SMREAD();

-                addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, &unscaled, 0xfff<<1, 1, rex, NULL, 0, 0);

-                STH(x1, wback, fixedaddress);

+            switch((nextop>>3)&7) {

+                case 0:

+                    INST_NAME("POP Ew");

+                    POP1_16(x1);

+                    if (MODREG) {

+                        wback = TO_NAT((nextop & 7) + (rex.b << 3));

+                        BFIz(wback, x1, 0, 16);

+                    } else {

+                        SMREAD();

+                        addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, &unscaled, 0xfff<<1, 1, rex, NULL, 0, 0);

+                        STH(x1, wback, fixedaddress);

+                    }

+                    break;

+                default:

+                    DEFAULT;

             }

             break;

         case 0x90:

@@ -1174,26 +1187,32 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
             break;

 

         case 0xC7:

-            INST_NAME("MOV Ew, Iw");

             nextop = F8;

-            if(MODREG) {

-                ed = TO_NAT((nextop & 7) + (rex.b << 3));

-                u16 = F16;

-                if(u16) {

-                    MOV32w(x1, u16);

-                    BFIz(ed, x1, 0, 16);

-                } else

-                    BFCz(ed, 0, 16);

-            } else {

-                addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, &unscaled, 0xfff<<1, 1, rex, &lock, 0, 2);

-                u16 = F16;

-                if(u16) {

-                    MOV32w(x1, u16);

-                    STH(x1, ed, fixedaddress);

-                } else {

-                    STH(xZR, ed, fixedaddress);

-                }

-                SMWRITELOCK(lock);

+            switch((nextop>>3)&7) {

+                case 0:

+                    INST_NAME("MOV Ew, Iw");

+                    if(MODREG) {

+                        ed = TO_NAT((nextop & 7) + (rex.b << 3));

+                        u16 = F16;

+                        if(u16) {

+                            MOV32w(x1, u16);

+                            BFIz(ed, x1, 0, 16);

+                        } else

+                            BFCz(ed, 0, 16);

+                    } else {

+                        addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, &unscaled, 0xfff<<1, 1, rex, &lock, 0, 2);

+                        u16 = F16;

+                        if(u16) {

+                            MOV32w(x1, u16);

+                            STH(x1, ed, fixedaddress);

+                        } else {

+                            STH(xZR, ed, fixedaddress);

+                        }

+                        SMWRITELOCK(lock);

+                    }

+                    break;

+                default:

+                    DEFAULT;

             }

             break;

 

diff --git a/src/dynarec/arm64/dynarec_arm64_66f0.c b/src/dynarec/arm64/dynarec_arm64_66f0.c
index 9516216c..4851c69b 100644
--- a/src/dynarec/arm64/dynarec_arm64_66f0.c
+++ b/src/dynarec/arm64/dynarec_arm64_66f0.c
@@ -49,16 +49,16 @@ uintptr_t dynarec64_66F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
     switch(opcode) {
 
         case 0x01:
-            INST_NAME("LOCK ADD Ew, Gw");
-            SETFLAGS(X_ALL, SF_SET_PENDING);
             nextop = F8;
-            GETGW(x5);
             if(MODREG) {
-                ed = TO_NAT((nextop & 7) + (rex.b << 3));
-                UXTHw(x6, ed);
-                emit_add16(dyn, ninst, x6, x5, x3, x4);
-                BFIx(ed, x6, 0, 16);
+                INST_NAME("Invalid LOCK");
+                UDF(0);
+                *need_epilog = 1;
+                *ok = 0;
             } else {
+                INST_NAME("LOCK ADD Ew, Gw");
+                SETFLAGS(X_ALL, SF_SET_PENDING);
+                GETGW(x5);
                 addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 0);
                 if(cpuext.atomics) {
                     UFLAG_IF {
@@ -78,16 +78,16 @@ uintptr_t dynarec64_66F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
             break;
 
         case 0x09:
-            INST_NAME("LOCK OR Ew, Gw");
-            SETFLAGS(X_ALL, SF_SET_PENDING);
             nextop = F8;
-            GETGW(x5);
             if(MODREG) {
-                ed = TO_NAT((nextop & 7) + (rex.b << 3));
-                UXTHw(x6, ed);
-                emit_or16(dyn, ninst, x6, x5, x3, x4);
-                BFIx(ed, x6, 0, 16);
+                INST_NAME("Invalid LOCK");
+                UDF(0);
+                *need_epilog = 1;
+                *ok = 0;
             } else {
+                INST_NAME("LOCK OR Ew, Gw");
+                SETFLAGS(X_ALL, SF_SET_PENDING);
+                GETGW(x5);
                 addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 0);
                 if(cpuext.atomics) {
                     UFLAG_IF {
@@ -111,19 +111,17 @@ uintptr_t dynarec64_66F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
             switch(opcode) {
 
                 case 0xB1:
-                    INST_NAME("LOCK CMPXCHG Ew, Gw");
-                    SETFLAGS(X_ALL, SF_SET_PENDING);
                     nextop = F8;
-                    GETGD;
-                    UXTHw(x6, xRAX);
                     if(MODREG) {
-                        ed = TO_NAT((nextop & 7) + (rex.b << 3));
-                        wback = 0;
-                        UXTHw(x1, ed);
-                        CMPSxw_REG(x6, x1);
-                        B_MARK(cNE);
-                        BFIx(ed, gd, 0, 16);
+                        INST_NAME("Invalid LOCK");
+                        UDF(0);
+                        *need_epilog = 1;
+                        *ok = 0;
                     } else {
+                        INST_NAME("LOCK CMPXCHG Ew, Gw");
+                        SETFLAGS(X_ALL, SF_SET_PENDING);
+                        GETGD;
+                        UXTHw(x6, xRAX);
                         addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 0);
                         if(!ALIGNED_ATOMICH) {
                             if(cpuext.uscat) {
@@ -164,25 +162,25 @@ uintptr_t dynarec64_66F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
                             CBNZx_MARK3(x4);
                             STRH_U12(gd, wback, 0);
                         }
+                        MARK;
+                        // Common part (and fallback for EAX != Ed)
+                        UFLAG_IF {emit_cmp16(dyn, ninst, x6, x1, x3, x4, x5);}
+                        BFIx(xRAX, x1, 0, 16);
                     }
-                    MARK;
-                    // Common part (and fallback for EAX != Ed)
-                    UFLAG_IF {emit_cmp16(dyn, ninst, x6, x1, x3, x4, x5);}
-                    BFIx(xRAX, x1, 0, 16);
                     break;
 
                 case 0xC1:
-                    INST_NAME("LOCK XADD Gw, Ew");
-                    SETFLAGS(X_ALL, SF_SET_PENDING);
                     nextop = F8;
-                    gd = TO_NAT(((nextop & 0x38) >> 3) + (rex.r << 3));
-                    UXTHx(x5, gd);
                     if(MODREG) {
-                        ed = TO_NAT((nextop & 7) + (rex.b << 3));
-                        BFIx(gd, ed, 0, 16);
-                        emit_add16(dyn, ninst, x5, gd, x3, x4);
-                        BFIx(ed, x5, 0, 16);
+                        INST_NAME("Invalid LOCK");
+                        UDF(0);
+                        *need_epilog = 1;
+                        *ok = 0;
                     } else {
+                        INST_NAME("LOCK XADD Gw, Ew");
+                        SETFLAGS(X_ALL, SF_SET_PENDING);
+                        gd = TO_NAT(((nextop & 0x38) >> 3) + (rex.r << 3));
+                        UXTHx(x5, gd);
                         addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 0);
                         if(cpuext.atomics) {
                             LDADDALH(x5, x1, wback);
@@ -207,17 +205,17 @@ uintptr_t dynarec64_66F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
             break;
 
         case 0x11:
-            INST_NAME("LOCK ADC Ew, Gw");
-            READFLAGS(X_CF);
-            SETFLAGS(X_ALL, SF_SET_PENDING);
             nextop = F8;
-            GETGW(x5);
             if(MODREG) {
-                ed = TO_NAT((nextop & 7) + (rex.b << 3));
-                UXTHw(x6, ed);
-                emit_adc16(dyn, ninst, x6, x5, x3, x4);
-                BFIx(ed, x6, 0, 16);
+                INST_NAME("Invalid LOCK");
+                UDF(0);
+                *need_epilog = 1;
+                *ok = 0;
             } else {
+                INST_NAME("LOCK ADC Ew, Gw");
+                READFLAGS(X_CF);
+                SETFLAGS(X_ALL, SF_SET_PENDING);
+                GETGW(x5);
                 addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 0);
                 MARKLOCK;
                 LDAXRH(x1, wback);
@@ -228,16 +226,16 @@ uintptr_t dynarec64_66F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
             break;
 
         case 0x21:
-            INST_NAME("LOCK AND Ew, Gw");
-            SETFLAGS(X_ALL, SF_SET_PENDING);
             nextop = F8;
-            GETGW(x5);
             if(MODREG) {
-                ed = TO_NAT((nextop & 7) + (rex.b << 3));
-                UXTHw(x6, ed);
-                emit_and16(dyn, ninst, x6, gd, x3, x4);
-                BFIx(ed, x6, 0, 16);
+                INST_NAME("Invalid LOCK");
+                UDF(0);
+                *need_epilog = 1;
+                *ok = 0;
             } else {
+                INST_NAME("LOCK AND Ew, Gw");
+                SETFLAGS(X_ALL, SF_SET_PENDING);
+                GETGW(x5);
                 addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 0);
                 if(cpuext.atomics) {
                     MVNw_REG(x3, gd);
@@ -262,20 +260,18 @@ uintptr_t dynarec64_66F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
             nextop = F8;
             switch((nextop>>3)&7) {
                 case 0: //ADD
-                    if(opcode==0x81) {
-                        INST_NAME("LOCK ADD Ew, Iw");
-                    } else {
-                        INST_NAME("LOCK ADD Ew, Ib");
-                    }
-                    SETFLAGS(X_ALL, SF_SET_PENDING);
                     if(MODREG) {
-                        if(opcode==0x81) i16 = F16S; else i16 = F8S;
-                        ed = TO_NAT((nextop & 7) + (rex.b << 3));
-                        MOV32w(x5, i16);
-                        UXTHw(x6, ed);
-                        emit_add16(dyn, ninst, x6, x5, x3, x4);
-                        BFIx(ed, x6, 0, 16);
+                        INST_NAME("Invalid LOCK");
+                        UDF(0);
+                        *need_epilog = 1;
+                        *ok = 0;
                     } else {
+                        if(opcode==0x81) {
+                            INST_NAME("LOCK ADD Ew, Iw");
+                        } else {
+                            INST_NAME("LOCK ADD Ew, Ib");
+                        }
+                        SETFLAGS(X_ALL, SF_SET_PENDING);
                         addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, (opcode==0x81)?2:1);
                         if(opcode==0x81) i16 = F16S; else i16 = F8S;
                         MOV32w(x5, i16);
@@ -321,15 +317,14 @@ uintptr_t dynarec64_66F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
                     }
                     break;
                 case 1: //OR
-                    if(opcode==0x81) {INST_NAME("LOCK OR Ew, Iw");} else {INST_NAME("LOCK OR Ew, Ib");}
-                    SETFLAGS(X_ALL, SF_SET_PENDING);
                     if(MODREG) {
-                        if(opcode==0x81) i16 = F16S; else i16 = F8S;
-                        ed = TO_NAT((nextop & 7) + (rex.b << 3));
-                        UXTHw(x6, ed);
-                        emit_or16c(dyn, ninst, x6, i16, x3, x4);
-                        BFIx(ed, x6, 0, 16);
+                        INST_NAME("Invalid LOCK");
+                        UDF(0);
+                        *need_epilog = 1;
+                        *ok = 0;
                     } else {
+                        if(opcode==0x81) {INST_NAME("LOCK OR Ew, Iw");} else {INST_NAME("LOCK OR Ew, Ib");}
+                        SETFLAGS(X_ALL, SF_SET_PENDING);
                         addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, (opcode==0x81)?2:1);
                         if(opcode==0x81) i16 = F16S; else i16 = F8S;
                         if(!i64) {MOV32w(x5, i16);}
@@ -356,17 +351,15 @@ uintptr_t dynarec64_66F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
                     }
                     break;
                 case 2: //ADC
-                    if(opcode==0x81) {INST_NAME("LOCK ADC Ew, Iw");} else {INST_NAME("LOCK ADC Ew, Ib");}
-                    READFLAGS(X_CF);
-                    SETFLAGS(X_ALL, SF_SET_PENDING);
                     if(MODREG) {
-                        if(opcode==0x81) i16 = F16S; else i16 = F8S;
-                        ed = TO_NAT((nextop & 7) + (rex.b << 3));
-                        MOV32w(x5, i16);
-                        UXTHw(x6, ed);
-                        emit_adc16(dyn, ninst, x6, x5, x3, x4);
-                        BFIx(ed, x6, 0, 16);
+                        INST_NAME("Invalid LOCK");
+                        UDF(0);
+                        *need_epilog = 1;
+                        *ok = 0;
                     } else {
+                        if(opcode==0x81) {INST_NAME("LOCK ADC Ew, Iw");} else {INST_NAME("LOCK ADC Ew, Ib");}
+                        READFLAGS(X_CF);
+                        SETFLAGS(X_ALL, SF_SET_PENDING);
                         addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, (opcode==0x81)?2:1);
                         if(opcode==0x81) i16 = F16S; else i16 = F8S;
                         MOV32w(x5, i16);
@@ -378,17 +371,15 @@ uintptr_t dynarec64_66F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
                     }
                     break;
                 case 3: //SBB
-                    if(opcode==0x81) {INST_NAME("LOCK SBB Ew, Iw");} else {INST_NAME("LOCK SBB Ew, Ib");}
-                    READFLAGS(X_CF);
-                    SETFLAGS(X_ALL, SF_SET_PENDING);
                     if(MODREG) {
-                        if(opcode==0x81) i16 = F16S; else i16 = F8S;
-                        ed = TO_NAT((nextop & 7) + (rex.b << 3));
-                        MOV32w(x5, i16);
-                        UXTHw(x6, ed);
-                        emit_sbb16(dyn, ninst, x6, x5, x3, x4);
-                        BFIx(ed, x6, 0, 16);
+                        INST_NAME("Invalid LOCK");
+                        UDF(0);
+                        *need_epilog = 1;
+                        *ok = 0;
                     } else {
+                        if(opcode==0x81) {INST_NAME("LOCK SBB Ew, Iw");} else {INST_NAME("LOCK SBB Ew, Ib");}
+                        READFLAGS(X_CF);
+                        SETFLAGS(X_ALL, SF_SET_PENDING);
                         addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, (opcode==0x81)?2:1);
                         if(opcode==0x81) i16 = F16S; else i16 = F8S;
                         MOV32w(x5, i16);
@@ -400,15 +391,14 @@ uintptr_t dynarec64_66F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
                     }
                     break;
                 case 4: //AND
-                    if(opcode==0x81) {INST_NAME("LOCK AND Ew, Iw");} else {INST_NAME("LOCK AND Ew, Ib");}
-                    SETFLAGS(X_ALL, SF_SET_PENDING);
                     if(MODREG) {
-                        if(opcode==0x81) i16 = F16S; else i16 = F8S;
-                        ed = TO_NAT((nextop & 7) + (rex.b << 3));
-                        UXTHw(x6, ed);
-                        emit_and16c(dyn, ninst, x6, i16, x3, x4);
-                        BFIx(ed, x6, 0, 16);
+                        INST_NAME("Invalid LOCK");
+                        UDF(0);
+                        *need_epilog = 1;
+                        *ok = 0;
                     } else {
+                        if(opcode==0x81) {INST_NAME("LOCK AND Ew, Iw");} else {INST_NAME("LOCK AND Ew, Ib");}
+                        SETFLAGS(X_ALL, SF_SET_PENDING);
                         addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, (opcode==0x81)?2:1);
                         if(opcode==0x81) i16 = F16S; else i16 = F8S;
                         i64 = convert_bitmask_w(i16);
@@ -440,16 +430,14 @@ uintptr_t dynarec64_66F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
                     }
                     break;
                 case 5: //SUB
-                    if(opcode==0x81) {INST_NAME("LOCK SUB Ew, Iw");} else {INST_NAME("LOCK SUB Ew, Ib");}
-                    SETFLAGS(X_ALL, SF_SET_PENDING);
                     if(MODREG) {
-                        if(opcode==0x81) i16 = F16S; else i16 = F8S;
-                        ed = TO_NAT((nextop & 7) + (rex.b << 3));
-                        MOV32w(x5, i16);
-                        UXTHw(x6, ed);
-                        emit_sub16(dyn, ninst, x6, x5, x3, x4);
-                        BFIx(ed, x6, 0, 16);
+                        INST_NAME("Invalid LOCK");
+                        UDF(0);
+                        *need_epilog = 1;
+                        *ok = 0;
                     } else {
+                        if(opcode==0x81) {INST_NAME("LOCK SUB Ew, Iw");} else {INST_NAME("LOCK SUB Ew, Ib");}
+                        SETFLAGS(X_ALL, SF_SET_PENDING);
                         addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, (opcode==0x81)?2:1);
                         if(opcode==0x81) i16 = F16S; else i16 = F8S;
                         MOV32w(x5, i16);
@@ -496,15 +484,14 @@ uintptr_t dynarec64_66F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
                     }
                     break;
                 case 6: //XOR
-                    if(opcode==0x81) {INST_NAME("LOCK XOR Ew, Iw");} else {INST_NAME("LOCK XOR Ew, Ib");}
-                    SETFLAGS(X_ALL, SF_SET_PENDING);
                     if(MODREG) {
-                        if(opcode==0x81) i16 = F16S; else i16 = F8S;
-                        ed = TO_NAT((nextop & 7) + (rex.b << 3));
-                        UXTHw(x6, ed);
-                        emit_xor16c(dyn, ninst, x6, i16, x3, x4);
-                        BFIx(ed, x6, 0, 16);
+                        INST_NAME("Invalid LOCK");
+                        UDF(0);
+                        *need_epilog = 1;
+                        *ok = 0;
                     } else {
+                        if(opcode==0x81) {INST_NAME("LOCK XOR Ew, Iw");} else {INST_NAME("LOCK XOR Ew, Ib");}
+                        SETFLAGS(X_ALL, SF_SET_PENDING);
                         addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, (opcode==0x81)?2:1);
                         if(opcode==0x81) i16 = F16S; else i16 = F8S;
                         i64 = convert_bitmask_w(i16);
@@ -529,18 +516,10 @@ uintptr_t dynarec64_66F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
                     }
                     break;
                 case 7: //CMP
-                    if(opcode==0x81) {INST_NAME("(LOCK) CMP Ew, Iw");} else {INST_NAME("(LOCK) CMP Ew, Ib");}
-                    SETFLAGS(X_ALL, SF_SET_PENDING);
-                    GETEW(x6, (opcode==0x81)?2:1);
-                    (void)wb1;
-                    // No need to LOCK, this is readonly
-                    if(opcode==0x81) i16 = F16S; else i16 = F8S;
-                    if(i16) {
-                        MOV32w(x5, i16);
-                        emit_cmp16(dyn, ninst, x6, x5, x3, x4, x6);
-                    } else {
-                        emit_cmp16_0(dyn, ninst, ed, x3, x4);
-                    }
+                    INST_NAME("Invalid LOCK");
+                    UDF(0);
+                    *need_epilog = 1;
+                    *ok = 0;
                     break;
             }
             break;
@@ -550,14 +529,14 @@ uintptr_t dynarec64_66F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
                 switch((nextop>>3)&7)
                 {
                     case 0: // INC Ew
-                        INST_NAME("LOCK INC Ew");
-                        SETFLAGS(X_ALL&~X_CF, SF_SUBSET);
                         if(MODREG) {
-                            ed = TO_NAT((nextop & 7) + (rex.b << 3));
-                            UXTHw(x6, ed);
-                            emit_inc16(dyn, ninst, x6, x5, x3);
-                            BFIx(ed, x6, 0, 16);
+                            INST_NAME("Invalid LOCK");
+                            UDF(0);
+                            *need_epilog = 1;
+                            *ok = 0;
                         } else {
+                            INST_NAME("LOCK INC Ew");
+                            SETFLAGS(X_ALL&~X_CF, SF_SUBSET);
                             addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 0);
                             if(cpuext.atomics) {
                                 MOV32w(x3, 1);
@@ -577,14 +556,14 @@ uintptr_t dynarec64_66F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
                         }
                         break;
                     case 1: //DEC Ew
-                        INST_NAME("LOCK DEC Ew");
-                        SETFLAGS(X_ALL&~X_CF, SF_SUBSET);
                         if(MODREG) {
-                            ed = TO_NAT((nextop & 7) + (rex.b << 3));
-                            UXTHw(x6, ed);
-                            emit_dec16(dyn, ninst, x6, x5, x3);
-                            BFIx(ed, x6, 0, 16);
+                            INST_NAME("Invalid LOCK");
+                            UDF(0);
+                            *need_epilog = 1;
+                            *ok = 0;
                         } else {
+                            INST_NAME("LOCK DEC Ew");
+                            SETFLAGS(X_ALL&~X_CF, SF_SUBSET);
                             addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 0);
                             if(cpuext.atomics) {
                                 MOV32w(x3, -1);
diff --git a/src/dynarec/arm64/dynarec_arm64_67.c b/src/dynarec/arm64/dynarec_arm64_67.c
index 793fa503..3d942dd0 100644
--- a/src/dynarec/arm64/dynarec_arm64_67.c
+++ b/src/dynarec/arm64/dynarec_arm64_67.c
@@ -1389,45 +1389,57 @@ uintptr_t dynarec64_67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
             }

             break;

         case 0xC6:

-            INST_NAME("MOV Eb, Ib");

             nextop=F8;

-            if(MODREG) {   // reg <= u8

-                u8 = F8;

-                if(!rex.rex) {

-                    ed = (nextop&7);

-                    eb1 = TO_NAT(ed & 3); // Ax, Cx, Dx or Bx

-                    eb2 = (ed&4)>>2;    // L or H

-                } else {

-                    eb1 = TO_NAT((nextop & 7) + (rex.b << 3));

-                    eb2 = 0;

-                }

-                MOV32w(x3, u8);

-                BFIx(eb1, x3, eb2*8, 8);

-            } else {                    // mem <= u8

-                addr = geted32(dyn, addr, ninst, nextop, &wback, x1, &fixedaddress, &unscaled, 0xfff, 0, rex, &lock, 0, 1);

-                u8 = F8;

-                if(u8) {

-                    MOV32w(x3, u8);

-                    ed = x3;

-                } else

-                    ed = xZR;

-                STB(ed, wback, fixedaddress);

-                SMWRITELOCK(lock);

+            switch((nextop>>3)&7) {

+                case 0:

+                    INST_NAME("MOV Eb, Ib");

+                    if(MODREG) {   // reg <= u8

+                        u8 = F8;

+                        if(!rex.rex) {

+                            ed = (nextop&7);

+                            eb1 = TO_NAT(ed & 3); // Ax, Cx, Dx or Bx

+                            eb2 = (ed&4)>>2;    // L or H

+                        } else {

+                            eb1 = TO_NAT((nextop & 7) + (rex.b << 3));

+                            eb2 = 0;

+                        }

+                        MOV32w(x3, u8);

+                        BFIx(eb1, x3, eb2*8, 8);

+                    } else {                    // mem <= u8

+                        addr = geted32(dyn, addr, ninst, nextop, &wback, x1, &fixedaddress, &unscaled, 0xfff, 0, rex, &lock, 0, 1);

+                        u8 = F8;

+                        if(u8) {

+                            MOV32w(x3, u8);

+                            ed = x3;

+                        } else

+                            ed = xZR;

+                        STB(ed, wback, fixedaddress);

+                        SMWRITELOCK(lock);

+                    }

+                    break;

+                default:

+                    DEFAULT;

             }

             break;

         case 0xC7:

-            INST_NAME("MOV Ed, Id");

             nextop=F8;

-            if(MODREG) {   // reg <= i32

-                i64 = F32S;

-                ed = TO_NAT((nextop & 7) + (rex.b << 3));

-                MOV64xw(ed, i64);

-            } else {                    // mem <= i32

-                addr = geted32(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, &unscaled, 0xfff<<(2+rex.w), (1<<(2+rex.w))-1, rex, &lock, 0, 4);

-                i64 = F32S;

-                MOV64xw(x3, i64);

-                STxw(x3, ed, fixedaddress);

-                SMWRITELOCK(lock);

+            switch((nextop>>3)&7) {

+                case 0:

+                    INST_NAME("MOV Ed, Id");

+                    if(MODREG) {   // reg <= i32

+                        i64 = F32S;

+                        ed = TO_NAT((nextop & 7) + (rex.b << 3));

+                        MOV64xw(ed, i64);

+                    } else {                    // mem <= i32

+                        addr = geted32(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, &unscaled, 0xfff<<(2+rex.w), (1<<(2+rex.w))-1, rex, &lock, 0, 4);

+                        i64 = F32S;

+                        MOV64xw(x3, i64);

+                        STxw(x3, ed, fixedaddress);

+                        SMWRITELOCK(lock);

+                    }

+                    break;

+                default:

+                    DEFAULT;

             }

             break;

 

diff --git a/src/dynarec/arm64/dynarec_arm64_6764_32.c b/src/dynarec/arm64/dynarec_arm64_6764_32.c
index 68167880..9b1c71a7 100644
--- a/src/dynarec/arm64/dynarec_arm64_6764_32.c
+++ b/src/dynarec/arm64/dynarec_arm64_6764_32.c
@@ -88,17 +88,23 @@ uintptr_t dynarec64_6764_32(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, in
             break;
 
         case 0x8F:
-            INST_NAME("POP Seg:Ed");
             nextop=F8;
-            if(MODREG) {   // reg <= reg
-                POP1_32(x1);
-                MOVxw_REG(TO_NAT((nextop & 7) + (rex.b << 3)), x1);
-            } else {                    // mem <= reg
-                grab_segdata(dyn, addr, ninst, x4, seg, (MODREG));
-                POP1_32(x1);
-                addr = geted16(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, &unscaled, 0xfff<<2, 3, 0);
-                ADDz_REG(x4, x4, ed);
-                STz(x1, x4, fixedaddress);
+            switch((nextop>>3)&7) {
+                case 0:
+                    INST_NAME("POP Seg:Ed");
+                    if(MODREG) {   // reg <= reg
+                        POP1_32(x1);
+                        MOVxw_REG(TO_NAT((nextop & 7) + (rex.b << 3)), x1);
+                    } else {                    // mem <= reg
+                        grab_segdata(dyn, addr, ninst, x4, seg, (MODREG));
+                        POP1_32(x1);
+                        addr = geted16(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, &unscaled, 0xfff<<2, 3, 0);
+                        ADDz_REG(x4, x4, ed);
+                        STz(x1, x4, fixedaddress);
+                    }
+                    break;
+                default:
+                    DEFAULT;
             }
             break;
 
diff --git a/src/dynarec/arm64/dynarec_arm64_f0.c b/src/dynarec/arm64/dynarec_arm64_f0.c
index b90aaa3b..0c6624bd 100644
--- a/src/dynarec/arm64/dynarec_arm64_f0.c
+++ b/src/dynarec/arm64/dynarec_arm64_f0.c
@@ -54,23 +54,16 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
 
     switch(opcode) {
         case 0x00:
-            INST_NAME("LOCK ADD Eb, Gb");
-            SETFLAGS(X_ALL, SF_SET_PENDING);
             nextop = F8;
-            GETGB(x2);
             if (MODREG) {
-                if(rex.rex) {
-                    wback = TO_NAT((nextop & 0x07) + (rex.b << 3));
-                    wb2 = 0;
-                } else {
-                    wback = (nextop&7);
-                    wb2 = (wback>>2);
-                    wback = TO_NAT(wback & 3);
-                }
-                UBFXw(x1, wback, wb2*8, 8);
-                emit_add8(dyn, ninst, x1, x2, x4, x3);
-                BFIx(wback, x1, wb2*8, 8);
+                INST_NAME("Invalid LOCK");
+                UDF(0);
+                *need_epilog = 1;
+                *ok = 0;
             } else {
+                INST_NAME("LOCK ADD Eb, Gb");
+                SETFLAGS(X_ALL, SF_SET_PENDING);
+                GETGB(x2);
                 addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 0);
                 if(cpuext.atomics) {
                     UFLAG_IF {
@@ -89,14 +82,16 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
             }
             break;
         case 0x01:
-            INST_NAME("LOCK ADD Ed, Gd");
-            SETFLAGS(X_ALL, SF_SET_PENDING);
             nextop = F8;
-            GETGD;
             if(MODREG) {
-                ed = TO_NAT((nextop & 7) + (rex.b << 3));
-                emit_add32(dyn, ninst, rex, ed, gd, x3, x4);
+                INST_NAME("Invalid LOCK");
+                UDF(0);
+                *need_epilog = 1;
+                *ok = 0;
             } else {
+                INST_NAME("LOCK ADD Ed, Gd");
+                SETFLAGS(X_ALL, SF_SET_PENDING);
+                GETGD;
                 addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 0);
                 if(!ALIGNED_ATOMICxw) {
                     if(cpuext.uscat) {
@@ -141,23 +136,16 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
             break;
 
         case 0x08:
-            INST_NAME("LOCK OR Eb, Gb");
-            SETFLAGS(X_ALL, SF_SET_PENDING);
             nextop = F8;
-            GETGB(x2);
             if (MODREG) {
-                if(rex.rex) {
-                    wback = TO_NAT((nextop & 0x07) + (rex.b << 3));
-                    wb2 = 0;
-                } else {
-                    wback = (nextop&7);
-                    wb2 = (wback>>2);
-                    wback = TO_NAT(wback & 3);
-                }
-                UBFXw(x1, wback, wb2*8, 8);
-                emit_or8(dyn, ninst, x1, x2, x4, x3);
-                BFIx(wback, x1, wb2*8, 8);
+                INST_NAME("Invalid LOCK");
+                UDF(0);
+                *need_epilog = 1;
+                *ok = 0;
             } else {
+                INST_NAME("LOCK OR Eb, Gb");
+                SETFLAGS(X_ALL, SF_SET_PENDING);
+                GETGB(x2);
                 addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 0);
                 if(cpuext.atomics) {
                     LDSETALB(x2, x1, wback);
@@ -174,14 +162,16 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
             }
             break;
         case 0x09:
-            INST_NAME("LOCK OR Ed, Gd");
-            SETFLAGS(X_ALL, SF_SET_PENDING);
             nextop = F8;
-            GETGD;
             if(MODREG) {
-                ed = TO_NAT((nextop & 7) + (rex.b << 3));
-                emit_or32(dyn, ninst, rex, ed, gd, x3, x4);
+                INST_NAME("Invalid LOCK");
+                UDF(0);
+                *need_epilog = 1;
+                *ok = 0;
             } else {
+                INST_NAME("LOCK OR Ed, Gd");
+                SETFLAGS(X_ALL, SF_SET_PENDING);
+                GETGD;
                 addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 0);
                 if(cpuext.atomics) {
                     LDSETALxw(gd, x1, wback);
@@ -203,35 +193,20 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
             switch(nextop) {
 
                 case 0xAB:
-                    INST_NAME("LOCK BTS Ed, Gd");
-                    if(!BOX64ENV(dynarec_safeflags)) {
-                        SETFLAGS(X_ALL&~X_ZF, SF_SUBSET);
-                    } else {
-                        SETFLAGS(X_CF, SF_SUBSET);
-                    }
                     nextop = F8;
-                    GETGD;
                     if(MODREG) {
-                        ed = TO_NAT((nextop & 7) + (rex.b << 3));
-                        wback = 0;
-                        if(rex.w) {
-                            ANDx_mask(x2, gd, 1, 0, 0b00101);  //mask=0x000000000000003f
-                        } else {
-                            ANDw_mask(x2, gd, 0, 0b00100);  //mask=0x00000001f
-                        }
-                        LSRxw_REG(x4, ed, x2);
-                        if(rex.w) {
-                            ANDSx_mask(x4, x4, 1, 0, 0);  //mask=1
+                        INST_NAME("Invalid LOCK");
+                        UDF(0);
+                        *need_epilog = 1;
+                        *ok = 0;
+                    } else {
+                        INST_NAME("LOCK BTS Ed, Gd");
+                        if(!BOX64ENV(dynarec_safeflags)) {
+                            SETFLAGS(X_ALL&~X_ZF, SF_SUBSET);
                         } else {
-                            ANDSw_mask(x4, x4, 0, 0);  //mask=1
-                        }
-                        IFX(X_CF) {
-                            BFIw(xFlags, x4, F_CF, 1);
+                            SETFLAGS(X_CF, SF_SUBSET);
                         }
-                        MOV32w(x4, 1);
-                        LSLxw_REG(x4, x4, x2);
-                        ORRxw_REG(ed, ed, x4);
-                    } else {
+                        GETGD;
                         // Will fetch only 1 byte, to avoid alignment issue
                         ANDw_mask(x2, gd, 0, 0b00010);  //mask=0x000000007
                         addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 0);
@@ -265,30 +240,17 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                 case 0xB0:
                     switch(rep) {
                         case 0:
-                            INST_NAME("LOCK CMPXCHG Eb, Gb");
-                            SETFLAGS(X_ALL, SF_SET_PENDING);
                             nextop = F8;
-                            GETGB(x1);
-                            UBFXx(x6, xRAX, 0, 8);
                             if(MODREG) {
-                                if(rex.rex) {
-                                    wback = TO_NAT((nextop & 7) + (rex.b << 3));
-                                    wb2 = 0;
-                                } else {
-                                    wback = (nextop&7);
-                                    wb2 = (wback>>2)*8;
-                                    wback = TO_NAT(wback & 3);
-                                }
-                                UBFXx(x2, wback, wb2, 8);
-                                wb1 = 0;
-                                ed = x2;
-                                UFLAG_IF {emit_cmp8(dyn, ninst, x6, ed, x3, x4, x5);}
-                                SUBxw_REG(x6, x6, x2);
-                                CBNZxw_MARK2(x6);
-                                BFIx(wback, gd, wb2, 8);
-                                MARK2;
-                                BFIx(xRAX, x2, 0, 8);
+                                INST_NAME("Invalid LOCK");
+                                UDF(0);
+                                *need_epilog = 1;
+                                *ok = 0;
                             } else {
+                                INST_NAME("LOCK CMPXCHG Eb, Gb");
+                                SETFLAGS(X_ALL, SF_SET_PENDING);
+                                GETGB(x1);
+                                UBFXx(x6, xRAX, 0, 8);
                                 addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 0);
                                 if(cpuext.atomics) {
                                     UFLAG_IF {
@@ -321,24 +283,16 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                 case 0xB1:
                     switch(rep) {
                         case 0:
-                            INST_NAME("LOCK CMPXCHG Ed, Gd");
-                            SETFLAGS(X_ALL, SF_SET_PENDING);
                             nextop = F8;
-                            GETGD;
                             if(MODREG) {
-                                ed = TO_NAT((nextop & 7) + (rex.b << 3));
-                                wback = 0;
-                                UFLAG_IF {
-                                    emit_cmp32(dyn, ninst, rex, xRAX, ed, x3, x4, x5);
-                                } else {
-                                    CMPSxw_REG(xRAX, ed);
-                                }
-                                MOVxw_REG(x1, ed); // save value
-                                Bcond(cNE, 4 + (rex.w ? 4 : 8));
-                                MOVxw_REG(ed, gd);
-                                if (!rex.w) { B_NEXT_nocond; }
-                                MOVxw_REG(xRAX, x1);
+                                INST_NAME("Invalid LOCK");
+                                UDF(0);
+                                *need_epilog = 1;
+                                *ok = 0;
                             } else {
+                                INST_NAME("LOCK CMPXCHG Ed, Gd");
+                                SETFLAGS(X_ALL, SF_SET_PENDING);
+                                GETGD;
                                 addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 0);
                                 UFLAG_IF { MOVxw_REG(x6, xRAX); }
                                 if(!ALIGNED_ATOMICxw) {
@@ -412,30 +366,20 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     break;
 
                 case 0xB3:
-                    INST_NAME("LOCK BTR Ed, Gd");
-                    if(!BOX64ENV(dynarec_safeflags)) {
-                        SETFLAGS(X_ALL&~X_ZF, SF_SUBSET);
-                    } else {
-                        SETFLAGS(X_CF, SF_SUBSET);
-                    }
                     nextop = F8;
-                    GETGD;
                     if(MODREG) {
-                        ed = TO_NAT((nextop & 7) + (rex.b << 3));
-                        wback = 0;
-                        if(rex.w) {
-                            ANDx_mask(x2, gd, 1, 0, 0b00101);  //mask=0x000000000000003f
+                        INST_NAME("Invalid LOCK");
+                        UDF(0);
+                        *need_epilog = 1;
+                        *ok = 0;
+                    } else {
+                        INST_NAME("LOCK BTR Ed, Gd");
+                        if(!BOX64ENV(dynarec_safeflags)) {
+                            SETFLAGS(X_ALL&~X_ZF, SF_SUBSET);
                         } else {
-                            ANDw_mask(x2, gd, 0, 0b00100);  //mask=0x00000001f
-                        }
-                        IFX(X_CF) {
-                            LSRxw_REG(x4, ed, x2);
-                            BFIw(xFlags, x4, F_CF, 1);
+                            SETFLAGS(X_CF, SF_SUBSET);
                         }
-                        MOV32w(x4, 1);
-                        LSLxw_REG(x4, x4, x2);
-                        BICxw_REG(ed, ed, x4);
-                    } else {
+                        GETGD;
                         // Will fetch only 1 byte, to avoid alignment issue
                         ANDw_mask(x2, gd, 0, 0b00010);  //mask=0x000000007
                         addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 0);
@@ -471,55 +415,24 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                 nextop = F8;
                 switch((nextop>>3)&7) {
                     case 4:
-                        INST_NAME("LOCK BT Ed, Ib");
-                        if(!BOX64ENV(dynarec_safeflags)) {
-                            SETFLAGS(X_ALL&~X_ZF, SF_SUBSET);
-                        } else {
-                            SETFLAGS(X_CF, SF_SUBSET);
-                        }
-                        gd = x2;
-                        if(MODREG) {
-                            ed = TO_NAT((nextop & 7) + (rex.b << 3));
-                            u8 = F8;
-                            u8&=rex.w?0x3f:0x1f;
-                            IFX(X_CF) {
-                                BFXILxw(xFlags, ed, u8, 1);  // inject 1 bit from u8 to F_CF (i.e. pos 0)
-                            }
-                        } else {
-                            // Will fetch only 1 byte, to avoid alignment issue
-                            addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 1);
-                            u8 = F8;
-                            if(u8>>3) {
-                                ADDx_U12(x3, wback, u8>>3);
-                                wback = x3;
-                            }
-                            MARKLOCK;
-                            LDAXRB(x1, wback);
-                            ed = x1;
-                            wback = x3;
-                            IFX(X_CF) {
-                                BFXILxw(xFlags, x1, u8&7, 1);  // inject 1 bit from u8 to F_CF (i.e. pos 0)
-                            }
-                        }
+                        INST_NAME("Invalid LOCK");
+                        UDF(0);
+                        *need_epilog = 1;
+                        *ok = 0;
                         break;
                     case 5:
-                        INST_NAME("LOCK BTS Ed, Ib");
-                        if(!BOX64ENV(dynarec_safeflags)) {
-                            SETFLAGS(X_ALL&~X_ZF, SF_SUBSET);
-                        } else {
-                            SETFLAGS(X_CF, SF_SUBSET);
-                        }
                         if(MODREG) {
-                            ed = TO_NAT((nextop & 7) + (rex.b << 3));
-                            wback = 0;
-                            u8 = F8;
-                            u8&=(rex.w?0x3f:0x1f);
-                            IFX(X_CF) {
-                                BFXILxw(xFlags, ed, u8, 1);  // inject 1 bit from u8 to F_CF (i.e. pos 0)
-                            }
-                            mask = convert_bitmask_xw(1LL<<u8);
-                            ORRxw_mask(ed, ed, (mask>>12)&1, mask&0x3F, (mask>>6)&0x3F);
+                            INST_NAME("Invalid LOCK");
+                            UDF(0);
+                            *need_epilog = 1;
+                            *ok = 0;
                         } else {
+                            INST_NAME("LOCK BTS Ed, Ib");
+                            if(!BOX64ENV(dynarec_safeflags)) {
+                                SETFLAGS(X_ALL&~X_ZF, SF_SUBSET);
+                            } else {
+                                SETFLAGS(X_CF, SF_SUBSET);
+                            }
                             // Will fetch only 1 byte, to avoid alignment issue
                             addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 1);
                             u8 = F8;
@@ -548,22 +461,18 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                         }
                         break;
                     case 6:
-                        INST_NAME("LOCK BTR Ed, Ib");
-                        if(!BOX64ENV(dynarec_safeflags)) {
-                            SETFLAGS(X_ALL&~X_ZF, SF_SUBSET);
-                        } else {
-                            SETFLAGS(X_CF, SF_SUBSET);
-                        }
                         if(MODREG) {
-                            ed = TO_NAT((nextop & 7) + (rex.b << 3));
-                            wback = 0;
-                            u8 = F8;
-                            u8&=(rex.w?0x3f:0x1f);
-                            IFX(X_CF) {
-                                BFXILxw(xFlags, ed, u8, 1);  // inject 1 bit from u8 to F_CF (i.e. pos 0)
-                            }
-                            BFCxw(ed, u8, 1);
+                            INST_NAME("Invalid LOCK");
+                            UDF(0);
+                            *need_epilog = 1;
+                            *ok = 0;
                         } else {
+                            INST_NAME("LOCK BTR Ed, Ib");
+                            if(!BOX64ENV(dynarec_safeflags)) {
+                                SETFLAGS(X_ALL&~X_ZF, SF_SUBSET);
+                            } else {
+                                SETFLAGS(X_CF, SF_SUBSET);
+                            }
                             addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 1);
                             u8 = F8;
                             if(u8>>3) {
@@ -590,23 +499,18 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                         }
                         break;
                     case 7:
-                        INST_NAME("LOCK BTC Ed, Ib");
-                        if(!BOX64ENV(dynarec_safeflags)) {
-                            SETFLAGS(X_ALL&~X_ZF, SF_SUBSET);
-                        } else {
-                            SETFLAGS(X_CF, SF_SUBSET);
-                        }
                         if(MODREG) {
-                            ed = TO_NAT((nextop & 7) + (rex.b << 3));
-                            wback = 0;
-                            u8 = F8;
-                            u8&=(rex.w?0x3f:0x1f);
-                            IFX(X_CF) {
-                                BFXILxw(xFlags, ed, u8, 1);  // inject 1 bit from u8 to F_CF (i.e. pos 0)
-                            }
-                            MOV32w(x4, 1);
-                            EORxw_REG_LSL(ed, ed, x4, u8);
+                            INST_NAME("Invalid LOCK");
+                            UDF(0);
+                            *need_epilog = 1;
+                            *ok = 0;
                         } else {
+                            INST_NAME("LOCK BTC Ed, Ib");
+                            if(!BOX64ENV(dynarec_safeflags)) {
+                                SETFLAGS(X_ALL&~X_ZF, SF_SUBSET);
+                            } else {
+                                SETFLAGS(X_CF, SF_SUBSET);
+                            }
                             addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 1);
                             u8 = F8;
                             if(u8>>3) {
@@ -638,30 +542,20 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                 }
                 break;
                 case 0xBB:
-                    INST_NAME("LOCK BTC Ed, Gd");
-                    if(!BOX64ENV(dynarec_safeflags)) {
-                        SETFLAGS(X_ALL&~X_ZF, SF_SUBSET);
-                    } else {
-                        SETFLAGS(X_CF, SF_SUBSET);
-                    }
                     nextop = F8;
-                    GETGD;
                     if(MODREG) {
-                        ed = TO_NAT((nextop & 7) + (rex.b << 3));
-                        wback = 0;
-                        if(rex.w) {
-                            ANDx_mask(x2, gd, 1, 0, 0b00101);  //mask=0x000000000000003f
+                        INST_NAME("Invalid LOCK");
+                        UDF(0);
+                        *need_epilog = 1;
+                        *ok = 0;
+                    } else {
+                        INST_NAME("LOCK BTC Ed, Gd");
+                        if(!BOX64ENV(dynarec_safeflags)) {
+                            SETFLAGS(X_ALL&~X_ZF, SF_SUBSET);
                         } else {
-                            ANDw_mask(x2, gd, 0, 0b00100);  //mask=0x00000001f
-                        }
-                        IFX(X_CF) {
-                            LSRxw_REG(x4, ed, x2);
-                            BFIw(xFlags, x4, F_CF, 1);
+                            SETFLAGS(X_CF, SF_SUBSET);
                         }
-                        MOV32w(x4, 1);
-                        LSLxw_REG(x4, x4, x2);
-                        EORxw_REG(ed, ed, x4);
-                    } else {
+                        GETGD;
                         // Will fetch only 1 byte, to avoid alignment issue
                         ANDw_mask(x2, gd, 0, 0b00010);  //mask=0x000000007
                         addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 0);
@@ -696,18 +590,16 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                 case 0xC0:
                     switch(rep) {
                         case 0:
-                            INST_NAME("LOCK XADD Eb, Gb");
-                            SETFLAGS(X_ALL, SF_SET_PENDING);
                             nextop = F8;
-                            GETGB(x1);
                             if(MODREG) {
-                                ed = TO_NAT((nextop & 7) + (rex.b << 3));
-                                GETEB(x2, 0);
-                                gd = x2; ed = x1;    // swap gd/ed
-                                emit_add8(dyn, ninst, x1, x2, x4, x5);
-                                GBBACK; // gb gets x2 (old ed)
-                                EBBACK; // eb gets x1 (sum)
+                                INST_NAME("Invalid LOCK");
+                                UDF(0);
+                                *need_epilog = 1;
+                                *ok = 0;
                             } else {
+                                INST_NAME("LOCK XADD Eb, Gb");
+                                SETFLAGS(X_ALL, SF_SET_PENDING);
+                                GETGB(x1);
                                 addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 0);
                                 if(cpuext.atomics) {
                                     UFLAG_IF {
@@ -739,17 +631,16 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                 case 0xC1:
                     switch(rep) {
                         case 0:
-                            INST_NAME("LOCK XADD Ed, Gd");
-                            SETFLAGS(X_ALL, SF_SET_PENDING);
                             nextop = F8;
-                            GETGD;
                             if(MODREG) {
-                                ed = TO_NAT((nextop & 7) + (rex.b << 3));
-                                MOVxw_REG(x1, ed);
-                                MOVxw_REG(ed, gd);
-                                MOVxw_REG(gd, x1);
-                                emit_add32(dyn, ninst, rex, ed, gd, x3, x4);
+                                INST_NAME("Invalid LOCK");
+                                UDF(0);
+                                *need_epilog = 1;
+                                *ok = 0;
                             } else {
+                                INST_NAME("LOCK XADD Ed, Gd");
+                                SETFLAGS(X_ALL, SF_SET_PENDING);
+                                GETGD;
                                 addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 0);
                                 if(!ALIGNED_ATOMICxw) {
                                     if(cpuext.uscat) {
@@ -811,97 +702,104 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     nextop = F8;
                     switch((nextop>>3)&7) {
                         case 1:
-                        if (rex.w) {
-                            INST_NAME("LOCK CMPXCHG16B Gq, Eq");
+                        if(MODREG) {
+                            INST_NAME("Invalid LOCK");
+                            UDF(0);
+                            *need_epilog = 1;
+                            *ok = 0;
                         } else {
-                            INST_NAME("LOCK CMPXCHG8B Gq, Eq");
-                        }
-                        SETFLAGS(X_ZF, SF_SUBSET);
-                        addr = geted(dyn, addr, ninst, nextop, &wback, x1, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 0);
-                        if(!ALIGNED_ATOMICxw) {
-                            if(cpuext.uscat) {
-                                if(rex.w) {
-                                    TSTx_mask(wback, 1, 0, 3);
-                                    B_MARK2(cNE);
-                                } else {
-                                    ANDx_mask(x2, wback, 1, 0, 3);  // mask = F
-                                    CMPSw_U12(x2, 8);
-                                    B_MARK2(cGT);
-                                }
+                            if (rex.w) {
+                                INST_NAME("LOCK CMPXCHG16B Gq, Eq");
                             } else {
-                                TSTx_mask(wback, 1, 0, 2+rex.w);    // mask=7 or F
-                                B_MARK2(cNE);    // unaligned
+                                INST_NAME("LOCK CMPXCHG8B Gq, Eq");
                             }
-                        }
-                        if(cpuext.atomics) {
-                            MOVx_REG(x2, xRAX);
-                            MOVx_REG(x3, xRDX);
-                            MOVx_REG(x4, xRBX);
-                            MOVx_REG(x5, xRCX);
-                            CASPALxw(x2, x4, wback);
-                            UFLAG_IF {
-                                CMPSxw_REG(x2, xRAX);
-                                CCMPxw(x3, xRDX, 0, cEQ);
-                                IFNATIVE(NF_EQ) {} else {CSETw(x1, cEQ);}
-                            }
-                            MOVx_REG(xRAX, x2);
-                            MOVx_REG(xRDX, x3);
+                            SETFLAGS(X_ZF, SF_SUBSET);
+                            addr = geted(dyn, addr, ninst, nextop, &wback, x1, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 0);
                             if(!ALIGNED_ATOMICxw) {
-                                B_MARK3_nocond;
-                            }
-                        } else {
-                            MARKLOCK;
-                            LDAXPxw(x2, x3, wback);
-                            CMPSxw_REG(xRAX, x2);
-                            CCMPxw(xRDX, x3, 0, cEQ);
-                            B_MARK(cNE);    // EAX!=ED[0] || EDX!=Ed[1]
-                            STLXPxw(x4, xRBX, xRCX, wback);
-                            CBNZx_MARKLOCK(x4);
-                            UFLAG_IF {
-                                IFNATIVE(NF_EQ) {} else {MOV32w(x1, 1);}
+                                if(cpuext.uscat) {
+                                    if(rex.w) {
+                                        TSTx_mask(wback, 1, 0, 3);
+                                        B_MARK2(cNE);
+                                    } else {
+                                        ANDx_mask(x2, wback, 1, 0, 3);  // mask = F
+                                        CMPSw_U12(x2, 8);
+                                        B_MARK2(cGT);
+                                    }
+                                } else {
+                                    TSTx_mask(wback, 1, 0, 2+rex.w);    // mask=7 or F
+                                    B_MARK2(cNE);    // unaligned
+                                }
                             }
-                            B_MARK3_nocond;
-                            MARK;
-                            STLXPxw(x4, x2, x3, wback); // write back, to be sure it was "atomic"
-                            CBNZx_MARKLOCK(x4);
-                            MOVxw_REG(xRAX, x2);
-                            MOVxw_REG(xRDX, x3);
-                            UFLAG_IF {
-                                IFNATIVE(NF_EQ) {} else {MOV32w(x1, 0);}
+                            if(cpuext.atomics) {
+                                MOVx_REG(x2, xRAX);
+                                MOVx_REG(x3, xRDX);
+                                MOVx_REG(x4, xRBX);
+                                MOVx_REG(x5, xRCX);
+                                CASPALxw(x2, x4, wback);
+                                UFLAG_IF {
+                                    CMPSxw_REG(x2, xRAX);
+                                    CCMPxw(x3, xRDX, 0, cEQ);
+                                    IFNATIVE(NF_EQ) {} else {CSETw(x1, cEQ);}
+                                }
+                                MOVx_REG(xRAX, x2);
+                                MOVx_REG(xRDX, x3);
+                                if(!ALIGNED_ATOMICxw) {
+                                    B_MARK3_nocond;
+                                }
+                            } else {
+                                MARKLOCK;
+                                LDAXPxw(x2, x3, wback);
+                                CMPSxw_REG(xRAX, x2);
+                                CCMPxw(xRDX, x3, 0, cEQ);
+                                B_MARK(cNE);    // EAX!=ED[0] || EDX!=Ed[1]
+                                STLXPxw(x4, xRBX, xRCX, wback);
+                                CBNZx_MARKLOCK(x4);
+                                UFLAG_IF {
+                                    IFNATIVE(NF_EQ) {} else {MOV32w(x1, 1);}
+                                }
+                                B_MARK3_nocond;
+                                MARK;
+                                STLXPxw(x4, x2, x3, wback); // write back, to be sure it was "atomic"
+                                CBNZx_MARKLOCK(x4);
+                                MOVxw_REG(xRAX, x2);
+                                MOVxw_REG(xRDX, x3);
+                                UFLAG_IF {
+                                    IFNATIVE(NF_EQ) {} else {MOV32w(x1, 0);}
+                                }
+                                if(!ALIGNED_ATOMICxw) {
+                                    B_MARK3_nocond;
+                                }
                             }
                             if(!ALIGNED_ATOMICxw) {
+                                MARK2;
+                                LDPxw_S7_offset(x2, x3, wback, 0);
+                                LDAXRB(x5, wback);
+                                SUBxw_UXTB(x5, x5, x2);
+                                CBNZw_MARK2(x5);
+                                CMPSxw_REG(xRAX, x2);
+                                CCMPxw(xRDX, x3, 0, cEQ);
+                                B_MARKSEG(cNE);    // EAX!=ED[0] || EDX!=Ed[1]
+                                STLXRB(x4, xRBX, wback);
+                                CBNZx_MARK2(x4);
+                                STPxw_S7_offset(xRBX, xRCX, wback, 0);
+                                UFLAG_IF {
+                                    IFNATIVE(NF_EQ) {} else {MOV32w(x1, 1);}
+                                }
                                 B_MARK3_nocond;
+                                MARKSEG;
+                                STLXRB(x4, x5, wback); //write back
+                                CBNZx_MARK2(x4);
+                                MOVxw_REG(xRAX, x2);
+                                MOVxw_REG(xRDX, x3);
+                                UFLAG_IF {
+                                    IFNATIVE(NF_EQ) {} else {MOV32w(x1, 0);}
+                                }
                             }
-                        }
-                        if(!ALIGNED_ATOMICxw) {
-                            MARK2;
-                            LDPxw_S7_offset(x2, x3, wback, 0);
-                            LDAXRB(x5, wback);
-                            SUBxw_UXTB(x5, x5, x2);
-                            CBNZw_MARK2(x5);
-                            CMPSxw_REG(xRAX, x2);
-                            CCMPxw(xRDX, x3, 0, cEQ);
-                            B_MARKSEG(cNE);    // EAX!=ED[0] || EDX!=Ed[1]
-                            STLXRB(x4, xRBX, wback);
-                            CBNZx_MARK2(x4);
-                            STPxw_S7_offset(xRBX, xRCX, wback, 0);
-                            UFLAG_IF {
-                                IFNATIVE(NF_EQ) {} else {MOV32w(x1, 1);}
-                            }
-                            B_MARK3_nocond;
-                            MARKSEG;
-                            STLXRB(x4, x5, wback); //write back
-                            CBNZx_MARK2(x4);
-                            MOVxw_REG(xRAX, x2);
-                            MOVxw_REG(xRDX, x3);
+                            MARK3;
                             UFLAG_IF {
-                                IFNATIVE(NF_EQ) {} else {MOV32w(x1, 0);}
+                                IFNATIVE(NF_EQ) {} else {BFIw(xFlags, x1, F_ZF, 1);}
                             }
                         }
-                        MARK3;
-                        UFLAG_IF {
-                            IFNATIVE(NF_EQ) {} else {BFIw(xFlags, x1, F_ZF, 1);}
-                        }
                         break;
                     default:
                         DEFAULT;
@@ -914,23 +812,16 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
             break;
         case 0x10:
             INST_NAME("LOCK ADC Eb, Gb");
-            READFLAGS(X_CF);
-            SETFLAGS(X_ALL, SF_SET_PENDING);
             nextop = F8;
-            GETGB(x2);
             if (MODREG) {
-                if(rex.rex) {
-                    wback = TO_NAT((nextop & 0x07) + (rex.b << 3));
-                    wb2 = 0;
-                } else {
-                    wback = (nextop&7);
-                    wb2 = (wback>>2);
-                    wback = TO_NAT(wback & 3);
-                }
-                UBFXw(x1, wback, wb2*8, 8);
-                emit_adc8(dyn, ninst, x1, x2, x4, x5);
-                BFIx(wback, x1, wb2*8, 8);
+                INST_NAME("Invalid LOCK");
+                UDF(0);
+                *need_epilog = 1;
+                *ok = 0;
             } else {
+                READFLAGS(X_CF);
+                SETFLAGS(X_ALL, SF_SET_PENDING);
+                GETGB(x2);
                 addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 0);
                 MARKLOCK;
                 LDAXRB(x1, wback);
@@ -940,15 +831,17 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
             }
             break;
         case 0x11:
-            INST_NAME("LOCK ADC Ed, Gd");
-            READFLAGS(X_CF);
-            SETFLAGS(X_ALL, SF_SET_PENDING);
             nextop = F8;
-            GETGD;
             if(MODREG) {
-                ed = TO_NAT((nextop & 7) + (rex.b << 3));
-                emit_adc32(dyn, ninst, rex, ed, gd, x3, x4);
+                INST_NAME("Invalid LOCK");
+                UDF(0);
+                *need_epilog = 1;
+                *ok = 0;
             } else {
+                INST_NAME("LOCK ADC Ed, Gd");
+                READFLAGS(X_CF);
+                SETFLAGS(X_ALL, SF_SET_PENDING);
+                GETGD;
                 addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 0);
                 MARKLOCK;
                 LDAXRxw(x1, wback);
@@ -958,16 +851,16 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
             }
             break;
         case 0x20:
-            INST_NAME("LOCK AND Eb, Gb");
-            SETFLAGS(X_ALL, SF_SET_PENDING);
             nextop = F8;
-            GETGD;
             if(MODREG) {
-                GETEB(x1, 0);
-                GETGB(x2);
-                emit_and8(dyn, ninst, x1, x2, x4, x5);
-                EBBACK;
+                INST_NAME("Invalid LOCK");
+                UDF(0);
+                *need_epilog = 1;
+                *ok = 0;
             } else {
+                INST_NAME("LOCK AND Eb, Gb");
+                SETFLAGS(X_ALL, SF_SET_PENDING);
+                GETGD;
                 addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 0);
                 GETGB(x5);
                 if(cpuext.atomics) {
@@ -988,14 +881,16 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
             }
             break;
         case 0x21:
-            INST_NAME("LOCK AND Ed, Gd");
-            SETFLAGS(X_ALL, SF_SET_PENDING);
             nextop = F8;
-            GETGD;
             if(MODREG) {
-                ed = TO_NAT((nextop & 7) + (rex.b << 3));
-                emit_and32(dyn, ninst, rex, ed, gd, x3, x4);
+                INST_NAME("Invalid LOCK");
+                UDF(0);
+                *need_epilog = 1;
+                *ok = 0;
             } else {
+                INST_NAME("LOCK AND Ed, Gd");
+                SETFLAGS(X_ALL, SF_SET_PENDING);
+                GETGD;
                 addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 0);
                 if(cpuext.atomics) {
                     MVNxw_REG(x1, gd);
@@ -1016,14 +911,16 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
             break;
 
         case 0x29:
-            INST_NAME("LOCK SUB Ed, Gd");
-            SETFLAGS(X_ALL, SF_SET_PENDING);
             nextop = F8;
-            GETGD;
             if(MODREG) {
-                ed = TO_NAT((nextop & 7) + (rex.b << 3));
-                emit_sub32(dyn, ninst, rex, ed, gd, x3, x4);
+                INST_NAME("Invalid LOCK");
+                UDF(0);
+                *need_epilog = 1;
+                *ok = 0;
             } else {
+                INST_NAME("LOCK SUB Ed, Gd");
+                SETFLAGS(X_ALL, SF_SET_PENDING);
+                GETGD;
                 addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 0);
                 if(!ALIGNED_ATOMICxw) {
                     if(cpuext.uscat) {
@@ -1073,14 +970,16 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
             break;
 
         case 0x31:
-            INST_NAME("LOCK XOR Ed, Gd");
-            SETFLAGS(X_ALL, SF_SET_PENDING);
             nextop = F8;
-            GETGD;
             if (MODREG) {
-                ed = TO_NAT((nextop & 7) + (rex.b << 3));
-                emit_xor32(dyn, ninst, rex, ed, gd, x3, x4);
+                INST_NAME("Invalid LOCK");
+                UDF(0);
+                *need_epilog = 1;
+                *ok = 0;
             } else {
+                INST_NAME("LOCK XOR Ed, Gd");
+                SETFLAGS(X_ALL, SF_SET_PENDING);
+                GETGD;
                 addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 0);
                 if(!ALIGNED_ATOMICxw) {
                     if(cpuext.uscat) {
@@ -1131,15 +1030,14 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
             nextop = F8;
             switch((nextop>>3)&7) {
                 case 0: //ADD
-                    INST_NAME("ADD Eb, Ib");
-                    SETFLAGS(X_ALL, SF_SET_PENDING);
                     if(MODREG) {
-                        GETEB(x1, 1);
-                        u8 = F8;
-                        emit_add8c(dyn, ninst, x1, u8, x2, x4);
-                        wb1 = 0;
-                        EBBACK;
+                        INST_NAME("Invalid LOCK");
+                        UDF(0);
+                        *need_epilog = 1;
+                        *ok = 0;
                     } else {
+                        INST_NAME("ADD Eb, Ib");
+                        SETFLAGS(X_ALL, SF_SET_PENDING);
                         addr = geted(dyn, addr, ninst, nextop, &wback, x5, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 1);
                         u8 = F8;
                         wb1 = 1;
@@ -1162,15 +1060,14 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     }
                     break;
                 case 1: //OR
-                    INST_NAME("OR Eb, Ib");
-                    SETFLAGS(X_ALL, SF_SET_PENDING);
                     if(MODREG) {
-                        GETEB(x1, 1);
-                        u8 = F8;
-                        emit_or8c(dyn, ninst, x1, u8, x2, x4);
-                        wb1 = 0;
-                        EBBACK;
+                        INST_NAME("Invalid LOCK");
+                        UDF(0);
+                        *need_epilog = 1;
+                        *ok = 0;
                     } else {
+                        INST_NAME("OR Eb, Ib");
+                        SETFLAGS(X_ALL, SF_SET_PENDING);
                         addr = geted(dyn, addr, ninst, nextop, &wback, x5, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 1);
                         u8 = F8;
                         wb1 = 1;
@@ -1192,16 +1089,15 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     }
                     break;
                 case 2: //ADC
-                    INST_NAME("ADC Eb, Ib");
-                    READFLAGS(X_CF);
-                    SETFLAGS(X_ALL, SF_SET_PENDING);
                     if(MODREG) {
-                        GETEB(x1, 1);
-                        u8 = F8;
-                        emit_adc8c(dyn, ninst, x1, u8, x2, x4, x5);
-                        wb1 = 0;
-                        EBBACK;
+                        INST_NAME("Invalid LOCK");
+                        UDF(0);
+                        *need_epilog = 1;
+                        *ok = 0;
                     } else {
+                        INST_NAME("ADC Eb, Ib");
+                        READFLAGS(X_CF);
+                        SETFLAGS(X_ALL, SF_SET_PENDING);
                         addr = geted(dyn, addr, ninst, nextop, &wback, x5, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 1);
                         u8 = F8;
                         wb1 = 1;
@@ -1213,16 +1109,15 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     }
                     break;
                 case 3: //SBB
-                    INST_NAME("SBB Eb, Ib");
-                    READFLAGS(X_CF);
-                    SETFLAGS(X_ALL, SF_SET_PENDING);
                     if(MODREG) {
-                        GETEB(x1, 1);
-                        u8 = F8;
-                        emit_sbb8c(dyn, ninst, x1, u8, x2, x4, x5);
-                        wb1 = 0;
-                        EBBACK;
+                        INST_NAME("Invalid LOCK");
+                        UDF(0);
+                        *need_epilog = 1;
+                        *ok = 0;
                     } else {
+                        INST_NAME("SBB Eb, Ib");
+                        READFLAGS(X_CF);
+                        SETFLAGS(X_ALL, SF_SET_PENDING);
                         addr = geted(dyn, addr, ninst, nextop, &wback, x5, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 1);
                         u8 = F8;
                         wb1 = 1;
@@ -1234,15 +1129,14 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     }
                     break;
                 case 4: //AND
-                    INST_NAME("AND Eb, Ib");
-                    SETFLAGS(X_ALL, SF_SET_PENDING);
                     if(MODREG) {
-                        GETEB(x1, 1);
-                        u8 = F8;
-                        emit_and8c(dyn, ninst, x1, u8, x2, x4);
-                        wb1 = 0;
-                        EBBACK;
+                        INST_NAME("Invalid LOCK");
+                        UDF(0);
+                        *need_epilog = 1;
+                        *ok = 0;
                     } else {
+                        INST_NAME("AND Eb, Ib");
+                        SETFLAGS(X_ALL, SF_SET_PENDING);
                         addr = geted(dyn, addr, ninst, nextop, &wback, x5, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 1);
                         u8 = F8;
                         wb1 = 1;
@@ -1264,15 +1158,14 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     }
                     break;
                 case 5: //SUB
-                    INST_NAME("SUB Eb, Ib");
-                    SETFLAGS(X_ALL, SF_SET_PENDING);
                     if(MODREG) {
-                        GETEB(x1, 1);
-                        u8 = F8;
-                        emit_sub8c(dyn, ninst, x1, u8, x2, x4, x5);
-                        wb1 = 0;
-                        EBBACK;
+                        INST_NAME("Invalid LOCK");
+                        UDF(0);
+                        *need_epilog = 1;
+                        *ok = 0;
                     } else {
+                        INST_NAME("SUB Eb, Ib");
+                        SETFLAGS(X_ALL, SF_SET_PENDING);
                         addr = geted(dyn, addr, ninst, nextop, &wback, x5, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 1);
                         u8 = F8;
                         wb1 = 1;
@@ -1294,15 +1187,14 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     }
                     break;
                 case 6: //XOR
-                    INST_NAME("XOR Eb, Ib");
-                    SETFLAGS(X_ALL, SF_SET_PENDING);
                     if(MODREG) {
-                        GETEB(x1, 1);
-                        u8 = F8;
-                        emit_xor8c(dyn, ninst, x1, u8, x2, x4);
-                        wb1 = 0;
-                        EBBACK;
+                        INST_NAME("Invalid LOCK");
+                        UDF(0);
+                        *need_epilog = 1;
+                        *ok = 0;
                     } else {
+                        INST_NAME("XOR Eb, Ib");
+                        SETFLAGS(X_ALL, SF_SET_PENDING);
                         addr = geted(dyn, addr, ninst, nextop, &wback, x5, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 1);
                         u8 = F8;
                         wb1 = 1;
@@ -1324,16 +1216,10 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     }
                     break;
                 case 7: //CMP
-                    INST_NAME("CMP Eb, Ib");
-                    SETFLAGS(X_ALL, SF_SET_PENDING);
-                    GETEB(x1, 1);
-                    u8 = F8;
-                    if(u8) {
-                        MOV32w(x2, u8);
-                        emit_cmp8(dyn, ninst, x1, x2, x3, x4, x5);
-                    } else {
-                        emit_cmp8_0(dyn, ninst, x1, x3, x4);
-                    }
+                    INST_NAME("Invalid LOCK");
+                    UDF(0);
+                    *need_epilog = 1;
+                    *ok = 0;
                     break;
                 default:
                     DEFAULT;
@@ -1344,18 +1230,18 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
             nextop = F8;
             switch((nextop>>3)&7) {
                 case 0: //ADD
-                    if(opcode==0x81) {
-                        INST_NAME("LOCK ADD Ed, Id");
-                    } else {
-                        INST_NAME("LOCK ADD Ed, Ib");
-                    }
-                    SETFLAGS(X_ALL, SF_SET_PENDING);
                     if(MODREG) {
-                        if(opcode==0x81) i64 = F32S; else i64 = F8S;
-                        ed = TO_NAT((nextop & 7) + (rex.b << 3));
-                        MOV64xw(x5, i64);
-                        emit_add32(dyn, ninst, rex, ed, x5, x3, x4);
+                        INST_NAME("Invalid LOCK");
+                        UDF(0);
+                        *need_epilog = 1;
+                        *ok = 0;
                     } else {
+                        if(opcode==0x81) {
+                            INST_NAME("LOCK ADD Ed, Id");
+                        } else {
+                            INST_NAME("LOCK ADD Ed, Ib");
+                        }
+                        SETFLAGS(X_ALL, SF_SET_PENDING);
                         addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, (opcode==0x81)?4:1);
                         if(opcode==0x81) i64 = F32S; else i64 = F8S;
                         if((i64<=-0x1000) || (i64>=0x1000)) {
@@ -1422,13 +1308,14 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     }
                     break;
                 case 1: //OR
-                    if(opcode==0x81) {INST_NAME("LOCK OR Ed, Id");} else {INST_NAME("LOCK OR Ed, Ib");}
-                    SETFLAGS(X_ALL, SF_SET_PENDING);
                     if(MODREG) {
-                        if(opcode==0x81) i64 = F32S; else i64 = F8S;
-                        ed = TO_NAT((nextop & 7) + (rex.b << 3));
-                        emit_or32c(dyn, ninst, rex, ed, i64, x3, x4);
+                        INST_NAME("Invalid LOCK");
+                        UDF(0);
+                        *need_epilog = 1;
+                        *ok = 0;
                     } else {
+                        if(opcode==0x81) {INST_NAME("LOCK OR Ed, Id");} else {INST_NAME("LOCK OR Ed, Ib");}
+                        SETFLAGS(X_ALL, SF_SET_PENDING);
                         addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, (opcode==0x81)?4:1);
                         if(opcode==0x81) i64 = F32S; else i64 = F8S;
                         if(wback==xRSP && !i64) {
@@ -1454,15 +1341,15 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     }
                     break;
                 case 2: //ADC
-                    if(opcode==0x81) {INST_NAME("LOCK ADC Ed, Id");} else {INST_NAME("LOCK ADC Ed, Ib");}
-                    READFLAGS(X_CF);
-                    SETFLAGS(X_ALL, SF_SET_PENDING);
                     if(MODREG) {
-                        if(opcode==0x81) i64 = F32S; else i64 = F8S;
-                        ed = TO_NAT((nextop & 7) + (rex.b << 3));
-                        MOV64xw(x5, i64);
-                        emit_adc32(dyn, ninst, rex, ed, x5, x3, x4);
+                        INST_NAME("Invalid LOCK");
+                        UDF(0);
+                        *need_epilog = 1;
+                        *ok = 0;
                     } else {
+                        if(opcode==0x81) {INST_NAME("LOCK ADC Ed, Id");} else {INST_NAME("LOCK ADC Ed, Ib");}
+                        READFLAGS(X_CF);
+                        SETFLAGS(X_ALL, SF_SET_PENDING);
                         addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, (opcode==0x81)?4:1);
                         if(opcode==0x81) i64 = F32S; else i64 = F8S;
                         MOV64xw(x5, i64);
@@ -1474,15 +1361,15 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     }
                     break;
                 case 3: //SBB
-                    if(opcode==0x81) {INST_NAME("LOCK SBB Ed, Id");} else {INST_NAME("LOCK SBB Ed, Ib");}
-                    READFLAGS(X_CF);
-                    SETFLAGS(X_ALL, SF_SET_PENDING);
                     if(MODREG) {
-                        if(opcode==0x81) i64 = F32S; else i64 = F8S;
-                        ed = TO_NAT((nextop & 7) + (rex.b << 3));
-                        MOV64xw(x5, i64);
-                        emit_sbb32(dyn, ninst, rex, ed, x5, x3, x4);
+                        INST_NAME("Invalid LOCK");
+                        UDF(0);
+                        *need_epilog = 1;
+                        *ok = 0;
                     } else {
+                        if(opcode==0x81) {INST_NAME("LOCK SBB Ed, Id");} else {INST_NAME("LOCK SBB Ed, Ib");}
+                        READFLAGS(X_CF);
+                        SETFLAGS(X_ALL, SF_SET_PENDING);
                         addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, (opcode==0x81)?4:1);
                         if(opcode==0x81) i64 = F32S; else i64 = F8S;
                         MOV64xw(x5, i64);
@@ -1494,14 +1381,14 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     }
                     break;
                 case 4: //AND
-                    if(opcode==0x81) {INST_NAME("LOCK AND Ed, Id");} else {INST_NAME("LOCK AND Ed, Ib");}
-                    SETFLAGS(X_ALL, SF_SET_PENDING);
                     if(MODREG) {
-                        if(opcode==0x81) i64 = F32S; else i64 = F8S;
-                        ed = TO_NAT((nextop & 7) + (rex.b << 3));
-                        MOV64xw(x5, i64);
-                        emit_and32(dyn, ninst, rex, ed, x5, x3, x4);
+                        INST_NAME("Invalid LOCK");
+                        UDF(0);
+                        *need_epilog = 1;
+                        *ok = 0;
                     } else {
+                        if(opcode==0x81) {INST_NAME("LOCK AND Ed, Id");} else {INST_NAME("LOCK AND Ed, Ib");}
+                        SETFLAGS(X_ALL, SF_SET_PENDING);
                         addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, (opcode==0x81)?4:1);
                         if(opcode==0x81) i64 = F32S; else i64 = F8S;
                         if(cpuext.atomics) {
@@ -1523,13 +1410,14 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     }
                     break;
                 case 5: //SUB
-                    if(opcode==0x81) {INST_NAME("LOCK SUB Ed, Id");} else {INST_NAME("LOCK SUB Ed, Ib");}
-                    SETFLAGS(X_ALL, SF_SET_PENDING);
                     if(MODREG) {
-                        if(opcode==0x81) i64 = F32S; else i64 = F8S;
-                        ed = TO_NAT((nextop & 7) + (rex.b << 3));
-                        emit_sub32c(dyn, ninst, rex, ed, i64, x3, x4, x5);
+                        INST_NAME("Invalid LOCK");
+                        UDF(0);
+                        *need_epilog = 1;
+                        *ok = 0;
                     } else {
+                        if(opcode==0x81) {INST_NAME("LOCK SUB Ed, Id");} else {INST_NAME("LOCK SUB Ed, Ib");}
+                        SETFLAGS(X_ALL, SF_SET_PENDING);
                         addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, (opcode==0x81)?4:1);
                         if(opcode==0x81) i64 = F32S; else i64 = F8S;
                         if((i64<=-0x1000) || (i64>=0x1000)) {
@@ -1604,14 +1492,14 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     }
                     break;
                 case 6: //XOR
-                    if(opcode==0x81) {INST_NAME("LOCK XOR Ed, Id");} else {INST_NAME("LOCK XOR Ed, Ib");}
-                    SETFLAGS(X_ALL, SF_SET_PENDING);
                     if(MODREG) {
-                        if(opcode==0x81) i64 = F32S; else i64 = F8S;
-                        ed = TO_NAT((nextop & 7) + (rex.b << 3));
-                        MOV64xw(x5, i64);
-                        emit_xor32(dyn, ninst, rex, ed, x5, x3, x4);
+                        INST_NAME("Invalid LOCK");
+                        UDF(0);
+                        *need_epilog = 1;
+                        *ok = 0;
                     } else {
+                        if(opcode==0x81) {INST_NAME("LOCK XOR Ed, Id");} else {INST_NAME("LOCK XOR Ed, Ib");}
+                        SETFLAGS(X_ALL, SF_SET_PENDING);
                         addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, (opcode==0x81)?4:1);
                         if(opcode==0x81) i64 = F32S; else i64 = F8S;
                         if(cpuext.atomics) {
@@ -1632,41 +1520,24 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     }
                     break;
                 case 7: //CMP
-                    if(opcode==0x81) {INST_NAME("(LOCK) CMP Ed, Id");} else {INST_NAME("(LOCK) CMP Ed, Ib");}
-                    SETFLAGS(X_ALL, SF_SET_PENDING);
-                    GETED((opcode==0x81)?4:1);
-                    // No need to LOCK, this is readonly
-                    if(opcode==0x81) i64 = F32S; else i64 = F8S;
-                    if(i64) {
-                        MOV64xw(x5, i64);
-                        emit_cmp32(dyn, ninst, rex, ed, x5, x3, x4, x6);
-                    } else {
-                        emit_cmp32_0(dyn, ninst, rex, ed, x3, x4);
-                    }
+                    INST_NAME("Invalid LOCK");
+                    UDF(0);
+                    *need_epilog = 1;
+                    *ok = 0;
                     break;
             }
             break;
 
         case 0x86:
-            INST_NAME("LOCK XCHG Eb, Gb");
-            // Do the swap
             nextop = F8;
             if(MODREG) {
-                GETGB(x4);
-                if(rex.rex) {
-                    ed = TO_NAT((nextop & 7) + (rex.b << 3));
-                    eb1 = ed;
-                    eb2 = 0;
-                } else {
-                    ed = (nextop&7);
-                    eb1 = TO_NAT(ed & 3);
-                    eb2 = ((ed&4)<<1);
-                }
-                UBFXw(x1, eb1, eb2, 8);
-                // do the swap 14 -> ed, 1 -> gd
-                BFIx(gb1, x1, gb2, 8);
-                BFIx(eb1, x4, eb2, 8);
+                INST_NAME("Invalid LOCK");
+                UDF(0);
+                *need_epilog = 1;
+                *ok = 0;
             } else {
+                INST_NAME("LOCK XCHG Eb, Gb");
+                // Do the swap
                 GETGB(x4);
                 addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 0);
                 if(cpuext.atomics) {
@@ -1683,15 +1554,14 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
             }
             break;
         case 0x87:
-            INST_NAME("LOCK XCHG Ed, Gd");
             nextop = F8;
             if(MODREG) {
-                GETGD;
-                GETED(0);
-                MOVxw_REG(x1, gd);
-                MOVxw_REG(gd, ed);
-                MOVxw_REG(ed, x1);
+                INST_NAME("Invalid LOCK");
+                UDF(0);
+                *need_epilog = 1;
+                *ok = 0;
             } else {
+                INST_NAME("LOCK XCHG Ed, Gd");
                 GETGD;
                 addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 0);
                 if(!ALIGNED_ATOMICxw) {
@@ -1740,19 +1610,19 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
             switch((nextop>>3)&7) {
                 case 0:
                 case 1:
-                    INST_NAME("LOCK TEST Eb, Ib");
-                    SETFLAGS(X_ALL, SF_SET_PENDING);
-                    GETEB(x1, 1);
-                    u8 = F8;
-                    emit_test8c(dyn, ninst, x1, u8, x3, x4, x5);
+                    INST_NAME("Invalid LOCK");
+                    UDF(0);
+                    *need_epilog = 1;
+                    *ok = 0;
                     break;
                 case 2:
-                    INST_NAME("LOCK NOT Eb");
                     if(MODREG) {
-                        GETEB(x1, 0);
-                        MVNw_REG(x1, x1);
-                        EBBACK;
+                        INST_NAME("Invalid LOCK");
+                        UDF(0);
+                        *need_epilog = 1;
+                        *ok = 0;
                     } else {
+                        INST_NAME("LOCK NOT Eb");
                         addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 0);
                         if(cpuext.atomics) {
                             MOV32w(x1, 0xff);
@@ -1774,12 +1644,13 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
             nextop = F8;
             switch((nextop>>3)&7) {
                 case 2:
-                    INST_NAME("LOCK NOT Ed");
                     if(MODREG) {
-                        GETED(x1);
-                        MVNw_REG(x1, x1);
-                        EBBACK;
+                        INST_NAME("Invalid LOCK");
+                        UDF(0);
+                        *need_epilog = 1;
+                        *ok = 0;
                     } else {
+                        INST_NAME("LOCK NOT Ed");
                         addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 0);
                         if(cpuext.atomics) {
                             MOV64x(x1, ~0LL);
@@ -1803,13 +1674,14 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
             switch((nextop>>3)&7)
             {
                 case 0: // INC Eb
-                    INST_NAME("LOCK INC Eb");
-                    SETFLAGS(X_ALL&~X_CF, SF_SUBSET);
                     if(MODREG) {
-                        GETEB(x1, 0);
-                        emit_inc8(dyn, ninst, x1, x2, x4);
-                        EBBACK;
+                        INST_NAME("Invalid LOCK");
+                        UDF(0);
+                        *need_epilog = 1;
+                        *ok = 0;
                     } else {
+                        INST_NAME("LOCK INC Eb");
+                        SETFLAGS(X_ALL&~X_CF, SF_SUBSET);
                         addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 0);
                         MARKLOCK;
                         if(cpuext.atomics) {
@@ -1829,13 +1701,14 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     }
                     break;
                 case 1: //DEC Eb
-                    INST_NAME("LOCK DEC Eb");
-                    SETFLAGS(X_ALL&~X_CF, SF_SUBSET);
                     if(MODREG) {
-                        GETEB(x1, 0);
-                        emit_dec8(dyn, ninst, x1, x2, x4);
-                        EBBACK;
+                        INST_NAME("Invalid LOCK");
+                        UDF(0);
+                        *need_epilog = 1;
+                        *ok = 0;
                     } else {
+                        INST_NAME("LOCK DEC Eb");
+                        SETFLAGS(X_ALL&~X_CF, SF_SUBSET);
                         addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 0);
                         if(cpuext.atomics) {
                             MOV32w(x3, -1);
@@ -1863,12 +1736,14 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
             switch((nextop>>3)&7)
             {
                 case 0: // INC Ed
-                    INST_NAME("LOCK INC Ed");
-                    SETFLAGS(X_ALL&~X_CF, SF_SUBSET);
                     if(MODREG) {
-                        ed = TO_NAT((nextop & 7) + (rex.b << 3));
-                        emit_inc32(dyn, ninst, rex, ed, x3, x4);
+                        INST_NAME("Invalid LOCK");
+                        UDF(0);
+                        *need_epilog = 1;
+                        *ok = 0;
                     } else {
+                        INST_NAME("LOCK INC Ed");
+                        SETFLAGS(X_ALL&~X_CF, SF_SUBSET);
                         addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 0);
                         if(!ALIGNED_ATOMICxw) {
                             if(cpuext.uscat) {
@@ -1917,12 +1792,14 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     }
                     break;
                 case 1: //DEC Ed
-                    INST_NAME("LOCK DEC Ed");
-                    SETFLAGS(X_ALL&~X_CF, SF_SUBSET);
                     if(MODREG) {
-                        ed = TO_NAT((nextop & 7) + (rex.b << 3));
-                        emit_dec32(dyn, ninst, rex, ed, x3, x4);
+                        INST_NAME("Invalid LOCK");
+                        UDF(0);
+                        *need_epilog = 1;
+                        *ok = 0;
                     } else {
+                        INST_NAME("LOCK DEC Ed");
+                        SETFLAGS(X_ALL&~X_CF, SF_SUBSET);
                         addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 0);
                         if(!ALIGNED_ATOMICxw) {
                             if(cpuext.uscat) {
@@ -1971,7 +1848,11 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     }
                     break;
                 default:
-                    DEFAULT;
+                    INST_NAME("Invalid LOCK");
+                    UDF(0);
+                    *need_epilog = 1;
+                    *ok = 0;
+                    break;
             }
             break;