diff options
| author | xctan <xctan@cirno.icu> | 2023-06-02 14:19:45 +0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-06-02 08:19:45 +0200 |
| commit | 5e19c8f142a11bca2613c1e54004bb848e08ac6a (patch) | |
| tree | 832c79ff66d28e5b8c36a128fea80a47c2434d13 /src | |
| parent | a6737720f4abca8794fffbff1ba0dfbd9ef9b22b (diff) | |
| download | box64-5e19c8f142a11bca2613c1e54004bb848e08ac6a.tar.gz box64-5e19c8f142a11bca2613c1e54004bb848e08ac6a.zip | |
[RV64_DYNAREC] Added more opcodes for ICEY (#816)
* [RV64_DYNAREC] Added 66 AF SCASW opcode
* [RV64_DYNAREC] Added DD /7 FNSTSW opcode
* [RV64_DYNAREC] Added {D0,D2} /0 ROL opcode
* [RV64_DYNAREC] Added {D0,D2} /{4,6} SHL opcodeDiffstat (limited to 'src')
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_00_3.c | 35 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_66.c | 48 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_dd.c | 17 |
3 files changed, 100 insertions, 0 deletions
diff --git a/src/dynarec/rv64/dynarec_rv64_00_3.c b/src/dynarec/rv64/dynarec_rv64_00_3.c index 00de07fe..9d6fa74e 100644 --- a/src/dynarec/rv64/dynarec_rv64_00_3.c +++ b/src/dynarec/rv64/dynarec_rv64_00_3.c @@ -358,6 +358,24 @@ uintptr_t dynarec64_00_3(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int case 0xD2: // TODO: Jump if CL is 0 nextop = F8; switch((nextop>>3)&7) { + case 0: + if(opcode==0xD0) { + INST_NAME("ROL Eb, 1"); + MOV32w(x2, 1); + } else { + INST_NAME("ROL Eb, CL"); + ANDI(x2, xRCX, 7); + } + SETFLAGS(X_OF|X_CF, SF_PENDING); + GETEB(x1, 0); + UFLAG_OP12(ed, x2); + SLL(x3, ed, x2); + SRLI(x4, x3, 8); + OR(ed, x3, x4); + EBBACK(x5, 1); + UFLAG_RES(ed); + UFLAG_DF(x3, d_rol8); + break; case 1: if(opcode==0xD0) { INST_NAME("ROR Eb, 1"); @@ -377,6 +395,23 @@ uintptr_t dynarec64_00_3(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int UFLAG_RES(ed); UFLAG_DF(x3, d_ror8); break; + case 4: + case 6: + if(opcode==0xD0) { + INST_NAME("SHL Eb, 1"); + MOV32w(x2, 1); + } else { + INST_NAME("SHL Eb, CL"); + ANDI(x2, xRCX, 7); + } + SETFLAGS(X_ALL, SF_PENDING); + GETEB(x1, 0); + UFLAG_OP12(ed, x2) + SLL(ed, ed, x2); + EBBACK(x5, 1); + UFLAG_RES(ed); + UFLAG_DF(x3, d_shl8); + break; case 5: if(opcode==0xD0) { INST_NAME("SHR Eb, 1"); diff --git a/src/dynarec/rv64/dynarec_rv64_66.c b/src/dynarec/rv64/dynarec_rv64_66.c index 36359a20..ddf79b51 100644 --- a/src/dynarec/rv64/dynarec_rv64_66.c +++ b/src/dynarec/rv64/dynarec_rv64_66.c @@ -538,6 +538,54 @@ uintptr_t dynarec64_66(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni ADD(xRDI, xRDI, x3); } break; + + case 0xAF: + switch (rep) { + case 1: + case 2: + if(rep==1) {INST_NAME("REPNZ SCASW");} else {INST_NAME("REPZ SCASW");} + MAYSETFLAGS(); + SETFLAGS(X_ALL, SF_SET_PENDING); + CBZ_NEXT(xRCX); + GETDIR(x3, x1, rex.w?8:2); + if (rex.w) { + MARK; + LD(x2, xRDI, 0); + ADD(xRDI, xRDI, x3); + ADDI(xRCX, xRCX, -1); + if (rep==1) {BEQ_MARK3(xRAX, x2);} else {BNE_MARK3(xRAX, x2);} + BNE_MARK(xRCX, xZR); + MARK3; + emit_cmp32(dyn, ninst, rex, xRAX, x2, x3, x4, x5, x6); + } else { + ZEXTH(x1, xRAX); + MARK; + LHU(x2, xRDI, 0); + ADD(xRDI, xRDI, x3); + ADDI(xRCX, xRCX, -1); + if (rep==1) {BEQ_MARK3(x1, x2);} else {BNE_MARK3(x1, x2);} + BNE_MARK(xRCX, xZR); + MARK3; + emit_cmp16(dyn, ninst, x1, x2, x3, x4, x5, x6); + } + break; + default: + INST_NAME("SCASW"); + SETFLAGS(X_ALL, SF_SET_PENDING); + GETDIR(x3, x1, rex.w?8:2); + if (rex.w) { + LD(x2, xRDI, 0); + emit_cmp32(dyn, ninst, rex, xRAX, x2, x3, x4, x5, x6); + } else { + ZEXTH(x1, xRAX); + LHU(x2, xRDI, 0); + emit_cmp16(dyn, ninst, x1, x2, x3, x4, x5, x6); + } + ADD(xRDI, xRDI, x3); + break; + } + break; + case 0xB8: case 0xB9: case 0xBA: diff --git a/src/dynarec/rv64/dynarec_rv64_dd.c b/src/dynarec/rv64/dynarec_rv64_dd.c index fa1a6a13..c6151196 100644 --- a/src/dynarec/rv64/dynarec_rv64_dd.c +++ b/src/dynarec/rv64/dynarec_rv64_dd.c @@ -155,6 +155,23 @@ uintptr_t dynarec64_DD(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni FSD(v1, wback, fixedaddress); x87_do_pop(dyn, ninst, x3); break; + case 7: + INST_NAME("FNSTSW m2byte"); + fpu_purgecache(dyn, ninst, 0, x1, x2, x3); + addr = geted(dyn, addr, ninst, nextop, &ed, x4, x6, &fixedaddress, rex, NULL, 0, 0); + LWU(x2, xEmu, offsetof(x64emu_t, top)); + LHU(x3, xEmu, offsetof(x64emu_t, sw)); + if(dyn->e.x87stack) { + // update top + ADDI(x2, x2, -dyn->e.x87stack); + ANDI(x2, x2, 7); + } + MOV32w(x5, ~0x3800); + AND(x3, x3, x5); // mask out TOP + SLLI(x2, x2, 11); // shift TOP to bit 11 + OR(x3, x3, x2); // inject TOP + SH(x3, ed, fixedaddress); // store whole sw flags + break; default: DEFAULT; } |