diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2025-10-14 09:23:15 +0200 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2025-10-14 09:23:15 +0200 |
| commit | f5a64f93b60b98a7e76af9c8e85fc81e6ef109b4 (patch) | |
| tree | b8d1763c9ac3a1d2809307e10d00cbcb462c8baf | |
| parent | 6732546e605c6ce6cd088ee0b61fdc1960a440fa (diff) | |
| download | box64-f5a64f93b60b98a7e76af9c8e85fc81e6ef109b4.tar.gz box64-f5a64f93b60b98a7e76af9c8e85fc81e6ef109b4.zip | |
[ARM64_DYNAREC] Better handling for invalid opcodes
| -rw-r--r-- | src/dynarec/arm64/dynarec_arm64_00.c | 223 | ||||
| -rw-r--r-- | src/dynarec/arm64/dynarec_arm64_64.c | 129 | ||||
| -rw-r--r-- | src/dynarec/arm64/dynarec_arm64_66.c | 91 | ||||
| -rw-r--r-- | src/dynarec/arm64/dynarec_arm64_66f0.c | 247 | ||||
| -rw-r--r-- | src/dynarec/arm64/dynarec_arm64_67.c | 80 | ||||
| -rw-r--r-- | src/dynarec/arm64/dynarec_arm64_6764_32.c | 26 | ||||
| -rw-r--r-- | src/dynarec/arm64/dynarec_arm64_f0.c | 927 |
7 files changed, 842 insertions, 881 deletions
diff --git a/src/dynarec/arm64/dynarec_arm64_00.c b/src/dynarec/arm64/dynarec_arm64_00.c index bcf25b21..4b150f03 100644 --- a/src/dynarec/arm64/dynarec_arm64_00.c +++ b/src/dynarec/arm64/dynarec_arm64_00.c @@ -952,17 +952,17 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin } break; case 0x62: - INST_NAME("BOUND Gd, Ed"); nextop = F8; - if(rex.is32bits && MODREG) { + if(rex.is32bits && !MODREG) { + INST_NAME("BOUND Gd, Ed"); addr = geted(dyn, addr, ninst, nextop, &wback, x1, &fixedaddress, NULL, 0, 0, rex, NULL, 0, 0); LDRxw_U12(x2, wback, 0); - LDRxw_U12(x3, wback, 4+(rex.w*4)); + LDRxw_U12(x3, wback, 4); GETGD; GETIP(ip); - CMPSxw_REG(gd, x2); + CMPSw_REG(gd, x2); B_MARK(cLT); - CMPSxw_REG(gd, x3); + CMPSw_REG(gd, x3); B_MARK(cGT); B_NEXT_nocond; MARK; @@ -970,17 +970,15 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin CALL_S(const_native_br, -1); LOAD_XEMU_CALL(xRIP); } else { + INST_NAME("Illegal 62"); if(BOX64DRENV(dynarec_safeflags)>1) { READFLAGS(X_PEND); } else { SETFLAGS(X_ALL, SF_SET_NODF); // Hack to set flags in "don't care" state } GETIP(ip); - STORE_XEMU_CALL(xRIP); - CALL_S(const_native_ud, -1); - LOAD_XEMU_CALL(xRIP); - jump_to_epilog(dyn, 0, xRIP, ninst); - *need_epilog = 0; + UDF(0); + *need_epilog = 1; *ok = 0; } break; @@ -1234,8 +1232,11 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin case 0x82: if(!rex.is32bits) { - DEFAULT; - return ip; + INST_NAME("Invalid 82"); + UDF(0); + *need_epilog = 1; + *ok = 0; + return addr; } // fallthru case 0x80: @@ -1635,18 +1636,25 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin } break; case 0x8C: - INST_NAME("MOV Ed, Seg"); nextop=F8; u8 = (nextop&0x38)>>3; - if (MODREG) { - gd = TO_NAT((nextop & 7) + (rex.b << 3)); - LDRH_U12(gd, xEmu, offsetof(x64emu_t, segs[u8])); - UXTHw(gd, gd); + if(u8>5) { + INST_NAME("Invalid MOV Ed, Seg"); + UDF(0); + *need_epilog = 1; + *ok = 0; } else { - LDRH_U12(x3, xEmu, offsetof(x64emu_t, segs[u8])); - addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, &unscaled, 0xfff<<1, 1, rex, NULL, 0, 0); - STH(x3, wback, fixedaddress); - SMWRITE2(); + INST_NAME("MOV Ed, Seg"); + if (MODREG) { + gd = TO_NAT((nextop & 7) + (rex.b << 3)); + LDRH_U12(gd, xEmu, offsetof(x64emu_t, segs[u8])); + UXTHw(gd, gd); + } else { + LDRH_U12(x3, xEmu, offsetof(x64emu_t, segs[u8])); + addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, &unscaled, 0xfff<<1, 1, rex, NULL, 0, 0); + STH(x3, wback, fixedaddress); + SMWRITE2(); + } } break; case 0x8D: @@ -1666,31 +1674,50 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin } break; case 0x8E: - INST_NAME("MOV Seg,Ew"); nextop = F8; u8 = (nextop&0x38)>>3; - if (MODREG) { - ed = TO_NAT((nextop & 7) + (rex.b << 3)); + if((u8>5) || (u8==1)) { + INST_NAME("Invalid MOV Seg,Ed"); + UDF(0); + *need_epilog = 1; + *ok = 0; } else { - SMREAD(); - addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, &unscaled, 0xfff<<1, 1, rex, NULL, 0, 0); - LDH(x1, wback, fixedaddress); - ed = x1; + INST_NAME("MOV Seg,Ed"); + if (MODREG) { + ed = TO_NAT((nextop & 7) + (rex.b << 3)); + } else { + SMREAD(); + addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, &unscaled, 0xfff<<1, 1, rex, NULL, 0, 0); + LDH(x1, wback, fixedaddress); + ed = x1; + } + STRH_U12(ed, xEmu, offsetof(x64emu_t, segs[u8])); + STRw_U12(wZR, xEmu, offsetof(x64emu_t, segs_serial[u8])); } - STRH_U12(ed, xEmu, offsetof(x64emu_t, segs[u8])); - STRw_U12(wZR, xEmu, offsetof(x64emu_t, segs_serial[u8])); break; case 0x8F: - INST_NAME("POP Ed"); nextop = F8; - SMREAD(); - if(MODREG) { - POP1z(TO_NAT((nextop & 7) + (rex.b << 3))); - } else { - POP1z(x2); // so this can handle POP [ESP] and maybe some variant too - addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, &unscaled, 0xfff<<(2+rex.is32bits), (1<<(2+rex.is32bits))-1, rex, NULL, 0, 0); - STz(x2, ed, fixedaddress); - SMWRITE(); + switch((nextop>>3)&7) { + case 0: + INST_NAME("POP Ed"); + SMREAD(); + if(MODREG) { + POP1z(TO_NAT((nextop & 7) + (rex.b << 3))); + } else { + POP1z(x2); // so this can handle POP [ESP] and maybe some variant too + addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, &unscaled, 0xfff<<(2+rex.is32bits), (1<<(2+rex.is32bits))-1, rex, NULL, 0, 0); + STz(x2, ed, fixedaddress); + SMWRITE(); + } + break; + case 3: + INST_NAME("Invalid 8F /3"); + UDF(0); + *need_epilog = 1; + *ok = 0; + break; + default: + DEFAULT; } break; case 0x90: @@ -2598,65 +2625,77 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin } break; case 0xC6: - INST_NAME("MOV Eb, Ib"); nextop=F8; - if(MODREG) { // reg <= u8 - u8 = F8; - if(!rex.rex) { - ed = (nextop&7); - eb1 = TO_NAT(ed & 3); // Ax, Cx, Dx or Bx - eb2 = (ed&4)>>2; // L or H - } else { - eb1 = TO_NAT((nextop & 7) + (rex.b << 3)); - eb2 = 0; - } - MOV32w(x3, u8); - BFIx(eb1, x3, eb2*8, 8); - } else { // mem <= u8 - addr = geted(dyn, addr, ninst, nextop, &wback, x1, &fixedaddress, &unscaled, 0xfff, 0, rex, &lock, 0, 1); - u8 = F8; - if(u8) { - MOV32w(x3, u8); - ed = x3; - } else - ed = xZR; - STB(ed, wback, fixedaddress); - SMWRITELOCK(lock); + switch((nextop>>3)&7) { + case 0: + INST_NAME("MOV Eb, Ib"); + if(MODREG) { // reg <= u8 + u8 = F8; + if(!rex.rex) { + ed = (nextop&7); + eb1 = TO_NAT(ed & 3); // Ax, Cx, Dx or Bx + eb2 = (ed&4)>>2; // L or H + } else { + eb1 = TO_NAT((nextop & 7) + (rex.b << 3)); + eb2 = 0; + } + MOV32w(x3, u8); + BFIx(eb1, x3, eb2*8, 8); + } else { // mem <= u8 + addr = geted(dyn, addr, ninst, nextop, &wback, x1, &fixedaddress, &unscaled, 0xfff, 0, rex, &lock, 0, 1); + u8 = F8; + if(u8) { + MOV32w(x3, u8); + ed = x3; + } else + ed = xZR; + STB(ed, wback, fixedaddress); + SMWRITELOCK(lock); + } + break; + default: + DEFAULT; } break; case 0xC7: - INST_NAME("MOV Ed, Id"); nextop=F8; - if(MODREG) { // reg <= i32 - i64 = F32S; - ed = TO_NAT((nextop & 7) + (rex.b << 3)); - MOV64xw(ed, i64); - } else { // mem <= i32 - IF_UNALIGNED(ip) { - MESSAGE(LOG_DEBUG, "\tUnaligned path"); - addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, &lock, 0, 4); - i64 = F32S; - if(i64) { - MOV64xw(x3, i64); - ed = x3; - } else - ed = xZR; - for(int i=0; i<(1<<(2+rex.w)); ++i) { - STURB_I9(ed, wback, i); - if(ed!=xZR) - RORxw(ed, ed, 8); + switch((nextop>>3)&7) { + case 0: + INST_NAME("MOV Ed, Id"); + if(MODREG) { // reg <= i32 + i64 = F32S; + ed = TO_NAT((nextop & 7) + (rex.b << 3)); + MOV64xw(ed, i64); + } else { // mem <= i32 + IF_UNALIGNED(ip) { + MESSAGE(LOG_DEBUG, "\tUnaligned path"); + addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, &lock, 0, 4); + i64 = F32S; + if(i64) { + MOV64xw(x3, i64); + ed = x3; + } else + ed = xZR; + for(int i=0; i<(1<<(2+rex.w)); ++i) { + STURB_I9(ed, wback, i); + if(ed!=xZR) + RORxw(ed, ed, 8); + } + } else { + addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, &unscaled, 0xfff<<(2+rex.w), (1<<(2+rex.w))-1, rex, &lock, 0, 4); + i64 = F32S; + if(i64) { + MOV64xw(x3, i64); + ed = x3; + } else + ed = xZR; + STxw(ed, wback, fixedaddress); + } + SMWRITELOCK(lock); } - } else { - addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, &unscaled, 0xfff<<(2+rex.w), (1<<(2+rex.w))-1, rex, &lock, 0, 4); - i64 = F32S; - if(i64) { - MOV64xw(x3, i64); - ed = x3; - } else - ed = xZR; - STxw(ed, wback, fixedaddress); - } - SMWRITELOCK(lock); + break; + default: + DEFAULT; } break; case 0xC8: diff --git a/src/dynarec/arm64/dynarec_arm64_64.c b/src/dynarec/arm64/dynarec_arm64_64.c index 494accda..a00edf07 100644 --- a/src/dynarec/arm64/dynarec_arm64_64.c +++ b/src/dynarec/arm64/dynarec_arm64_64.c @@ -991,34 +991,47 @@ uintptr_t dynarec64_64(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin nextop = F8; grab_segdata(dyn, addr, ninst, x4, seg, (MODREG)); u8 = (nextop&0x38)>>3; - if (MODREG) { - ed = TO_NAT((nextop & 7) + (rex.b << 3)); + if((u8>5) || (u8==1)) { + INST_NAME("Invalid MOV Seg,Ew"); + UDF(0); + *need_epilog = 1; + *ok = 0; } else { - SMREAD(); - addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, NULL, 0, 0); - LDRH_REGz(x1, x4, wback); - ed = x1; + if (MODREG) { + ed = TO_NAT((nextop & 7) + (rex.b << 3)); + } else { + SMREAD(); + addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, NULL, 0, 0); + LDRH_REGz(x1, x4, wback); + ed = x1; + } + STRH_U12(ed, xEmu, offsetof(x64emu_t, segs[u8])); + STRw_U12(wZR, xEmu, offsetof(x64emu_t, segs_serial[u8])); } - STRH_U12(ed, xEmu, offsetof(x64emu_t, segs[u8])); - STRw_U12(wZR, xEmu, offsetof(x64emu_t, segs_serial[u8])); break; case 0x8F: - INST_NAME("POP FS:Ed"); nextop = F8; grab_segdata(dyn, addr, ninst, x4, seg, (MODREG)); - if(MODREG) { - POP1z(TO_NAT((nextop & 7) + (rex.b << 3))); - } else { - POP1z(x2); // so this can handle POP [ESP] and maybe some variant too - addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, &unscaled, 0, 0, rex, NULL, 0, 0); - if(ed==xRSP) { - STRz_REGz(x2, x4, ed); - } else { - // complicated to just allow a segfault that can be recovered correctly - SUBz_U12(xRSP, xRSP, rex.is32bits?4:8); - STRz_REGz(x2, x4, ed); - ADDz_U12(xRSP, xRSP, rex.is32bits?4:8); - } + switch((nextop>>3)&7) { + case 0: + INST_NAME("POP FS:Ed"); + if(MODREG) { + POP1z(TO_NAT((nextop & 7) + (rex.b << 3))); + } else { + POP1z(x2); // so this can handle POP [ESP] and maybe some variant too + addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, &unscaled, 0, 0, rex, NULL, 0, 0); + if(ed==xRSP) { + STRz_REGz(x2, x4, ed); + } else { + // complicated to just allow a segfault that can be recovered correctly + SUBz_U12(xRSP, xRSP, rex.is32bits?4:8); + STRz_REGz(x2, x4, ed); + ADDz_U12(xRSP, xRSP, rex.is32bits?4:8); + } + } + break; + default: + DEFAULT; } break; case 0x90: @@ -1083,43 +1096,55 @@ uintptr_t dynarec64_64(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin break; case 0xC6: - INST_NAME("MOV Seg:Eb, Ib"); nextop=F8; grab_segdata(dyn, addr, ninst, x4, seg, (MODREG)); - if(MODREG) { // reg <= u8 - u8 = F8; - if(!rex.rex) { - ed = (nextop&7); - eb1 = TO_NAT(ed & 3); // Ax, Cx, Dx or Bx - eb2 = (ed&4)>>2; // L or H - } else { - eb1 = TO_NAT((nextop & 7) + (rex.b << 3)); - eb2 = 0; - } - MOV32w(x3, u8); - BFIx(eb1, x3, eb2*8, 8); - } else { // mem <= u8 - addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, NULL, 0, 0, rex, NULL, 0, 1); - u8 = F8; - MOV32w(x3, u8); - STRB_REGz(x3, x4, ed); - SMWRITE2(); + switch((nextop>>3)&7) { + case 0: + INST_NAME("MOV Seg:Eb, Ib"); + if(MODREG) { // reg <= u8 + u8 = F8; + if(!rex.rex) { + ed = (nextop&7); + eb1 = TO_NAT(ed & 3); // Ax, Cx, Dx or Bx + eb2 = (ed&4)>>2; // L or H + } else { + eb1 = TO_NAT((nextop & 7) + (rex.b << 3)); + eb2 = 0; + } + MOV32w(x3, u8); + BFIx(eb1, x3, eb2*8, 8); + } else { // mem <= u8 + addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, NULL, 0, 0, rex, NULL, 0, 1); + u8 = F8; + MOV32w(x3, u8); + STRB_REGz(x3, x4, ed); + SMWRITE2(); + } + break; + default: + DEFAULT; } break; case 0xC7: - INST_NAME("MOV Seg:Ed, Id"); nextop=F8; grab_segdata(dyn, addr, ninst, x4, seg, (MODREG)); - if(MODREG) { // reg <= i32 - i64 = F32S; - ed = TO_NAT((nextop & 7) + (rex.b << 3)); - MOV64xw(ed, i64); - } else { // mem <= i32 - addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, NULL, 0, 0, rex, NULL, 0, 4); - i64 = F32S; - MOV64xw(x3, i64); - STRxw_REGz(x3, x4, ed); - SMWRITE2(); + switch((nextop>>3)&7) { + case 0: + INST_NAME("MOV Seg:Ed, Id"); + if(MODREG) { // reg <= i32 + i64 = F32S; + ed = TO_NAT((nextop & 7) + (rex.b << 3)); + MOV64xw(ed, i64); + } else { // mem <= i32 + addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, NULL, 0, 0, rex, NULL, 0, 4); + i64 = F32S; + MOV64xw(x3, i64); + STRxw_REGz(x3, x4, ed); + SMWRITE2(); + } + break; + default: + DEFAULT; } break; diff --git a/src/dynarec/arm64/dynarec_arm64_66.c b/src/dynarec/arm64/dynarec_arm64_66.c index 1e1daeaf..c26e0f0d 100644 --- a/src/dynarec/arm64/dynarec_arm64_66.c +++ b/src/dynarec/arm64/dynarec_arm64_66.c @@ -717,28 +717,41 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin INST_NAME("MOV Seg,Ew"); nextop = F8; u8 = (nextop&0x38)>>3; - if (MODREG) { - ed = TO_NAT((nextop & 7) + (rex.b << 3)); + if((u8>5) || (u8==1)) { + INST_NAME("Invalid MOV Seg,Ew"); + UDF(0); + *need_epilog = 1; + *ok = 0; } else { - SMREAD(); - addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, &unscaled, 0xfff<<1, 1, rex, NULL, 0, 0); - LDH(x1, wback, fixedaddress); - ed = x1; + if (MODREG) { + ed = TO_NAT((nextop & 7) + (rex.b << 3)); + } else { + SMREAD(); + addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, &unscaled, 0xfff<<1, 1, rex, NULL, 0, 0); + LDH(x1, wback, fixedaddress); + ed = x1; + } + STRH_U12(ed, xEmu, offsetof(x64emu_t, segs[u8])); + STRw_U12(wZR, xEmu, offsetof(x64emu_t, segs_serial[u8])); } - STRH_U12(ed, xEmu, offsetof(x64emu_t, segs[u8])); - STRw_U12(wZR, xEmu, offsetof(x64emu_t, segs_serial[u8])); break; case 0x8F: - INST_NAME("POP Ew"); nextop = F8; - POP1_16(x1); - if (MODREG) { - wback = TO_NAT((nextop & 7) + (rex.b << 3)); - BFIz(wback, x1, 0, 16); - } else { - SMREAD(); - addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, &unscaled, 0xfff<<1, 1, rex, NULL, 0, 0); - STH(x1, wback, fixedaddress); + switch((nextop>>3)&7) { + case 0: + INST_NAME("POP Ew"); + POP1_16(x1); + if (MODREG) { + wback = TO_NAT((nextop & 7) + (rex.b << 3)); + BFIz(wback, x1, 0, 16); + } else { + SMREAD(); + addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, &unscaled, 0xfff<<1, 1, rex, NULL, 0, 0); + STH(x1, wback, fixedaddress); + } + break; + default: + DEFAULT; } break; case 0x90: @@ -1174,26 +1187,32 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin break; case 0xC7: - INST_NAME("MOV Ew, Iw"); nextop = F8; - if(MODREG) { - ed = TO_NAT((nextop & 7) + (rex.b << 3)); - u16 = F16; - if(u16) { - MOV32w(x1, u16); - BFIz(ed, x1, 0, 16); - } else - BFCz(ed, 0, 16); - } else { - addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, &unscaled, 0xfff<<1, 1, rex, &lock, 0, 2); - u16 = F16; - if(u16) { - MOV32w(x1, u16); - STH(x1, ed, fixedaddress); - } else { - STH(xZR, ed, fixedaddress); - } - SMWRITELOCK(lock); + switch((nextop>>3)&7) { + case 0: + INST_NAME("MOV Ew, Iw"); + if(MODREG) { + ed = TO_NAT((nextop & 7) + (rex.b << 3)); + u16 = F16; + if(u16) { + MOV32w(x1, u16); + BFIz(ed, x1, 0, 16); + } else + BFCz(ed, 0, 16); + } else { + addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, &unscaled, 0xfff<<1, 1, rex, &lock, 0, 2); + u16 = F16; + if(u16) { + MOV32w(x1, u16); + STH(x1, ed, fixedaddress); + } else { + STH(xZR, ed, fixedaddress); + } + SMWRITELOCK(lock); + } + break; + default: + DEFAULT; } break; diff --git a/src/dynarec/arm64/dynarec_arm64_66f0.c b/src/dynarec/arm64/dynarec_arm64_66f0.c index 9516216c..4851c69b 100644 --- a/src/dynarec/arm64/dynarec_arm64_66f0.c +++ b/src/dynarec/arm64/dynarec_arm64_66f0.c @@ -49,16 +49,16 @@ uintptr_t dynarec64_66F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n switch(opcode) { case 0x01: - INST_NAME("LOCK ADD Ew, Gw"); - SETFLAGS(X_ALL, SF_SET_PENDING); nextop = F8; - GETGW(x5); if(MODREG) { - ed = TO_NAT((nextop & 7) + (rex.b << 3)); - UXTHw(x6, ed); - emit_add16(dyn, ninst, x6, x5, x3, x4); - BFIx(ed, x6, 0, 16); + INST_NAME("Invalid LOCK"); + UDF(0); + *need_epilog = 1; + *ok = 0; } else { + INST_NAME("LOCK ADD Ew, Gw"); + SETFLAGS(X_ALL, SF_SET_PENDING); + GETGW(x5); addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 0); if(cpuext.atomics) { UFLAG_IF { @@ -78,16 +78,16 @@ uintptr_t dynarec64_66F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n break; case 0x09: - INST_NAME("LOCK OR Ew, Gw"); - SETFLAGS(X_ALL, SF_SET_PENDING); nextop = F8; - GETGW(x5); if(MODREG) { - ed = TO_NAT((nextop & 7) + (rex.b << 3)); - UXTHw(x6, ed); - emit_or16(dyn, ninst, x6, x5, x3, x4); - BFIx(ed, x6, 0, 16); + INST_NAME("Invalid LOCK"); + UDF(0); + *need_epilog = 1; + *ok = 0; } else { + INST_NAME("LOCK OR Ew, Gw"); + SETFLAGS(X_ALL, SF_SET_PENDING); + GETGW(x5); addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 0); if(cpuext.atomics) { UFLAG_IF { @@ -111,19 +111,17 @@ uintptr_t dynarec64_66F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n switch(opcode) { case 0xB1: - INST_NAME("LOCK CMPXCHG Ew, Gw"); - SETFLAGS(X_ALL, SF_SET_PENDING); nextop = F8; - GETGD; - UXTHw(x6, xRAX); if(MODREG) { - ed = TO_NAT((nextop & 7) + (rex.b << 3)); - wback = 0; - UXTHw(x1, ed); - CMPSxw_REG(x6, x1); - B_MARK(cNE); - BFIx(ed, gd, 0, 16); + INST_NAME("Invalid LOCK"); + UDF(0); + *need_epilog = 1; + *ok = 0; } else { + INST_NAME("LOCK CMPXCHG Ew, Gw"); + SETFLAGS(X_ALL, SF_SET_PENDING); + GETGD; + UXTHw(x6, xRAX); addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 0); if(!ALIGNED_ATOMICH) { if(cpuext.uscat) { @@ -164,25 +162,25 @@ uintptr_t dynarec64_66F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n CBNZx_MARK3(x4); STRH_U12(gd, wback, 0); } + MARK; + // Common part (and fallback for EAX != Ed) + UFLAG_IF {emit_cmp16(dyn, ninst, x6, x1, x3, x4, x5);} + BFIx(xRAX, x1, 0, 16); } - MARK; - // Common part (and fallback for EAX != Ed) - UFLAG_IF {emit_cmp16(dyn, ninst, x6, x1, x3, x4, x5);} - BFIx(xRAX, x1, 0, 16); break; case 0xC1: - INST_NAME("LOCK XADD Gw, Ew"); - SETFLAGS(X_ALL, SF_SET_PENDING); nextop = F8; - gd = TO_NAT(((nextop & 0x38) >> 3) + (rex.r << 3)); - UXTHx(x5, gd); if(MODREG) { - ed = TO_NAT((nextop & 7) + (rex.b << 3)); - BFIx(gd, ed, 0, 16); - emit_add16(dyn, ninst, x5, gd, x3, x4); - BFIx(ed, x5, 0, 16); + INST_NAME("Invalid LOCK"); + UDF(0); + *need_epilog = 1; + *ok = 0; } else { + INST_NAME("LOCK XADD Gw, Ew"); + SETFLAGS(X_ALL, SF_SET_PENDING); + gd = TO_NAT(((nextop & 0x38) >> 3) + (rex.r << 3)); + UXTHx(x5, gd); addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 0); if(cpuext.atomics) { LDADDALH(x5, x1, wback); @@ -207,17 +205,17 @@ uintptr_t dynarec64_66F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n break; case 0x11: - INST_NAME("LOCK ADC Ew, Gw"); - READFLAGS(X_CF); - SETFLAGS(X_ALL, SF_SET_PENDING); nextop = F8; - GETGW(x5); if(MODREG) { - ed = TO_NAT((nextop & 7) + (rex.b << 3)); - UXTHw(x6, ed); - emit_adc16(dyn, ninst, x6, x5, x3, x4); - BFIx(ed, x6, 0, 16); + INST_NAME("Invalid LOCK"); + UDF(0); + *need_epilog = 1; + *ok = 0; } else { + INST_NAME("LOCK ADC Ew, Gw"); + READFLAGS(X_CF); + SETFLAGS(X_ALL, SF_SET_PENDING); + GETGW(x5); addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 0); MARKLOCK; LDAXRH(x1, wback); @@ -228,16 +226,16 @@ uintptr_t dynarec64_66F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n break; case 0x21: - INST_NAME("LOCK AND Ew, Gw"); - SETFLAGS(X_ALL, SF_SET_PENDING); nextop = F8; - GETGW(x5); if(MODREG) { - ed = TO_NAT((nextop & 7) + (rex.b << 3)); - UXTHw(x6, ed); - emit_and16(dyn, ninst, x6, gd, x3, x4); - BFIx(ed, x6, 0, 16); + INST_NAME("Invalid LOCK"); + UDF(0); + *need_epilog = 1; + *ok = 0; } else { + INST_NAME("LOCK AND Ew, Gw"); + SETFLAGS(X_ALL, SF_SET_PENDING); + GETGW(x5); addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 0); if(cpuext.atomics) { MVNw_REG(x3, gd); @@ -262,20 +260,18 @@ uintptr_t dynarec64_66F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n nextop = F8; switch((nextop>>3)&7) { case 0: //ADD - if(opcode==0x81) { - INST_NAME("LOCK ADD Ew, Iw"); - } else { - INST_NAME("LOCK ADD Ew, Ib"); - } - SETFLAGS(X_ALL, SF_SET_PENDING); if(MODREG) { - if(opcode==0x81) i16 = F16S; else i16 = F8S; - ed = TO_NAT((nextop & 7) + (rex.b << 3)); - MOV32w(x5, i16); - UXTHw(x6, ed); - emit_add16(dyn, ninst, x6, x5, x3, x4); - BFIx(ed, x6, 0, 16); + INST_NAME("Invalid LOCK"); + UDF(0); + *need_epilog = 1; + *ok = 0; } else { + if(opcode==0x81) { + INST_NAME("LOCK ADD Ew, Iw"); + } else { + INST_NAME("LOCK ADD Ew, Ib"); + } + SETFLAGS(X_ALL, SF_SET_PENDING); addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, (opcode==0x81)?2:1); if(opcode==0x81) i16 = F16S; else i16 = F8S; MOV32w(x5, i16); @@ -321,15 +317,14 @@ uintptr_t dynarec64_66F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n } break; case 1: //OR - if(opcode==0x81) {INST_NAME("LOCK OR Ew, Iw");} else {INST_NAME("LOCK OR Ew, Ib");} - SETFLAGS(X_ALL, SF_SET_PENDING); if(MODREG) { - if(opcode==0x81) i16 = F16S; else i16 = F8S; - ed = TO_NAT((nextop & 7) + (rex.b << 3)); - UXTHw(x6, ed); - emit_or16c(dyn, ninst, x6, i16, x3, x4); - BFIx(ed, x6, 0, 16); + INST_NAME("Invalid LOCK"); + UDF(0); + *need_epilog = 1; + *ok = 0; } else { + if(opcode==0x81) {INST_NAME("LOCK OR Ew, Iw");} else {INST_NAME("LOCK OR Ew, Ib");} + SETFLAGS(X_ALL, SF_SET_PENDING); addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, (opcode==0x81)?2:1); if(opcode==0x81) i16 = F16S; else i16 = F8S; if(!i64) {MOV32w(x5, i16);} @@ -356,17 +351,15 @@ uintptr_t dynarec64_66F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n } break; case 2: //ADC - if(opcode==0x81) {INST_NAME("LOCK ADC Ew, Iw");} else {INST_NAME("LOCK ADC Ew, Ib");} - READFLAGS(X_CF); - SETFLAGS(X_ALL, SF_SET_PENDING); if(MODREG) { - if(opcode==0x81) i16 = F16S; else i16 = F8S; - ed = TO_NAT((nextop & 7) + (rex.b << 3)); - MOV32w(x5, i16); - UXTHw(x6, ed); - emit_adc16(dyn, ninst, x6, x5, x3, x4); - BFIx(ed, x6, 0, 16); + INST_NAME("Invalid LOCK"); + UDF(0); + *need_epilog = 1; + *ok = 0; } else { + if(opcode==0x81) {INST_NAME("LOCK ADC Ew, Iw");} else {INST_NAME("LOCK ADC Ew, Ib");} + READFLAGS(X_CF); + SETFLAGS(X_ALL, SF_SET_PENDING); addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, (opcode==0x81)?2:1); if(opcode==0x81) i16 = F16S; else i16 = F8S; MOV32w(x5, i16); @@ -378,17 +371,15 @@ uintptr_t dynarec64_66F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n } break; case 3: //SBB - if(opcode==0x81) {INST_NAME("LOCK SBB Ew, Iw");} else {INST_NAME("LOCK SBB Ew, Ib");} - READFLAGS(X_CF); - SETFLAGS(X_ALL, SF_SET_PENDING); if(MODREG) { - if(opcode==0x81) i16 = F16S; else i16 = F8S; - ed = TO_NAT((nextop & 7) + (rex.b << 3)); - MOV32w(x5, i16); - UXTHw(x6, ed); - emit_sbb16(dyn, ninst, x6, x5, x3, x4); - BFIx(ed, x6, 0, 16); + INST_NAME("Invalid LOCK"); + UDF(0); + *need_epilog = 1; + *ok = 0; } else { + if(opcode==0x81) {INST_NAME("LOCK SBB Ew, Iw");} else {INST_NAME("LOCK SBB Ew, Ib");} + READFLAGS(X_CF); + SETFLAGS(X_ALL, SF_SET_PENDING); addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, (opcode==0x81)?2:1); if(opcode==0x81) i16 = F16S; else i16 = F8S; MOV32w(x5, i16); @@ -400,15 +391,14 @@ uintptr_t dynarec64_66F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n } break; case 4: //AND - if(opcode==0x81) {INST_NAME("LOCK AND Ew, Iw");} else {INST_NAME("LOCK AND Ew, Ib");} - SETFLAGS(X_ALL, SF_SET_PENDING); if(MODREG) { - if(opcode==0x81) i16 = F16S; else i16 = F8S; - ed = TO_NAT((nextop & 7) + (rex.b << 3)); - UXTHw(x6, ed); - emit_and16c(dyn, ninst, x6, i16, x3, x4); - BFIx(ed, x6, 0, 16); + INST_NAME("Invalid LOCK"); + UDF(0); + *need_epilog = 1; + *ok = 0; } else { + if(opcode==0x81) {INST_NAME("LOCK AND Ew, Iw");} else {INST_NAME("LOCK AND Ew, Ib");} + SETFLAGS(X_ALL, SF_SET_PENDING); addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, (opcode==0x81)?2:1); if(opcode==0x81) i16 = F16S; else i16 = F8S; i64 = convert_bitmask_w(i16); @@ -440,16 +430,14 @@ uintptr_t dynarec64_66F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n } break; case 5: //SUB - if(opcode==0x81) {INST_NAME("LOCK SUB Ew, Iw");} else {INST_NAME("LOCK SUB Ew, Ib");} - SETFLAGS(X_ALL, SF_SET_PENDING); if(MODREG) { - if(opcode==0x81) i16 = F16S; else i16 = F8S; - ed = TO_NAT((nextop & 7) + (rex.b << 3)); - MOV32w(x5, i16); - UXTHw(x6, ed); - emit_sub16(dyn, ninst, x6, x5, x3, x4); - BFIx(ed, x6, 0, 16); + INST_NAME("Invalid LOCK"); + UDF(0); + *need_epilog = 1; + *ok = 0; } else { + if(opcode==0x81) {INST_NAME("LOCK SUB Ew, Iw");} else {INST_NAME("LOCK SUB Ew, Ib");} + SETFLAGS(X_ALL, SF_SET_PENDING); addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, (opcode==0x81)?2:1); if(opcode==0x81) i16 = F16S; else i16 = F8S; MOV32w(x5, i16); @@ -496,15 +484,14 @@ uintptr_t dynarec64_66F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n } break; case 6: //XOR - if(opcode==0x81) {INST_NAME("LOCK XOR Ew, Iw");} else {INST_NAME("LOCK XOR Ew, Ib");} - SETFLAGS(X_ALL, SF_SET_PENDING); if(MODREG) { - if(opcode==0x81) i16 = F16S; else i16 = F8S; - ed = TO_NAT((nextop & 7) + (rex.b << 3)); - UXTHw(x6, ed); - emit_xor16c(dyn, ninst, x6, i16, x3, x4); - BFIx(ed, x6, 0, 16); + INST_NAME("Invalid LOCK"); + UDF(0); + *need_epilog = 1; + *ok = 0; } else { + if(opcode==0x81) {INST_NAME("LOCK XOR Ew, Iw");} else {INST_NAME("LOCK XOR Ew, Ib");} + SETFLAGS(X_ALL, SF_SET_PENDING); addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, (opcode==0x81)?2:1); if(opcode==0x81) i16 = F16S; else i16 = F8S; i64 = convert_bitmask_w(i16); @@ -529,18 +516,10 @@ uintptr_t dynarec64_66F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n } break; case 7: //CMP - if(opcode==0x81) {INST_NAME("(LOCK) CMP Ew, Iw");} else {INST_NAME("(LOCK) CMP Ew, Ib");} - SETFLAGS(X_ALL, SF_SET_PENDING); - GETEW(x6, (opcode==0x81)?2:1); - (void)wb1; - // No need to LOCK, this is readonly - if(opcode==0x81) i16 = F16S; else i16 = F8S; - if(i16) { - MOV32w(x5, i16); - emit_cmp16(dyn, ninst, x6, x5, x3, x4, x6); - } else { - emit_cmp16_0(dyn, ninst, ed, x3, x4); - } + INST_NAME("Invalid LOCK"); + UDF(0); + *need_epilog = 1; + *ok = 0; break; } break; @@ -550,14 +529,14 @@ uintptr_t dynarec64_66F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n switch((nextop>>3)&7) { case 0: // INC Ew - INST_NAME("LOCK INC Ew"); - SETFLAGS(X_ALL&~X_CF, SF_SUBSET); if(MODREG) { - ed = TO_NAT((nextop & 7) + (rex.b << 3)); - UXTHw(x6, ed); - emit_inc16(dyn, ninst, x6, x5, x3); - BFIx(ed, x6, 0, 16); + INST_NAME("Invalid LOCK"); + UDF(0); + *need_epilog = 1; + *ok = 0; } else { + INST_NAME("LOCK INC Ew"); + SETFLAGS(X_ALL&~X_CF, SF_SUBSET); addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 0); if(cpuext.atomics) { MOV32w(x3, 1); @@ -577,14 +556,14 @@ uintptr_t dynarec64_66F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n } break; case 1: //DEC Ew - INST_NAME("LOCK DEC Ew"); - SETFLAGS(X_ALL&~X_CF, SF_SUBSET); if(MODREG) { - ed = TO_NAT((nextop & 7) + (rex.b << 3)); - UXTHw(x6, ed); - emit_dec16(dyn, ninst, x6, x5, x3); - BFIx(ed, x6, 0, 16); + INST_NAME("Invalid LOCK"); + UDF(0); + *need_epilog = 1; + *ok = 0; } else { + INST_NAME("LOCK DEC Ew"); + SETFLAGS(X_ALL&~X_CF, SF_SUBSET); addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 0); if(cpuext.atomics) { MOV32w(x3, -1); diff --git a/src/dynarec/arm64/dynarec_arm64_67.c b/src/dynarec/arm64/dynarec_arm64_67.c index 793fa503..3d942dd0 100644 --- a/src/dynarec/arm64/dynarec_arm64_67.c +++ b/src/dynarec/arm64/dynarec_arm64_67.c @@ -1389,45 +1389,57 @@ uintptr_t dynarec64_67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin } break; case 0xC6: - INST_NAME("MOV Eb, Ib"); nextop=F8; - if(MODREG) { // reg <= u8 - u8 = F8; - if(!rex.rex) { - ed = (nextop&7); - eb1 = TO_NAT(ed & 3); // Ax, Cx, Dx or Bx - eb2 = (ed&4)>>2; // L or H - } else { - eb1 = TO_NAT((nextop & 7) + (rex.b << 3)); - eb2 = 0; - } - MOV32w(x3, u8); - BFIx(eb1, x3, eb2*8, 8); - } else { // mem <= u8 - addr = geted32(dyn, addr, ninst, nextop, &wback, x1, &fixedaddress, &unscaled, 0xfff, 0, rex, &lock, 0, 1); - u8 = F8; - if(u8) { - MOV32w(x3, u8); - ed = x3; - } else - ed = xZR; - STB(ed, wback, fixedaddress); - SMWRITELOCK(lock); + switch((nextop>>3)&7) { + case 0: + INST_NAME("MOV Eb, Ib"); + if(MODREG) { // reg <= u8 + u8 = F8; + if(!rex.rex) { + ed = (nextop&7); + eb1 = TO_NAT(ed & 3); // Ax, Cx, Dx or Bx + eb2 = (ed&4)>>2; // L or H + } else { + eb1 = TO_NAT((nextop & 7) + (rex.b << 3)); + eb2 = 0; + } + MOV32w(x3, u8); + BFIx(eb1, x3, eb2*8, 8); + } else { // mem <= u8 + addr = geted32(dyn, addr, ninst, nextop, &wback, x1, &fixedaddress, &unscaled, 0xfff, 0, rex, &lock, 0, 1); + u8 = F8; + if(u8) { + MOV32w(x3, u8); + ed = x3; + } else + ed = xZR; + STB(ed, wback, fixedaddress); + SMWRITELOCK(lock); + } + break; + default: + DEFAULT; } break; case 0xC7: - INST_NAME("MOV Ed, Id"); nextop=F8; - if(MODREG) { // reg <= i32 - i64 = F32S; - ed = TO_NAT((nextop & 7) + (rex.b << 3)); - MOV64xw(ed, i64); - } else { // mem <= i32 - addr = geted32(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, &unscaled, 0xfff<<(2+rex.w), (1<<(2+rex.w))-1, rex, &lock, 0, 4); - i64 = F32S; - MOV64xw(x3, i64); - STxw(x3, ed, fixedaddress); - SMWRITELOCK(lock); + switch((nextop>>3)&7) { + case 0: + INST_NAME("MOV Ed, Id"); + if(MODREG) { // reg <= i32 + i64 = F32S; + ed = TO_NAT((nextop & 7) + (rex.b << 3)); + MOV64xw(ed, i64); + } else { // mem <= i32 + addr = geted32(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, &unscaled, 0xfff<<(2+rex.w), (1<<(2+rex.w))-1, rex, &lock, 0, 4); + i64 = F32S; + MOV64xw(x3, i64); + STxw(x3, ed, fixedaddress); + SMWRITELOCK(lock); + } + break; + default: + DEFAULT; } break; diff --git a/src/dynarec/arm64/dynarec_arm64_6764_32.c b/src/dynarec/arm64/dynarec_arm64_6764_32.c index 68167880..9b1c71a7 100644 --- a/src/dynarec/arm64/dynarec_arm64_6764_32.c +++ b/src/dynarec/arm64/dynarec_arm64_6764_32.c @@ -88,17 +88,23 @@ uintptr_t dynarec64_6764_32(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, in break; case 0x8F: - INST_NAME("POP Seg:Ed"); nextop=F8; - if(MODREG) { // reg <= reg - POP1_32(x1); - MOVxw_REG(TO_NAT((nextop & 7) + (rex.b << 3)), x1); - } else { // mem <= reg - grab_segdata(dyn, addr, ninst, x4, seg, (MODREG)); - POP1_32(x1); - addr = geted16(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, &unscaled, 0xfff<<2, 3, 0); - ADDz_REG(x4, x4, ed); - STz(x1, x4, fixedaddress); + switch((nextop>>3)&7) { + case 0: + INST_NAME("POP Seg:Ed"); + if(MODREG) { // reg <= reg + POP1_32(x1); + MOVxw_REG(TO_NAT((nextop & 7) + (rex.b << 3)), x1); + } else { // mem <= reg + grab_segdata(dyn, addr, ninst, x4, seg, (MODREG)); + POP1_32(x1); + addr = geted16(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, &unscaled, 0xfff<<2, 3, 0); + ADDz_REG(x4, x4, ed); + STz(x1, x4, fixedaddress); + } + break; + default: + DEFAULT; } break; diff --git a/src/dynarec/arm64/dynarec_arm64_f0.c b/src/dynarec/arm64/dynarec_arm64_f0.c index b90aaa3b..0c6624bd 100644 --- a/src/dynarec/arm64/dynarec_arm64_f0.c +++ b/src/dynarec/arm64/dynarec_arm64_f0.c @@ -54,23 +54,16 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin switch(opcode) { case 0x00: - INST_NAME("LOCK ADD Eb, Gb"); - SETFLAGS(X_ALL, SF_SET_PENDING); nextop = F8; - GETGB(x2); if (MODREG) { - if(rex.rex) { - wback = TO_NAT((nextop & 0x07) + (rex.b << 3)); - wb2 = 0; - } else { - wback = (nextop&7); - wb2 = (wback>>2); - wback = TO_NAT(wback & 3); - } - UBFXw(x1, wback, wb2*8, 8); - emit_add8(dyn, ninst, x1, x2, x4, x3); - BFIx(wback, x1, wb2*8, 8); + INST_NAME("Invalid LOCK"); + UDF(0); + *need_epilog = 1; + *ok = 0; } else { + INST_NAME("LOCK ADD Eb, Gb"); + SETFLAGS(X_ALL, SF_SET_PENDING); + GETGB(x2); addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 0); if(cpuext.atomics) { UFLAG_IF { @@ -89,14 +82,16 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin } break; case 0x01: - INST_NAME("LOCK ADD Ed, Gd"); - SETFLAGS(X_ALL, SF_SET_PENDING); nextop = F8; - GETGD; if(MODREG) { - ed = TO_NAT((nextop & 7) + (rex.b << 3)); - emit_add32(dyn, ninst, rex, ed, gd, x3, x4); + INST_NAME("Invalid LOCK"); + UDF(0); + *need_epilog = 1; + *ok = 0; } else { + INST_NAME("LOCK ADD Ed, Gd"); + SETFLAGS(X_ALL, SF_SET_PENDING); + GETGD; addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 0); if(!ALIGNED_ATOMICxw) { if(cpuext.uscat) { @@ -141,23 +136,16 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin break; case 0x08: - INST_NAME("LOCK OR Eb, Gb"); - SETFLAGS(X_ALL, SF_SET_PENDING); nextop = F8; - GETGB(x2); if (MODREG) { - if(rex.rex) { - wback = TO_NAT((nextop & 0x07) + (rex.b << 3)); - wb2 = 0; - } else { - wback = (nextop&7); - wb2 = (wback>>2); - wback = TO_NAT(wback & 3); - } - UBFXw(x1, wback, wb2*8, 8); - emit_or8(dyn, ninst, x1, x2, x4, x3); - BFIx(wback, x1, wb2*8, 8); + INST_NAME("Invalid LOCK"); + UDF(0); + *need_epilog = 1; + *ok = 0; } else { + INST_NAME("LOCK OR Eb, Gb"); + SETFLAGS(X_ALL, SF_SET_PENDING); + GETGB(x2); addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 0); if(cpuext.atomics) { LDSETALB(x2, x1, wback); @@ -174,14 +162,16 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin } break; case 0x09: - INST_NAME("LOCK OR Ed, Gd"); - SETFLAGS(X_ALL, SF_SET_PENDING); nextop = F8; - GETGD; if(MODREG) { - ed = TO_NAT((nextop & 7) + (rex.b << 3)); - emit_or32(dyn, ninst, rex, ed, gd, x3, x4); + INST_NAME("Invalid LOCK"); + UDF(0); + *need_epilog = 1; + *ok = 0; } else { + INST_NAME("LOCK OR Ed, Gd"); + SETFLAGS(X_ALL, SF_SET_PENDING); + GETGD; addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 0); if(cpuext.atomics) { LDSETALxw(gd, x1, wback); @@ -203,35 +193,20 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin switch(nextop) { case 0xAB: - INST_NAME("LOCK BTS Ed, Gd"); - if(!BOX64ENV(dynarec_safeflags)) { - SETFLAGS(X_ALL&~X_ZF, SF_SUBSET); - } else { - SETFLAGS(X_CF, SF_SUBSET); - } nextop = F8; - GETGD; if(MODREG) { - ed = TO_NAT((nextop & 7) + (rex.b << 3)); - wback = 0; - if(rex.w) { - ANDx_mask(x2, gd, 1, 0, 0b00101); //mask=0x000000000000003f - } else { - ANDw_mask(x2, gd, 0, 0b00100); //mask=0x00000001f - } - LSRxw_REG(x4, ed, x2); - if(rex.w) { - ANDSx_mask(x4, x4, 1, 0, 0); //mask=1 + INST_NAME("Invalid LOCK"); + UDF(0); + *need_epilog = 1; + *ok = 0; + } else { + INST_NAME("LOCK BTS Ed, Gd"); + if(!BOX64ENV(dynarec_safeflags)) { + SETFLAGS(X_ALL&~X_ZF, SF_SUBSET); } else { - ANDSw_mask(x4, x4, 0, 0); //mask=1 - } - IFX(X_CF) { - BFIw(xFlags, x4, F_CF, 1); + SETFLAGS(X_CF, SF_SUBSET); } - MOV32w(x4, 1); - LSLxw_REG(x4, x4, x2); - ORRxw_REG(ed, ed, x4); - } else { + GETGD; // Will fetch only 1 byte, to avoid alignment issue ANDw_mask(x2, gd, 0, 0b00010); //mask=0x000000007 addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 0); @@ -265,30 +240,17 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin case 0xB0: switch(rep) { case 0: - INST_NAME("LOCK CMPXCHG Eb, Gb"); - SETFLAGS(X_ALL, SF_SET_PENDING); nextop = F8; - GETGB(x1); - UBFXx(x6, xRAX, 0, 8); if(MODREG) { - if(rex.rex) { - wback = TO_NAT((nextop & 7) + (rex.b << 3)); - wb2 = 0; - } else { - wback = (nextop&7); - wb2 = (wback>>2)*8; - wback = TO_NAT(wback & 3); - } - UBFXx(x2, wback, wb2, 8); - wb1 = 0; - ed = x2; - UFLAG_IF {emit_cmp8(dyn, ninst, x6, ed, x3, x4, x5);} - SUBxw_REG(x6, x6, x2); - CBNZxw_MARK2(x6); - BFIx(wback, gd, wb2, 8); - MARK2; - BFIx(xRAX, x2, 0, 8); + INST_NAME("Invalid LOCK"); + UDF(0); + *need_epilog = 1; + *ok = 0; } else { + INST_NAME("LOCK CMPXCHG Eb, Gb"); + SETFLAGS(X_ALL, SF_SET_PENDING); + GETGB(x1); + UBFXx(x6, xRAX, 0, 8); addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 0); if(cpuext.atomics) { UFLAG_IF { @@ -321,24 +283,16 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin case 0xB1: switch(rep) { case 0: - INST_NAME("LOCK CMPXCHG Ed, Gd"); - SETFLAGS(X_ALL, SF_SET_PENDING); nextop = F8; - GETGD; if(MODREG) { - ed = TO_NAT((nextop & 7) + (rex.b << 3)); - wback = 0; - UFLAG_IF { - emit_cmp32(dyn, ninst, rex, xRAX, ed, x3, x4, x5); - } else { - CMPSxw_REG(xRAX, ed); - } - MOVxw_REG(x1, ed); // save value - Bcond(cNE, 4 + (rex.w ? 4 : 8)); - MOVxw_REG(ed, gd); - if (!rex.w) { B_NEXT_nocond; } - MOVxw_REG(xRAX, x1); + INST_NAME("Invalid LOCK"); + UDF(0); + *need_epilog = 1; + *ok = 0; } else { + INST_NAME("LOCK CMPXCHG Ed, Gd"); + SETFLAGS(X_ALL, SF_SET_PENDING); + GETGD; addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 0); UFLAG_IF { MOVxw_REG(x6, xRAX); } if(!ALIGNED_ATOMICxw) { @@ -412,30 +366,20 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin break; case 0xB3: - INST_NAME("LOCK BTR Ed, Gd"); - if(!BOX64ENV(dynarec_safeflags)) { - SETFLAGS(X_ALL&~X_ZF, SF_SUBSET); - } else { - SETFLAGS(X_CF, SF_SUBSET); - } nextop = F8; - GETGD; if(MODREG) { - ed = TO_NAT((nextop & 7) + (rex.b << 3)); - wback = 0; - if(rex.w) { - ANDx_mask(x2, gd, 1, 0, 0b00101); //mask=0x000000000000003f + INST_NAME("Invalid LOCK"); + UDF(0); + *need_epilog = 1; + *ok = 0; + } else { + INST_NAME("LOCK BTR Ed, Gd"); + if(!BOX64ENV(dynarec_safeflags)) { + SETFLAGS(X_ALL&~X_ZF, SF_SUBSET); } else { - ANDw_mask(x2, gd, 0, 0b00100); //mask=0x00000001f - } - IFX(X_CF) { - LSRxw_REG(x4, ed, x2); - BFIw(xFlags, x4, F_CF, 1); + SETFLAGS(X_CF, SF_SUBSET); } - MOV32w(x4, 1); - LSLxw_REG(x4, x4, x2); - BICxw_REG(ed, ed, x4); - } else { + GETGD; // Will fetch only 1 byte, to avoid alignment issue ANDw_mask(x2, gd, 0, 0b00010); //mask=0x000000007 addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 0); @@ -471,55 +415,24 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin nextop = F8; switch((nextop>>3)&7) { case 4: - INST_NAME("LOCK BT Ed, Ib"); - if(!BOX64ENV(dynarec_safeflags)) { - SETFLAGS(X_ALL&~X_ZF, SF_SUBSET); - } else { - SETFLAGS(X_CF, SF_SUBSET); - } - gd = x2; - if(MODREG) { - ed = TO_NAT((nextop & 7) + (rex.b << 3)); - u8 = F8; - u8&=rex.w?0x3f:0x1f; - IFX(X_CF) { - BFXILxw(xFlags, ed, u8, 1); // inject 1 bit from u8 to F_CF (i.e. pos 0) - } - } else { - // Will fetch only 1 byte, to avoid alignment issue - addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 1); - u8 = F8; - if(u8>>3) { - ADDx_U12(x3, wback, u8>>3); - wback = x3; - } - MARKLOCK; - LDAXRB(x1, wback); - ed = x1; - wback = x3; - IFX(X_CF) { - BFXILxw(xFlags, x1, u8&7, 1); // inject 1 bit from u8 to F_CF (i.e. pos 0) - } - } + INST_NAME("Invalid LOCK"); + UDF(0); + *need_epilog = 1; + *ok = 0; break; case 5: - INST_NAME("LOCK BTS Ed, Ib"); - if(!BOX64ENV(dynarec_safeflags)) { - SETFLAGS(X_ALL&~X_ZF, SF_SUBSET); - } else { - SETFLAGS(X_CF, SF_SUBSET); - } if(MODREG) { - ed = TO_NAT((nextop & 7) + (rex.b << 3)); - wback = 0; - u8 = F8; - u8&=(rex.w?0x3f:0x1f); - IFX(X_CF) { - BFXILxw(xFlags, ed, u8, 1); // inject 1 bit from u8 to F_CF (i.e. pos 0) - } - mask = convert_bitmask_xw(1LL<<u8); - ORRxw_mask(ed, ed, (mask>>12)&1, mask&0x3F, (mask>>6)&0x3F); + INST_NAME("Invalid LOCK"); + UDF(0); + *need_epilog = 1; + *ok = 0; } else { + INST_NAME("LOCK BTS Ed, Ib"); + if(!BOX64ENV(dynarec_safeflags)) { + SETFLAGS(X_ALL&~X_ZF, SF_SUBSET); + } else { + SETFLAGS(X_CF, SF_SUBSET); + } // Will fetch only 1 byte, to avoid alignment issue addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 1); u8 = F8; @@ -548,22 +461,18 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin } break; case 6: - INST_NAME("LOCK BTR Ed, Ib"); - if(!BOX64ENV(dynarec_safeflags)) { - SETFLAGS(X_ALL&~X_ZF, SF_SUBSET); - } else { - SETFLAGS(X_CF, SF_SUBSET); - } if(MODREG) { - ed = TO_NAT((nextop & 7) + (rex.b << 3)); - wback = 0; - u8 = F8; - u8&=(rex.w?0x3f:0x1f); - IFX(X_CF) { - BFXILxw(xFlags, ed, u8, 1); // inject 1 bit from u8 to F_CF (i.e. pos 0) - } - BFCxw(ed, u8, 1); + INST_NAME("Invalid LOCK"); + UDF(0); + *need_epilog = 1; + *ok = 0; } else { + INST_NAME("LOCK BTR Ed, Ib"); + if(!BOX64ENV(dynarec_safeflags)) { + SETFLAGS(X_ALL&~X_ZF, SF_SUBSET); + } else { + SETFLAGS(X_CF, SF_SUBSET); + } addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 1); u8 = F8; if(u8>>3) { @@ -590,23 +499,18 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin } break; case 7: - INST_NAME("LOCK BTC Ed, Ib"); - if(!BOX64ENV(dynarec_safeflags)) { - SETFLAGS(X_ALL&~X_ZF, SF_SUBSET); - } else { - SETFLAGS(X_CF, SF_SUBSET); - } if(MODREG) { - ed = TO_NAT((nextop & 7) + (rex.b << 3)); - wback = 0; - u8 = F8; - u8&=(rex.w?0x3f:0x1f); - IFX(X_CF) { - BFXILxw(xFlags, ed, u8, 1); // inject 1 bit from u8 to F_CF (i.e. pos 0) - } - MOV32w(x4, 1); - EORxw_REG_LSL(ed, ed, x4, u8); + INST_NAME("Invalid LOCK"); + UDF(0); + *need_epilog = 1; + *ok = 0; } else { + INST_NAME("LOCK BTC Ed, Ib"); + if(!BOX64ENV(dynarec_safeflags)) { + SETFLAGS(X_ALL&~X_ZF, SF_SUBSET); + } else { + SETFLAGS(X_CF, SF_SUBSET); + } addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 1); u8 = F8; if(u8>>3) { @@ -638,30 +542,20 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin } break; case 0xBB: - INST_NAME("LOCK BTC Ed, Gd"); - if(!BOX64ENV(dynarec_safeflags)) { - SETFLAGS(X_ALL&~X_ZF, SF_SUBSET); - } else { - SETFLAGS(X_CF, SF_SUBSET); - } nextop = F8; - GETGD; if(MODREG) { - ed = TO_NAT((nextop & 7) + (rex.b << 3)); - wback = 0; - if(rex.w) { - ANDx_mask(x2, gd, 1, 0, 0b00101); //mask=0x000000000000003f + INST_NAME("Invalid LOCK"); + UDF(0); + *need_epilog = 1; + *ok = 0; + } else { + INST_NAME("LOCK BTC Ed, Gd"); + if(!BOX64ENV(dynarec_safeflags)) { + SETFLAGS(X_ALL&~X_ZF, SF_SUBSET); } else { - ANDw_mask(x2, gd, 0, 0b00100); //mask=0x00000001f - } - IFX(X_CF) { - LSRxw_REG(x4, ed, x2); - BFIw(xFlags, x4, F_CF, 1); + SETFLAGS(X_CF, SF_SUBSET); } - MOV32w(x4, 1); - LSLxw_REG(x4, x4, x2); - EORxw_REG(ed, ed, x4); - } else { + GETGD; // Will fetch only 1 byte, to avoid alignment issue ANDw_mask(x2, gd, 0, 0b00010); //mask=0x000000007 addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 0); @@ -696,18 +590,16 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin case 0xC0: switch(rep) { case 0: - INST_NAME("LOCK XADD Eb, Gb"); - SETFLAGS(X_ALL, SF_SET_PENDING); nextop = F8; - GETGB(x1); if(MODREG) { - ed = TO_NAT((nextop & 7) + (rex.b << 3)); - GETEB(x2, 0); - gd = x2; ed = x1; // swap gd/ed - emit_add8(dyn, ninst, x1, x2, x4, x5); - GBBACK; // gb gets x2 (old ed) - EBBACK; // eb gets x1 (sum) + INST_NAME("Invalid LOCK"); + UDF(0); + *need_epilog = 1; + *ok = 0; } else { + INST_NAME("LOCK XADD Eb, Gb"); + SETFLAGS(X_ALL, SF_SET_PENDING); + GETGB(x1); addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 0); if(cpuext.atomics) { UFLAG_IF { @@ -739,17 +631,16 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin case 0xC1: switch(rep) { case 0: - INST_NAME("LOCK XADD Ed, Gd"); - SETFLAGS(X_ALL, SF_SET_PENDING); nextop = F8; - GETGD; if(MODREG) { - ed = TO_NAT((nextop & 7) + (rex.b << 3)); - MOVxw_REG(x1, ed); - MOVxw_REG(ed, gd); - MOVxw_REG(gd, x1); - emit_add32(dyn, ninst, rex, ed, gd, x3, x4); + INST_NAME("Invalid LOCK"); + UDF(0); + *need_epilog = 1; + *ok = 0; } else { + INST_NAME("LOCK XADD Ed, Gd"); + SETFLAGS(X_ALL, SF_SET_PENDING); + GETGD; addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 0); if(!ALIGNED_ATOMICxw) { if(cpuext.uscat) { @@ -811,97 +702,104 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin nextop = F8; switch((nextop>>3)&7) { case 1: - if (rex.w) { - INST_NAME("LOCK CMPXCHG16B Gq, Eq"); + if(MODREG) { + INST_NAME("Invalid LOCK"); + UDF(0); + *need_epilog = 1; + *ok = 0; } else { - INST_NAME("LOCK CMPXCHG8B Gq, Eq"); - } - SETFLAGS(X_ZF, SF_SUBSET); - addr = geted(dyn, addr, ninst, nextop, &wback, x1, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 0); - if(!ALIGNED_ATOMICxw) { - if(cpuext.uscat) { - if(rex.w) { - TSTx_mask(wback, 1, 0, 3); - B_MARK2(cNE); - } else { - ANDx_mask(x2, wback, 1, 0, 3); // mask = F - CMPSw_U12(x2, 8); - B_MARK2(cGT); - } + if (rex.w) { + INST_NAME("LOCK CMPXCHG16B Gq, Eq"); } else { - TSTx_mask(wback, 1, 0, 2+rex.w); // mask=7 or F - B_MARK2(cNE); // unaligned + INST_NAME("LOCK CMPXCHG8B Gq, Eq"); } - } - if(cpuext.atomics) { - MOVx_REG(x2, xRAX); - MOVx_REG(x3, xRDX); - MOVx_REG(x4, xRBX); - MOVx_REG(x5, xRCX); - CASPALxw(x2, x4, wback); - UFLAG_IF { - CMPSxw_REG(x2, xRAX); - CCMPxw(x3, xRDX, 0, cEQ); - IFNATIVE(NF_EQ) {} else {CSETw(x1, cEQ);} - } - MOVx_REG(xRAX, x2); - MOVx_REG(xRDX, x3); + SETFLAGS(X_ZF, SF_SUBSET); + addr = geted(dyn, addr, ninst, nextop, &wback, x1, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 0); if(!ALIGNED_ATOMICxw) { - B_MARK3_nocond; - } - } else { - MARKLOCK; - LDAXPxw(x2, x3, wback); - CMPSxw_REG(xRAX, x2); - CCMPxw(xRDX, x3, 0, cEQ); - B_MARK(cNE); // EAX!=ED[0] || EDX!=Ed[1] - STLXPxw(x4, xRBX, xRCX, wback); - CBNZx_MARKLOCK(x4); - UFLAG_IF { - IFNATIVE(NF_EQ) {} else {MOV32w(x1, 1);} + if(cpuext.uscat) { + if(rex.w) { + TSTx_mask(wback, 1, 0, 3); + B_MARK2(cNE); + } else { + ANDx_mask(x2, wback, 1, 0, 3); // mask = F + CMPSw_U12(x2, 8); + B_MARK2(cGT); + } + } else { + TSTx_mask(wback, 1, 0, 2+rex.w); // mask=7 or F + B_MARK2(cNE); // unaligned + } } - B_MARK3_nocond; - MARK; - STLXPxw(x4, x2, x3, wback); // write back, to be sure it was "atomic" - CBNZx_MARKLOCK(x4); - MOVxw_REG(xRAX, x2); - MOVxw_REG(xRDX, x3); - UFLAG_IF { - IFNATIVE(NF_EQ) {} else {MOV32w(x1, 0);} + if(cpuext.atomics) { + MOVx_REG(x2, xRAX); + MOVx_REG(x3, xRDX); + MOVx_REG(x4, xRBX); + MOVx_REG(x5, xRCX); + CASPALxw(x2, x4, wback); + UFLAG_IF { + CMPSxw_REG(x2, xRAX); + CCMPxw(x3, xRDX, 0, cEQ); + IFNATIVE(NF_EQ) {} else {CSETw(x1, cEQ);} + } + MOVx_REG(xRAX, x2); + MOVx_REG(xRDX, x3); + if(!ALIGNED_ATOMICxw) { + B_MARK3_nocond; + } + } else { + MARKLOCK; + LDAXPxw(x2, x3, wback); + CMPSxw_REG(xRAX, x2); + CCMPxw(xRDX, x3, 0, cEQ); + B_MARK(cNE); // EAX!=ED[0] || EDX!=Ed[1] + STLXPxw(x4, xRBX, xRCX, wback); + CBNZx_MARKLOCK(x4); + UFLAG_IF { + IFNATIVE(NF_EQ) {} else {MOV32w(x1, 1);} + } + B_MARK3_nocond; + MARK; + STLXPxw(x4, x2, x3, wback); // write back, to be sure it was "atomic" + CBNZx_MARKLOCK(x4); + MOVxw_REG(xRAX, x2); + MOVxw_REG(xRDX, x3); + UFLAG_IF { + IFNATIVE(NF_EQ) {} else {MOV32w(x1, 0);} + } + if(!ALIGNED_ATOMICxw) { + B_MARK3_nocond; + } } if(!ALIGNED_ATOMICxw) { + MARK2; + LDPxw_S7_offset(x2, x3, wback, 0); + LDAXRB(x5, wback); + SUBxw_UXTB(x5, x5, x2); + CBNZw_MARK2(x5); + CMPSxw_REG(xRAX, x2); + CCMPxw(xRDX, x3, 0, cEQ); + B_MARKSEG(cNE); // EAX!=ED[0] || EDX!=Ed[1] + STLXRB(x4, xRBX, wback); + CBNZx_MARK2(x4); + STPxw_S7_offset(xRBX, xRCX, wback, 0); + UFLAG_IF { + IFNATIVE(NF_EQ) {} else {MOV32w(x1, 1);} + } B_MARK3_nocond; + MARKSEG; + STLXRB(x4, x5, wback); //write back + CBNZx_MARK2(x4); + MOVxw_REG(xRAX, x2); + MOVxw_REG(xRDX, x3); + UFLAG_IF { + IFNATIVE(NF_EQ) {} else {MOV32w(x1, 0);} + } } - } - if(!ALIGNED_ATOMICxw) { - MARK2; - LDPxw_S7_offset(x2, x3, wback, 0); - LDAXRB(x5, wback); - SUBxw_UXTB(x5, x5, x2); - CBNZw_MARK2(x5); - CMPSxw_REG(xRAX, x2); - CCMPxw(xRDX, x3, 0, cEQ); - B_MARKSEG(cNE); // EAX!=ED[0] || EDX!=Ed[1] - STLXRB(x4, xRBX, wback); - CBNZx_MARK2(x4); - STPxw_S7_offset(xRBX, xRCX, wback, 0); - UFLAG_IF { - IFNATIVE(NF_EQ) {} else {MOV32w(x1, 1);} - } - B_MARK3_nocond; - MARKSEG; - STLXRB(x4, x5, wback); //write back - CBNZx_MARK2(x4); - MOVxw_REG(xRAX, x2); - MOVxw_REG(xRDX, x3); + MARK3; UFLAG_IF { - IFNATIVE(NF_EQ) {} else {MOV32w(x1, 0);} + IFNATIVE(NF_EQ) {} else {BFIw(xFlags, x1, F_ZF, 1);} } } - MARK3; - UFLAG_IF { - IFNATIVE(NF_EQ) {} else {BFIw(xFlags, x1, F_ZF, 1);} - } break; default: DEFAULT; @@ -914,23 +812,16 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin break; case 0x10: INST_NAME("LOCK ADC Eb, Gb"); - READFLAGS(X_CF); - SETFLAGS(X_ALL, SF_SET_PENDING); nextop = F8; - GETGB(x2); if (MODREG) { - if(rex.rex) { - wback = TO_NAT((nextop & 0x07) + (rex.b << 3)); - wb2 = 0; - } else { - wback = (nextop&7); - wb2 = (wback>>2); - wback = TO_NAT(wback & 3); - } - UBFXw(x1, wback, wb2*8, 8); - emit_adc8(dyn, ninst, x1, x2, x4, x5); - BFIx(wback, x1, wb2*8, 8); + INST_NAME("Invalid LOCK"); + UDF(0); + *need_epilog = 1; + *ok = 0; } else { + READFLAGS(X_CF); + SETFLAGS(X_ALL, SF_SET_PENDING); + GETGB(x2); addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 0); MARKLOCK; LDAXRB(x1, wback); @@ -940,15 +831,17 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin } break; case 0x11: - INST_NAME("LOCK ADC Ed, Gd"); - READFLAGS(X_CF); - SETFLAGS(X_ALL, SF_SET_PENDING); nextop = F8; - GETGD; if(MODREG) { - ed = TO_NAT((nextop & 7) + (rex.b << 3)); - emit_adc32(dyn, ninst, rex, ed, gd, x3, x4); + INST_NAME("Invalid LOCK"); + UDF(0); + *need_epilog = 1; + *ok = 0; } else { + INST_NAME("LOCK ADC Ed, Gd"); + READFLAGS(X_CF); + SETFLAGS(X_ALL, SF_SET_PENDING); + GETGD; addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 0); MARKLOCK; LDAXRxw(x1, wback); @@ -958,16 +851,16 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin } break; case 0x20: - INST_NAME("LOCK AND Eb, Gb"); - SETFLAGS(X_ALL, SF_SET_PENDING); nextop = F8; - GETGD; if(MODREG) { - GETEB(x1, 0); - GETGB(x2); - emit_and8(dyn, ninst, x1, x2, x4, x5); - EBBACK; + INST_NAME("Invalid LOCK"); + UDF(0); + *need_epilog = 1; + *ok = 0; } else { + INST_NAME("LOCK AND Eb, Gb"); + SETFLAGS(X_ALL, SF_SET_PENDING); + GETGD; addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 0); GETGB(x5); if(cpuext.atomics) { @@ -988,14 +881,16 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin } break; case 0x21: - INST_NAME("LOCK AND Ed, Gd"); - SETFLAGS(X_ALL, SF_SET_PENDING); nextop = F8; - GETGD; if(MODREG) { - ed = TO_NAT((nextop & 7) + (rex.b << 3)); - emit_and32(dyn, ninst, rex, ed, gd, x3, x4); + INST_NAME("Invalid LOCK"); + UDF(0); + *need_epilog = 1; + *ok = 0; } else { + INST_NAME("LOCK AND Ed, Gd"); + SETFLAGS(X_ALL, SF_SET_PENDING); + GETGD; addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 0); if(cpuext.atomics) { MVNxw_REG(x1, gd); @@ -1016,14 +911,16 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin break; case 0x29: - INST_NAME("LOCK SUB Ed, Gd"); - SETFLAGS(X_ALL, SF_SET_PENDING); nextop = F8; - GETGD; if(MODREG) { - ed = TO_NAT((nextop & 7) + (rex.b << 3)); - emit_sub32(dyn, ninst, rex, ed, gd, x3, x4); + INST_NAME("Invalid LOCK"); + UDF(0); + *need_epilog = 1; + *ok = 0; } else { + INST_NAME("LOCK SUB Ed, Gd"); + SETFLAGS(X_ALL, SF_SET_PENDING); + GETGD; addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 0); if(!ALIGNED_ATOMICxw) { if(cpuext.uscat) { @@ -1073,14 +970,16 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin break; case 0x31: - INST_NAME("LOCK XOR Ed, Gd"); - SETFLAGS(X_ALL, SF_SET_PENDING); nextop = F8; - GETGD; if (MODREG) { - ed = TO_NAT((nextop & 7) + (rex.b << 3)); - emit_xor32(dyn, ninst, rex, ed, gd, x3, x4); + INST_NAME("Invalid LOCK"); + UDF(0); + *need_epilog = 1; + *ok = 0; } else { + INST_NAME("LOCK XOR Ed, Gd"); + SETFLAGS(X_ALL, SF_SET_PENDING); + GETGD; addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 0); if(!ALIGNED_ATOMICxw) { if(cpuext.uscat) { @@ -1131,15 +1030,14 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin nextop = F8; switch((nextop>>3)&7) { case 0: //ADD - INST_NAME("ADD Eb, Ib"); - SETFLAGS(X_ALL, SF_SET_PENDING); if(MODREG) { - GETEB(x1, 1); - u8 = F8; - emit_add8c(dyn, ninst, x1, u8, x2, x4); - wb1 = 0; - EBBACK; + INST_NAME("Invalid LOCK"); + UDF(0); + *need_epilog = 1; + *ok = 0; } else { + INST_NAME("ADD Eb, Ib"); + SETFLAGS(X_ALL, SF_SET_PENDING); addr = geted(dyn, addr, ninst, nextop, &wback, x5, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 1); u8 = F8; wb1 = 1; @@ -1162,15 +1060,14 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin } break; case 1: //OR - INST_NAME("OR Eb, Ib"); - SETFLAGS(X_ALL, SF_SET_PENDING); if(MODREG) { - GETEB(x1, 1); - u8 = F8; - emit_or8c(dyn, ninst, x1, u8, x2, x4); - wb1 = 0; - EBBACK; + INST_NAME("Invalid LOCK"); + UDF(0); + *need_epilog = 1; + *ok = 0; } else { + INST_NAME("OR Eb, Ib"); + SETFLAGS(X_ALL, SF_SET_PENDING); addr = geted(dyn, addr, ninst, nextop, &wback, x5, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 1); u8 = F8; wb1 = 1; @@ -1192,16 +1089,15 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin } break; case 2: //ADC - INST_NAME("ADC Eb, Ib"); - READFLAGS(X_CF); - SETFLAGS(X_ALL, SF_SET_PENDING); if(MODREG) { - GETEB(x1, 1); - u8 = F8; - emit_adc8c(dyn, ninst, x1, u8, x2, x4, x5); - wb1 = 0; - EBBACK; + INST_NAME("Invalid LOCK"); + UDF(0); + *need_epilog = 1; + *ok = 0; } else { + INST_NAME("ADC Eb, Ib"); + READFLAGS(X_CF); + SETFLAGS(X_ALL, SF_SET_PENDING); addr = geted(dyn, addr, ninst, nextop, &wback, x5, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 1); u8 = F8; wb1 = 1; @@ -1213,16 +1109,15 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin } break; case 3: //SBB - INST_NAME("SBB Eb, Ib"); - READFLAGS(X_CF); - SETFLAGS(X_ALL, SF_SET_PENDING); if(MODREG) { - GETEB(x1, 1); - u8 = F8; - emit_sbb8c(dyn, ninst, x1, u8, x2, x4, x5); - wb1 = 0; - EBBACK; + INST_NAME("Invalid LOCK"); + UDF(0); + *need_epilog = 1; + *ok = 0; } else { + INST_NAME("SBB Eb, Ib"); + READFLAGS(X_CF); + SETFLAGS(X_ALL, SF_SET_PENDING); addr = geted(dyn, addr, ninst, nextop, &wback, x5, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 1); u8 = F8; wb1 = 1; @@ -1234,15 +1129,14 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin } break; case 4: //AND - INST_NAME("AND Eb, Ib"); - SETFLAGS(X_ALL, SF_SET_PENDING); if(MODREG) { - GETEB(x1, 1); - u8 = F8; - emit_and8c(dyn, ninst, x1, u8, x2, x4); - wb1 = 0; - EBBACK; + INST_NAME("Invalid LOCK"); + UDF(0); + *need_epilog = 1; + *ok = 0; } else { + INST_NAME("AND Eb, Ib"); + SETFLAGS(X_ALL, SF_SET_PENDING); addr = geted(dyn, addr, ninst, nextop, &wback, x5, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 1); u8 = F8; wb1 = 1; @@ -1264,15 +1158,14 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin } break; case 5: //SUB - INST_NAME("SUB Eb, Ib"); - SETFLAGS(X_ALL, SF_SET_PENDING); if(MODREG) { - GETEB(x1, 1); - u8 = F8; - emit_sub8c(dyn, ninst, x1, u8, x2, x4, x5); - wb1 = 0; - EBBACK; + INST_NAME("Invalid LOCK"); + UDF(0); + *need_epilog = 1; + *ok = 0; } else { + INST_NAME("SUB Eb, Ib"); + SETFLAGS(X_ALL, SF_SET_PENDING); addr = geted(dyn, addr, ninst, nextop, &wback, x5, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 1); u8 = F8; wb1 = 1; @@ -1294,15 +1187,14 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin } break; case 6: //XOR - INST_NAME("XOR Eb, Ib"); - SETFLAGS(X_ALL, SF_SET_PENDING); if(MODREG) { - GETEB(x1, 1); - u8 = F8; - emit_xor8c(dyn, ninst, x1, u8, x2, x4); - wb1 = 0; - EBBACK; + INST_NAME("Invalid LOCK"); + UDF(0); + *need_epilog = 1; + *ok = 0; } else { + INST_NAME("XOR Eb, Ib"); + SETFLAGS(X_ALL, SF_SET_PENDING); addr = geted(dyn, addr, ninst, nextop, &wback, x5, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 1); u8 = F8; wb1 = 1; @@ -1324,16 +1216,10 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin } break; case 7: //CMP - INST_NAME("CMP Eb, Ib"); - SETFLAGS(X_ALL, SF_SET_PENDING); - GETEB(x1, 1); - u8 = F8; - if(u8) { - MOV32w(x2, u8); - emit_cmp8(dyn, ninst, x1, x2, x3, x4, x5); - } else { - emit_cmp8_0(dyn, ninst, x1, x3, x4); - } + INST_NAME("Invalid LOCK"); + UDF(0); + *need_epilog = 1; + *ok = 0; break; default: DEFAULT; @@ -1344,18 +1230,18 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin nextop = F8; switch((nextop>>3)&7) { case 0: //ADD - if(opcode==0x81) { - INST_NAME("LOCK ADD Ed, Id"); - } else { - INST_NAME("LOCK ADD Ed, Ib"); - } - SETFLAGS(X_ALL, SF_SET_PENDING); if(MODREG) { - if(opcode==0x81) i64 = F32S; else i64 = F8S; - ed = TO_NAT((nextop & 7) + (rex.b << 3)); - MOV64xw(x5, i64); - emit_add32(dyn, ninst, rex, ed, x5, x3, x4); + INST_NAME("Invalid LOCK"); + UDF(0); + *need_epilog = 1; + *ok = 0; } else { + if(opcode==0x81) { + INST_NAME("LOCK ADD Ed, Id"); + } else { + INST_NAME("LOCK ADD Ed, Ib"); + } + SETFLAGS(X_ALL, SF_SET_PENDING); addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, (opcode==0x81)?4:1); if(opcode==0x81) i64 = F32S; else i64 = F8S; if((i64<=-0x1000) || (i64>=0x1000)) { @@ -1422,13 +1308,14 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin } break; case 1: //OR - if(opcode==0x81) {INST_NAME("LOCK OR Ed, Id");} else {INST_NAME("LOCK OR Ed, Ib");} - SETFLAGS(X_ALL, SF_SET_PENDING); if(MODREG) { - if(opcode==0x81) i64 = F32S; else i64 = F8S; - ed = TO_NAT((nextop & 7) + (rex.b << 3)); - emit_or32c(dyn, ninst, rex, ed, i64, x3, x4); + INST_NAME("Invalid LOCK"); + UDF(0); + *need_epilog = 1; + *ok = 0; } else { + if(opcode==0x81) {INST_NAME("LOCK OR Ed, Id");} else {INST_NAME("LOCK OR Ed, Ib");} + SETFLAGS(X_ALL, SF_SET_PENDING); addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, (opcode==0x81)?4:1); if(opcode==0x81) i64 = F32S; else i64 = F8S; if(wback==xRSP && !i64) { @@ -1454,15 +1341,15 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin } break; case 2: //ADC - if(opcode==0x81) {INST_NAME("LOCK ADC Ed, Id");} else {INST_NAME("LOCK ADC Ed, Ib");} - READFLAGS(X_CF); - SETFLAGS(X_ALL, SF_SET_PENDING); if(MODREG) { - if(opcode==0x81) i64 = F32S; else i64 = F8S; - ed = TO_NAT((nextop & 7) + (rex.b << 3)); - MOV64xw(x5, i64); - emit_adc32(dyn, ninst, rex, ed, x5, x3, x4); + INST_NAME("Invalid LOCK"); + UDF(0); + *need_epilog = 1; + *ok = 0; } else { + if(opcode==0x81) {INST_NAME("LOCK ADC Ed, Id");} else {INST_NAME("LOCK ADC Ed, Ib");} + READFLAGS(X_CF); + SETFLAGS(X_ALL, SF_SET_PENDING); addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, (opcode==0x81)?4:1); if(opcode==0x81) i64 = F32S; else i64 = F8S; MOV64xw(x5, i64); @@ -1474,15 +1361,15 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin } break; case 3: //SBB - if(opcode==0x81) {INST_NAME("LOCK SBB Ed, Id");} else {INST_NAME("LOCK SBB Ed, Ib");} - READFLAGS(X_CF); - SETFLAGS(X_ALL, SF_SET_PENDING); if(MODREG) { - if(opcode==0x81) i64 = F32S; else i64 = F8S; - ed = TO_NAT((nextop & 7) + (rex.b << 3)); - MOV64xw(x5, i64); - emit_sbb32(dyn, ninst, rex, ed, x5, x3, x4); + INST_NAME("Invalid LOCK"); + UDF(0); + *need_epilog = 1; + *ok = 0; } else { + if(opcode==0x81) {INST_NAME("LOCK SBB Ed, Id");} else {INST_NAME("LOCK SBB Ed, Ib");} + READFLAGS(X_CF); + SETFLAGS(X_ALL, SF_SET_PENDING); addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, (opcode==0x81)?4:1); if(opcode==0x81) i64 = F32S; else i64 = F8S; MOV64xw(x5, i64); @@ -1494,14 +1381,14 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin } break; case 4: //AND - if(opcode==0x81) {INST_NAME("LOCK AND Ed, Id");} else {INST_NAME("LOCK AND Ed, Ib");} - SETFLAGS(X_ALL, SF_SET_PENDING); if(MODREG) { - if(opcode==0x81) i64 = F32S; else i64 = F8S; - ed = TO_NAT((nextop & 7) + (rex.b << 3)); - MOV64xw(x5, i64); - emit_and32(dyn, ninst, rex, ed, x5, x3, x4); + INST_NAME("Invalid LOCK"); + UDF(0); + *need_epilog = 1; + *ok = 0; } else { + if(opcode==0x81) {INST_NAME("LOCK AND Ed, Id");} else {INST_NAME("LOCK AND Ed, Ib");} + SETFLAGS(X_ALL, SF_SET_PENDING); addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, (opcode==0x81)?4:1); if(opcode==0x81) i64 = F32S; else i64 = F8S; if(cpuext.atomics) { @@ -1523,13 +1410,14 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin } break; case 5: //SUB - if(opcode==0x81) {INST_NAME("LOCK SUB Ed, Id");} else {INST_NAME("LOCK SUB Ed, Ib");} - SETFLAGS(X_ALL, SF_SET_PENDING); if(MODREG) { - if(opcode==0x81) i64 = F32S; else i64 = F8S; - ed = TO_NAT((nextop & 7) + (rex.b << 3)); - emit_sub32c(dyn, ninst, rex, ed, i64, x3, x4, x5); + INST_NAME("Invalid LOCK"); + UDF(0); + *need_epilog = 1; + *ok = 0; } else { + if(opcode==0x81) {INST_NAME("LOCK SUB Ed, Id");} else {INST_NAME("LOCK SUB Ed, Ib");} + SETFLAGS(X_ALL, SF_SET_PENDING); addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, (opcode==0x81)?4:1); if(opcode==0x81) i64 = F32S; else i64 = F8S; if((i64<=-0x1000) || (i64>=0x1000)) { @@ -1604,14 +1492,14 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin } break; case 6: //XOR - if(opcode==0x81) {INST_NAME("LOCK XOR Ed, Id");} else {INST_NAME("LOCK XOR Ed, Ib");} - SETFLAGS(X_ALL, SF_SET_PENDING); if(MODREG) { - if(opcode==0x81) i64 = F32S; else i64 = F8S; - ed = TO_NAT((nextop & 7) + (rex.b << 3)); - MOV64xw(x5, i64); - emit_xor32(dyn, ninst, rex, ed, x5, x3, x4); + INST_NAME("Invalid LOCK"); + UDF(0); + *need_epilog = 1; + *ok = 0; } else { + if(opcode==0x81) {INST_NAME("LOCK XOR Ed, Id");} else {INST_NAME("LOCK XOR Ed, Ib");} + SETFLAGS(X_ALL, SF_SET_PENDING); addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, (opcode==0x81)?4:1); if(opcode==0x81) i64 = F32S; else i64 = F8S; if(cpuext.atomics) { @@ -1632,41 +1520,24 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin } break; case 7: //CMP - if(opcode==0x81) {INST_NAME("(LOCK) CMP Ed, Id");} else {INST_NAME("(LOCK) CMP Ed, Ib");} - SETFLAGS(X_ALL, SF_SET_PENDING); - GETED((opcode==0x81)?4:1); - // No need to LOCK, this is readonly - if(opcode==0x81) i64 = F32S; else i64 = F8S; - if(i64) { - MOV64xw(x5, i64); - emit_cmp32(dyn, ninst, rex, ed, x5, x3, x4, x6); - } else { - emit_cmp32_0(dyn, ninst, rex, ed, x3, x4); - } + INST_NAME("Invalid LOCK"); + UDF(0); + *need_epilog = 1; + *ok = 0; break; } break; case 0x86: - INST_NAME("LOCK XCHG Eb, Gb"); - // Do the swap nextop = F8; if(MODREG) { - GETGB(x4); - if(rex.rex) { - ed = TO_NAT((nextop & 7) + (rex.b << 3)); - eb1 = ed; - eb2 = 0; - } else { - ed = (nextop&7); - eb1 = TO_NAT(ed & 3); - eb2 = ((ed&4)<<1); - } - UBFXw(x1, eb1, eb2, 8); - // do the swap 14 -> ed, 1 -> gd - BFIx(gb1, x1, gb2, 8); - BFIx(eb1, x4, eb2, 8); + INST_NAME("Invalid LOCK"); + UDF(0); + *need_epilog = 1; + *ok = 0; } else { + INST_NAME("LOCK XCHG Eb, Gb"); + // Do the swap GETGB(x4); addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 0); if(cpuext.atomics) { @@ -1683,15 +1554,14 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin } break; case 0x87: - INST_NAME("LOCK XCHG Ed, Gd"); nextop = F8; if(MODREG) { - GETGD; - GETED(0); - MOVxw_REG(x1, gd); - MOVxw_REG(gd, ed); - MOVxw_REG(ed, x1); + INST_NAME("Invalid LOCK"); + UDF(0); + *need_epilog = 1; + *ok = 0; } else { + INST_NAME("LOCK XCHG Ed, Gd"); GETGD; addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 0); if(!ALIGNED_ATOMICxw) { @@ -1740,19 +1610,19 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin switch((nextop>>3)&7) { case 0: case 1: - INST_NAME("LOCK TEST Eb, Ib"); - SETFLAGS(X_ALL, SF_SET_PENDING); - GETEB(x1, 1); - u8 = F8; - emit_test8c(dyn, ninst, x1, u8, x3, x4, x5); + INST_NAME("Invalid LOCK"); + UDF(0); + *need_epilog = 1; + *ok = 0; break; case 2: - INST_NAME("LOCK NOT Eb"); if(MODREG) { - GETEB(x1, 0); - MVNw_REG(x1, x1); - EBBACK; + INST_NAME("Invalid LOCK"); + UDF(0); + *need_epilog = 1; + *ok = 0; } else { + INST_NAME("LOCK NOT Eb"); addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 0); if(cpuext.atomics) { MOV32w(x1, 0xff); @@ -1774,12 +1644,13 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin nextop = F8; switch((nextop>>3)&7) { case 2: - INST_NAME("LOCK NOT Ed"); if(MODREG) { - GETED(x1); - MVNw_REG(x1, x1); - EBBACK; + INST_NAME("Invalid LOCK"); + UDF(0); + *need_epilog = 1; + *ok = 0; } else { + INST_NAME("LOCK NOT Ed"); addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 0); if(cpuext.atomics) { MOV64x(x1, ~0LL); @@ -1803,13 +1674,14 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin switch((nextop>>3)&7) { case 0: // INC Eb - INST_NAME("LOCK INC Eb"); - SETFLAGS(X_ALL&~X_CF, SF_SUBSET); if(MODREG) { - GETEB(x1, 0); - emit_inc8(dyn, ninst, x1, x2, x4); - EBBACK; + INST_NAME("Invalid LOCK"); + UDF(0); + *need_epilog = 1; + *ok = 0; } else { + INST_NAME("LOCK INC Eb"); + SETFLAGS(X_ALL&~X_CF, SF_SUBSET); addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 0); MARKLOCK; if(cpuext.atomics) { @@ -1829,13 +1701,14 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin } break; case 1: //DEC Eb - INST_NAME("LOCK DEC Eb"); - SETFLAGS(X_ALL&~X_CF, SF_SUBSET); if(MODREG) { - GETEB(x1, 0); - emit_dec8(dyn, ninst, x1, x2, x4); - EBBACK; + INST_NAME("Invalid LOCK"); + UDF(0); + *need_epilog = 1; + *ok = 0; } else { + INST_NAME("LOCK DEC Eb"); + SETFLAGS(X_ALL&~X_CF, SF_SUBSET); addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 0); if(cpuext.atomics) { MOV32w(x3, -1); @@ -1863,12 +1736,14 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin switch((nextop>>3)&7) { case 0: // INC Ed - INST_NAME("LOCK INC Ed"); - SETFLAGS(X_ALL&~X_CF, SF_SUBSET); if(MODREG) { - ed = TO_NAT((nextop & 7) + (rex.b << 3)); - emit_inc32(dyn, ninst, rex, ed, x3, x4); + INST_NAME("Invalid LOCK"); + UDF(0); + *need_epilog = 1; + *ok = 0; } else { + INST_NAME("LOCK INC Ed"); + SETFLAGS(X_ALL&~X_CF, SF_SUBSET); addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 0); if(!ALIGNED_ATOMICxw) { if(cpuext.uscat) { @@ -1917,12 +1792,14 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin } break; case 1: //DEC Ed - INST_NAME("LOCK DEC Ed"); - SETFLAGS(X_ALL&~X_CF, SF_SUBSET); if(MODREG) { - ed = TO_NAT((nextop & 7) + (rex.b << 3)); - emit_dec32(dyn, ninst, rex, ed, x3, x4); + INST_NAME("Invalid LOCK"); + UDF(0); + *need_epilog = 1; + *ok = 0; } else { + INST_NAME("LOCK DEC Ed"); + SETFLAGS(X_ALL&~X_CF, SF_SUBSET); addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 0); if(!ALIGNED_ATOMICxw) { if(cpuext.uscat) { @@ -1971,7 +1848,11 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin } break; default: - DEFAULT; + INST_NAME("Invalid LOCK"); + UDF(0); + *need_epilog = 1; + *ok = 0; + break; } break; |