diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_660f.c | 61 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_helper.h | 19 |
2 files changed, 77 insertions, 3 deletions
diff --git a/src/dynarec/rv64/dynarec_rv64_660f.c b/src/dynarec/rv64/dynarec_rv64_660f.c index bac50efc..05b13987 100644 --- a/src/dynarec/rv64/dynarec_rv64_660f.c +++ b/src/dynarec/rv64/dynarec_rv64_660f.c @@ -49,7 +49,13 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int MAYUSE(j64); switch(opcode) { - + case 0x14: + INST_NAME("UNPCKLPD Gx, Ex"); + nextop = F8; + GETEXSD(d0, 0); + GETGX(x3); + FSD(d0, x3, 8); + break; case 0x1F: INST_NAME("NOP (multibyte)"); nextop = F8; @@ -121,6 +127,42 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ORI(xFlags, xFlags, 1<<F_ZF); } break; + case 0x54: + INST_NAME("ANDPD Gx, Ex"); + nextop = F8; + GETEX(x1, 0); + GETGX(x2); + SSE_LOOP_Q(x3, x4, AND(x3, x3, x4)); + break; + case 0x55: + INST_NAME("ANDNPD Gx, Ex"); + nextop = F8; + GETEX(x1, 0); + GETGX(x2); + SSE_LOOP_Q(x3, x4, NOT(x3, x3); AND(x3, x3, x4)); + break; + case 0x57: + INST_NAME("XORPD Gx, Ex"); + nextop = F8; + GETEX(x1, 0); + GETGX(x2); + SSE_LOOP_Q(x3, x4, XOR(x3, x3, x4)); + break; + case 0x62: + INST_NAME("PUNPCKLDQ Gx,Ex"); + nextop = F8; + GETEX(x1, 0); + GETGX(x2); + // GX->ud[3] = EX->ud[1]; + LWU(x3, x1, fixedaddress+1*4); + SW(x3, x2, 3*4); + // GX->ud[2] = GX->ud[1]; + LWU(x3, x2, 1*4); + SW(x3, x2, 2*4); + // GX->ud[1] = EX->ud[0]; + LWU(x3, x1, fixedaddress+0*4); + SW(x3, x2, 1*4); + break; case 0x6C: INST_NAME("PUNPCKLQDQ Gx,Ex"); nextop = F8; @@ -308,6 +350,13 @@ 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 0xD4: + INST_NAME("PADDQ Gx,Ex"); + nextop = F8; + GETGX(x1); + GETEX(x2, 0); + SSE_LOOP_Q(x3, x4, ADD(x3, x3, x4)); + break; case 0xDB: INST_NAME("PAND Gx,Ex"); nextop = F8; @@ -343,12 +392,20 @@ 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 0xFD: + INST_NAME("PADDW Gx,Ex"); + nextop = F8; + nextop = F8; + GETGX(x1); + GETEX(x2, 0); + SSE_LOOP_WQ(x3, x4, ADDW(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)); + SSE_LOOP_DQ(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 4fb77d50..565fe018 100644 --- a/src/dynarec/rv64/dynarec_rv64_helper.h +++ b/src/dynarec/rv64/dynarec_rv64_helper.h @@ -335,12 +335,29 @@ F; \ SW(GX1, gback, i*4); +#define SSE_LOOP_W_ITEM(GX1, EX1, F, i) \ + LHU(GX1, gback, i*2); \ + LHU(EX1, wback, fixedaddress+i*2); \ + F; \ + SH(GX1, gback, i*2); + // 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) \ + SSE_LOOP_D_ITEM(GX1, EX1, F, 3) + +#define SSE_LOOP_DQ(GX1, EX1, F) \ + SSE_LOOP_D_ITEM(GX1, EX1, F, 0) \ + SSE_LOOP_D_ITEM(GX1, EX1, F, 1) + +#define SSE_LOOP_WQ(GX1, EX1, F) \ + SSE_LOOP_W_ITEM(GX1, EX1, F, 0) \ + SSE_LOOP_W_ITEM(GX1, EX1, F, 1) \ + SSE_LOOP_W_ITEM(GX1, EX1, F, 2) \ + SSE_LOOP_W_ITEM(GX1, EX1, F, 3) + #define SSE_LOOP_DS_ITEM(EX1, F, i) \ LWU(EX1, wback, fixedaddress+i*4); \ |