diff options
| author | xctan <xctan@cirno.icu> | 2023-07-28 17:31:46 +0000 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-07-28 19:31:46 +0200 |
| commit | f5fadea30e6d71046293f382d98f9f570bd31321 (patch) | |
| tree | 096a4f129e648a6b3ab522b9995be0d18508553e /src | |
| parent | bedfb82066a283e370b1cae60d0f860665dcb904 (diff) | |
| download | box64-f5fadea30e6d71046293f382d98f9f570bd31321.tar.gz box64-f5fadea30e6d71046293f382d98f9f570bd31321.zip | |
[RV64_DYNAREC] Added more opcodes for Yuzu (#911)
* [RV64_DYNAREC] Fixed PTEST opcode * [RV64_DYNAREC] Added 64 66 89 MOV opcode * [RV64_DYNAREC] Added 66 87 XCHG opcode
Diffstat (limited to 'src')
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_66.c | 61 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_660f.c | 2 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_6664.c | 30 |
3 files changed, 91 insertions, 2 deletions
diff --git a/src/dynarec/rv64/dynarec_rv64_66.c b/src/dynarec/rv64/dynarec_rv64_66.c index 49a7ef65..66a9f1c1 100644 --- a/src/dynarec/rv64/dynarec_rv64_66.c +++ b/src/dynarec/rv64/dynarec_rv64_66.c @@ -427,6 +427,67 @@ uintptr_t dynarec64_66(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni GETGW(x2); emit_test16(dyn, ninst, x1, x2, x3, x4, x5); break; + case 0x87: + INST_NAME("(LOCK)XCHG Ew, Gw"); + nextop = F8; + if(MODREG) { + GETGD; + GETED(0); + ADDI(x1, gd, 0); + LUI(x3, 0xffff0); + AND(gd, gd, x3); + ZEXTH(x4, ed); + OR(gd, gd, x4); + AND(ed, ed, x3); + ZEXTH(x4, x1); + OR(ed, ed, x4); + } else { + GETGD; + addr = geted(dyn, addr, ninst, nextop, &ed, x2, x1, &fixedaddress, rex, LOCK_LOCK, 0, 0); + SMDMB(); + + ANDI(x3, ed, 1); + BNEZ_MARK(x3); + + ANDI(x3, ed, 0b10); + LUI(x5, 0xffff0); + ZEXTH(x6, gd); + BNEZ_MARK3(x3); + + MARKLOCK; + LR_W(x1, ed, 1, 0); + AND(x3, x1, x5); + OR(x3, x3, x6); + SC_W(x3, x3, ed, 0, 1); + BNEZ_MARKLOCK(x3); + ZEXTH(x1, x1); + B_MARK2_nocond; + + MARK3; + NOT(x5, x5); + SLLI(x5, x5, 16); + SLLI(x6, x6, 16); + NOT(x5, x5); + LR_W(x1, ed, 1, 0); + AND(x3, x1, x5); + OR(x3, x3, x6); + SC_W(x3, x3, ed, 0, 1); + BNEZ(x3, -4 * 4); + SRLI(x1, x1, 16); + ZEXTH(x1, x1); + B_MARK2_nocond; + + MARK; + LHU(x1, ed, 0); + SH(gd, ed, 0); + + MARK2; + SMDMB(); + LUI(x5, 0xffff0); + AND(gd, gd, x5); + OR(gd, gd, x1); + } + break; case 0x89: INST_NAME("MOV Ew, Gw"); nextop = F8; diff --git a/src/dynarec/rv64/dynarec_rv64_660f.c b/src/dynarec/rv64/dynarec_rv64_660f.c index 3f51289e..86bf0dbe 100644 --- a/src/dynarec/rv64/dynarec_rv64_660f.c +++ b/src/dynarec/rv64/dynarec_rv64_660f.c @@ -411,7 +411,7 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int AND(x4, x4, x6); OR(x3, x3, x4); BNEZ(x3, 8); - ORI(xFlags, xFlags, 1<<F_ZF); + ORI(xFlags, xFlags, 1<<F_CF); } } break; diff --git a/src/dynarec/rv64/dynarec_rv64_6664.c b/src/dynarec/rv64/dynarec_rv64_6664.c index a139e3ae..3acac902 100644 --- a/src/dynarec/rv64/dynarec_rv64_6664.c +++ b/src/dynarec/rv64/dynarec_rv64_6664.c @@ -37,6 +37,35 @@ uintptr_t dynarec64_6664(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int GETREX(); switch(opcode) { + case 0x89: + INST_NAME("MOV FS:Ew, Gw"); + nextop = F8; + GETGD; // don't need GETGW here + if(MODREG) { + ed = xRAX+(nextop&7)+(rex.b<<3); + if(rex.w) { + ADDI(ed, gd, 0); + } else { + if(ed!=gd) { + LUI(x1, 0xffff0); + AND(gd, gd, x1); + ZEXTH(x1, ed); + OR(gd, gd, x1); + } + } + } else { + grab_segdata(dyn, addr, ninst, x4, seg); + addr = geted(dyn, addr, ninst, nextop, &ed, x2, x1, &fixedaddress, rex, NULL, 1, 0); + ADD(x4, ed, x4); + if(rex.w) { + SD(gd, x4, fixedaddress); + } else { + SH(gd, x4, fixedaddress); + } + SMWRITE(); + } + break; + case 0x8B: INST_NAME("MOV Gd, FS:Ed"); nextop=F8; @@ -69,7 +98,6 @@ uintptr_t dynarec64_6664(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int } break; - default: DEFAULT; } |