diff options
| author | Yang Liu <liuyang22@iscas.ac.cn> | 2023-12-07 23:24:23 +0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-12-07 16:24:23 +0100 |
| commit | 92fff0c903e28feb8c5cde79cf835cd9209c7f53 (patch) | |
| tree | 27527cc663cabcf27bb90b21987c54acf46aae90 /src | |
| parent | 06319911d4681f2a38ca50a4cf0c36617dba4097 (diff) | |
| download | box64-92fff0c903e28feb8c5cde79cf835cd9209c7f53.tar.gz box64-92fff0c903e28feb8c5cde79cf835cd9209c7f53.zip | |
[DYNAREC_RV64] Added unaligned support for some LOCK opcodes (#1123)
Diffstat (limited to 'src')
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_f0.c | 46 |
1 files changed, 43 insertions, 3 deletions
diff --git a/src/dynarec/rv64/dynarec_rv64_f0.c b/src/dynarec/rv64/dynarec_rv64_f0.c index c4373c44..469ae5bb 100644 --- a/src/dynarec/rv64/dynarec_rv64_f0.c +++ b/src/dynarec/rv64/dynarec_rv64_f0.c @@ -214,13 +214,30 @@ uintptr_t dynarec64_F0(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni } else { SMDMB(); addr = geted(dyn, addr, ninst, nextop, &wback, x2, x1, &fixedaddress, rex, LOCK_LOCK, 0, 0); + // TODO: Add support for BOX4_DYNAREC_ALIGNED_ATOMICS. + ANDI(x1, wback, (1 << (rex.w + 2)) - 1); + BNEZ_MARK3(x1); + // Aligned MARKLOCK; LRxw(x1, wback, 1, 1); SUBxw(x3, x1, xRAX); - BNE_MARK(x3, xZR); + BNEZ_MARK(x3); // EAX == Ed SCxw(x4, gd, wback, 1, 1); BNEZ_MARKLOCK(x4); + B_MARK_nocond; + MARK3; + // Unaligned + ANDI(x5, wback, -(1 << (rex.w + 2))); + MARK2; // Use MARK2 as a "MARKLOCK" since we're running out of marks. + LDxw(x6, wback, 0); + LRxw(x1, x5, 1, 1); + SUBxw(x3, x6, xRAX); + BNEZ_MARK(x3); + // EAX == Ed + SCxw(x4, x1, x5, 1, 1); + BNEZ_MARK2(x4); + SDxw(gd, wback, 0); MARK; UFLAG_IF {emit_cmp32(dyn, ninst, rex, xRAX, x1, x3, x4, x5, x6);} MVxw(xRAX, x1); @@ -533,11 +550,16 @@ uintptr_t dynarec64_F0(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni ed = xRAX+(nextop&7)+(rex.b<<3); emit_add32c(dyn, ninst, rex, ed, i64, x3, x4, x5, x6); } else { + SMDMB(); addr = geted(dyn, addr, ninst, nextop, &wback, x2, x1, &fixedaddress, rex, LOCK_LOCK, 0, (opcode==0x81)?4:1); if(opcode==0x81) i64 = F32S; else i64 = F8S; + // TODO: Add support for BOX4_DYNAREC_ALIGNED_ATOMICS. + ANDI(x1, wback, (1 << (rex.w + 2)) - 1); + BNEZ_MARK3(x1); + // Aligned MARKLOCK; LRxw(x1, wback, 1, 1); - if(i64>=-2048 && i64<2048) + if (i64 >= -2048 && i64 < 2048) ADDIxw(x4, x1, i64); else { MOV64xw(x4, i64); @@ -545,8 +567,26 @@ uintptr_t dynarec64_F0(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni } SCxw(x3, x4, wback, 1, 1); BNEZ_MARKLOCK(x3); - IFX(X_ALL|X_PEND) + B_MARK_nocond; + MARK3; + // Unaligned + ANDI(x5, wback, -(1 << (rex.w + 2))); + MARK2; // Use MARK2 as a "MARKLOCK" since we're running out of marks. + LDxw(x6, wback, 0); + LRxw(x1, x5, 1, 1); + if (i64 >= -2048 && i64 < 2048) + ADDIxw(x4, x6, i64); + else { + MOV64xw(x4, i64); + ADDxw(x4, x6, x4); + } + SCxw(x3, x1, x5, 1, 1); + BNEZ_MARK2(x3); + SDxw(x4, wback, 0); + MARK; + IFX (X_ALL | X_PEND) emit_add32c(dyn, ninst, rex, x1, i64, x3, x4, x5, x6); + SMDMB(); } break; case 1: // OR |