diff options
| author | Yang Liu <liuyang22@iscas.ac.cn> | 2025-05-21 18:36:36 +0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-05-21 12:36:36 +0200 |
| commit | 8c51be6985e0281ebbb62093b59f295b266e0369 (patch) | |
| tree | a1d6a329b6b819596f369bfbddf6f193d582aad6 /src | |
| parent | f25af13f795756fd70285fe9a285077497158630 (diff) | |
| download | box64-8c51be6985e0281ebbb62093b59f295b266e0369.tar.gz box64-8c51be6985e0281ebbb62093b59f295b266e0369.zip | |
[RV64_DYNAREC] Implemented unaligned path for LOCK INC/DEC opcodes (#2656)
Diffstat (limited to 'src')
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_f0.c | 42 |
1 files changed, 34 insertions, 8 deletions
diff --git a/src/dynarec/rv64/dynarec_rv64_f0.c b/src/dynarec/rv64/dynarec_rv64_f0.c index 84816cea..4a7f3257 100644 --- a/src/dynarec/rv64/dynarec_rv64_f0.c +++ b/src/dynarec/rv64/dynarec_rv64_f0.c @@ -851,13 +851,26 @@ uintptr_t dynarec64_F0(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni emit_inc32(dyn, ninst, rex, ed, x3, x4, x5, x6); } else { addr = geted(dyn, addr, ninst, nextop, &wback, x2, x1, &fixedaddress, rex, LOCK_LOCK, 0, 0); - MARKLOCK; - LRxw(x1, wback, 1, 1); + ANDI(x1, wback, (1 << (rex.w + 2)) - 1); + BNEZ_MARK3(x1); + // Aligned + ADDIxw(x4, xZR, 1); + AMOADDxw(x1, x4, wback, 1, 1); + B_MARK_nocond; + MARK3; + // Unaligned + ANDI(x5, wback, -(1 << (rex.w + 2))); + MARKLOCK2; + LDxw(x1, wback, 0); + LRxw(x6, x5, 1, 1); ADDIxw(x4, x1, 1); - SCxw(x3, x4, wback, 1, 1); - BNEZ_MARKLOCK(x3); + SCxw(x3, x6, x5, 1, 1); + BNEZ_MARKLOCK2(x3); + SDxw(x4, wback, 0); + MARK; IFXORNAT (X_ALL | X_PEND) emit_inc32(dyn, ninst, rex, x1, x3, x4, x5, x6); + SMDMB(); } break; case 1: // DEC Ed @@ -869,13 +882,26 @@ uintptr_t dynarec64_F0(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni emit_dec32(dyn, ninst, rex, ed, x3, x4, x5, x6); } else { addr = geted(dyn, addr, ninst, nextop, &wback, x2, x1, &fixedaddress, rex, LOCK_LOCK, 0, 0); - MARKLOCK; - LRxw(x1, wback, 1, 1); + ANDI(x1, wback, (1 << (rex.w + 2)) - 1); + BNEZ_MARK3(x1); + // Aligned + ADDIxw(x4, xZR, -1); + AMOADDxw(x1, x4, wback, 1, 1); + B_MARK_nocond; + MARK3; + // Unaligned + ANDI(x5, wback, -(1 << (rex.w + 2))); + MARKLOCK2; + LDxw(x1, wback, 0); + LRxw(x6, x5, 1, 1); ADDIxw(x4, x1, -1); - SCxw(x3, x4, wback, 1, 1); - BNEZ_MARKLOCK(x3); + SCxw(x3, x6, x5, 1, 1); + BNEZ_MARKLOCK2(x3); + SDxw(x4, wback, 0); + MARK; IFXORNAT (X_ALL | X_PEND) emit_dec32(dyn, ninst, rex, x1, x3, x4, x5, x6); + SMDMB(); } break; default: |