diff options
| author | Yang Liu <liuyang22@iscas.ac.cn> | 2023-12-25 01:03:41 +0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-12-24 18:03:41 +0100 |
| commit | 10062373d1a482c566af53ca5eef30374634e795 (patch) | |
| tree | 38caf060f3fdbe3178751edf18fa94c3356c271b /src | |
| parent | 68e3c2be9b25df05451f3d635971b7acbf12a953 (diff) | |
| download | box64-10062373d1a482c566af53ca5eef30374634e795.tar.gz box64-10062373d1a482c566af53ca5eef30374634e795.zip | |
[DYNAREC_RV64] Added more opcodes for ets2 (#1162)
* [DYNAREC_RV64] Added F2 0F 7C HADDPS opcode * [DYNAREC_RV64] Added 0F 38 C8..CD opcodes * [DYNAREC_RV64] Added DF C0..C7 FFREEP opcodes
Diffstat (limited to 'src')
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_0f.c | 60 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_df.c | 3 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_f20f.c | 37 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_helper.c | 10 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_helper.h | 3 |
5 files changed, 112 insertions, 1 deletions
diff --git a/src/dynarec/rv64/dynarec_rv64_0f.c b/src/dynarec/rv64/dynarec_rv64_0f.c index b69cd487..22b21694 100644 --- a/src/dynarec/rv64/dynarec_rv64_0f.c +++ b/src/dynarec/rv64/dynarec_rv64_0f.c @@ -17,6 +17,7 @@ #include "dynarec_native.h" #include "my_cpuid.h" #include "emu/x87emu_private.h" +#include "emu/x64shaext.h" #include "bitutils.h" #include "rv64_printer.h" @@ -387,6 +388,65 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni // SSE3 nextop = F8; switch (nextop) { + case 0xC8 ... 0xCD: + u8 = nextop; + switch (u8) { + case 0xC8: + INST_NAME("SHA1NEXTE Gx, Ex"); + break; + case 0xC9: + INST_NAME("SHA1MSG1 Gx, Ex"); + break; + case 0xCA: + INST_NAME("SHA1MSG2 Gx, Ex"); + break; + case 0xCB: + INST_NAME("SHA256RNDS2 Gx, Ex"); + break; + case 0xCC: + INST_NAME("SHA256MSG1 Gx, Ex"); + break; + case 0xCD: + INST_NAME("SHA256MSG2 Gx, Ex"); + break; + } + nextop = F8; + if (MODREG) { + ed = (nextop & 7) + (rex.b << 3); + sse_reflect_reg(dyn, ninst, ed); + ADDI(x2, xEmu, offsetof(x64emu_t, xmm[ed])); + } else { + SMREAD(); + addr = geted(dyn, addr, ninst, nextop, &ed, x2, x1, &fixedaddress, rex, NULL, 0, 0); + if (ed != x2) { + MV(x2, ed); + } + } + GETG; + sse_forget_reg(dyn, ninst, gd); + ADDI(x1, xEmu, offsetof(x64emu_t, xmm[gd])); + sse_reflect_reg(dyn, ninst, 0); + switch (u8) { + case 0xC8: + CALL(sha1nexte, -1); + break; + case 0xC9: + CALL(sha1msg1, -1); + break; + case 0xCA: + CALL(sha1msg2, -1); + break; + case 0xCB: + CALL(sha256rnds2, -1); + break; + case 0xCC: + CALL(sha256msg1, -1); + break; + case 0xCD: + CALL(sha256msg2, -1); + break; + } + break; case 0xF0: INST_NAME("MOVBE Gd, Ed"); nextop = F8; diff --git a/src/dynarec/rv64/dynarec_rv64_df.c b/src/dynarec/rv64/dynarec_rv64_df.c index 08e603e5..2a2884c5 100644 --- a/src/dynarec/rv64/dynarec_rv64_df.c +++ b/src/dynarec/rv64/dynarec_rv64_df.c @@ -41,7 +41,8 @@ uintptr_t dynarec64_DF(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni switch(nextop) { case 0xC0 ... 0xC7: INST_NAME("FFREEP STx"); - DEFAULT; + // not handling Tag... + X87_POP_OR_FAIL(dyn, ninst, x3); break; case 0xE0: diff --git a/src/dynarec/rv64/dynarec_rv64_f20f.c b/src/dynarec/rv64/dynarec_rv64_f20f.c index 62b66544..04f23a70 100644 --- a/src/dynarec/rv64/dynarec_rv64_f20f.c +++ b/src/dynarec/rv64/dynarec_rv64_f20f.c @@ -34,6 +34,7 @@ uintptr_t dynarec64_F20F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int int v0, v1; int q0; int d0, d1; + int s0, s1; int64_t fixedaddress, gdoffset; int unscaled; @@ -272,6 +273,42 @@ uintptr_t dynarec64_F20F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int SD(x3, gback, gdoffset+8); } break; + case 0x7C: + INST_NAME("HADDPS Gx, Ex"); + nextop = F8; + GETGX(); + GETEX(x2, 0); + s0 = fpu_get_scratch(dyn); + s1 = fpu_get_scratch(dyn); + // GX->f[0] += GX->f[1]; + FLW(s0, gback, gdoffset + 0); + FLW(s1, gback, gdoffset + 4); + FADDS(s0, s0, s1); + FSW(s0, gback, gdoffset + 0); + // GX->f[1] = GX->f[2] + GX->f[3]; + FLW(s0, gback, gdoffset + 8); + FLW(s1, gback, gdoffset + 12); + FADDS(s0, s0, s1); + FSW(s0, gback, gdoffset + 4); + if (MODREG && gd == (nextop & 7) + (rex.b << 3)) { + // GX->f[2] = GX->f[0]; + FLW(s1, gback, gdoffset + 0); + FSW(s1, gback, gdoffset + 8); + // GX->f[3] = GX->f[1]; + FSW(s0, gback, gdoffset + 12); + } else { + // GX->f[2] = EX->f[0] + EX->f[1]; + FLW(s0, wback, fixedaddress + 0); + FLW(s1, wback, fixedaddress + 4); + FADDS(s0, s0, s1); + FSW(s0, gback, gdoffset + 8); + // GX->f[3] = EX->f[2] + EX->f[3]; + FLW(s0, wback, fixedaddress + 8); + FLW(s1, wback, fixedaddress + 12); + FADDS(s0, s0, s1); + FSW(s0, gback, gdoffset + 12); + } + break; case 0xC2: INST_NAME("CMPSD Gx, Ex, Ib"); nextop = F8; diff --git a/src/dynarec/rv64/dynarec_rv64_helper.c b/src/dynarec/rv64/dynarec_rv64_helper.c index 19b4c316..7ef65dc8 100644 --- a/src/dynarec/rv64/dynarec_rv64_helper.c +++ b/src/dynarec/rv64/dynarec_rv64_helper.c @@ -1555,6 +1555,16 @@ static void sse_reflectcache(dynarec_rv64_t* dyn, int ninst, int s1) } } +void sse_reflect_reg(dynarec_rv64_t* dyn, int ninst, int a) +{ + if (dyn->e.ssecache[a].v == -1) + return; + if (dyn->e.ssecache[a].single) + FSW(dyn->e.ssecache[a].reg, xEmu, offsetof(x64emu_t, xmm[a])); + else + FSD(dyn->e.ssecache[a].reg, xEmu, offsetof(x64emu_t, xmm[a])); +} + void fpu_pushcache(dynarec_rv64_t* dyn, int ninst, int s1, int not07) { // need to save 0..1 && 10..17 (maybe) && 28..31 diff --git a/src/dynarec/rv64/dynarec_rv64_helper.h b/src/dynarec/rv64/dynarec_rv64_helper.h index 3fb8e654..8b631a07 100644 --- a/src/dynarec/rv64/dynarec_rv64_helper.h +++ b/src/dynarec/rv64/dynarec_rv64_helper.h @@ -1177,6 +1177,7 @@ void* rv64_next(x64emu_t* emu, uintptr_t addr); #define sse_get_reg_empty STEPNAME(sse_get_reg_empty) #define sse_forget_reg STEPNAME(sse_forget_reg) #define sse_purge07cache STEPNAME(sse_purge07cache) +#define sse_reflect_reg STEPNAME(sse_reflect_reg) #define fpu_pushcache STEPNAME(fpu_pushcache) #define fpu_popcache STEPNAME(fpu_popcache) @@ -1377,6 +1378,8 @@ int sse_get_reg_empty(dynarec_rv64_t* dyn, int ninst, int s1, int a, int single) void sse_forget_reg(dynarec_rv64_t* dyn, int ninst, int a); // purge the XMM0..XMM7 cache (before function call) void sse_purge07cache(dynarec_rv64_t* dyn, int ninst, int s1); +// Push current value to the cache +void sse_reflect_reg(dynarec_rv64_t* dyn, int ninst, int a); // common coproc helpers // reset the cache |