diff options
| author | Yang Liu <liuyang22@iscas.ac.cn> | 2024-08-17 00:16:20 +0800 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2024-08-16 18:47:21 +0200 |
| commit | 0f1bce0f32a8429fc414f92cb6b85ff0d30b5d8f (patch) | |
| tree | 644684c4a1a49a6156453d074fec121e3f3edf4a /src | |
| parent | bc0b5b118115d8b220fd16d03e2729d2fe3ebf2d (diff) | |
| download | box64-0f1bce0f32a8429fc414f92cb6b85ff0d30b5d8f.tar.gz box64-0f1bce0f32a8429fc414f92cb6b85ff0d30b5d8f.zip | |
[RV64_DYNAREC] Added more opcodes (#1740)
* [RV64_DYNAREC] Added more opcodes * more opcodes * more
Diffstat (limited to 'src')
| -rw-r--r-- | src/dynarec/arm64/dynarec_arm64_660f.c | 4 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_0f.c | 33 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_660f.c | 124 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_f20f.c | 31 | ||||
| -rw-r--r-- | src/emu/x64run660f.c | 4 |
5 files changed, 147 insertions, 49 deletions
diff --git a/src/dynarec/arm64/dynarec_arm64_660f.c b/src/dynarec/arm64/dynarec_arm64_660f.c index a8625e23..c967374d 100644 --- a/src/dynarec/arm64/dynarec_arm64_660f.c +++ b/src/dynarec/arm64/dynarec_arm64_660f.c @@ -1006,7 +1006,7 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n VMOVeD(q0, 0, v1, 0); break; case 0x0C: - INST_NAME("PBLENDPS Gx, Ex, Ib"); + INST_NAME("BLENDPS Gx, Ex, Ib"); nextop = F8; GETGX(q0, 1); GETEX(q1, 0, 1); @@ -1021,7 +1021,7 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n } break; case 0x0D: - INST_NAME("PBLENDPD Gx, Ex, Ib"); + INST_NAME("BLENDPD Gx, Ex, Ib"); nextop = F8; GETGX(q0, 1); GETEX(q1, 0, 1); diff --git a/src/dynarec/rv64/dynarec_rv64_0f.c b/src/dynarec/rv64/dynarec_rv64_0f.c index e3af9d94..0c691c05 100644 --- a/src/dynarec/rv64/dynarec_rv64_0f.c +++ b/src/dynarec/rv64/dynarec_rv64_0f.c @@ -66,21 +66,26 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni if(MODREG) { switch(nextop) { case 0xD0: - //TODO - DEFAULT; - /*INST_NAME("FAKE xgetbv"); - nextop = F8; - addr = fakeed(dyn, addr, ninst, nextop); - SETFLAGS(X_ALL, SF_SET_NODF); // Hack to set flags in "don't care" state - GETIP(ip); - STORE_XEMU_CALL(x3); - CALL(native_ud, -1); - LOAD_XEMU_CALL(); - jump_to_epilog(dyn, 0, xRIP, ninst); - *need_epilog = 0; - *ok = 0;*/ + INST_NAME("XGETBV"); + AND(x1, xRCX, xMASK); + BEQZ_MARK(x1); + UDF(); + MARK; + MOV32w(xRAX, 0b111); + MOV32w(xRDX, 0); + break; + case 0xE0: + case 0xE1: + case 0xE2: + case 0xE3: + case 0xE4: + case 0xE5: + case 0xE6: + case 0xE7: + INST_NAME("SMSW Ed"); + ed = xRAX + (nextop & 7) + (rex.b << 3); + MOV32w(ed, (1 << 0) | (1 << 4)); // only PE and ET set... break; - case 0xF9: INST_NAME("RDTSCP"); NOTEST(x1); diff --git a/src/dynarec/rv64/dynarec_rv64_660f.c b/src/dynarec/rv64/dynarec_rv64_660f.c index 00c9c66c..8fb7734d 100644 --- a/src/dynarec/rv64/dynarec_rv64_660f.c +++ b/src/dynarec/rv64/dynarec_rv64_660f.c @@ -684,6 +684,13 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int SD(x3, gback, gdoffset + i * 8); } break; + case 0x29: + INST_NAME("PCMPEQQ Gx, Ex"); // SSE4 opcode! + nextop = F8; + GETGX(); + GETEX(x2, 0, 8); + SSE_LOOP_Q(x3, x4, XOR(x3, x3, x4); SNEZ(x3, x3); ADDI(x3, x3, -1)); + break; case 0x2B: INST_NAME("PACKUSDW Gx, Ex"); nextop = F8; @@ -1055,37 +1062,6 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int case 0x3A: // these are some more SSSE3+ opcodes opcode = F8; switch (opcode) { - case 0x0B: - INST_NAME("ROUNDSD Gx, Ex, Ib"); - nextop = F8; - GETEXSD(d0, 1); - GETGXSD_empty(v0); - d1 = fpu_get_scratch(dyn); - v1 = fpu_get_scratch(dyn); - u8 = F8; - FEQD(x2, d0, d0); - BNEZ_MARK(x2); - if (v0 != d0) FMVD(v0, d0); - B_NEXT_nocond; - MARK; // d0 is not nan - FABSD(v1, d0); - MOV64x(x3, 1ULL << __DBL_MANT_DIG__); - FCVTDL(d1, x3, RD_RTZ); - FLTD(x3, v1, d1); - BNEZ_MARK2(x3); - if (v0 != d0) FMVD(v0, d0); - B_NEXT_nocond; - MARK2; - if (u8 & 4) { - u8 = sse_setround(dyn, ninst, x4, x2); - FCVTLD(x5, d0, RD_DYN); - FCVTDL(v0, x5, RD_RTZ); - x87_restoreround(dyn, ninst, u8); - } else { - FCVTLD(x5, d0, round_round[u8 & 3]); - FCVTDL(v0, x5, RD_RTZ); - } - break; case 0x09: INST_NAME("ROUNDPD Gx, Ex, Ib"); nextop = F8; @@ -1142,6 +1118,80 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int MARK2; FSD(d0, gback, gdoffset + 8); break; + case 0x0A: + INST_NAME("ROUNDSS Gx, Ex, Ib"); + nextop = F8; + GETEXSS(d0, 1); + GETGXSS_empty(v0); + d1 = fpu_get_scratch(dyn); + v1 = fpu_get_scratch(dyn); + u8 = F8; + FEQS(x2, d0, d0); + BNEZ_MARK(x2); + if (v0 != d0) FMVS(v0, d0); + B_NEXT_nocond; + MARK; // d0 is not nan + FABSS(v1, d0); + MOV64x(x3, 1ULL << __FLT_MANT_DIG__); + FCVTSW(d1, x3, RD_RTZ); + FLTS(x3, v1, d1); + BNEZ_MARK2(x3); + if (v0 != d0) FMVS(v0, d0); + B_NEXT_nocond; + MARK2; + if (u8 & 4) { + u8 = sse_setround(dyn, ninst, x4, x2); + FCVTWS(x5, d0, RD_DYN); + FCVTSW(v0, x5, RD_RTZ); + x87_restoreround(dyn, ninst, u8); + } else { + FCVTWS(x5, d0, round_round[u8 & 3]); + FCVTSW(v0, x5, RD_RTZ); + } + break; + case 0x0B: + INST_NAME("ROUNDSD Gx, Ex, Ib"); + nextop = F8; + GETEXSD(d0, 1); + GETGXSD_empty(v0); + d1 = fpu_get_scratch(dyn); + v1 = fpu_get_scratch(dyn); + u8 = F8; + FEQD(x2, d0, d0); + BNEZ_MARK(x2); + if (v0 != d0) FMVD(v0, d0); + B_NEXT_nocond; + MARK; // d0 is not nan + FABSD(v1, d0); + MOV64x(x3, 1ULL << __DBL_MANT_DIG__); + FCVTDL(d1, x3, RD_RTZ); + FLTD(x3, v1, d1); + BNEZ_MARK2(x3); + if (v0 != d0) FMVD(v0, d0); + B_NEXT_nocond; + MARK2; + if (u8 & 4) { + u8 = sse_setround(dyn, ninst, x4, x2); + FCVTLD(x5, d0, RD_DYN); + FCVTDL(v0, x5, RD_RTZ); + x87_restoreround(dyn, ninst, u8); + } else { + FCVTLD(x5, d0, round_round[u8 & 3]); + FCVTDL(v0, x5, RD_RTZ); + } + break; + case 0x0C: + INST_NAME("BLENDPS Gx, Ex, Ib"); + nextop = F8; + GETGX(); + GETEX(x2, 1, 12); + u8 = F8 & 0b1111; + for (int i = 0; i < 4; ++i) + if (u8 & (1 << i)) { + LWU(x1, wback, fixedaddress + i * 4); + SW(x1, gback, gdoffset + i * 4); + } + break; case 0x0E: INST_NAME("PBLENDW Gx, Ex, Ib"); nextop = F8; @@ -1265,6 +1315,18 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int SMWRITE2(); } break; + case 0x17: + INST_NAME("EXTRACTPS Ew, Gx, Ib"); + nextop = F8; + GETGX(); + GETED(1); + u8 = F8; + LWU(ed, gback, gdoffset + 4 * (u8 & 3)); + if (wback) { + SW(ed, wback, fixedaddress); + SMWRITE2(); + } + break; case 0x20: INST_NAME("PINSRB Gx, ED, Ib"); nextop = F8; diff --git a/src/dynarec/rv64/dynarec_rv64_f20f.c b/src/dynarec/rv64/dynarec_rv64_f20f.c index a7942c7e..73fea164 100644 --- a/src/dynarec/rv64/dynarec_rv64_f20f.c +++ b/src/dynarec/rv64/dynarec_rv64_f20f.c @@ -416,6 +416,37 @@ uintptr_t dynarec64_F20F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int NEG(x2, x2); FMVDX(d0, x2); break; + case 0xD0: + INST_NAME("ADDSUBPS Gx, Ex"); + nextop = F8; + GETGX(); + GETEX(x2, 0, 12); + d0 = fpu_get_scratch(dyn); + d1 = fpu_get_scratch(dyn); + // GX->f[0] -= EX->f[0]; + FLW(d0, wback, fixedaddress + 0); + FLW(d1, gback, gdoffset + 0); + FSUBS(d1, d1, d0); + FSW(d1, gback, gdoffset + 0); + + // GX->f[1] += EX->f[1]; + FLW(d0, wback, fixedaddress + 4); + FLW(d1, gback, gdoffset + 4); + FADDS(d1, d1, d0); + FSW(d1, gback, gdoffset + 4); + + // GX->f[2] -= EX->f[2]; + FLW(d0, wback, fixedaddress + 8); + FLW(d1, gback, gdoffset + 8); + FSUBS(d1, d1, d0); + FSW(d1, gback, gdoffset + 8); + + // GX->f[3] += EX->f[3]; + FLW(d0, wback, fixedaddress + 12); + FLW(d1, gback, gdoffset + 12); + FADDS(d1, d1, d0); + FSW(d1, gback, gdoffset + 12); + break; case 0xE6: INST_NAME("CVTPD2DQ Gx, Ex"); nextop = F8; diff --git a/src/emu/x64run660f.c b/src/emu/x64run660f.c index 84ed4e25..35fd6eab 100644 --- a/src/emu/x64run660f.c +++ b/src/emu/x64run660f.c @@ -966,7 +966,7 @@ uintptr_t Run660F(x64emu_t *emu, rex_t rex, uintptr_t addr) } break; - case 0x0C: /* PBLENDPS Gx, Ex, Ib */ + case 0x0C: /* BLENDPS Gx, Ex, Ib */ nextop = F8; GETEX(1); GETGX; @@ -976,7 +976,7 @@ uintptr_t Run660F(x64emu_t *emu, rex_t rex, uintptr_t addr) GX->ud[i] = EX->ud[i]; } break; - case 0x0D: /* PBLENDPD Gx, Ex, Ib */ + case 0x0D: /* BLENDPD Gx, Ex, Ib */ nextop = F8; GETEX(1); GETGX; |