diff options
| author | Yang Liu <liuyang22@iscas.ac.cn> | 2024-02-22 20:37:46 +0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-02-22 13:37:46 +0100 |
| commit | 3ec2ebabfc97b484cfabca9d4e9c181c5b10a8c8 (patch) | |
| tree | 60317809135795d2b56201ac34418c534d82d00b /src | |
| parent | 77dcb025fd3e6a069e31e8a19c3b061b82d3fa28 (diff) | |
| download | box64-3ec2ebabfc97b484cfabca9d4e9c181c5b10a8c8.tar.gz box64-3ec2ebabfc97b484cfabca9d4e9c181c5b10a8c8.zip | |
[RV64_DYNAREC] Added more opcodes (#1277)
* Added 66 0F 38 25 PMOVSXDQ opcode * Added 0F 3A CC opcode * Added 67 F7 /4 MUL opcode * Added 67 C1 /5 SHR opcode
Diffstat (limited to 'src')
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_0f.c | 26 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_660f.c | 11 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_67.c | 45 |
3 files changed, 82 insertions, 0 deletions
diff --git a/src/dynarec/rv64/dynarec_rv64_0f.c b/src/dynarec/rv64/dynarec_rv64_0f.c index f98aaec5..27507db9 100644 --- a/src/dynarec/rv64/dynarec_rv64_0f.c +++ b/src/dynarec/rv64/dynarec_rv64_0f.c @@ -470,6 +470,32 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni DEFAULT; } break; + case 0x3A: // more SSE3 opcodes + opcode = F8; + switch (opcode) { + case 0xCC: + INST_NAME("SHA1RNDS4 Gx, Ex, Ib"); + 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, &wback, x2, x1, &fixedaddress, rex, NULL, 0, 1); + if (wback != x2) MV(x2, wback); + } + u8 = F8; + GETG; + sse_forget_reg(dyn, ninst, gd); + ADDI(x1, xEmu, offsetof(x64emu_t, xmm[gd])); + MOV32w(x3, u8); + CALL(sha1rnds4, -1); + break; + default: + DEFAULT; + } + break; #define GO(GETFLAGS, NO, YES, F) \ READFLAGS(F); \ diff --git a/src/dynarec/rv64/dynarec_rv64_660f.c b/src/dynarec/rv64/dynarec_rv64_660f.c index adc7855e..92c73c61 100644 --- a/src/dynarec/rv64/dynarec_rv64_660f.c +++ b/src/dynarec/rv64/dynarec_rv64_660f.c @@ -523,6 +523,17 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int SW(x4, gback, gdoffset + i * 4); } break; + case 0x25: + INST_NAME("PMOVSXDQ Gx, Ex"); + nextop = F8; + GETGX(); + GETEX(x2, 0); + for (int i = 1; i >= 0; --i) { + // GX->sq[i] = EX->sd[i]; + LW(x4, wback, fixedaddress + i * 4); + SD(x4, gback, gdoffset + i * 8); + } + break; case 0x28: INST_NAME("PMULDQ Gx, Ex"); nextop = F8; diff --git a/src/dynarec/rv64/dynarec_rv64_67.c b/src/dynarec/rv64/dynarec_rv64_67.c index a25261b7..effbb677 100644 --- a/src/dynarec/rv64/dynarec_rv64_67.c +++ b/src/dynarec/rv64/dynarec_rv64_67.c @@ -654,6 +654,23 @@ uintptr_t dynarec64_67(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni } break; + case 0xC1: + nextop = F8; + switch ((nextop >> 3) & 7) { + case 5: + INST_NAME("SHR Ed, Ib"); + SETFLAGS(X_ALL, SF_SET_PENDING); + GETED32(1); + u8 = (F8) & (rex.w ? 0x3f : 0x1f); + emit_shr32c(dyn, ninst, rex, ed, u8, x3, x4); + if (u8) + WBACK; + break; + default: + DEFAULT; + } + break; + case 0xC7: INST_NAME("MOV Ed, Id"); nextop = F8; @@ -727,6 +744,34 @@ uintptr_t dynarec64_67(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni break; #undef GO + case 0xF7: + nextop = F8; + switch ((nextop >> 3) & 7) { + case 4: + INST_NAME("MUL EAX, Ed"); + SETFLAGS(X_ALL, SF_PENDING); + GETED32(0); + if (rex.w) { + if (ed == xRDX) + gd = x3; + else + gd = xRDX; + MULHU(gd, xRAX, ed); + MUL(xRAX, xRAX, ed); + if (gd != xRDX) MV(xRDX, gd); + } else { + MUL(xRDX, xRAX, ed); // 64 <- 32x32 + AND(xRAX, xRDX, xMASK); + SRLIW(xRDX, xRDX, 32); + } + UFLAG_RES(xRAX); + UFLAG_OP1(xRDX); + UFLAG_DF(x2, rex.w ? d_mul64 : d_mul32); + break; + default: + DEFAULT; + } + break; default: DEFAULT; } |