diff options
| author | Yang Liu <liuyang22@iscas.ac.cn> | 2023-04-08 20:49:35 +0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-04-08 14:49:35 +0200 |
| commit | 24a374500c3f0aa3579949c26fba24702ada74c8 (patch) | |
| tree | e38b8b009a7e9e7bbd5cfbee4a2c4d1a4d70e94f /src | |
| parent | b9cd6d3505b567dc4f5e0848e74f495961de397a (diff) | |
| download | box64-24a374500c3f0aa3579949c26fba24702ada74c8.tar.gz box64-24a374500c3f0aa3579949c26fba24702ada74c8.zip | |
[RV64_DYNAREC] Added more opcodes for Stardew Valley and some fixes (#674)
* [RV64_DYNAREC] Added 86 (LOCK)XCHG opcode * [RV64_DYNAREC] Added 66 0F 61 PUNPCKLWD opcode * [RV64_DYNAREC] Added 66 0F 72 /4 PSRAD opcode * [RV64_DYNAREC] Added F0 81,83 /5 LOCK SUB opcode * [RV64_DYNAREC] Fixed 86 (LOCK) XCHG opcode * [RV64_DYNAREC] Fixed 87 (LOCK) XCHG opcode again * [RV64_DYNAREC] Fixed 86 (LOCK) XCHG opcode again * [RV64_DYNAREC] Fixed 66 0F 72 /4 PSRAD opcode
Diffstat (limited to 'src')
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_00.c | 25 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_660f.c | 33 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_f0.c | 34 |
3 files changed, 87 insertions, 5 deletions
diff --git a/src/dynarec/rv64/dynarec_rv64_00.c b/src/dynarec/rv64/dynarec_rv64_00.c index 0dae504d..2454662d 100644 --- a/src/dynarec/rv64/dynarec_rv64_00.c +++ b/src/dynarec/rv64/dynarec_rv64_00.c @@ -723,7 +723,28 @@ uintptr_t dynarec64_00(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni GETED(0); emit_test32(dyn, ninst, rex, ed, gd, x3, x4, x5); break; - + case 0x86: + INST_NAME("(LOCK)XCHG Eb, Gb"); + nextop = F8; + if(MODREG) { + GETGB(x1); + GETEB(x2, 0); + MV(x4, gd); + MV(gd, ed); + MV(ed, x4); + GBBACK(x4); + EBBACK(x4, 0); + } else { + 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(); + gd = x1; + GBBACK(x3); + } + break; case 0x87: INST_NAME("(LOCK)XCHG Ed, Gd"); nextop = F8; @@ -738,7 +759,7 @@ uintptr_t dynarec64_00(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni addr = geted(dyn, addr, ninst, nextop, &ed, x2, x1, &fixedaddress, rex, LOCK_LOCK, 0, 0); SMDMB(); ANDI(x3, ed, (1<<(2+rex.w))-1); - BEQ_MARK(x3, xZR); + BNE_MARK(x3, xZR); MARKLOCK; LRxw(x1, ed, 1, 0); SCxw(x3, gd, ed, 0, 1); diff --git a/src/dynarec/rv64/dynarec_rv64_660f.c b/src/dynarec/rv64/dynarec_rv64_660f.c index 0de4e4eb..cbffe1c1 100644 --- a/src/dynarec/rv64/dynarec_rv64_660f.c +++ b/src/dynarec/rv64/dynarec_rv64_660f.c @@ -155,6 +155,30 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int GETGX(x2); SSE_LOOP_Q(x3, x4, XOR(x3, x3, x4)); break; + case 0x61: + INST_NAME("PUNPCKLWD Gx,Ex"); + nextop = F8; + GETEX(x1, 0); + GETGX(x2); + for(int i=3; i>0; --i) { + // GX->uw[2 * i] = GX->uw[i]; + LHU(x3, gback, i*2); + SH(x3, gback, 2*i*2); + } + if (MODREG && (ed==gd)) { + for(int i=0; i<4; ++i) { + // GX->uw[2 * i + 1] = GX->uw[2 * i]; + LHU(x3, gback, 2*i*2); + SH(x3, gback, (2*i+1)*2); + } + } else { + for(int i=0; i<4; ++i) { + // GX->uw[2 * i + 1] = EX->uw[i]; + LHU(x3, wback, fixedaddress+i*2); + SH(x3, gback, (2*i+1)*2); + } + } + break; case 0x62: INST_NAME("PUNPCKLDQ Gx,Ex"); nextop = F8; @@ -256,6 +280,15 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int } } break; + case 4: + INST_NAME("PSRAD Ex, Ib"); + GETEX(x1, 1); + u8 = F8; + if(u8>31) u8=31; + if (u8) { + SSE_LOOP_DS(x3, SRAIW(x3, x3, u8)); + } + break; case 6: INST_NAME("PSLLD Ex, Ib"); GETEX(x1, 1); diff --git a/src/dynarec/rv64/dynarec_rv64_f0.c b/src/dynarec/rv64/dynarec_rv64_f0.c index a14b4b18..ec3fb824 100644 --- a/src/dynarec/rv64/dynarec_rv64_f0.c +++ b/src/dynarec/rv64/dynarec_rv64_f0.c @@ -156,11 +156,11 @@ uintptr_t dynarec64_F0(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni if(opcode==0x81) i64 = F32S; else i64 = F8S; MARKLOCK; LRxw(x1, wback, 1, 1); - if(i64>-2048 && i64<2047) - ADDI(x4, x1, i64); + if(i64>=-2048 && i64<2048) + ADDIxw(x4, x1, i64); else { MOV64xw(x4, i64); - ADD(x4, x1, x4); + ADDxw(x4, x1, x4); } SCxw(x3, x4, wback, 1, 1); BNEZ_MARKLOCK(x3); @@ -168,6 +168,34 @@ uintptr_t dynarec64_F0(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni emit_add32c(dyn, ninst, rex, x1, i64, x3, x4, x5, x6); } break; + case 5: // SUB + if(opcode==0x81) { + INST_NAME("LOCK SUB Ed, Id"); + } else { + INST_NAME("LOCK SUB Ed, Ib"); + } + SETFLAGS(X_ALL, SF_SET_PENDING); + if(MODREG) { + if(opcode==0x81) i64 = F32S; else i64 = F8S; + ed = xRAX+(nextop&7)+(rex.b<<3); + emit_sub32(dyn, ninst, rex, ed, i64, x3, x4, x5); + } else { + 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; + MARKLOCK; + LRxw(x1, wback, 1, 1); + if (i64>-2048 && i64<=2048) { + ADDIxw(x4, x1, -i64); + } else { + MOV64xw(x4, i64); + SUBxw(x4, x1, x4); + } + SCxw(x3, x4, wback, 1, 1); + BNEZ_MARKLOCK(x3); + IFX(X_ALL|X_PEND) + emit_sub32c(dyn, ninst, rex, x1, i64, x3, x4, x5, x6); + } + break; default: DEFAULT; } |