diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2024-02-06 16:13:36 +0100 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2024-02-06 16:13:36 +0100 |
| commit | a60d9459683d309171748615b940e57464f1e250 (patch) | |
| tree | 8013b5b958a4d5ee586b43f136f269324e5864b9 /src | |
| parent | f8fa53aa3bb5a15072000cf0ef10333a5383871a (diff) | |
| download | box64-a60d9459683d309171748615b940e57464f1e250.tar.gz box64-a60d9459683d309171748615b940e57464f1e250.zip | |
[ARM64_DYNAREC] Added an unaligned path for F0 0F C7 /1 opcode
Diffstat (limited to 'src')
| -rw-r--r-- | src/dynarec/arm64/dynarec_arm64_f0.c | 36 |
1 files changed, 36 insertions, 0 deletions
diff --git a/src/dynarec/arm64/dynarec_arm64_f0.c b/src/dynarec/arm64/dynarec_arm64_f0.c index 3748b561..85d0a87c 100644 --- a/src/dynarec/arm64/dynarec_arm64_f0.c +++ b/src/dynarec/arm64/dynarec_arm64_f0.c @@ -646,10 +646,16 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin case 0xC7: switch(rep) { case 0: + switch((nextop>>3)&7) { + case 1: INST_NAME("LOCK CMPXCHG8B Gq, Eq"); SETFLAGS(X_ZF, SF_SUBSET); nextop = F8; addr = geted(dyn, addr, ninst, nextop, &wback, x1, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 0); + if(!ALIGNED_ATOMICxw) { + TSTx_mask(wback, 1, 0, 1+rex.w); // mask=3 or 7 + B_MARK(cNE); // unaligned + } if(arm64_atomics) { MOVx_REG(x2, xRAX); MOVx_REG(x3, xRDX); @@ -663,6 +669,9 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin } MOVx_REG(xRAX, x2); MOVx_REG(xRDX, x3); + if(!ALIGNED_ATOMICxw) { + B_NEXT_nocond; + } } else { MARKLOCK; LDAXPxw(x2, x3, wback); @@ -681,6 +690,30 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin UFLAG_IF { MOV32w(x1, 0); } + if(!ALIGNED_ATOMICxw) { + B_MARK3_nocond; + } + } + if(!ALIGNED_ATOMICxw) { + MARK; + LDPxw_S7_offset(x2, x3, wback, 0); + LDAXRB(x4, wback); + CMPSxw_REG(xRAX, x2); + CCMPxw(xRDX, x3, 0, cEQ); + B_MARK(cNE); // EAX!=ED[0] || EDX!=Ed[1] + STLXRB(x4, xRBX, wback); + CBNZx_MARK(x4); + STPxw_S7_offset(xRBX, xRCX, wback, 0); + UFLAG_IF { + MOV32w(x1, 1); + } + B_MARK3_nocond; + MARK; + MOVxw_REG(xRAX, x2); + MOVxw_REG(xRDX, x3); + UFLAG_IF { + MOV32w(x1, 0); + } } MARK3; SMDMB(); @@ -690,6 +723,9 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin break; default: DEFAULT; + } + default: + DEFAULT; } break; |