diff options
| author | Yang Liu <liuyang22@iscas.ac.cn> | 2024-02-23 02:10:56 +0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-02-22 19:10:56 +0100 |
| commit | 61413769775bb9428c6f2b89037d32ea580d5a75 (patch) | |
| tree | 218a5b7d977c9ec18813b117c7da549866ecbb22 /src | |
| parent | 3ec2ebabfc97b484cfabca9d4e9c181c5b10a8c8 (diff) | |
| download | box64-61413769775bb9428c6f2b89037d32ea580d5a75.tar.gz box64-61413769775bb9428c6f2b89037d32ea580d5a75.zip | |
[RV64_DYNAREC] Added 2 more 66 0F opcodes for test17 (#1278)
* Added 66 0F 38 03 PHADDSW opcode * Added 66 0F 38 05 PHSUBW opcode
Diffstat (limited to 'src')
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_660f.c | 78 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_helper.h | 10 |
2 files changed, 70 insertions, 18 deletions
diff --git a/src/dynarec/rv64/dynarec_rv64_660f.c b/src/dynarec/rv64/dynarec_rv64_660f.c index 92c73c61..d5d2c2c9 100644 --- a/src/dynarec/rv64/dynarec_rv64_660f.c +++ b/src/dynarec/rv64/dynarec_rv64_660f.c @@ -345,7 +345,36 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int SW(x3, gback, gdoffset + 3 * 4); } break; - + case 0x03: + INST_NAME("PHADDSW Gx, Ex"); + nextop = F8; + GETGX(); + for (int i = 0; i < 4; ++i) { + // tmp32s = GX->sw[i*2+0]+GX->sw[i*2+1]; + // GX->sw[i] = sat(tmp32s); + LH(x3, gback, gdoffset + 2 * (i * 2 + 0)); + LH(x4, gback, gdoffset + 2 * (i * 2 + 1)); + ADDW(x3, x3, x4); + SAT16(x3, x4); + SH(x3, gback, gdoffset + 2 * i); + } + if (MODREG && gd == (nextop & 7) + (rex.b << 3)) { + // GX->q[1] = GX->q[0]; + LD(x3, gback, gdoffset + 0); + SD(x3, gback, gdoffset + 8); + } else { + GETEX(x2, 0); + for (int i = 0; i < 4; ++i) { + // tmp32s = EX->sw[i*2+0] + EX->sw[i*2+1]; + // GX->sw[4+i] = sat(tmp32s); + LH(x3, wback, fixedaddress + 2 * (i * 2 + 0)); + LH(x4, wback, fixedaddress + 2 * (i * 2 + 1)); + ADDW(x3, x3, x4); + SAT16(x3, x4); + SH(x3, gback, gdoffset + 2 * (4 + i)); + } + } + break; case 0x04: INST_NAME("PADDUBSW Gx, Ex"); nextop = F8; @@ -373,7 +402,32 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int SH(x3, gback, gdoffset + i * 2); } break; - + case 0x05: + INST_NAME("PHSUBW Gx, Ex"); + nextop = F8; + GETGX(); + for (int i = 0; i < 4; ++i) { + // GX->sw[i] = GX->sw[i*2+0] - GX->sw[i*2+1]; + LH(x3, gback, gdoffset + 2 * (i * 2 + 0)); + LH(x4, gback, gdoffset + 2 * (i * 2 + 1)); + SUBW(x3, x3, x4); + SH(x3, gback, gdoffset + 2 * i); + } + if (MODREG && gd == (nextop & 7) + (rex.b << 3)) { + // GX->q[1] = GX->q[0]; + LD(x3, gback, gdoffset + 0); + SD(x3, gback, gdoffset + 8); + } else { + GETEX(x2, 0); + for (int i = 0; i < 4; ++i) { + // GX->sw[4+i] = EX->sw[i*2+0] - EX->sw[i*2+1]; + LH(x3, wback, fixedaddress + 2 * (i * 2 + 0)); + LH(x4, wback, fixedaddress + 2 * (i * 2 + 1)); + SUBW(x3, x3, x4); + SH(x3, gback, gdoffset + 2 * (4 + i)); + } + } + break; case 0x08: INST_NAME("PSIGNB Gx, Ex"); nextop = F8; @@ -2802,17 +2856,11 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int GETEX(x2, 0); for (int i = 0; i < 8; ++i) { // tmp32s = (int32_t)GX->sw[i] - EX->sw[i]; - // GX->sw[i] = (tmp32s>32767)?32767:((tmp32s<-32768)?-32768:tmp32s); + // GX->sw[i] = sat16(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); + SAT16(x3, x4); SH(x3, gback, gdoffset + 2 * i); } break; @@ -2867,17 +2915,11 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int GETEX(x2, 0); for (int i = 0; i < 8; ++i) { // tmp32s = (int32_t)GX->sw[i] + EX->sw[i]; - // GX->sw[i] = (tmp32s>32767)?32767:((tmp32s<-32768)?-32768:tmp32s); + // GX->sw[i] = sat16(tmp32s); LH(x3, gback, gdoffset + 2 * i); LH(x4, wback, fixedaddress + 2 * i); ADDW(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); + SAT16(x3, x4); SH(x3, gback, gdoffset + 2 * i); } break; diff --git a/src/dynarec/rv64/dynarec_rv64_helper.h b/src/dynarec/rv64/dynarec_rv64_helper.h index 9fd7267d..a7b3f5f1 100644 --- a/src/dynarec/rv64/dynarec_rv64_helper.h +++ b/src/dynarec/rv64/dynarec_rv64_helper.h @@ -1600,4 +1600,14 @@ uintptr_t dynarec64_F30F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int #define FCOMS(v1, v2, s1, s2, s3, s4, s5) FCOM(S, v1, v2, s1, s2, s3, s4, s5) #define FCOMD(v1, v2, s1, s2, s3, s4, s5) FCOM(D, v1, v2, s1, s2, s3, s4, s5) +// reg = (reg < -32768) ? -32768 : ((reg > 32767) ? 32767 : reg) +#define SAT16(reg, s) \ + LUI(s, 0xFFFF8); /* -32768 */ \ + BGE(reg, s, 4 + 2 * 4); \ + MV(reg, s); \ + J(4 + 4 * 3); \ + LUI(s, 8); /* 32768 */ \ + BLT(reg, s, 4 + 4); \ + ADDIW(reg, s, -1); + #endif //__DYNAREC_RV64_HELPER_H__ |