about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorYang Liu <liuyang22@iscas.ac.cn>2023-12-22 23:51:33 +0800
committerGitHub <noreply@github.com>2023-12-22 16:51:33 +0100
commit9c7320422458f746326c8123b92173eacc53dae8 (patch)
tree79cb6be3ad5ed89ebe23cee0217e8f7594da5d70 /src
parent7da59d5a3919383cca0b68a3a9d6e74d23d1f19e (diff)
downloadbox64-9c7320422458f746326c8123b92173eacc53dae8.tar.gz
box64-9c7320422458f746326c8123b92173eacc53dae8.zip
[DYNAREC_RV64] Added more opcodes and fixes (#1154)
* [DYNAREC_RV64] Added 66 0F 38 28 PMULDQ opcode

* [DYNAREC_RV64] Added DD /6 FSAVE opcode

* [DYNAREC_RV64] Added 66 8C MOV opcode

* [DYNAREC_RV64] Fixed DF /1 /2 opcodes

* [DYNAREC_RV64] Added DB /1 FISTTP opcode
Diffstat (limited to 'src')
-rw-r--r--src/dynarec/rv64/dynarec_rv64_66.c12
-rw-r--r--src/dynarec/rv64/dynarec_rv64_660f.c13
-rw-r--r--src/dynarec/rv64/dynarec_rv64_db.c19
-rw-r--r--src/dynarec/rv64/dynarec_rv64_dd.c8
-rw-r--r--src/dynarec/rv64/dynarec_rv64_df.c12
5 files changed, 60 insertions, 4 deletions
diff --git a/src/dynarec/rv64/dynarec_rv64_66.c b/src/dynarec/rv64/dynarec_rv64_66.c
index fdc2d7e4..d4e196c6 100644
--- a/src/dynarec/rv64/dynarec_rv64_66.c
+++ b/src/dynarec/rv64/dynarec_rv64_66.c
@@ -570,6 +570,18 @@ uintptr_t dynarec64_66(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                 OR(gd, gd, x1);
             }
             break;
+        case 0x8C:
+            INST_NAME("MOV Ed, Seg");
+            nextop = F8;
+            if ((nextop & 0xC0) == 0xC0) { // reg <= seg
+                LHU(xRAX + (nextop & 7) + (rex.b << 3), xEmu, offsetof(x64emu_t, segs[(nextop & 0x38) >> 3]));
+            } else { // mem <= seg
+                addr = geted(dyn, addr, ninst, nextop, &ed, x2, x1, &fixedaddress, rex, NULL, 1, 0);
+                LHU(x3, xEmu, offsetof(x64emu_t, segs[(nextop & 0x38) >> 3]));
+                SH(x3, ed, fixedaddress);
+                SMWRITE2();
+            }
+            break;
         case 0x90:
         case 0x91:
         case 0x92:
diff --git a/src/dynarec/rv64/dynarec_rv64_660f.c b/src/dynarec/rv64/dynarec_rv64_660f.c
index f7953c56..b3b92a49 100644
--- a/src/dynarec/rv64/dynarec_rv64_660f.c
+++ b/src/dynarec/rv64/dynarec_rv64_660f.c
@@ -522,7 +522,18 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
                         SW(x4, gback, gdoffset + i * 4);
                     }
                     break;
-
+                case 0x28:
+                    INST_NAME("PMULDQ Gx, Ex");
+                    nextop = F8;
+                    GETEX(x2, 0);
+                    GETGX();
+                    for (int i = 1; i >= 0; --i) {
+                        LW(x3, wback, fixedaddress + i * 8);
+                        LW(x4, gback, gdoffset + i * 8);
+                        MUL(x3, x3, x4);
+                        SD(x3, gback, gdoffset + i * 8);
+                    }
+                    break;
                 case 0x2B:
                     INST_NAME("PACKUSDW Gx, Ex");
                     nextop = F8;
diff --git a/src/dynarec/rv64/dynarec_rv64_db.c b/src/dynarec/rv64/dynarec_rv64_db.c
index f6c1f704..d60fcfbd 100644
--- a/src/dynarec/rv64/dynarec_rv64_db.c
+++ b/src/dynarec/rv64/dynarec_rv64_db.c
@@ -220,7 +220,24 @@ uintptr_t dynarec64_DB(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                     break;
                 case 1:
                     INST_NAME("FISTTP Ed, ST0");
-                    DEFAULT;
+                    v1 = x87_get_st(dyn, ninst, x1, x2, 0, EXT_CACHE_ST_D);
+                    addr = geted(dyn, addr, ninst, nextop, &wback, x3, x4, &fixedaddress, rex, NULL, 1, 0);
+                    if (!box64_dynarec_fastround) {
+                        FSFLAGSI(0); // reset all bits
+                    }
+                    FCVTWD(x4, v1, RD_RTZ);
+                    if (!box64_dynarec_fastround) {
+                        FRFLAGS(x5); // get back FPSR to check the IOC bit
+                        ANDI(x5, x5, 1 << FR_NV);
+                        BNEZ_MARK(x5);
+                        SEXT_W(x5, x4);
+                        BEQ_MARK2(x5, x4);
+                        MARK;
+                        MOV32w(x4, 0x80000000);
+                    }
+                    MARK2;
+                    SW(x4, wback, fixedaddress);
+                    X87_POP_OR_FAIL(dyn, ninst, x3);
                     break;
                 case 2:
                     INST_NAME("FIST Ed, ST0");
diff --git a/src/dynarec/rv64/dynarec_rv64_dd.c b/src/dynarec/rv64/dynarec_rv64_dd.c
index 47718d64..35273745 100644
--- a/src/dynarec/rv64/dynarec_rv64_dd.c
+++ b/src/dynarec/rv64/dynarec_rv64_dd.c
@@ -173,6 +173,14 @@ uintptr_t dynarec64_DD(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                     FSD(v1, wback, fixedaddress);
                     X87_POP_OR_FAIL(dyn, ninst, x3);
                     break;
+                case 6:
+                    INST_NAME("FSAVE m108byte");
+                    MESSAGE(LOG_DUMP, "Need Optimization\n");
+                    fpu_purgecache(dyn, ninst, 0, x1, x2, x3);
+                    addr = geted(dyn, addr, ninst, nextop, &ed, x4, x6, &fixedaddress, rex, NULL, 0, 0);
+                    if (ed != x1) { MV(x1, ed); }
+                    CALL(native_fsave, -1);
+                    break;
                 case 7:
                     INST_NAME("FNSTSW m2byte");
                     fpu_purgecache(dyn, ninst, 0, x1, x2, x3);
diff --git a/src/dynarec/rv64/dynarec_rv64_df.c b/src/dynarec/rv64/dynarec_rv64_df.c
index 704e1302..08e603e5 100644
--- a/src/dynarec/rv64/dynarec_rv64_df.c
+++ b/src/dynarec/rv64/dynarec_rv64_df.c
@@ -131,7 +131,11 @@ uintptr_t dynarec64_DF(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                     if(!box64_dynarec_fastround) {
                         FSFLAGSI(0); // reset all bits
                     }
-                    FCVTWD(x4, v1, RD_RTZ);
+                    if (ST_IS_F(0)) {
+                        FCVTWS(x4, v1, RD_RTZ);
+                    } else {
+                        FCVTWD(x4, v1, RD_RTZ);
+                    }
                     if(!box64_dynarec_fastround) {
                         FRFLAGS(x5);   // get back FPSR to check the IOC bit
                         ANDI(x5, x5, 1<<FR_NV);
@@ -154,7 +158,11 @@ uintptr_t dynarec64_DF(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                     if(!box64_dynarec_fastround) {
                         FSFLAGSI(0); // reset all bits
                     }
-                    FCVTWD(x4, v1, RD_DYN);
+                    if (ST_IS_F(0)) {
+                        FCVTWS(x4, v1, RD_DYN);
+                    } else {
+                        FCVTWD(x4, v1, RD_DYN);
+                    }
                     x87_restoreround(dyn, ninst, u8);
                     if(!box64_dynarec_fastround) {
                         FRFLAGS(x5);   // get back FPSR to check the IOC bit