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