diff options
| author | Yang Liu <liuyang22@iscas.ac.cn> | 2024-12-19 04:38:17 +0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-12-18 21:38:17 +0100 |
| commit | 39aa02c19cc3df73d264bd668b2a600e4b922a16 (patch) | |
| tree | b1ca909279b4581704aaf0dd1d754d311e67d07b | |
| parent | 7dcb86f500c461a345d6d413b8eb543f3ee733dc (diff) | |
| download | box64-39aa02c19cc3df73d264bd668b2a600e4b922a16.tar.gz box64-39aa02c19cc3df73d264bd668b2a600e4b922a16.zip | |
[RV64_DYNAREC] Added more LOCK prefix opcodes (#2169)
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_f0.c | 79 |
1 files changed, 79 insertions, 0 deletions
diff --git a/src/dynarec/rv64/dynarec_rv64_f0.c b/src/dynarec/rv64/dynarec_rv64_f0.c index a7ef099a..39768752 100644 --- a/src/dynarec/rv64/dynarec_rv64_f0.c +++ b/src/dynarec/rv64/dynarec_rv64_f0.c @@ -94,6 +94,44 @@ uintptr_t dynarec64_F0(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni case 0x0F: nextop = F8; switch (nextop) { + case 0xAB: + INST_NAME("LOCK BTS Ed, Gd"); + SETFLAGS(X_ALL & ~X_ZF, SF_SUBSET, NAT_FLAGS_NOFUSION); + SET_DFNONE(); + nextop = F8; + GETGD; + if (MODREG) { + ed = TO_NAT((nextop & 7) + (rex.b << 3)); + wback = 0; + BEXT(x4, ed, gd, x2); + ANDI(xFlags, xFlags, ~1); + OR(xFlags, xFlags, x4); + ADDI(x4, xZR, 1); + ANDI(x2, gd, rex.w ? 0x3f : 0x1f); + SLL(x4, x4, x2); + OR(ed, ed, x4); + if (!rex.w) ZEROUP(ed); + } else { + SMDMB(); + addr = geted(dyn, addr, ninst, nextop, &wback, x3, x1, &fixedaddress, rex, LOCK_LOCK, 0, 0); + SRAIxw(x1, gd, 5 + rex.w); + ADDSL(x3, wback, x1, 2 + rex.w, x1); + ed = x1; + wback = x3; + MARKLOCK; + LRxw(ed, wback, 1, 1); + BEXT(x4, ed, gd, x2); + ANDI(xFlags, xFlags, ~1); + OR(xFlags, xFlags, x4); + ADDI(x4, xZR, 1); + ANDI(x2, gd, rex.w ? 0x3f : 0x1f); + SLL(x4, x4, x2); + OR(ed, ed, x4); + SCxw(x7, ed, wback, 1, 1); + BNEZ_MARKLOCK(x7); + SMDMB(); + } + break; case 0xB0: switch (rep) { case 0: @@ -236,6 +274,47 @@ uintptr_t dynarec64_F0(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni DEFAULT; } break; + case 0xB3: + INST_NAME("LOCK BTR Ed, Gd"); + SETFLAGS(X_ALL & ~X_ZF, SF_SUBSET, NAT_FLAGS_NOFUSION); + SET_DFNONE(); + nextop = F8; + GETGD; + if (MODREG) { + ed = TO_NAT((nextop & 7) + (rex.b << 3)); + wback = 0; + BEXT(x4, ed, gd, x2); // F_CF is 1 + ANDI(xFlags, xFlags, ~1); + OR(xFlags, xFlags, x4); + ADDI(x4, xZR, 1); + ANDI(x2, gd, rex.w ? 0x3f : 0x1f); + SLL(x4, x4, x2); + NOT(x4, x4); + AND(ed, ed, x4); + if (!rex.w) ZEROUP(ed); + } else { + SMDMB(); + addr = geted(dyn, addr, ninst, nextop, &wback, x3, x1, &fixedaddress, rex, LOCK_LOCK, 0, 0); + SRAIxw(x1, gd, 5 + rex.w); + ADDSL(x3, wback, x1, 2 + rex.w, x1); + LDxw(x1, x3, fixedaddress); + ed = x1; + wback = x3; + MARKLOCK; + LRxw(ed, wback, 1, 1); + BEXT(x4, ed, gd, x2); // F_CF is 1 + ANDI(xFlags, xFlags, ~1); + OR(xFlags, xFlags, x4); + ADDI(x4, xZR, 1); + ANDI(x2, gd, rex.w ? 0x3f : 0x1f); + SLL(x4, x4, x2); + NOT(x4, x4); + AND(ed, ed, x4); + SCxw(x7, ed, wback, 1, 1); + BNEZ_MARKLOCK(x7); + SMDMB(); + } + break; case 0xC1: switch (rep) { case 0: |