diff options
| author | Yang Liu <numbksco@gmail.com> | 2023-06-08 19:35:15 +0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-06-08 13:35:15 +0200 |
| commit | 361de53d868cb2345c2df0275b8d148921c460b3 (patch) | |
| tree | 9c27db6145e9be7855b3e3b4c914b928d9364df6 /src | |
| parent | 4021f6d8c320c086fe7e6e4437414b646dda5062 (diff) | |
| download | box64-361de53d868cb2345c2df0275b8d148921c460b3.tar.gz box64-361de53d868cb2345c2df0275b8d148921c460b3.zip | |
[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
Diffstat (limited to 'src')
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_00_2.c | 6 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_00_3.c | 6 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_64.c | 70 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_660f.c | 26 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_f20f.c | 7 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_f30f.c | 25 |
6 files changed, 136 insertions, 4 deletions
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<<F_TF)); } break; + case 0x9F: + INST_NAME("LAHF"); + READFLAGS(X_CF|X_PF|X_AF|X_ZF|X_SF); + ANDI(xRAX, xFlags, 0xFF); + SLLI(xRAX, xRAX, 8); + break; case 0xA1: INST_NAME("MOV EAX,Od"); u64 = F64; diff --git a/src/dynarec/rv64/dynarec_rv64_00_3.c b/src/dynarec/rv64/dynarec_rv64_00_3.c index 9019042e..ef933e6f 100644 --- a/src/dynarec/rv64/dynarec_rv64_00_3.c +++ b/src/dynarec/rv64/dynarec_rv64_00_3.c @@ -742,6 +742,12 @@ uintptr_t dynarec64_00_3(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int case 0xF0: addr = dynarec64_F0(dyn, addr, ip, ninst, rex, rep, ok, need_epilog); break; + case 0xF5: + INST_NAME("CMC"); + READFLAGS(X_CF); + SETFLAGS(X_CF, SF_SUBSET); + XORI(xFlags, xFlags, 1<<F_CF); + break; case 0xF6: nextop = F8; switch((nextop>>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; |