about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorYang Liu <liuyang22@iscas.ac.cn>2023-04-24 02:53:11 +0800
committerGitHub <noreply@github.com>2023-04-23 20:53:11 +0200
commitb49a1904dfdcd4ee28903dc8ae9cc12ab5c33db0 (patch)
tree7456d6639f79fbd7c14fed943654eadc45f7578c
parent1a70b54129e27de9ff2908f10f78e41cbbba2c43 (diff)
downloadbox64-b49a1904dfdcd4ee28903dc8ae9cc12ab5c33db0.tar.gz
box64-b49a1904dfdcd4ee28903dc8ae9cc12ab5c33db0.zip
[RV64_DYNAREC] Added more 66 0F opcodes (#734)
* Added 66 0F ED PADDSW opcode

* Added 66 0F DC PADDUSB opcode

* Added 66 0F E0 PAVGB opcode

* Added 66 0F E3 PAVGW opcode

* Added 66 0F E1 PSRAW opcode

* Added 66 0F E2 PSRAD opcode

* Added 66 0F C6 SHUFPD opcode

* Added 66 0F 2B MOVNTPD opcode

* Added 66 0F E7 MOVNTDQ opcode

* Added 66 0F E9 PSUBSW opcode

* Added 66 0F D8 PSUBUSB opcode
-rw-r--r--src/dynarec/rv64/dynarec_rv64_660f.c188
1 files changed, 174 insertions, 14 deletions
diff --git a/src/dynarec/rv64/dynarec_rv64_660f.c b/src/dynarec/rv64/dynarec_rv64_660f.c
index b71af6d0..596c3218 100644
--- a/src/dynarec/rv64/dynarec_rv64_660f.c
+++ b/src/dynarec/rv64/dynarec_rv64_660f.c
@@ -80,20 +80,6 @@ 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;
@@ -115,6 +101,20 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
             LD(x3, wback, fixedaddress+8);
             SD(x3, gback, 8);
             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 0x1F:
             INST_NAME("NOP (multibyte)");
             nextop = F8;
@@ -159,6 +159,13 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
             SSE_LOOP_MV_Q2(x3);
             if(!MODREG) SMWRITE2();
             break;
+        case 0x2B:
+            INST_NAME("MOVNTPD Ex, Gx");
+            nextop = F8;
+            GETGX(x1);
+            GETEX(x2, 0);
+            SSE_LOOP_MV_Q2(x3);
+            break;
         case 0x2E:
             // no special check...
         case 0x2F:
@@ -1092,6 +1099,22 @@ 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 0xC6:
+            INST_NAME("SHUFPD Gx, Ex, Ib");
+            nextop = F8;
+            GETGX(x1);
+            u8 = F8;
+            if (MODREG && gd==(nextop&7)+(rex.b<<3) && u8==0) {
+                LD(x3, gback, 0);
+                SD(x3, gback, 8);
+                break;
+            }
+            GETEX(x2, 1)
+            LD(x3, gback, 8*(u8&1));
+            LD(x4, wback, fixedaddress+8*((u8>>1)&1));
+            SD(x3, gback, 0);
+            SD(x4, gback, 8);
+            break;
         case 0xD1:
             INST_NAME("PSRLW Gx,Ex");
             nextop = F8;
@@ -1178,6 +1201,21 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
                 OR(gd, gd, x3);
             }
             break;
+        case 0xD8:
+            INST_NAME("PSUBUSB Gx, Ex");
+            nextop = F8;
+            GETGX(x1);
+            GETEX(x2, 0);
+            for(int i=0; i<16; ++i) {
+                LBU(x3, gback, i);
+                LBU(x4, wback, fixedaddress+i);
+                SUB(x3, x3, x4);
+                NOT(x4, x3);
+                SRAI(x4, x4, 63);
+                AND(x3, x3, x4);
+                SB(x3, gback, i);
+            }
+            break;
         case 0xD9:
             INST_NAME("PSUBUSW Gx, Ex");
             nextop = F8;
@@ -1192,6 +1230,21 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
             GETEX(x2, 0);
             SSE_LOOP_Q(x3, x4, AND(x3, x3, x4));
             break;
+        case 0xDC:
+            INST_NAME("PADDUSB Gx,Ex");
+            nextop = F8;
+            GETGX(x1);
+            GETEX(x2, 0);
+            ADDI(x5, xZR, 0xFF);
+            for(int i=0; i<16; ++i) {
+                LBU(x3, gback, i);
+                LBU(x4, wback, fixedaddress+i);
+                ADD(x3, x3, x4);
+                BLT(x3, x5, 8);
+                ADDI(x3, xZR, 0xFF);
+                SB(x3, gback, i);
+            }
+            break;
         case 0xDD:
             INST_NAME("PADDUSW Gx,Ex");
             nextop = F8;
@@ -1216,6 +1269,64 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
             GETEX(x2, 0);
             SSE_LOOP_Q(x3, x4, NOT(x3, x3); AND(x3, x3, x4));
             break;
+         case 0xE0:
+            INST_NAME("PAVGB Gx, Ex");
+            nextop = F8;
+            GETGX(x1);
+            GETEX(x2, 0);
+            for (int i=0; i<16; ++i) {
+                LBU(x3, gback, i);
+                LBU(x4, wback, fixedaddress+i);
+                ADDW(x3, x3, x4);
+                ADDIW(x3, x3, 1);
+                SRAIW(x3, x3, 1);
+                SB(x3, gback, i);
+            }
+            break;
+        case 0xE1:
+            INST_NAME("PSRAW Gx,Ex");
+            nextop = F8;
+            GETGX(x1);
+            GETEX(x2, 0);
+            ADDI(x4, xZR, 16);
+            LD(x3, wback, fixedaddress);
+            BLTU(x3, x4, 8);
+            SUBI(x3, x4, 1);
+            for (int i=0; i<8; ++i) {
+                LH(x4, gback, 2*i);
+                SRAW(x4, x4, x3);
+                SH(x4, gback, 2*i);
+            }
+            break;
+        case 0xE2:
+            INST_NAME("PSRAD Gx,Ex");
+            nextop = F8;
+            GETGX(x1);
+            GETEX(x2, 0);
+            ADDI(x4, xZR, 32);
+            LD(x3, wback, fixedaddress);
+            BLTU(x3, x4, 8);
+            SUBI(x3, x4, 1);
+            for (int i=0; i<4; ++i) {
+                LW(x4, gback, 4*i);
+                SRAW(x4, x4, x3);
+                SW(x4, gback, 4*i);
+            }
+            break;
+        case 0xE3:
+            INST_NAME("PAVGW Gx,Ex");
+            nextop = F8;
+            GETGX(x1);
+            GETEX(x2, 0);
+            for (int i=0; i<8; ++i) {
+                LHU(x3, gback, 2*i);
+                LHU(x4, wback, fixedaddress+2*i);
+                ADDW(x3, x3, x4);
+                ADDIW(x3, x3, 1);
+                SRAIW(x3, x3, 1);
+                SH(x3, gback, 2*i);
+            }
+            break;
         case 0xE4:
             INST_NAME("PMULHUW Gx,Ex");
             nextop = F8;
@@ -1229,6 +1340,13 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
                 SH(x3, gback, 2*i);
             }
             break;
+        case 0xE7:
+            INST_NAME("MOVNTDQ Ex, Gx");
+            nextop = F8;
+            GETGX(x1);
+            GETEX(x2, 0);
+            SSE_LOOP_MV_Q2(x3);
+            break;
         case 0xE8:
             INST_NAME("PSUBSB Gx,Ex");
             nextop = F8;
@@ -1253,6 +1371,27 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
                 SB(x3, gback, i);
             }
             break;
+        case 0xE9:
+            INST_NAME("PSUBSW Gx,Ex");
+            nextop = F8;
+            GETGX(x1);
+            GETEX(x2, 0);
+            for(int i=0; i<8; ++i) {
+                // tmp32s = (int32_t)GX->sw[i] - EX->sw[i];
+                // GX->sw[i] = (tmp32s>32767)?32767:((tmp32s<-32768)?-32768:tmp32s);
+                LH(x3, gback, 2*i);
+                LH(x4, wback, fixedaddress+2*i);
+                SUBW(x3, x3, x4);
+                LUI(x4, 0xFFFF8); // -32768
+                BGE(x3, x4, 12);
+                SH(x4, gback, 2*i);
+                J(20); // continue
+                LUI(x4, 8); // 32768
+                BLT(x3, x4, 8);
+                ADDIW(x3, x4, -1);
+                SH(x3, gback, 2*i);
+            }
+            break;
         case 0xEB:
             INST_NAME("POR Gx,Ex");
             nextop = F8;
@@ -1284,6 +1423,27 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
                 SB(x3, gback, i);
             }
             break;
+        case 0xED:
+            INST_NAME("PADDSW Gx,Ex");
+            nextop = F8;
+            GETGX(x1);
+            GETEX(x2, 0);
+            for(int i=0; i<8; ++i) {
+                // tmp32s = (int32_t)GX->sw[i] + EX->sw[i];
+                // GX->sw[i] = (tmp32s>32767)?32767:((tmp32s<-32768)?-32768:tmp32s);
+                LH(x3, gback, 2*i);
+                LH(x4, wback, fixedaddress+2*i);
+                ADDW(x3, x3, x4);
+                LUI(x4, 0xFFFF8); // -32768
+                BGE(x3, x4, 12);
+                SH(x4, gback, 2*i);
+                J(20); // continue
+                LUI(x4, 8); // 32768
+                BLT(x3, x4, 8);
+                ADDIW(x3, x4, -1);
+                SH(x3, gback, 2*i);
+            }
+            break;
         case 0xEE:
             INST_NAME("PMAXSW Gx,Ex");
             nextop = F8;