about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorYang Liu <liuyang22@iscas.ac.cn>2023-04-21 18:08:49 +0800
committerGitHub <noreply@github.com>2023-04-21 12:08:49 +0200
commit2dec48f8af1a1455f8ee3a802c82087bbba70973 (patch)
tree2d3f9311a6a39c528c5442564b545f318a825484 /src
parent3f8ec8d46e478204f279dab2ad11b43cb2b9b808 (diff)
downloadbox64-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.c110
-rw-r--r--src/dynarec/rv64/dynarec_rv64_f30f.c27
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;