about summary refs log tree commit diff stats
path: root/src/dynarec/arm64/dynarec_arm64_f0.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/dynarec/arm64/dynarec_arm64_f0.c')
-rw-r--r--src/dynarec/arm64/dynarec_arm64_f0.c927
1 files changed, 404 insertions, 523 deletions
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;