diff options
| author | Yang Liu <liuyang22@iscas.ac.cn> | 2023-12-11 01:33:46 +0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-12-10 18:33:46 +0100 |
| commit | 9d72c9db1bf113f9a8dba629893ec548b4714c14 (patch) | |
| tree | e4b15d185b2f82e96b1c57aa8959e0972f7e38be /src | |
| parent | 486df332dd2da9ffb2c586417b1ad6f184218a16 (diff) | |
| download | box64-9d72c9db1bf113f9a8dba629893ec548b4714c14.tar.gz box64-9d72c9db1bf113f9a8dba629893ec548b4714c14.zip | |
[DYNAREC_RV64] Added more opcodes for flatout.exe (#1134)
* [DYNAREC_RV64] Added more DA opcodes * [DYNAREC_RV64] Added 0F E9 PSUBSW opcode * [DYNAREC_RV64] Added 0F D9 PSUBUSW opcode * [DYNAREC_RV64] Added more DD opcode * [DYNAREC_RV64] Added more DE opcodes
Diffstat (limited to 'src')
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_0f.c | 52 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_da.c | 44 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_dd.c | 25 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_de.c | 26 |
4 files changed, 123 insertions, 24 deletions
diff --git a/src/dynarec/rv64/dynarec_rv64_0f.c b/src/dynarec/rv64/dynarec_rv64_0f.c index a03ef8e0..c08083ee 100644 --- a/src/dynarec/rv64/dynarec_rv64_0f.c +++ b/src/dynarec/rv64/dynarec_rv64_0f.c @@ -1723,6 +1723,13 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni GETEM(x2, 0); MMX_LOOP_WS(x3, x4, MULW(x3, x3, x4)); break; + case 0xD9: + INST_NAME("PSUBUSW Gm, Em"); + nextop = F8; + GETGM(); + GETEM(x2, 0); + MMX_LOOP_W(x3, x4, SUB(x3, x3, x4); SLT(x4, xZR, x3); NEG(x4, x4); AND(x3, x3, x4)); + break; case 0xDB: INST_NAME("PAND Gm, Em"); nextop = F8; @@ -1764,16 +1771,6 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni SH(x4, gback, gdoffset + i * 2); } break; - case 0xEB: - INST_NAME("POR Gm, Em"); - nextop = F8; - GETGM(); - GETEM(x2, 0); - LD(x3, gback, gdoffset); - LD(x4, wback, fixedaddress); - OR(x3, x3, x4); - SD(x3, gback, gdoffset); - break; case 0xE7: INST_NAME("MOVNTQ Em, Gm"); nextop = F8; @@ -1786,14 +1783,45 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni FSD(v0, ed, fixedaddress); } break; + case 0xE9: + INST_NAME("PSUBSW Gm,Em"); + nextop = F8; + GETGM(); + GETEM(x2, 0); + for (int i = 0; i < 4; ++i) { + // tmp32s = (int32_t)GM->sw[i] - EM->sw[i]; + // GM->sw[i] = (tmp32s>32767)?32767:((tmp32s<-32768)?-32768:tmp32s); + LH(x3, gback, gdoffset + 2 * i); + LH(x4, wback, fixedaddress + 2 * i); + SUBW(x3, x3, x4); + LUI(x4, 0xFFFF8); // -32768 + BGE(x3, x4, 12); + SH(x4, gback, gdoffset + 2 * i); + J(20); // continue + LUI(x4, 8); // 32768 + BLT(x3, x4, 8); + ADDIW(x3, x4, -1); + SH(x3, gback, gdoffset + 2 * i); + } + break; + case 0xEB: + INST_NAME("POR Gm, Em"); + nextop = F8; + GETGM(); + GETEM(x2, 0); + LD(x3, gback, gdoffset); + LD(x4, wback, fixedaddress); + OR(x3, x3, x4); + SD(x3, gback, gdoffset); + break; case 0xED: INST_NAME("PADDSW Gm,Em"); nextop = F8; GETGM(); GETEM(x2, 0); for (int i = 0; i < 4; ++i) { - // tmp32s = (int32_t)GX->sw[i] + EX->sw[i]; - // GX->sw[i] = (tmp32s>32767)?32767:((tmp32s<-32768)?-32768:tmp32s); + // tmp32s = (int32_t)GM->sw[i] + EM->sw[i]; + // GM->sw[i] = (tmp32s>32767)?32767:((tmp32s<-32768)?-32768:tmp32s); LH(x3, gback, gdoffset + 2 * i); LH(x4, wback, fixedaddress + 2 * i); ADDW(x3, x3, x4); diff --git a/src/dynarec/rv64/dynarec_rv64_da.c b/src/dynarec/rv64/dynarec_rv64_da.c index 519ba92f..61584090 100644 --- a/src/dynarec/rv64/dynarec_rv64_da.c +++ b/src/dynarec/rv64/dynarec_rv64_da.c @@ -51,7 +51,16 @@ uintptr_t dynarec64_DA(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni case 0xC5: case 0xC6: case 0xC7: - DEFAULT; + INST_NAME("FCMOVB ST0, STx"); + READFLAGS(X_CF); + v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_COMBINE(0, nextop & 7)); + v2 = x87_get_st(dyn, ninst, x1, x2, nextop & 7, X87_COMBINE(0, nextop & 7)); + ANDI(x1, xFlags, 1 << F_CF); + CBZ_NEXT(x1); + if (ST_IS_F(0)) + FMVS(v1, v2); + else + FMVD(v1, v2); break; case 0xC8: case 0xC9: @@ -61,7 +70,16 @@ uintptr_t dynarec64_DA(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni case 0xCD: case 0xCE: case 0xCF: - DEFAULT; + INST_NAME("FCMOVE ST0, STx"); + READFLAGS(X_ZF); + v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_COMBINE(0, nextop & 7)); + v2 = x87_get_st(dyn, ninst, x1, x2, nextop & 7, X87_COMBINE(0, nextop & 7)); + ANDI(x1, xFlags, 1 << F_ZF); + CBZ_NEXT(x1); + if (ST_IS_F(0)) + FMVS(v1, v2); + else + FMVD(v1, v2); break; case 0xD0: case 0xD1: @@ -71,7 +89,16 @@ uintptr_t dynarec64_DA(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni case 0xD5: case 0xD6: case 0xD7: - DEFAULT; + INST_NAME("FCMOVBE ST0, STx"); + READFLAGS(X_CF | X_ZF); + v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_COMBINE(0, nextop & 7)); + v2 = x87_get_st(dyn, ninst, x1, x2, nextop & 7, X87_COMBINE(0, nextop & 7)); + ANDI(x1, xFlags, (1 << F_CF) | (1 << F_ZF)); + CBZ_NEXT(x1); + if (ST_IS_F(0)) + FMVS(v1, v2); + else + FMVD(v1, v2); break; case 0xD8: case 0xD9: @@ -81,7 +108,16 @@ uintptr_t dynarec64_DA(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni case 0xDD: case 0xDE: case 0xDF: - DEFAULT; + INST_NAME("FCMOVU ST0, STx"); + READFLAGS(X_PF); + v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_COMBINE(0, nextop & 7)); + v2 = x87_get_st(dyn, ninst, x1, x2, nextop & 7, X87_COMBINE(0, nextop & 7)); + ANDI(x1, xFlags, (1 << F_PF)); + CBZ_NEXT(x1); + if (ST_IS_F(0)) + FMVS(v1, v2); + else + FMVD(v1, v2); break; case 0xE9: INST_NAME("FUCOMPP ST0, ST1"); diff --git a/src/dynarec/rv64/dynarec_rv64_dd.c b/src/dynarec/rv64/dynarec_rv64_dd.c index b5a282e1..47718d64 100644 --- a/src/dynarec/rv64/dynarec_rv64_dd.c +++ b/src/dynarec/rv64/dynarec_rv64_dd.c @@ -64,7 +64,13 @@ uintptr_t dynarec64_DD(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni case 0xD6: case 0xD7: INST_NAME("FST ST0, STx"); - DEFAULT; + v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_COMBINE(0, nextop & 7)); + v2 = x87_get_st(dyn, ninst, x1, x2, nextop & 7, X87_COMBINE(0, nextop & 7)); + if (ST_IS_F(0)) { + FMVS(v2, v1); + } else { + FMVD(v2, v1); + } break; case 0xD8: INST_NAME("FSTP ST0, ST0"); @@ -93,7 +99,13 @@ uintptr_t dynarec64_DD(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni case 0xE6: case 0xE7: INST_NAME("FUCOM ST0, STx"); - DEFAULT; + v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_COMBINE(0, nextop & 7)); + v2 = x87_get_st(dyn, ninst, x1, x2, nextop & 7, X87_COMBINE(0, nextop & 7)); + if (ST_IS_F(0)) { + FCOMS(v1, v2, x1, x2, x3, x4, x5); + } else { + FCOMD(v1, v2, x1, x2, x3, x4, x5); + } break; case 0xE8: case 0xE9: @@ -104,7 +116,14 @@ uintptr_t dynarec64_DD(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni case 0xEE: case 0xEF: INST_NAME("FUCOMP ST0, STx"); - DEFAULT; + v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_COMBINE(0, nextop & 7)); + v2 = x87_get_st(dyn, ninst, x1, x2, nextop & 7, X87_COMBINE(0, nextop & 7)); + if (ST_IS_F(0)) { + FCOMS(v1, v2, x1, x2, x3, x4, x5); + } else { + FCOMD(v1, v2, x1, x2, x3, x4, x5); + } + X87_POP_OR_FAIL(dyn, ninst, x3); break; case 0xC8: case 0xC9: diff --git a/src/dynarec/rv64/dynarec_rv64_de.c b/src/dynarec/rv64/dynarec_rv64_de.c index 6712a97c..f20cc686 100644 --- a/src/dynarec/rv64/dynarec_rv64_de.c +++ b/src/dynarec/rv64/dynarec_rv64_de.c @@ -80,12 +80,27 @@ uintptr_t dynarec64_DE(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni case 0xD5: case 0xD6: case 0xD7: - // INST_NAME("FCOMP ST0, STx"); //yep - DEFAULT; + INST_NAME("FCOMP ST0, STx"); // yep + v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_COMBINE(0, nextop & 7)); + v2 = x87_get_st(dyn, ninst, x1, x2, nextop & 7, X87_COMBINE(0, nextop & 7)); + if (ST_IS_F(0)) { + FCOMS(v1, v2, x1, x2, x3, x4, x5); + } else { + FCOMD(v1, v2, x1, x2, x3, x4, x5); + } + X87_POP_OR_FAIL(dyn, ninst, x3); break; case 0xD9: - // INST_NAME("FCOMPP ST0, STx"); - DEFAULT; + INST_NAME("FCOMPP ST0, STx"); + v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_COMBINE(0, nextop & 7)); + v2 = x87_get_st(dyn, ninst, x1, x2, nextop & 7, X87_COMBINE(0, nextop & 7)); + if (ST_IS_F(0)) { + FCOMS(v1, v2, x1, x2, x3, x4, x5); + } else { + FCOMD(v1, v2, x1, x2, x3, x4, x5); + } + X87_POP_OR_FAIL(dyn, ninst, x3); + X87_POP_OR_FAIL(dyn, ninst, x3); break; case 0xE0: case 0xE1: @@ -166,7 +181,8 @@ uintptr_t dynarec64_DE(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni case 0xDD: case 0xDE: case 0xDF: - return 0; + DEFAULT; + break; default: switch((nextop>>3)&7) { default: |