about summary refs log tree commit diff stats
path: root/src/dynarec/rv64/dynarec_rv64_d8.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/dynarec/rv64/dynarec_rv64_d8.c')
-rw-r--r--src/dynarec/rv64/dynarec_rv64_d8.c67
1 files changed, 63 insertions, 4 deletions
diff --git a/src/dynarec/rv64/dynarec_rv64_d8.c b/src/dynarec/rv64/dynarec_rv64_d8.c
index beadb202..7f14468b 100644
--- a/src/dynarec/rv64/dynarec_rv64_d8.c
+++ b/src/dynarec/rv64/dynarec_rv64_d8.c
@@ -1,7 +1,6 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <stddef.h>
-#include <pthread.h>
 #include <errno.h>
 
 #include "debug.h"
@@ -50,13 +49,73 @@ uintptr_t dynarec64_D8(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
         case 0xD0 ... 0xD7:
 
         case 0xD8 ... 0xDF:
-
+            INST_NAME("FCOMP ST0, STx");
+            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));
+            LHU(x3, xEmu, offsetof(x64emu_t, sw));
+            MOV32w(x1, 0b1110100011111111); // mask off c0,c1,c2,c3
+            AND(x3, x3, x1);
+            if(ST_IS_F(0)) {
+                FEQS(x5, v1, v1);
+                FEQS(x4, v2, v2);
+                AND(x5, x5, x4);
+                BEQZ(x5, 24); // undefined/NaN
+                FEQS(x5, v1, v2);
+                BNEZ(x5, 28); // equal
+                FLTS(x3, v1, v2); // x3 = (v1<v2)?1:0
+                SLLI(x1, x3, 8);
+                J(20); // end
+                // undefined/NaN
+                LUI(x1, 1);
+                ADDI(x1, x1, 0b010100000000);
+                J(8); // end
+                // equal
+                LUI(x1, 1);
+                // end
+            } else {
+                FEQD(x5, v1, v1);
+                FEQD(x4, v2, v2);
+                AND(x5, x5, x4);
+                BEQZ(x5, 24); // undefined/NaN
+                FEQD(x5, v1, v2);
+                BNEZ(x5, 28); // equal
+                FLTD(x3, v1, v2); // x3 = (v1<v2)?1:0
+                SLLI(x1, x3, 8);
+                J(20); // end
+                // undefined/NaN
+                LUI(x1, 1);
+                ADDI(x1, x1, 0b010100000000);
+                J(8); // end
+                // equal
+                LUI(x1, 1);
+                // end
+            }
+            OR(x3, x3, x1);
+            SH(x3, xEmu, offsetof(x64emu_t, sw));
+            x87_do_pop(dyn, ninst, x3);
+            break;
         case 0xE0 ... 0xE7:
-
+            INST_NAME("FSUB ST0, STx");
+            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)) {
+                FSUBS(v1, v1, v2);
+            } else {
+                FSUBD(v1, v1, v2);
+            }
+            break;
         case 0xE8 ... 0xEF:
 
         case 0xF0 ... 0xF7:
-
+            INST_NAME("FDIV ST0, STx");
+            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)) {
+                FDIVS(v1, v1, v2);
+            } else {
+                FDIVD(v1, v1, v2);
+            }
+            break;
         case 0xF8 ... 0xFF:
             DEFAULT;
             break;