From 361de53d868cb2345c2df0275b8d148921c460b3 Mon Sep 17 00:00:00 2001 From: Yang Liu Date: Thu, 8 Jun 2023 19:35:15 +0800 Subject: [DYNAREC_RV64] Added more opcodes (#828) * [RV64_DYNAREC] Added 64 0F 11 opcodes * Added F2 0F F0 LDDQU opcode * Added F3 0F 12 MOVSLDUP opcode * Added 66 0F 38 DB AESIMC opcode * Added F3 0F 53 RCPSS * Added F5 CMC opcode * Added 9F LAHF opcode * Added 66 0F 38 10 PBLENDVB opcode * Fixed typo * Fxied typo * Fixed review --- src/dynarec/rv64/dynarec_rv64_00_2.c | 6 ++++ src/dynarec/rv64/dynarec_rv64_00_3.c | 6 ++++ src/dynarec/rv64/dynarec_rv64_64.c | 70 ++++++++++++++++++++++++++++++++++-- src/dynarec/rv64/dynarec_rv64_660f.c | 26 ++++++++++++-- src/dynarec/rv64/dynarec_rv64_f20f.c | 7 ++++ src/dynarec/rv64/dynarec_rv64_f30f.c | 25 +++++++++++++ 6 files changed, 136 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/dynarec/rv64/dynarec_rv64_00_2.c b/src/dynarec/rv64/dynarec_rv64_00_2.c index 5bfeec16..746488c6 100644 --- a/src/dynarec/rv64/dynarec_rv64_00_2.c +++ b/src/dynarec/rv64/dynarec_rv64_00_2.c @@ -509,6 +509,12 @@ uintptr_t dynarec64_00_2(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ANDI(xFlags, xFlags, ~(1<>3)&7) { diff --git a/src/dynarec/rv64/dynarec_rv64_64.c b/src/dynarec/rv64/dynarec_rv64_64.c index af49865b..fb73b049 100644 --- a/src/dynarec/rv64/dynarec_rv64_64.c +++ b/src/dynarec/rv64/dynarec_rv64_64.c @@ -33,12 +33,12 @@ uintptr_t dynarec64_64(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni uint8_t nextop; uint8_t u8; uint8_t gd, ed, eb1, eb2, gb1, gb2; - uint8_t wback, wb1, wb2, wb; + uint8_t gback, wback, wb1, wb2, wb; int64_t i64, j64; int v0, v1; int q0; int d0; - int64_t fixedaddress; + int64_t fixedaddress, gdoffset; int unscaled; MAYUSE(eb1); MAYUSE(eb2); @@ -73,6 +73,72 @@ uintptr_t dynarec64_64(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni GETEDO(x4, 0, x5); emit_add32(dyn, ninst, rex, gd, ed, x3, x4, x5); break; + case 0x0F: + opcode = F8; + switch(opcode) { + case 0x11: + switch(rep) { + case 0: + INST_NAME("MOVUPS Ex,Gx"); + nextop = F8; + GETGX(); + GETEX(x2, 0); + if(!MODREG) { + grab_segdata(dyn, addr, ninst, x4, seg); + ADD(x4, x4, wback); + wback = x4; + } + LD(x3, gback, gdoffset+0); + LD(x5, gback, gdoffset+8); + SD(x3, wback, fixedaddress+0); + SD(x5, wback, fixedaddress+8); + if(!MODREG) + SMWRITE2(); + break; + case 1: + INST_NAME("MOVSD Ex, Gx"); + nextop = F8; + GETG; + v0 = sse_get_reg(dyn, ninst, x1, gd, 0); + if(MODREG) { + ed = (nextop&7)+ (rex.b<<3); + d0 = sse_get_reg(dyn, ninst, x1, ed, 0); + FMVD(d0, v0); + } else { + grab_segdata(dyn, addr, ninst, x4, seg); + addr = geted(dyn, addr, ninst, nextop, &ed, x1, x2, &fixedaddress, rex, NULL, 1, 0); + ADD(x4, x4, ed); + ed = x4; + FSD(v0, ed, fixedaddress); + SMWRITE2(); + } + break; + case 2: + INST_NAME("MOVSS Ex, Gx"); + nextop = F8; + GETG; + v0 = sse_get_reg(dyn, ninst, x1, gd, 1); + if(MODREG) { + q0 = sse_get_reg(dyn, ninst, x1, (nextop&7) + (rex.b<<3), 1); + FMVS(q0, v0); + } else { + grab_segdata(dyn, addr, ninst, x4, seg); + addr = geted(dyn, addr, ninst, nextop, &ed, x1, x2, &fixedaddress, rex, NULL, 1, 0); + ADD(x4, x4, ed); + ed = x4; + FSW(v0, ed, fixedaddress); + SMWRITE2(); + } + break; + default: + DEFAULT; + } + break; + + default: + DEFAULT; + } + break; case 0x2B: INST_NAME("SUB Gd, Seg:Ed"); SETFLAGS(X_ALL, SF_SET_PENDING); diff --git a/src/dynarec/rv64/dynarec_rv64_660f.c b/src/dynarec/rv64/dynarec_rv64_660f.c index 2b36300a..21c95103 100644 --- a/src/dynarec/rv64/dynarec_rv64_660f.c +++ b/src/dynarec/rv64/dynarec_rv64_660f.c @@ -368,7 +368,20 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int SH(x3, gback, gdoffset+i*2); } break; - + case 0x10: + INST_NAME("PBLENDVB Gx,Ex"); + nextop = F8; + GETGX(); + GETEX(x2, 0); + sse_forget_reg(dyn, ninst, 0); // forget xmm[0] + for (int i=0; i<16; ++i) { + LB(x3, xEmu, offsetof(x64emu_t, xmm[0])+i); + BGE(x3, xZR, 12); // continue + LBU(x3, wback, fixedaddress+i); + SB(x3, gback, gdoffset+i); + // continue + } + break; case 0x17: INST_NAME("PTEST Gx, Ex"); nextop = F8; @@ -648,7 +661,16 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int SW(x3, gback, gdoffset+i*4); } break; - + case 0xDB: + INST_NAME("AESIMC Gx, Ex"); // AES-NI + nextop = F8; + GETGX(); + GETEX(x2, 0); + SSE_LOOP_MV_Q(x3); + sse_forget_reg(dyn, ninst, gd); + MOV32w(x1, gd); + CALL(native_aesimc, -1); + break; case 0xDC: INST_NAME("AESENC Gx, Ex"); // AES-NI nextop = F8; diff --git a/src/dynarec/rv64/dynarec_rv64_f20f.c b/src/dynarec/rv64/dynarec_rv64_f20f.c index 52716ad4..d532c6f5 100644 --- a/src/dynarec/rv64/dynarec_rv64_f20f.c +++ b/src/dynarec/rv64/dynarec_rv64_f20f.c @@ -364,6 +364,13 @@ uintptr_t dynarec64_F20F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int x87_restoreround(dyn, ninst, u8); SD(xZR, gback, gdoffset+8); break; + case 0xF0: + INST_NAME("LDDQU Gx,Ex"); + nextop = F8; + GETGX(); + GETEX(x2, 0); + SSE_LOOP_MV_Q(x3); + break; default: DEFAULT; } diff --git a/src/dynarec/rv64/dynarec_rv64_f30f.c b/src/dynarec/rv64/dynarec_rv64_f30f.c index 0b0b0c31..383c6482 100644 --- a/src/dynarec/rv64/dynarec_rv64_f30f.c +++ b/src/dynarec/rv64/dynarec_rv64_f30f.c @@ -81,6 +81,21 @@ uintptr_t dynarec64_F30F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int } break; + case 0x12: + INST_NAME("MOVSLDUP Gx, Ex"); + nextop = F8; + GETGX(); + GETEX(x2, 0); + + // GX->ud[1] = GX->ud[0] = EX->ud[0]; + // GX->ud[3] = GX->ud[2] = EX->ud[2]; + LD(x3, wback, fixedaddress+0); + SD(x3, gback, gdoffset+0); + SD(x3, gback, gdoffset+4); + LD(x3, wback, fixedaddress+8); + SD(x3, gback, gdoffset+8); + SD(x3, gback, gdoffset+12); + break; case 0x1E: INST_NAME("NOP / ENDBR32 / ENDBR64"); nextop = F8; @@ -153,6 +168,16 @@ uintptr_t dynarec64_F30F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int GETGXSS_empty(v1); FSQRTS(v1, v0); break; + case 0x53: + INST_NAME("RCPSS Gx, Ex"); + nextop = F8; + GETEXSS(v0, 0); + GETGXSS_empty(v1); + q0 = fpu_get_scratch(dyn); + LUI(x3, 0x3F800); // 1.0f + FMVWX(q0, x3); + FDIVS(v1, q0, v0); + break; case 0x58: INST_NAME("ADDSS Gx, Ex"); nextop = F8; -- cgit 1.4.1