diff options
| author | Yang Liu <liuyang22@iscas.ac.cn> | 2024-05-23 18:04:09 +0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-05-23 12:04:09 +0200 |
| commit | bf9d297dcd840fb71797080d55f36714dbdf624a (patch) | |
| tree | 68e035804b4d84c14017696744f10a73f8ee1270 | |
| parent | 080cc772083be446132557e3b2e6aad1b59c0e3f (diff) | |
| download | box64-bf9d297dcd840fb71797080d55f36714dbdf624a.tar.gz box64-bf9d297dcd840fb71797080d55f36714dbdf624a.zip | |
[RV64_DYNAREC] Fixed LOCK XCHG byte opcode (#1526)
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_00_2.c | 38 |
1 files changed, 34 insertions, 4 deletions
diff --git a/src/dynarec/rv64/dynarec_rv64_00_2.c b/src/dynarec/rv64/dynarec_rv64_00_2.c index e62c73e9..fbabc49a 100644 --- a/src/dynarec/rv64/dynarec_rv64_00_2.c +++ b/src/dynarec/rv64/dynarec_rv64_00_2.c @@ -226,7 +226,7 @@ uintptr_t dynarec64_00_2(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int emit_test32(dyn, ninst, rex, ed, gd, x3, x4, x5); break; case 0x86: - INST_NAME("(LOCK)XCHG Eb, Gb"); + INST_NAME("(LOCK) XCHG Eb, Gb"); nextop = F8; if(MODREG) { GETGB(x1); @@ -240,9 +240,39 @@ uintptr_t dynarec64_00_2(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int GETGB(x3); addr = geted(dyn, addr, ninst, nextop, &ed, x2, x1, &fixedaddress, rex, LOCK_LOCK, 0, 0); SMDMB(); - LBU(x1, ed, 0); - SB(gd, ed, 0); - SMDMB(); + + // calculate shift amount + ANDI(x1, ed, 0x3); + SLLI(x1, x1, 3); + + // align address to 4-bytes to use ll.w/sc.w + ADDI(x4, xZR, 0xffc); + AND(x6, ed, x4); + + // load aligned data + LWU(x5, x6, 0); + + // insert gd byte into the aligned data + ADDI(x4, xZR, 0xff); + SLL(x4, x4, x1); + NOT(x4, x4); + AND(x4, x5, x4); + SLL(x5, gd, x1); + OR(x4, x4, x5); + + // do aligned ll/sc sequence + MARKLOCK; + LR_W(x1, x6, 1, 1); + SC_W(x5, x4, x6, 1, 1); + BNEZ_MARKLOCK(x5); + + // calculate shift amount again + ANDI(x4, ed, 0x3); + SLLI(x4, x4, 3); + + // extract loaded byte + SRL(x1, x1, x4); + gd = x1; GBBACK(x3); } |