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