diff options
| author | Yang Liu <liuyang22@iscas.ac.cn> | 2023-04-17 19:07:26 +0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-04-17 13:07:26 +0200 |
| commit | e360565266ed93a671963743f3755a7a09b5d87c (patch) | |
| tree | 026a6bc65d8839d256f7bbe339acab36ee9699cf /src | |
| parent | dce7be277520457f56b56ac4269a13b614ef5401 (diff) | |
| download | box64-e360565266ed93a671963743f3755a7a09b5d87c.tar.gz box64-e360565266ed93a671963743f3755a7a09b5d87c.zip | |
[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
Diffstat (limited to 'src')
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_00_2.c | 42 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_00_3.c | 5 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_0f.c | 45 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_660f.c | 28 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_f30f.c | 8 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_helper.h | 4 |
6 files changed, 126 insertions, 6 deletions
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<<F_DF); + BNEZ_MARK2(x1); + MARK; // Part with DF==0 + LBU(x1, xRSI, 0); + ADDI(xRSI, xRSI, 1); + LBU(x2, xRDI, 0); + ADDI(xRDI, xRDI, 1); + SUBI(xRCX, xRCX, 1); + if (rep==1) {BEQ_MARK3(x1, x2);} else {BNE_MARK3(x1, x2);} + BNEZ_MARK(xRCX); + B_MARK3_nocond; + MARK2; // Part with DF==1 + LBU(x1, xRSI, 0); + SUBI(xRSI, xRSI, 1); + LBU(x2, xRDI, 0); + SUBI(xRDI, xRDI, 1); + SUBI(xRCX, xRCX, 1); + if (rep==1) {BEQ_MARK3(x1, x2);} else {BNE_MARK3(x1, x2);} + BNEZ_MARK2(xRCX); + MARK3; // end + emit_cmp8(dyn, ninst, x1, x2, x3, x4, x5, x6); + break; + default: + INST_NAME("CMPSB"); + SETFLAGS(X_ALL, SF_SET_PENDING); + GETDIR(x3, x1, 1); + LBU(x1, xRSI, 0); + LBU(x2, xRDI, 0); + ADD(xRSI, xRSI, x3); + ADD(xRDI, xRDI, x3); + emit_cmp8(dyn, ninst, x1, x2, x3, x4, x5, x6); + break; + } + break; case 0xA8: INST_NAME("TEST AL, Ib"); SETFLAGS(X_ALL, SF_SET_PENDING); diff --git a/src/dynarec/rv64/dynarec_rv64_00_3.c b/src/dynarec/rv64/dynarec_rv64_00_3.c index 70e73582..11b0ac5e 100644 --- a/src/dynarec/rv64/dynarec_rv64_00_3.c +++ b/src/dynarec/rv64/dynarec_rv64_00_3.c @@ -904,7 +904,10 @@ uintptr_t dynarec64_00_3(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int SET_DFNONE(); ORI(xFlags, xFlags, 1 << F_CF); break; - + case 0xFC: + INST_NAME("CLD"); + ANDI(xFlags, xFlags, ~(1<<F_CF)); + break; case 0xFF: nextop = F8; switch((nextop>>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<reg2 (use j64) #define BLT_MARK2(reg1, reg2) Bxx_gen(LT, MARK2, reg1,reg2) -// Branch to MARK instruction unconditionnal (use j64) +// Branch to MARK2 instruction unconditionnal (use j64) #define B_MARK2_nocond Bxx_gen(__, MARK2, 0, 0) // Branch to MARK3 if reg1==reg2 (use j64) #define BEQ_MARK3(reg1, reg2) Bxx_gen(EQ, MARK3, reg1, reg2) @@ -483,6 +483,8 @@ #define BNE_MARK3(reg1, reg2) Bxx_gen(NE, MARK3, reg1, reg2) // Branch to MARK3 if reg1!=0 (use j64) #define BNEZ_MARK3(reg) BNE_MARK3(reg, xZR) +// Branch to MARK3 instruction unconditionnal (use j64) +#define B_MARK3_nocond Bxx_gen(__, MARK3, 0, 0) // Branch to MARKLOCK if reg1!=reg2 (use j64) #define BNE_MARKLOCK(reg1, reg2) Bxx_gen(NE, MARKLOCK, reg1, reg2) // Branch to MARKLOCK if reg1!=0 (use j64) |