diff options
| author | Yang Liu <liuyang22@iscas.ac.cn> | 2023-04-21 18:08:49 +0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-04-21 12:08:49 +0200 |
| commit | 2dec48f8af1a1455f8ee3a802c82087bbba70973 (patch) | |
| tree | 2d3f9311a6a39c528c5442564b545f318a825484 /src | |
| parent | 3f8ec8d46e478204f279dab2ad11b43cb2b9b808 (diff) | |
| download | box64-2dec48f8af1a1455f8ee3a802c82087bbba70973.tar.gz box64-2dec48f8af1a1455f8ee3a802c82087bbba70973.zip | |
[RV64_DYNAREC] Added more opcodes (#721)
* Added 66 0F D2 PSRLD opcode * Added 66 0F D1 PSRLW opcode * Added 66 0F F1/F2 opcodes and some refactor * Added F3 0F 70 PSHUFHW opcode * Added 66 0F 16 MOVHPD opcode
Diffstat (limited to 'src')
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_660f.c | 110 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_f30f.c | 27 |
2 files changed, 125 insertions, 12 deletions
diff --git a/src/dynarec/rv64/dynarec_rv64_660f.c b/src/dynarec/rv64/dynarec_rv64_660f.c index 79c5712d..b42d3bea 100644 --- a/src/dynarec/rv64/dynarec_rv64_660f.c +++ b/src/dynarec/rv64/dynarec_rv64_660f.c @@ -80,6 +80,20 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int LD(x3, wback, fixedaddress); SD(x3, gback, 0); break; + case 0x16: + INST_NAME("MOVHPD Gx, Eq"); + nextop = F8; + GETGX(x1); + if(MODREG) { + // access register instead of memory is bad opcode! + DEFAULT; + return addr; + } + SMREAD(); + addr = geted(dyn, addr, ninst, nextop, &wback, x2, x3, &fixedaddress, rex, NULL, 1, 0); + LD(x3, wback, fixedaddress); + SD(x3, gback, 8); + break; case 0x14: INST_NAME("UNPCKLPD Gx, Ex"); nextop = F8; @@ -1078,6 +1092,42 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int u8 = (F8)&7; LHU(gd, wback, fixedaddress+u8*2); break; + case 0xD1: + INST_NAME("PSRLW Gx,Ex"); + nextop = F8; + GETGX(x1); + GETEX(x2, 0); + LD(x3, wback, fixedaddress); + ADDI(x4, xZR, 16); + BLTU_MARK(x3, x4); + SD(xZR, gback, 0); + SD(xZR, gback, 8); + B_NEXT_nocond; + MARK; + for (int i=0; i<8; ++i) { + LHU(x5, gback, 2*i); + SRLW(x5, x5, x3); + SH(x5, gback, 2*i); + } + break; + case 0xD2: + INST_NAME("PSRLD Gx,Ex"); + nextop = F8; + GETGX(x1); + GETEX(x2, 0); + LD(x3, wback, fixedaddress); + ADDI(x4, xZR, 32); + BLTU_MARK(x3, x4); + SD(xZR, gback, 0); + SD(xZR, gback, 8); + B_NEXT_nocond; + MARK; + for (int i=0; i<4; ++i) { + LWU(x5, gback, 4*i); + SRLW(x5, x5, x3); + SW(x5, gback, 4*i); + } + break; case 0xD3: INST_NAME("PSRLQ Gx,Ex"); nextop = F8; @@ -1085,17 +1135,16 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int GETEX(x2, 0); LD(x3, wback, fixedaddress); ADDI(x4, xZR, 64); - BGE_MARK(x3, x4); - ANDI(x3, x3, 0xff); + BLTU_MARK(x3, x4); + SD(xZR, gback, 0); + SD(xZR, gback, 8); + B_NEXT_nocond; + MARK; for (int i=0; i<2; ++i) { LD(x5, gback, 8*i); SRL(x5, x5, x3); SD(x5, gback, 8*i); } - B_NEXT_nocond; - MARK; - SD(xZR, gback, 0); - SD(xZR, gback, 8); break; case 0xD4: INST_NAME("PADDQ Gx,Ex"); @@ -1219,6 +1268,44 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int SSE_LOOP_Q(x3, x4, XOR(x3, x3, x4)); } break; + case 0xF1: + INST_NAME("PSLLQ Gx,Ex"); + nextop = F8; + GETGX(x1); + GETEX(x2, 0); + ADDI(x4, xZR, 16); + LD(x3, wback, fixedaddress+0); + BLTU_MARK(x3, x4); + // just zero dest + SD(xZR, gback, 0); + SD(xZR, gback, 8); + B_NEXT_nocond; + MARK; + for (int i=0; i<8; ++i) { + LHU(x4, gback, 2*i); + SLLW(x4, x4, x3); + SH(x4, gback, 2*i); + } + break; + case 0xF2: + INST_NAME("PSLLQ Gx,Ex"); + nextop = F8; + GETGX(x1); + GETEX(x2, 0); + ADDI(x4, xZR, 32); + LD(x3, wback, fixedaddress+0); + BLTU_MARK(x3, x4); + // just zero dest + SD(xZR, gback, 0); + SD(xZR, gback, 8); + B_NEXT_nocond; + MARK; + for (int i=0; i<4; ++i) { + LWU(x4, gback, 4*i); + SLLW(x4, x4, x3); + SW(x4, gback, 4*i); + } + break; case 0xF3: INST_NAME("PSLLQ Gx,Ex"); nextop = F8; @@ -1232,12 +1319,11 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int SD(xZR, gback, 8); B_NEXT_nocond; MARK; - LD(x4, gback, 0); - LD(x5, gback, 8); - SLL(x4, x4, x3); - SLL(x5, x5, x3); - SD(x4, gback, 0); - SD(x5, gback, 8); + for (int i=0; i<2; ++i) { + LD(x4, gback, 8*i); + SLL(x4, x4, x3); + SD(x4, gback, 8*i); + } break; case 0xF4: INST_NAME("PMULUDQ Gx,Ex"); diff --git a/src/dynarec/rv64/dynarec_rv64_f30f.c b/src/dynarec/rv64/dynarec_rv64_f30f.c index c3d066c8..489d5ca0 100644 --- a/src/dynarec/rv64/dynarec_rv64_f30f.c +++ b/src/dynarec/rv64/dynarec_rv64_f30f.c @@ -200,6 +200,33 @@ uintptr_t dynarec64_F30F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int GETEX(x2, 0); SSE_LOOP_MV_Q(x3); break; + case 0x70: // TODO: Optimize this! + INST_NAME("PSHUFHW Gx, Ex, Ib"); + nextop = F8; + GETGX(x1); + GETEX(x2, 1); + u8 = F8; + int32_t idx; + + idx = 4+((u8>>(0*2))&3); + LHU(x3, wback, fixedaddress+idx*2); + idx = 4+((u8>>(1*2))&3); + LHU(x4, wback, fixedaddress+idx*2); + idx = 4+((u8>>(2*2))&3); + LHU(x5, wback, fixedaddress+idx*2); + idx = 4+((u8>>(3*2))&3); + LHU(x6, wback, fixedaddress+idx*2); + + SH(x3, gback, (4+0)*2); + SH(x4, gback, (4+1)*2); + SH(x5, gback, (4+2)*2); + SH(x6, gback, (4+3)*2); + + if (!(MODREG && (gd==ed))) { + LD(x3, wback, fixedaddress+0); + SD(x3, gback, 0); + } + break; case 0x7E: INST_NAME("MOVQ Gx, Ex"); nextop = F8; |