diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/dynarec/arm64/dynarec_arm64_66f0.c | 33 |
1 files changed, 33 insertions, 0 deletions
diff --git a/src/dynarec/arm64/dynarec_arm64_66f0.c b/src/dynarec/arm64/dynarec_arm64_66f0.c index a86bd625..57625e25 100644 --- a/src/dynarec/arm64/dynarec_arm64_66f0.c +++ b/src/dynarec/arm64/dynarec_arm64_66f0.c @@ -177,6 +177,7 @@ uintptr_t dynarec64_66F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n DEFAULT; } break; + case 0x11: INST_NAME("LOCK ADC Ew, Gw"); READFLAGS(X_CF); @@ -198,6 +199,38 @@ uintptr_t dynarec64_66F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n SMDMB(); } break; + + case 0x21: + INST_NAME("LOCK AND Ew, Gw"); + SETFLAGS(X_ALL, SF_SET_PENDING); + nextop = F8; + GETGW(x5); + if(MODREG) { + ed = xRAX+(nextop&7)+(rex.b<<3); + UXTHw(x6, ed); + emit_and16(dyn, ninst, x6, gd, x3, x4); + BFIx(ed, x6, 0, 16); + } else { + addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 0); + if(arm64_atomics) { + MVNw_REG(x3, gd); + UFLAG_IF { + LDCLRALH(x3, x1, wback); + emit_and16(dyn, ninst, x1, gd, x3, x4); + } else { + STCLRLH(x3, wback); + } + } else { + MARKLOCK; + LDAXRH(x1, wback); + emit_and16(dyn, ninst, x1, gd, x3, x4); + STLXRH(x3, x1, wback); + CBNZx_MARKLOCK(x3); + } + SMDMB(); + } + break; + case 0x81: case 0x83: nextop = F8; |