diff options
Diffstat (limited to 'src/dynarec/arm64/dynarec_arm64_f0.c')
| -rw-r--r-- | src/dynarec/arm64/dynarec_arm64_f0.c | 927 |
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; |