diff options
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 |