diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2025-03-10 14:33:40 +0100 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2025-03-10 14:33:40 +0100 |
| commit | 216cf51d4a3aaa9dacc58cdbc569d40ea64ac50e (patch) | |
| tree | 7ede107e7a486f9e8e288c5b08b0a85aff07cc94 /src | |
| parent | 1476b502a27226395535fd67123d72b10c8796cc (diff) | |
| download | box64-216cf51d4a3aaa9dacc58cdbc569d40ea64ac50e.tar.gz box64-216cf51d4a3aaa9dacc58cdbc569d40ea64ac50e.zip | |
[RV64_DYNAREC] Added 66 F0 81/83 /1 opcode
Diffstat (limited to 'src')
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_66f0.c | 66 |
1 files changed, 66 insertions, 0 deletions
diff --git a/src/dynarec/rv64/dynarec_rv64_66f0.c b/src/dynarec/rv64/dynarec_rv64_66f0.c index 22263a42..831f1606 100644 --- a/src/dynarec/rv64/dynarec_rv64_66f0.c +++ b/src/dynarec/rv64/dynarec_rv64_66f0.c @@ -125,6 +125,72 @@ uintptr_t dynarec64_66F0(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int } } break; + case 1: // OR + if (opcode == 0x81) { + INST_NAME("LOCK OR Ew, Iw"); + } else { + INST_NAME("LOCK OR Ew, Ib"); + } + SETFLAGS(X_ALL, SF_SET_PENDING, NAT_FLAGS_FUSION); + if (MODREG) { + if (opcode == 0x81) + u64 = F16; + else + u64 = (uint16_t)(int16_t)F8S; + ed = TO_NAT((nextop & 7) + (rex.b << 3)); + MOV64x(x5, u64); + ZEXTH(x6, ed); + emit_or16(dyn, ninst, x6, x5, x3, x4); + SRLI(ed, ed, 16); + SLLI(ed, ed, 16); + OR(ed, ed, x6); + } else { + addr = geted(dyn, addr, ninst, nextop, &wback, x2, x1, &fixedaddress, rex, LOCK_LOCK, 0, (opcode == 0x81) ? 2 : 1); + if (opcode == 0x81) + u64 = F16; + else + u64 = (uint16_t)(int16_t)F8S; + MOV64x(x5, u64); + + ANDI(x3, wback, 0b10); + BNEZ_MARK(x3); + + // lower 16 bits + MARKLOCK; + LR_W(x1, wback, 1, 1); + SRLIW(x3, x1, 16); + SLLIW(x3, x3, 16); + OR(x4, x1, x5); + OR(x4, x4, x3); + SC_W(x3, x4, wback, 1, 1); + BNEZ_MARKLOCK(x3); + IFXORNAT (X_ALL | X_PEND) { + SLLIW(x1, x1, 16); + SRLIW(x1, x1, 16); + } + B_MARK3_nocond; + + MARK; + // upper 16 bits + XORI(wback, wback, 0b10); + MARK2; + LR_W(x1, wback, 1, 1); + SLLIW(x3, x1, 16); + SRLIW(x3, x3, 16); + SRLIW(x1, x1, 16); + OR(x4, x1, x5); + SLLIW(x4, x4, 16); + OR(x4, x4, x3); + SC_W(x3, x4, wback, 1, 1); + BNEZ_MARK2(x3); + + MARK3; + // final + IFXORNAT (X_ALL | X_PEND) { + emit_or16(dyn, ninst, x1, x5, x3, x4); + } + } + break; default: DEFAULT; } |