about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorYang Liu <liuyang22@iscas.ac.cn>2023-12-10 04:37:11 +0800
committerGitHub <noreply@github.com>2023-12-09 21:37:11 +0100
commit0df1e38ded3e0ee608c90959b63b82901ef2c423 (patch)
tree64858501053b8703ad48186719aa22a681e25c4a /src
parent7344689ba63da491282020d5429e80385e63f314 (diff)
downloadbox64-0df1e38ded3e0ee608c90959b63b82901ef2c423.tar.gz
box64-0df1e38ded3e0ee608c90959b63b82901ef2c423.zip
[DYNAREC_RV64] Added more opcodes for flatout.exe (#1132)
* [DYNAREC_RV64] Fixed printer imm format typo

* [DYNAREC_RV64] Added more DC opcodes

* [DYNAREC_RV64] Added 9E SAHF opcode

* [DYNAREC_RV64] Added 66 A1 MOV opcode

* [DYNAREC_RV64] Added 0F 72 /6 PSLLD opcode

* [DYNAREC_RV64] Added 0F 72 /2 PSRLD opcode

* [DYNAREC_RV64] Added 0F F5 PMADDWD opcode

* [DYNAREC_RV64] Added 0F 72 /4 PSRAD opcode

* [DYNAREC_RV64] Added 0F FE PADDD opcode

* [DYNAREC_RV64] Added 0F 73 opcodes

* Fixed a bunch of mistakes

* Fixed printer

* Fix fix fix

* Fixed printer again

* Added 0F DB PAND opcode

* Fixed 0F 6E MOVD opcode
Diffstat (limited to 'src')
-rw-r--r--src/dynarec/rv64/dynarec_rv64_00_2.c13
-rw-r--r--src/dynarec/rv64/dynarec_rv64_0f.c146
-rw-r--r--src/dynarec/rv64/dynarec_rv64_66.c12
-rw-r--r--src/dynarec/rv64/dynarec_rv64_dc.c8
-rw-r--r--src/dynarec/rv64/dynarec_rv64_helper.h8
-rw-r--r--src/dynarec/rv64/rv64_printer.c5
6 files changed, 179 insertions, 13 deletions
diff --git a/src/dynarec/rv64/dynarec_rv64_00_2.c b/src/dynarec/rv64/dynarec_rv64_00_2.c
index bf1d1f73..bea16d2d 100644
--- a/src/dynarec/rv64/dynarec_rv64_00_2.c
+++ b/src/dynarec/rv64/dynarec_rv64_00_2.c
@@ -503,9 +503,20 @@ uintptr_t dynarec64_00_2(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
                 jump_to_epilog(dyn, addr, 0, ninst);
             }
             break;
+        case 0x9E:
+            INST_NAME("SAHF");
+            SETFLAGS(X_CF | X_PF | X_AF | X_ZF | X_SF, SF_SUBSET);
+            ADDI(x1, xZR, ~0b11010101);
+            AND(xFlags, xFlags, x1);
+            NOT(x1, x1);
+            SRLI(x2, xRAX, 8);
+            AND(x1, x1, x2);
+            OR(xFlags, xFlags, x1);
+            SET_DFNONE();
+            break;
         case 0x9F:
             INST_NAME("LAHF");
-            READFLAGS(X_CF|X_PF|X_AF|X_ZF|X_SF);
+            READFLAGS(X_CF | X_PF | X_AF | X_ZF | X_SF);
             ANDI(x1, xFlags, 0xFF);
             SLLI(x1, x1, 8);
             MOV64x(x2, 0xffffffffffff00ffLL);
diff --git a/src/dynarec/rv64/dynarec_rv64_0f.c b/src/dynarec/rv64/dynarec_rv64_0f.c
index 360cd9dd..283b6793 100644
--- a/src/dynarec/rv64/dynarec_rv64_0f.c
+++ b/src/dynarec/rv64/dynarec_rv64_0f.c
@@ -827,17 +827,10 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                 ed = xRAX + (nextop & 7) + (rex.b << 3);
             } else {
                 addr = geted(dyn, addr, ninst, nextop, &ed, x3, x2, &fixedaddress, rex, NULL, 1, 0);
-                if (rex.w) {
-                    LD(x4, ed, fixedaddress);
-                } else {
-                    LW(x4, ed, fixedaddress);
-                }
+                LDxw(x4, ed, fixedaddress);
                 ed = x4;
             }
-            if (rex.w)
-                SD(ed, gback, gdoffset + 0);
-            else
-                SW(ed, gback, gdoffset + 0);
+            SD(ed, gback, gdoffset + 0);
             break;
         case 0x6F:
             INST_NAME("MOVQ Gm, Em");
@@ -901,6 +894,94 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                     DEFAULT;
             }
             break;
+        case 0x72:
+            nextop = F8;
+            switch ((nextop >> 3) & 7) {
+                case 2:
+                    INST_NAME("PSRLD Em, Ib");
+                    GETEM(x4, 1);
+                    u8 = F8;
+                    if (u8) {
+                        if (u8 > 31) {
+                            SD(xZR, wback, fixedaddress);
+                        } else {
+                            LD(x1, wback, fixedaddress);
+                            SRLI(x2, x1, 32 + u8);
+                            SRLIW(x1, x1, u8);
+                            SW(x1, wback, fixedaddress);
+                            SW(x2, wback, fixedaddress + 4);
+                        }
+                    }
+                    break;
+                case 4:
+                    INST_NAME("PSRAD Em, Ib");
+                    GETEM(x4, 1);
+                    u8 = F8;
+                    if (u8 > 31) u8 = 31;
+                    if (u8) {
+                        LD(x1, wback, fixedaddress);
+                        SRAI(x2, x1, 32 + u8);
+                        SRAIW(x1, x1, u8);
+                        SW(x1, wback, fixedaddress);
+                        SW(x2, wback, fixedaddress + 4);
+                    }
+                    break;
+                case 6:
+                    INST_NAME("PSLLD Em, Ib");
+                    GETEM(x4, 1);
+                    u8 = F8;
+                    if (u8) {
+                        if (u8 > 31) {
+                            SD(xZR, wback, fixedaddress);
+                        } else {
+                            LD(x1, wback, fixedaddress);
+                            SRLI(x2, x1, 32);
+                            SLLIW(x1, x1, u8);
+                            SLLIW(x2, x2, u8);
+                            SW(x1, wback, fixedaddress);
+                            SW(x2, wback, fixedaddress + 4);
+                        }
+                    }
+                    break;
+                default:
+                    DEFAULT;
+            }
+            break;
+        case 0x73:
+            nextop = F8;
+            switch ((nextop >> 3) & 7) {
+                case 2:
+                    INST_NAME("PSRLQ Em, Ib");
+                    GETEM(x4, 1);
+                    u8 = F8;
+                    if (u8) {
+                        if (u8 > 63) {
+                            SD(xZR, wback, fixedaddress);
+                        } else if (u8) {
+                            LD(x1, wback, fixedaddress);
+                            SRLI(x1, x1, u8);
+                            SD(x1, wback, fixedaddress);
+                        }
+                    }
+                    break;
+                case 6:
+                    INST_NAME("PSLLQ Em, Ib");
+                    GETEM(x4, 1);
+                    u8 = F8;
+                    if (u8) {
+                        if (u8 > 63) {
+                            SD(xZR, wback, fixedaddress);
+                        } else {
+                            LD(x1, wback, fixedaddress);
+                            SLLI(x1, x1, u8);
+                            SD(x1, wback, fixedaddress);
+                        }
+                    }
+                    break;
+                default:
+                    DEFAULT;
+            }
+            break;
         case 0x75:
             INST_NAME("PCMPEQW Gm,Em");
             nextop = F8;
@@ -916,6 +997,20 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
             emu->fpu_stack = 0;*/
             // TODO: Check if something is needed here?
             break;
+        case 0x7E:
+            INST_NAME("MOVD Ed, Gm");
+            nextop = F8;
+            GETGM();
+            if ((nextop & 0xC0) == 0xC0) {
+                ed = xRAX + (nextop & 7) + (rex.b << 3);
+                LDxw(ed, gback, gdoffset);
+            } else {
+                addr = geted(dyn, addr, ninst, nextop, &wback, x3, x2, &fixedaddress, rex, NULL, 1, 0);
+                LDxw(x1, gback, gdoffset);
+                SDxw(x1, wback, fixedaddress);
+                SMWRITE2();
+            }
+            break;
         case 0x7F:
             INST_NAME("MOVQ Em, Gm");
             nextop = F8;
@@ -1586,6 +1681,16 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
             gd = xRAX + (opcode & 7) + (rex.b << 3);
             REV8xw(gd, gd, x1, x2, x3, x4);
             break;
+        case 0xDB:
+            INST_NAME("PAND Gm, Em");
+            nextop = F8;
+            GETGM();
+            GETEM(x4, 0);
+            LD(x1, wback, fixedaddress);
+            LD(x2, gback, gdoffset);
+            AND(x1, x1, x2);
+            SD(x1, gback, gdoffset);
+            break;
         case 0xE5:
             INST_NAME("PMULHW Gm,Em");
             nextop = F8;
@@ -1647,6 +1752,22 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                 SD(x3, gback, gdoffset + 0);
             }
             break;
+        case 0xF5:
+            INST_NAME("PMADDWD Gm, Em");
+            nextop = F8;
+            GETGM();
+            GETEM(x5, 0);
+            for (int i = 0; i < 2; ++i) {
+                LH(x1, gback, gdoffset + i * 4);
+                LH(x2, gback, gdoffset + i * 4 + 2);
+                LH(x3, wback, fixedaddress + i * 4);
+                LH(x4, wback, fixedaddress + i * 4 + 2);
+                MULW(x1, x1, x3);
+                MULW(x2, x2, x4);
+                ADDW(x1, x1, x2);
+                SW(x1, gback, gdoffset + i * 4);
+            }
+            break;
         case 0xF9:
             INST_NAME("PSUBW Gm, Em");
             nextop = F8;
@@ -1661,6 +1782,13 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
             GETEM(x2, 0);
             MMX_LOOP_W(x3, x4, ADDW(x3, x3, x4));
             break;
+        case 0xFE:
+            INST_NAME("PADDD Gm, Em");
+            nextop = F8;
+            GETGM();
+            GETEM(x2, 0);
+            MMX_LOOP_D(x3, x4, ADDW(x3, x3, x4));
+            break;
         default:
             DEFAULT;
     }
diff --git a/src/dynarec/rv64/dynarec_rv64_66.c b/src/dynarec/rv64/dynarec_rv64_66.c
index e78310f9..fdc2d7e4 100644
--- a/src/dynarec/rv64/dynarec_rv64_66.c
+++ b/src/dynarec/rv64/dynarec_rv64_66.c
@@ -607,7 +607,17 @@ uintptr_t dynarec64_66(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
             AND(x1, x1, x2);
             OR(xRAX, xRAX, x1);
             break;
-
+        case 0xA1:
+            INST_NAME("MOV EAX,Od");
+            if (rex.is32bits) u64 = F32; else u64 = F64;
+            MOV64z(x1, u64);
+            if (isLockAddress(u64)) lock = 1; else lock = 0;
+            SMREADLOCK(lock);
+            LHU(x2, x1, 0);
+            LUI(x3, 0xffff0);
+            AND(xRAX, xRAX, x3);
+            OR(xRAX, xRAX, x2);
+            break;
         case 0xA3:
             INST_NAME("MOV Od,EAX");
             if(rex.is32bits)
diff --git a/src/dynarec/rv64/dynarec_rv64_dc.c b/src/dynarec/rv64/dynarec_rv64_dc.c
index 006587b3..dbf7b314 100644
--- a/src/dynarec/rv64/dynarec_rv64_dc.c
+++ b/src/dynarec/rv64/dynarec_rv64_dc.c
@@ -39,7 +39,13 @@ uintptr_t dynarec64_DC(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
     switch(nextop) {
         case 0xC0 ... 0xC7:
             INST_NAME("FADD STx, ST0");
-            DEFAULT;
+            v2 = x87_get_st(dyn, ninst, x1, x2, 0, X87_COMBINE(0, nextop & 7));
+            v1 = x87_get_st(dyn, ninst, x1, x2, nextop & 7, X87_COMBINE(0, nextop & 7));
+            if (ST_IS_F(0)) {
+                FADDS(v1, v1, v2);
+            } else {
+                FADDD(v1, v1, v2);
+            }
             break;
         case 0xC8 ... 0xCF:
             INST_NAME("FMUL STx, ST0");
diff --git a/src/dynarec/rv64/dynarec_rv64_helper.h b/src/dynarec/rv64/dynarec_rv64_helper.h
index f6c5ea20..af6cc1a8 100644
--- a/src/dynarec/rv64/dynarec_rv64_helper.h
+++ b/src/dynarec/rv64/dynarec_rv64_helper.h
@@ -546,6 +546,14 @@
     SSE_LOOP_DS_ITEM(GX1, EX1, F, 2) \
     SSE_LOOP_DS_ITEM(GX1, EX1, F, 3)
 
+#define MMX_LOOP_D(GX1, EX1, F)                \
+    for (int i = 0; i < 2; ++i) {              \
+        LWU(GX1, gback, gdoffset + i * 4);     \
+        LWU(EX1, wback, fixedaddress + i * 4); \
+        F;                                     \
+        SW(GX1, gback, gdoffset + i * 4);      \
+    }
+
 #define MMX_LOOP_W(GX1, EX1, F)                \
     for (int i = 0; i < 4; ++i) {              \
         LHU(GX1, gback, gdoffset + i * 2);     \
diff --git a/src/dynarec/rv64/rv64_printer.c b/src/dynarec/rv64/rv64_printer.c
index 9d526bce..54f1ad51 100644
--- a/src/dynarec/rv64/rv64_printer.c
+++ b/src/dynarec/rv64/rv64_printer.c
@@ -445,7 +445,7 @@ static inline insn_t insn_th2type_read(uint32_t data)
 #define PRINT_imm_rel() snprintf(buff, sizeof(buff), "%s\tpc%s0x%x # 0x%"PRIx64, insn.name, insn.imm>=0?"+":"-", insn.imm>=0?insn.imm:-insn.imm, insn.imm+(uint64_t)addr); return buff
 #define PRINT_rd_immx() snprintf(buff, sizeof(buff), "%s\t%s, 0x%x", insn.name, RN(rd), insn.imm); return buff
 #define PRINT_rs1_rs2_imm() snprintf(buff, sizeof(buff), "%s\t%s, %s, %s0x%x", insn.name, RN(rs1), RN(rs2), insn.imm>=0?"":"-", insn.imm>=0?insn.imm:-insn.imm); return buff
-#define PRINT_rs1_rs2_imm_rel() snprintf(buff, sizeof(buff), "%s\t%s, %s, pc%s0x%d # 0x%"PRIx64, insn.name, RN(rs1), RN(rs2), insn.imm>=0?"+":"-", insn.imm>=0?insn.imm:-insn.imm, insn.imm+(uint64_t)addr); return buff
+#define PRINT_rs1_rs2_imm_rel() snprintf(buff, sizeof(buff), "%s\t%s, %s, pc%s0x%x # 0x%"PRIx64, insn.name, RN(rs1), RN(rs2), insn.imm>=0?"+":"-", insn.imm>=0?insn.imm:-insn.imm, insn.imm+(uint64_t)addr); return buff
 #define PRINT_fd_fs1() snprintf(buff, sizeof(buff), "%s\t%s, %s", insn.name, fpnames[insn.rd], fpnames[insn.rs1]); return buff
 #define PRINT_xd_fs1() snprintf(buff, sizeof(buff), "%s\t%s, %s", insn.name, gpnames[insn.rd], fpnames[insn.rs1]); return buff
 #define PRINT_fd_xs1() snprintf(buff, sizeof(buff), "%s\t%s, %s", insn.name, fpnames[insn.rd], gpnames[insn.rs1]); return buff
@@ -1020,9 +1020,11 @@ const char* rv64_print(uint32_t data, uintptr_t addr)
                 case 0x30:
                     insn.name = "roriw";
                     insn.imm &= 0b11111;
+                    break;
                 default:
                     goto unknown;
                 }
+                break;
             }
             default:
                 goto unknown;
@@ -1295,6 +1297,7 @@ const char* rv64_print(uint32_t data, uintptr_t addr)
                     goto unknown;
                 }
             }
+            break;
             case 0x4: {
                 switch (funct3) {
                     case 0x0: