diff options
| author | Yang Liu <liuyang22@iscas.ac.cn> | 2023-12-10 15:16:24 +0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-12-10 08:16:24 +0100 |
| commit | 486df332dd2da9ffb2c586417b1ad6f184218a16 (patch) | |
| tree | 8ab712f3b5a1c1f57c285cb6ce33248a016066fc /src | |
| parent | 8806c8ba8b9f8a34e666c30cc1139e55797a994d (diff) | |
| download | box64-486df332dd2da9ffb2c586417b1ad6f184218a16.tar.gz box64-486df332dd2da9ffb2c586417b1ad6f184218a16.zip | |
[DYNAREC_RV64] Added more opcodes for flatout.exe (#1133)
* [DYNAREC_RV64] Added 0F 6B PACKSSDW opcode * [DYNAREC_RV64] Added more 0F opcodes * [DYNAREC_RV64] Added 67 63 MOVSXD opcode
Diffstat (limited to 'src')
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_0f.c | 70 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_67.c | 23 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_helper.h | 8 |
3 files changed, 100 insertions, 1 deletions
diff --git a/src/dynarec/rv64/dynarec_rv64_0f.c b/src/dynarec/rv64/dynarec_rv64_0f.c index 283b6793..a03ef8e0 100644 --- a/src/dynarec/rv64/dynarec_rv64_0f.c +++ b/src/dynarec/rv64/dynarec_rv64_0f.c @@ -819,6 +819,41 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni SW(x3, gback, gdoffset + 1 * 4); } break; + case 0x6B: + INST_NAME("PACKSSDW Gm,Em"); + nextop = F8; + GETGM(); + for (int i = 0; i < 2; ++i) { + // GM->sw[i] = (GM->sd[i]<-32768)?-32768:((GM->sd[i]>32767)?32767:GM->sd[i]); + LW(x3, gback, gdoffset + i * 4); + LUI(x4, 0xFFFF8); // -32768 + BGE(x3, x4, 12); + SH(x4, gback, gdoffset + i * 2); + J(20); // continue + LUI(x4, 8); // 32768 + BLT(x3, x4, 8); + ADDIW(x3, x4, -1); + SH(x3, gback, gdoffset + i * 2); + } + if (MODREG && gd == (nextop & 7)) { + LWU(x3, gback, gdoffset); + SW(x3, gback, gdoffset + 4); + } else { + GETEM(x1, 0); + for (int i = 0; i < 2; ++i) { + // GM->sw[2+i] = (EM->sd[i]<-32768)?-32768:((EM->sd[i]>32767)?32767:EM->sd[i]); + LW(x3, wback, fixedaddress + i * 4); + LUI(x4, 0xFFFF8); // -32768 + BGE(x3, x4, 12); + SH(x4, gback, gdoffset + 4 + i * 2); + J(20); // continue + LUI(x4, 8); // 32768 + BLT(x3, x4, 8); + ADDIW(x3, x4, -1); + SH(x3, gback, gdoffset + 4 + i * 2); + } + } + break; case 0x6E: INST_NAME("MOVD Gm, Ed"); nextop = F8; @@ -1681,6 +1716,13 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni gd = xRAX + (opcode & 7) + (rex.b << 3); REV8xw(gd, gd, x1, x2, x3, x4); break; + case 0xD5: + INST_NAME("PMULLW Gm, Em"); + nextop = F8; + GETGM(); + GETEM(x2, 0); + MMX_LOOP_WS(x3, x4, MULW(x3, x3, x4)); + break; case 0xDB: INST_NAME("PAND Gm, Em"); nextop = F8; @@ -1704,6 +1746,34 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni SH(x3, gback, gdoffset + 2 * i); } break; + INST_NAME("PSUBSW Gm,Em"); + nextop = F8; + GETGM(); + GETEM(x2, 0); + for (int i = 0; i < 4; ++i) { + LH(x3, gback, gdoffset + i * 2); + LH(x4, wback, fixedaddress); + SUBW(x3, x3, x4); + LUI(x4, 0xFFFF8); // -32768 + BGE(x3, x4, 12); + SH(x4, gback, gdoffset + i * 2); + J(20); // continue + LUI(x4, 8); // 32768 + BLT(x3, x4, 8); + ADDIW(x3, x4, -1); + 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; diff --git a/src/dynarec/rv64/dynarec_rv64_67.c b/src/dynarec/rv64/dynarec_rv64_67.c index 9fc634f1..2ede9c3d 100644 --- a/src/dynarec/rv64/dynarec_rv64_67.c +++ b/src/dynarec/rv64/dynarec_rv64_67.c @@ -448,7 +448,28 @@ uintptr_t dynarec64_67(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni } else emit_cmp32_0(dyn, ninst, rex, xRAX, x3, x4); break; - + case 0x63: + INST_NAME("MOVSXD Gd, Ed"); + nextop = F8; + GETGD; + if (rex.w) { + if (MODREG) { // reg <= reg + ADDIW(gd, xRAX + (nextop & 7) + (rex.b << 3), 0); + } else { // mem <= reg + SMREAD(); + addr = geted32(dyn, addr, ninst, nextop, &ed, x2, x1, &fixedaddress, rex, &lock, 1, 0); + LW(gd, ed, fixedaddress); + } + } else { + if (MODREG) { // reg <= reg + AND(gd, xRAX + (nextop & 7) + (rex.b << 3), xMASK); + } else { // mem <= reg + SMREAD(); + addr = geted32(dyn, addr, ninst, nextop, &ed, x2, x1, &fixedaddress, rex, &lock, 1, 0); + LWU(gd, ed, fixedaddress); + } + } + break; case 0x66: opcode = F8; switch (opcode) { diff --git a/src/dynarec/rv64/dynarec_rv64_helper.h b/src/dynarec/rv64/dynarec_rv64_helper.h index af6cc1a8..5a6d1cdb 100644 --- a/src/dynarec/rv64/dynarec_rv64_helper.h +++ b/src/dynarec/rv64/dynarec_rv64_helper.h @@ -562,6 +562,14 @@ SH(GX1, gback, gdoffset + i * 2); \ } +#define MMX_LOOP_WS(GX1, EX1, F) \ + for (int i = 0; i < 4; ++i) { \ + LH(GX1, gback, gdoffset + i * 2); \ + LH(EX1, wback, fixedaddress + i * 2); \ + F; \ + SH(GX1, gback, gdoffset + i * 2); \ + } + #define SSE_LOOP_W(GX1, EX1, F) \ for (int i = 0; i < 8; ++i) { \ LHU(GX1, gback, gdoffset + i * 2); \ |