about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorLeslie Zhai <zhaixiang@loongson.cn>2024-12-12 18:23:17 +0800
committerGitHub <noreply@github.com>2024-12-12 11:23:17 +0100
commit7168167400d7fbe60e0d9034d95bdbcbf302af99 (patch)
tree179285b5f3b10ee5f28a438581f1d71f85164f5e /src
parent7e17c862cfd93af5813a5823a639cafbc12df1d9 (diff)
downloadbox64-7168167400d7fbe60e0d9034d95bdbcbf302af99.tar.gz
box64-7168167400d7fbe60e0d9034d95bdbcbf302af99.zip
[LA64_DYNAREC] Added more opcodes (#2145)
* [LA64_DYNAREC] Added more opcodes

* [LA64_DYNAREC] Optimize MOVZX Gw, Eb
Diffstat (limited to 'src')
-rw-r--r--src/dynarec/la64/dynarec_la64_0f.c26
-rw-r--r--src/dynarec/la64/dynarec_la64_660f.c36
-rw-r--r--src/dynarec/la64/dynarec_la64_67.c2
3 files changed, 64 insertions, 0 deletions
diff --git a/src/dynarec/la64/dynarec_la64_0f.c b/src/dynarec/la64/dynarec_la64_0f.c
index d2f907f9..db4c73c1 100644
--- a/src/dynarec/la64/dynarec_la64_0f.c
+++ b/src/dynarec/la64/dynarec_la64_0f.c
@@ -414,6 +414,32 @@ uintptr_t dynarec64_0F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                     DEFAULT;
             }
             break;
+        case 0x3A: // more SSE3 opcodes
+            opcode = F8;
+            switch (opcode) {
+                case 0xCC:
+                    INST_NAME("SHA1RNDS4 Gx, Ex, Ib");
+                    nextop = F8;
+                    if (MODREG) {
+                        ed = (nextop & 7) + (rex.b << 3);
+                        sse_reflect_reg(dyn, ninst, ed);
+                        ADDI_D(x2, xEmu, offsetof(x64emu_t, xmm[ed]));
+                    } else {
+                        SMREAD();
+                        addr = geted(dyn, addr, ninst, nextop, &wback, x2, x1, &fixedaddress, rex, NULL, 0, 1);
+                        if (wback != x2) MV(x2, wback);
+                    }
+                    u8 = F8;
+                    GETG;
+                    sse_forget_reg(dyn, ninst, gd);
+                    ADDI_D(x1, xEmu, offsetof(x64emu_t, xmm[gd]));
+                    MOV32w(x3, u8);
+                    CALL(sha1rnds4, -1);
+                    break;
+                default:
+                    DEFAULT;
+            }
+            break;
 
 #define GO(GETFLAGS, NO, YES, F, I)                                                          \
     READFLAGS(F);                                                                            \
diff --git a/src/dynarec/la64/dynarec_la64_660f.c b/src/dynarec/la64/dynarec_la64_660f.c
index 6dc339d9..3e8d3809 100644
--- a/src/dynarec/la64/dynarec_la64_660f.c
+++ b/src/dynarec/la64/dynarec_la64_660f.c
@@ -107,6 +107,21 @@ uintptr_t dynarec64_660F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int
             }
             VEXTRINS_D(v0, v1, 0x10);
             break;
+        case 0x15:
+            INST_NAME("UNPCKHPD Gx, Ex");
+            nextop = F8;
+            GETGX(v0, 1);
+            if (MODREG) {
+                v1 = sse_get_reg(dyn, ninst, x1, (nextop & 7) + (rex.b << 3), 0);
+            } else {
+                SMREAD();
+                addr = geted(dyn, addr, ninst, nextop, &ed, x2, x3, &fixedaddress, rex, NULL, 1, 0);
+                v1 = fpu_get_scratch(dyn);
+                ADDI_D(x1, ed, 8);
+                FLD_D(v1, x1, fixedaddress);
+            }
+            VSHUF4I_D(v0, v1, 0xd);
+            break;
         case 0x16:
             INST_NAME("MOVHPD Gx, Eq");
             nextop = F8;
@@ -1225,6 +1240,27 @@ uintptr_t dynarec64_660F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int
             GWBACK;
             UFLAG_DF(x1, d_imul16);
             break;
+        case 0xB6:
+            INST_NAME("MOVZX Gw, Eb");
+            nextop = F8;
+            if (MODREG) {
+                if (rex.rex) {
+                    eb1 = TO_NAT((nextop & 7) + (rex.b << 3));
+                    eb2 = 0;
+                } else {
+                    ed = (nextop & 7);
+                    eb1 = TO_NAT(ed & 3); // Ax, Cx, Dx or Bx
+                    eb2 = (ed & 4) >> 2;  // L or H
+                }
+                BSTRPICK_W(x1, eb1, eb2 * 8 + 7, eb2 * 8);
+            } else {
+                SMREAD();
+                addr = geted(dyn, addr, ninst, nextop, &ed, x2, x4, &fixedaddress, rex, NULL, 1, 0);
+                LD_BU(x1, ed, fixedaddress);
+            }
+            gd = TO_NAT(((nextop & 0x38) >> 3) + (rex.r << 3));
+            BSTRINS_D(gd, x1, 15, 0); // insert in Gw
+            break;
         case 0xBE:
             INST_NAME("MOVSX Gw, Eb");
             nextop = F8;
diff --git a/src/dynarec/la64/dynarec_la64_67.c b/src/dynarec/la64/dynarec_la64_67.c
index cb5d0d0e..7ba065d6 100644
--- a/src/dynarec/la64/dynarec_la64_67.c
+++ b/src/dynarec/la64/dynarec_la64_67.c
@@ -155,6 +155,8 @@ uintptr_t dynarec64_67(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                 ZEROUP2(gd, ed);
             }
             break;
+        case 0xE8:
+            return dynarec64_00(dyn, addr - 1, ip, ninst, rex, rep, ok, need_epilog); // addr-1, to "put back" opcode)
         case 0xF7:
             nextop = F8;
             switch ((nextop >> 3) & 7) {