diff options
| author | Yang Liu <liuyang22@iscas.ac.cn> | 2023-03-29 14:55:33 +0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-03-29 08:55:33 +0200 |
| commit | a665d2f62cb6f841954962005b73fbe371e031b5 (patch) | |
| tree | 6226a999b0947256c1aa93659431b918e34718a7 /src | |
| parent | 0baa5a82ad00e0bb3c024be2355dd58a9399e68a (diff) | |
| download | box64-a665d2f62cb6f841954962005b73fbe371e031b5.tar.gz box64-a665d2f62cb6f841954962005b73fbe371e031b5.zip | |
[RV64_DYNAREC] Added some 66 0F Pxxx opcodes (#650)
* [RV64_DYNAREC] Fixed typos * [RV64_DYNAREC] Added 66 0F FE PADDD opcode * [RV64_DYNAREC] Added 66 0F DB PAND opcode * [RV64_DYNAREC] Added 66 0F 76 PCMPEQD opcode * [RV64_DYNAREC] Added 66 0F 72 /2 PSRLD opcode * [RV64_DYNAREC] Added 66 0F DF PANDN opcode * [RV64_DYNAREC] Added 66 0F EB POR opcode * [RV64_DYNAREC] Fixed 66 0F 72 PSRLD opcode
Diffstat (limited to 'src')
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_660f.c | 59 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_helper.h | 43 | ||||
| -rw-r--r-- | src/emu/x64test.c | 2 |
3 files changed, 91 insertions, 13 deletions
diff --git a/src/dynarec/rv64/dynarec_rv64_660f.c b/src/dynarec/rv64/dynarec_rv64_660f.c index 22c61359..7a32c44c 100644 --- a/src/dynarec/rv64/dynarec_rv64_660f.c +++ b/src/dynarec/rv64/dynarec_rv64_660f.c @@ -107,7 +107,34 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int SD(x3, gback, 0); SD(x4, gback, 8); break; - + case 0x72: + nextop = F8; + switch((nextop>>3)&7) { + case 2: + INST_NAME("PSRLD Ex, Ib"); + GETEX(x1, 1); + u8 = F8; + if(u8) { + if (u8>31) { + // just zero dest + SD(xZR, x1, fixedaddress+0); + SD(xZR, x1, fixedaddress+8); + } else if(u8) { + SSE_LOOP_DS(x3, SRLI(x3, x3, u8)); + } + } + break; + default: + DEFAULT; + } + break; + case 0x76: + INST_NAME("PCMPEQD Gx,Ex"); + nextop = F8; + GETGX(x1); + GETEX(x2, 0); + SSE_LOOP_D(x3, x4, XOR(x3, x3, x4); SNEZ(x3, x3); ADDI(x3, x3, -1)); + break; case 0xAF: INST_NAME("IMUL Gw,Ew"); SETFLAGS(X_ALL, SF_PENDING); @@ -149,7 +176,27 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int AND(x1, x1, x5); OR(gd, gd, x1); break; - + case 0xDB: + INST_NAME("PAND Gx,Ex"); + nextop = F8; + GETGX(x1); + GETEX(x2, 0); + SSE_LOOP_Q(x3, x4, AND(x3, x3, x4)); + break; + case 0xDF: + INST_NAME("PANDN Gx,Ex"); + nextop = F8; + GETGX(x1); + GETEX(x2, 0); + SSE_LOOP_Q(x3, x4, NOT(x3, x3); AND(x3, x3, x4)); + break; + case 0xEB: + INST_NAME("POR Gx,Ex"); + nextop = F8; + GETGX(x1); + GETEX(x2, 0); + SSE_LOOP_Q(x3, x4, OR(x3, x3, x4)); + break; case 0xEF: INST_NAME("PXOR Gx, Ex"); nextop = F8; @@ -164,7 +211,13 @@ 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 0xFE: + INST_NAME("PADDD Gx,Ex"); + nextop = F8; + GETGX(x1); + GETEX(x2, 0); + SSE_LOOP_D(x3, x4, ADDW(x3, x3, x4)); + break; default: DEFAULT; } diff --git a/src/dynarec/rv64/dynarec_rv64_helper.h b/src/dynarec/rv64/dynarec_rv64_helper.h index 892fd076..b79a1a17 100644 --- a/src/dynarec/rv64/dynarec_rv64_helper.h +++ b/src/dynarec/rv64/dynarec_rv64_helper.h @@ -315,7 +315,7 @@ gback = a; \ ADDI(a, xEmu, offsetof(x64emu_t, xmm[gd])) -// Get Ex address in regenal register a, will purge SS or SD or it's reg and is loaded. May use x3. Use wback as load adress! +// Get Ex address in general register a, will purge SS or SD if it's reg and is loaded. May use x3. Use wback as load address! #define GETEX(a, D) \ if(MODREG) { \ ed = (nextop&7)+(rex.b<<3); \ @@ -329,16 +329,41 @@ addr = geted(dyn, addr, ninst, nextop, &wback, a, x3, &fixedaddress, rex, NULL, 1, D); \ } -// Loop for SSE opcode that use 64bits value and write to GX. -#define SSE_LOOP_Q(GX1, EX1, F) \ - LD(GX1, gback, 0); \ - LD(EX1, wback, fixedaddress+0); \ +#define SSE_LOOP_D_ITEM(GX1, EX1, F, i) \ + LWU(GX1, gback, i*4); \ + LWU(EX1, wback, fixedaddress+i*4); \ + F; \ + SW(GX1, gback, i*4); + +// Loop for SSE opcode that use 32bits value and write to GX. +#define SSE_LOOP_D(GX1, EX1, F) \ + SSE_LOOP_D_ITEM(GX1, EX1, F, 0) \ + SSE_LOOP_D_ITEM(GX1, EX1, F, 1) \ + SSE_LOOP_D_ITEM(GX1, EX1, F, 2) \ + SSE_LOOP_D_ITEM(GX1, EX1, F, 3) \ + +#define SSE_LOOP_DS_ITEM(EX1, F, i) \ + LWU(EX1, wback, fixedaddress+i*4); \ F; \ - SD(GX1, gback, 0); \ - LD(GX1, gback, 8); \ - LD(EX1, wback, fixedaddress+8); \ + SW(EX1, wback, fixedaddress+i*4); + +// Loop for SSE opcode that use 32bits value and write to EX. +#define SSE_LOOP_DS(EX1, F) \ + SSE_LOOP_DS_ITEM(EX1, F, 0) \ + SSE_LOOP_DS_ITEM(EX1, F, 1) \ + SSE_LOOP_DS_ITEM(EX1, F, 2) \ + SSE_LOOP_DS_ITEM(EX1, F, 3) + +#define SSE_LOOP_Q_ITEM(GX1, EX1, F, i) \ + LD(GX1, gback, i*8); \ + LD(EX1, wback, fixedaddress+i*8); \ F; \ - SD(GX1, gback, 8) + SD(GX1, gback, i*8); + +// Loop for SSE opcode that use 64bits value and write to GX. +#define SSE_LOOP_Q(GX1, EX1, F) \ + SSE_LOOP_Q_ITEM(GX1, EX1, F, 0) \ + SSE_LOOP_Q_ITEM(GX1, EX1, F, 1) // CALL will use x6 for the call address. Return value can be put in ret (unless ret is -1) // R0 will not be pushed/popd if ret is -2 diff --git a/src/emu/x64test.c b/src/emu/x64test.c index 151d3c8f..21a5355b 100644 --- a/src/emu/x64test.c +++ b/src/emu/x64test.c @@ -25,7 +25,7 @@ void print_banner(x64emu_t* ref) { printf_log(LOG_NONE, "Warning, difference between Interpreter and Dynarec in %p\n=======================================\n", (void*)ref->ip.q[0]); - printf_log(LOG_NONE, "DIF: Dynarec | Intepreter\n----------------------\n"); + printf_log(LOG_NONE, "DIFF: Dynarec | Interpreter\n----------------------\n"); } #define BANNER if(!banner) {banner=1; print_banner(ref);} void x64test_check(x64emu_t* ref, uintptr_t ip) |