From e360565266ed93a671963743f3755a7a09b5d87c Mon Sep 17 00:00:00 2001 From: Yang Liu Date: Mon, 17 Apr 2023 19:07:26 +0800 Subject: [RV64_DYNAREC] Added more opcodes (#705) * [RV64_DYNAREC] Added A6 CMPSB opcode * [RV64_DYNAREC] Added 0F 12 MOVHLPS/MOVLPS opcodes * Fixed A6 opcode * Added FC CLD opcode * Added 51 SQRTSS opcode * Added 66 0F 64 PCMPGTB opcode * Added 0F 5B CVTDQ2PS opcode * Added 0F 58 ADDPS opcode * Added 66 0F 65 PCMPGTW opcode --- src/dynarec/rv64/dynarec_rv64_00_2.c | 42 +++++++++++++++++++++++++++++++ src/dynarec/rv64/dynarec_rv64_00_3.c | 5 +++- src/dynarec/rv64/dynarec_rv64_0f.c | 45 +++++++++++++++++++++++++++++++--- src/dynarec/rv64/dynarec_rv64_660f.c | 28 +++++++++++++++++++++ src/dynarec/rv64/dynarec_rv64_f30f.c | 8 +++++- src/dynarec/rv64/dynarec_rv64_helper.h | 4 ++- 6 files changed, 126 insertions(+), 6 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 6d626ba3..f7572790 100644 --- a/src/dynarec/rv64/dynarec_rv64_00_2.c +++ b/src/dynarec/rv64/dynarec_rv64_00_2.c @@ -504,6 +504,48 @@ uintptr_t dynarec64_00_2(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ADD(xRDI, xRDI, x3); } break; + case 0xA6: + switch(rep) { + case 1: + case 2: + if(rep==1) {INST_NAME("REPNZ CMPSB");} else {INST_NAME("REPZ CMPSB");} + MAYSETFLAGS(); + SETFLAGS(X_ALL, SF_SET_PENDING); + CBZ_NEXT(xRCX); + ANDI(x1, xFlags, 1<>3)&7) { diff --git a/src/dynarec/rv64/dynarec_rv64_0f.c b/src/dynarec/rv64/dynarec_rv64_0f.c index 3cded7b4..21895f48 100644 --- a/src/dynarec/rv64/dynarec_rv64_0f.c +++ b/src/dynarec/rv64/dynarec_rv64_0f.c @@ -136,7 +136,21 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni if(!MODREG) SMWRITE2(); break; - + case 0x12: + nextop = F8; + if(MODREG) { + INST_NAME("MOVHLPS Gx,Ex"); + GETGX(x1); + GETEX(x2, 0); + LD(x3, wback, fixedaddress+8); + SD(x3, gback, 0); + } else { + INST_NAME("MOVLPS Gx,Ex"); + GETEXSD(v0, 0); + GETGXSD_empty(v1); + FMVD(v1, v0); + } + break; case 0x14: INST_NAME("UNPCKLPS Gx,Ex"); nextop = F8; @@ -343,7 +357,21 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni SSE_LOOP_Q(x3, x4, XOR(x3, x3, x4)); } break; - + case 0x58: + INST_NAME("ADDPS Gx, Ex"); + nextop = F8; + GETGX(x1); + GETEX(x2, 0); + s0 = fpu_get_scratch(dyn); + s1 = fpu_get_scratch(dyn); + for(int i=0; i<4; ++i) { + // GX->f[i] += EX->f[i]; + FLW(s0, wback, fixedaddress+i*4); + FLW(s1, gback, i*4); + FADDS(s1, s1, s0); + FSW(s1, gback, i*4); + } + break; case 0x5A: INST_NAME("CVTPS2PD Gx, Ex"); nextop = F8; @@ -358,7 +386,18 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni FSD(s0, gback, 0); FSD(s1, gback, 8); break; - + case 0x5B: + INST_NAME("CVTDQ2PS Gx, Ex"); + nextop = F8; + GETGX(x1); + GETEX(x2, 0); + s0 = fpu_get_scratch(dyn); + for (int i=0; i<4; ++i) { + LW(x3, wback, fixedaddress+i*4); + FCVTSW(s0, x3, RD_RNE); + FSW(s0, gback, i*4); + } + break; case 0x77: INST_NAME("EMMS"); // empty MMX, FPU now usable diff --git a/src/dynarec/rv64/dynarec_rv64_660f.c b/src/dynarec/rv64/dynarec_rv64_660f.c index 9c102d01..3cd22575 100644 --- a/src/dynarec/rv64/dynarec_rv64_660f.c +++ b/src/dynarec/rv64/dynarec_rv64_660f.c @@ -369,6 +369,34 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int LWU(x3, x1, fixedaddress+0*4); SW(x3, x2, 1*4); break; + case 0x64: + INST_NAME("PCMPGTB Gx,Ex"); + nextop = F8; + GETGX(x1); + GETEX(x2, 0); + for(int i=0; i<16; ++i) { + // GX->ub[i] = (GX->sb[i]>EX->sb[i])?0xFF:0x00; + LB(x3, wback, fixedaddress+i); + LB(x4, gback, i); + SLT(x3, x3, x4); + NEG(x3, x3); + SB(x3, gback, i); + } + break; + case 0x65: + INST_NAME("PCMPGTW Gx,Ex"); + nextop = F8; + GETGX(x1); + GETEX(x2, 0); + for(int i=0; i<8; ++i) { + // GX->uw[i] = (GX->sw[i]>EX->sw[i])?0xFFFF:0x0000; + LH(x3, wback, fixedaddress+i*2); + LH(x4, gback, i*2); + SLT(x3, x3, x4); + NEG(x3, x3); + SH(x3, gback, i*2); + } + break; case 0x66: INST_NAME("PCMPGTD Gx,Ex"); nextop = F8; diff --git a/src/dynarec/rv64/dynarec_rv64_f30f.c b/src/dynarec/rv64/dynarec_rv64_f30f.c index f90861bf..d1b51258 100644 --- a/src/dynarec/rv64/dynarec_rv64_f30f.c +++ b/src/dynarec/rv64/dynarec_rv64_f30f.c @@ -120,7 +120,13 @@ uintptr_t dynarec64_F30F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int } } break; - + case 0x51: + INST_NAME("SQRTSS Gx, Ex"); + nextop = F8; + GETEXSS(v0, 0); + GETGXSS_empty(v1); + FSQRTS(v1, v0); + break; case 0x58: INST_NAME("ADDSS Gx, Ex"); nextop = F8; diff --git a/src/dynarec/rv64/dynarec_rv64_helper.h b/src/dynarec/rv64/dynarec_rv64_helper.h index 18e425e3..284767da 100644 --- a/src/dynarec/rv64/dynarec_rv64_helper.h +++ b/src/dynarec/rv64/dynarec_rv64_helper.h @@ -475,7 +475,7 @@ #define BNEZ_MARK2(reg) BNE_MARK2(reg, xZR) // Branch to MARK2 if reg1