about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/dynarec/arm64/dynarec_arm64_helper.h12
-rw-r--r--src/dynarec/rv64/dynarec_rv64_00_3.c8
-rw-r--r--src/dynarec/rv64/dynarec_rv64_da.c67
-rw-r--r--src/dynarec/rv64/dynarec_rv64_db.c9
-rw-r--r--src/dynarec/rv64/dynarec_rv64_helper.h12
5 files changed, 92 insertions, 16 deletions
diff --git a/src/dynarec/arm64/dynarec_arm64_helper.h b/src/dynarec/arm64/dynarec_arm64_helper.h
index de7a02e3..38b2b4e3 100644
--- a/src/dynarec/arm64/dynarec_arm64_helper.h
+++ b/src/dynarec/arm64/dynarec_arm64_helper.h
@@ -768,22 +768,22 @@
 
 #define X87_PUSH_OR_FAIL(var, dyn, ninst, scratch, t) \
     if (dyn->n.stack == +8) {                         \
-        *ok = 0;                                      \
-        break;                                        \
+        DEFAULT;                                      \
+        return addr;                                  \
     }                                                 \
     var = x87_do_push(dyn, ninst, scratch, t);
 
 #define X87_PUSH_EMPTY_OR_FAIL(dyn, ninst, scratch) \
     if (dyn->n.stack == +8) {                       \
-        *ok = 0;                                    \
-        break;                                      \
+        DEFAULT;                                    \
+        return addr;                                \
     }                                               \
     x87_do_push_empty(dyn, ninst, scratch);
 
 #define X87_POP_OR_FAIL(dyn, ninst, scratch) \
     if (dyn->n.stack == -8) {                \
-        *ok = 0;                             \
-        break;                               \
+        DEFAULT;                             \
+        return addr;                         \
     }                                        \
     x87_do_pop(dyn, ninst, scratch);
 
diff --git a/src/dynarec/rv64/dynarec_rv64_00_3.c b/src/dynarec/rv64/dynarec_rv64_00_3.c
index 6d1296bd..1a468389 100644
--- a/src/dynarec/rv64/dynarec_rv64_00_3.c
+++ b/src/dynarec/rv64/dynarec_rv64_00_3.c
@@ -707,6 +707,14 @@ uintptr_t dynarec64_00_3(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
             }
             break;
 
+        case 0xD7:
+            INST_NAME("XLAT");
+            ANDI(x1, xRAX, 0xff);
+            ADD(x1, xRBX, x1);
+            LBU(x1, x1, 0);
+            ANDI(xRAX, xRAX, ~0xff);
+            OR(xRAX, xRAX, x1);
+            break;
         case 0xD8:
             addr = dynarec64_D8(dyn, addr, ip, ninst, rex, rep, ok, need_epilog);
             break;
diff --git a/src/dynarec/rv64/dynarec_rv64_da.c b/src/dynarec/rv64/dynarec_rv64_da.c
index 61584090..648a5f91 100644
--- a/src/dynarec/rv64/dynarec_rv64_da.c
+++ b/src/dynarec/rv64/dynarec_rv64_da.c
@@ -146,17 +146,78 @@ uintptr_t dynarec64_DA(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
 
         default:
             switch ((nextop >> 3) & 7) {
+                case 0:
+                    INST_NAME("FIADD ST0, Ed");
+                    v1 = x87_get_st(dyn, ninst, x1, x2, 0, EXT_CACHE_ST_D);
+                    v2 = fpu_get_scratch(dyn);
+                    addr = geted(dyn, addr, ninst, nextop, &ed, x2, x1, &fixedaddress, rex, NULL, 1, 0);
+                    LW(x1, ed, fixedaddress);
+                    FCVTDW(v2, x1, RD_RNE); // i32 -> double
+                    FADDD(v1, v1, v2);
+                    break;
+                case 1:
+                    INST_NAME("FIMUL ST0, Ed");
+                    v1 = x87_get_st(dyn, ninst, x1, x2, 0, EXT_CACHE_ST_D);
+                    v2 = fpu_get_scratch(dyn);
+                    addr = geted(dyn, addr, ninst, nextop, &ed, x2, x1, &fixedaddress, rex, NULL, 1, 0);
+                    LW(x1, ed, fixedaddress);
+                    FCVTDW(v2, x1, RD_RNE); // i32 -> double
+                    FMULD(v1, v1, v2);
+                    break;
+                case 2:
+                    INST_NAME("FICOM ST0, Ed");
+                    v1 = x87_get_st(dyn, ninst, x1, x2, 0, EXT_CACHE_ST_D);
+                    v2 = fpu_get_scratch(dyn);
+                    addr = geted(dyn, addr, ninst, nextop, &ed, x2, x1, &fixedaddress, rex, NULL, 1, 0);
+                    LW(x1, ed, fixedaddress);
+                    FCVTDW(v2, x1, RD_RNE); // i32 -> double
+                    FCOMD(v1, v2, x1, x2, x3, x4, x5);
+                    break;
+                case 3:
+                    INST_NAME("FICOMP ST0, Ed");
+                    v1 = x87_get_st(dyn, ninst, x1, x2, 0, EXT_CACHE_ST_D);
+                    v2 = fpu_get_scratch(dyn);
+                    addr = geted(dyn, addr, ninst, nextop, &ed, x2, x1, &fixedaddress, rex, NULL, 1, 0);
+                    LW(x1, ed, fixedaddress);
+                    FCVTDW(v2, x1, RD_RNE); // i32 -> double
+                    FCOMD(v1, v2, x1, x2, x3, x4, x5);
+                    X87_POP_OR_FAIL(dyn, ninst, x3);
+                    break;
+                case 4:
+                    INST_NAME("FISUB ST0, Ed");
+                    v1 = x87_get_st(dyn, ninst, x1, x2, 0, EXT_CACHE_ST_D);
+                    v2 = fpu_get_scratch(dyn);
+                    addr = geted(dyn, addr, ninst, nextop, &ed, x2, x1, &fixedaddress, rex, NULL, 1, 0);
+                    LW(x1, ed, fixedaddress);
+                    FCVTDW(v2, x1, RD_RNE); // i32 -> double
+                    FSUBD(v1, v1, v2);
+                    break;
+                case 5:
+                    INST_NAME("FISUBR ST0, Ed");
+                    v1 = x87_get_st(dyn, ninst, x1, x2, 0, EXT_CACHE_ST_D);
+                    v2 = fpu_get_scratch(dyn);
+                    addr = geted(dyn, addr, ninst, nextop, &ed, x2, x1, &fixedaddress, rex, NULL, 1, 0);
+                    LW(x1, ed, fixedaddress);
+                    FCVTDW(v2, x1, RD_RNE); // i32 -> double
+                    FSUBD(v1, v2, v1);
+                    break;
                 case 6:
                     INST_NAME("FIDIV ST0, Ed");
                     v1 = x87_get_st(dyn, ninst, x1, x2, 0, EXT_CACHE_ST_D);
                     v2 = fpu_get_scratch(dyn);
                     addr = geted(dyn, addr, ninst, nextop, &ed, x2, x1, &fixedaddress, rex, NULL, 1, 0);
                     LW(x1, ed, fixedaddress);
-                    FCVTDW(v2, x1, RD_RNE);
+                    FCVTDW(v2, x1, RD_RNE); // i32 -> double
                     FDIVD(v1, v1, v2);
                     break;
-                default:
-                    DEFAULT;
+                case 7:
+                    INST_NAME("FIDIVR ST0, Ed");
+                    v1 = x87_get_st(dyn, ninst, x1, x2, 0, EXT_CACHE_ST_D);
+                    v2 = fpu_get_scratch(dyn);
+                    addr = geted(dyn, addr, ninst, nextop, &ed, x2, x1, &fixedaddress, rex, NULL, 1, 0);
+                    LW(x1, ed, fixedaddress);
+                    FCVTDW(v2, x1, RD_RNE); // i32 -> double
+                    FDIVD(v1, v2, v1);
                     break;
             }
     }
diff --git a/src/dynarec/rv64/dynarec_rv64_db.c b/src/dynarec/rv64/dynarec_rv64_db.c
index d60fcfbd..71d77451 100644
--- a/src/dynarec/rv64/dynarec_rv64_db.c
+++ b/src/dynarec/rv64/dynarec_rv64_db.c
@@ -198,7 +198,14 @@ uintptr_t dynarec64_DB(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
         case 0xF6:
         case 0xF7:
             INST_NAME("FCOMI ST0, STx");
-            DEFAULT;
+            SETFLAGS(X_ALL, SF_SET);
+            v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_COMBINE(0, nextop & 7));
+            v2 = x87_get_st(dyn, ninst, x1, x2, nextop & 7, X87_COMBINE(0, nextop & 7));
+            if (ST_IS_F(0)) {
+                FCOMS(v1, v2, x1, x2, x3, x4, x5);
+            } else {
+                FCOMS(v1, v2, x1, x2, x3, x4, x5);
+            }
             break;
 
         case 0xE0:
diff --git a/src/dynarec/rv64/dynarec_rv64_helper.h b/src/dynarec/rv64/dynarec_rv64_helper.h
index e521e135..1e0bed93 100644
--- a/src/dynarec/rv64/dynarec_rv64_helper.h
+++ b/src/dynarec/rv64/dynarec_rv64_helper.h
@@ -884,22 +884,22 @@
 
 #define X87_PUSH_OR_FAIL(var, dyn, ninst, scratch, t) \
     if (dyn->e.stack == +8) {                         \
-        *ok = 0;                                      \
-        break;                                        \
+        DEFAULT;                                      \
+        return addr;                                  \
     }                                                 \
     var = x87_do_push(dyn, ninst, scratch, t);
 
 #define X87_PUSH_EMPTY_OR_FAIL(dyn, ninst, scratch) \
     if (dyn->e.stack == +8) {                       \
-        *ok = 0;                                    \
-        break;                                      \
+        DEFAULT;                                    \
+        return addr;                                \
     }                                               \
     x87_do_push_empty(dyn, ninst, scratch);
 
 #define X87_POP_OR_FAIL(dyn, ninst, scratch) \
     if (dyn->e.stack == -8) {                \
-        *ok = 0;                             \
-        break;                               \
+        DEFAULT;                             \
+        return addr;                         \
     }                                        \
     x87_do_pop(dyn, ninst, scratch);