about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorYang Liu <liuyang22@iscas.ac.cn>2024-02-22 20:37:46 +0800
committerGitHub <noreply@github.com>2024-02-22 13:37:46 +0100
commit3ec2ebabfc97b484cfabca9d4e9c181c5b10a8c8 (patch)
tree60317809135795d2b56201ac34418c534d82d00b
parent77dcb025fd3e6a069e31e8a19c3b061b82d3fa28 (diff)
downloadbox64-3ec2ebabfc97b484cfabca9d4e9c181c5b10a8c8.tar.gz
box64-3ec2ebabfc97b484cfabca9d4e9c181c5b10a8c8.zip
[RV64_DYNAREC] Added more opcodes (#1277)
* Added 66 0F 38 25 PMOVSXDQ opcode

* Added 0F 3A CC opcode

* Added 67 F7 /4 MUL opcode

* Added 67 C1 /5 SHR opcode
-rw-r--r--src/dynarec/rv64/dynarec_rv64_0f.c26
-rw-r--r--src/dynarec/rv64/dynarec_rv64_660f.c11
-rw-r--r--src/dynarec/rv64/dynarec_rv64_67.c45
3 files changed, 82 insertions, 0 deletions
diff --git a/src/dynarec/rv64/dynarec_rv64_0f.c b/src/dynarec/rv64/dynarec_rv64_0f.c
index f98aaec5..27507db9 100644
--- a/src/dynarec/rv64/dynarec_rv64_0f.c
+++ b/src/dynarec/rv64/dynarec_rv64_0f.c
@@ -470,6 +470,32 @@ uintptr_t dynarec64_0F(dynarec_rv64_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(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(x1, xEmu, offsetof(x64emu_t, xmm[gd]));
+                    MOV32w(x3, u8);
+                    CALL(sha1rnds4, -1);
+                    break;
+                default:
+                    DEFAULT;
+            }
+            break;
 
 #define GO(GETFLAGS, NO, YES, F)                                                             \
     READFLAGS(F);                                                                            \
diff --git a/src/dynarec/rv64/dynarec_rv64_660f.c b/src/dynarec/rv64/dynarec_rv64_660f.c
index adc7855e..92c73c61 100644
--- a/src/dynarec/rv64/dynarec_rv64_660f.c
+++ b/src/dynarec/rv64/dynarec_rv64_660f.c
@@ -523,6 +523,17 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
                         SW(x4, gback, gdoffset + i * 4);
                     }
                     break;
+                case 0x25:
+                    INST_NAME("PMOVSXDQ Gx, Ex");
+                    nextop = F8;
+                    GETGX();
+                    GETEX(x2, 0);
+                    for (int i = 1; i >= 0; --i) {
+                        // GX->sq[i] = EX->sd[i];
+                        LW(x4, wback, fixedaddress + i * 4);
+                        SD(x4, gback, gdoffset + i * 8);
+                    }
+                    break;
                 case 0x28:
                     INST_NAME("PMULDQ Gx, Ex");
                     nextop = F8;
diff --git a/src/dynarec/rv64/dynarec_rv64_67.c b/src/dynarec/rv64/dynarec_rv64_67.c
index a25261b7..effbb677 100644
--- a/src/dynarec/rv64/dynarec_rv64_67.c
+++ b/src/dynarec/rv64/dynarec_rv64_67.c
@@ -654,6 +654,23 @@ uintptr_t dynarec64_67(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
             }
             break;
 
+        case 0xC1:
+            nextop = F8;
+            switch ((nextop >> 3) & 7) {
+                case 5:
+                    INST_NAME("SHR Ed, Ib");
+                    SETFLAGS(X_ALL, SF_SET_PENDING);
+                    GETED32(1);
+                    u8 = (F8) & (rex.w ? 0x3f : 0x1f);
+                    emit_shr32c(dyn, ninst, rex, ed, u8, x3, x4);
+                    if (u8)
+                        WBACK;
+                    break;
+                default:
+                    DEFAULT;
+            }
+            break;
+
         case 0xC7:
             INST_NAME("MOV Ed, Id");
             nextop = F8;
@@ -727,6 +744,34 @@ uintptr_t dynarec64_67(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
             break;
         #undef GO
 
+        case 0xF7:
+            nextop = F8;
+            switch ((nextop >> 3) & 7) {
+                case 4:
+                    INST_NAME("MUL EAX, Ed");
+                    SETFLAGS(X_ALL, SF_PENDING);
+                    GETED32(0);
+                    if (rex.w) {
+                        if (ed == xRDX)
+                            gd = x3;
+                        else
+                            gd = xRDX;
+                        MULHU(gd, xRAX, ed);
+                        MUL(xRAX, xRAX, ed);
+                        if (gd != xRDX) MV(xRDX, gd);
+                    } else {
+                        MUL(xRDX, xRAX, ed); // 64 <- 32x32
+                        AND(xRAX, xRDX, xMASK);
+                        SRLIW(xRDX, xRDX, 32);
+                    }
+                    UFLAG_RES(xRAX);
+                    UFLAG_OP1(xRDX);
+                    UFLAG_DF(x2, rex.w ? d_mul64 : d_mul32);
+                    break;
+                default:
+                    DEFAULT;
+            }
+            break;
         default:
             DEFAULT;
     }