about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2021-03-11 20:21:11 +0100
committerptitSeb <sebastien.chev@gmail.com>2021-03-11 20:21:11 +0100
commit9479d7ae07349cabe2165dd477fd210aea4665e0 (patch)
treea5c7fa52135660f8ce3f95d936d2ff45ae0a48b0 /src
parent4827427ac026eb4a47e25f868728d4455e968e91 (diff)
downloadbox64-9479d7ae07349cabe2165dd477fd210aea4665e0.tar.gz
box64-9479d7ae07349cabe2165dd477fd210aea4665e0.zip
Added more x87 opcodes
Diffstat (limited to 'src')
-rwxr-xr-xsrc/emu/x64run.c9
-rw-r--r--src/emu/x64run66.c6
-rw-r--r--src/emu/x64run66d9.c99
-rw-r--r--src/emu/x64run66dd.c117
-rwxr-xr-xsrc/emu/x64run_private.h3
-rw-r--r--src/emu/x64runda.c139
-rw-r--r--src/emu/x64rundd.c2
-rw-r--r--src/emu/x64rundf.c35
8 files changed, 382 insertions, 28 deletions
diff --git a/src/emu/x64run.c b/src/emu/x64run.c
index ccf03289..3baa0fb2 100755
--- a/src/emu/x64run.c
+++ b/src/emu/x64run.c
@@ -808,7 +808,14 @@ x64emurun:
             if(emu->quit)
                 goto fini;
             break;
-
+        case 0xDA:                      /* x87 opcodes */
+            if(RunDA(emu, rex)) {
+                unimp = 1;
+                goto fini;
+            }
+            if(emu->quit)
+                goto fini;
+            break;
         case 0xDB:                      /* x87 opcodes */
             if(RunDB(emu, rex)) {
                 unimp = 1;
diff --git a/src/emu/x64run66.c b/src/emu/x64run66.c
index c2e8a5a0..1cbe7eda 100644
--- a/src/emu/x64run66.c
+++ b/src/emu/x64run66.c
@@ -262,6 +262,12 @@ int Run66(x64emu_t *emu, rex_t rex)
         }

         break;

 

+    case 0xD9:                              /* x87 opcdes */

+        return Run66D9(emu, rex);

+

+    case 0xDD:                              /* x87 opcdes */

+        return Run66DD(emu, rex);

+

     case 0xF7:                      /* GRP3 Ew(,Iw) */

         nextop = F8;

         tmp8u = (nextop>>3)&7;

diff --git a/src/emu/x64run66d9.c b/src/emu/x64run66d9.c
new file mode 100644
index 00000000..fae424ba
--- /dev/null
+++ b/src/emu/x64run66d9.c
@@ -0,0 +1,99 @@
+#define _GNU_SOURCE

+#include <stdint.h>

+#include <stdio.h>

+#include <stdlib.h>

+#include <math.h>

+#include <string.h>

+#include <signal.h>

+#include <sys/types.h>

+#include <unistd.h>

+

+#include "debug.h"

+#include "box64stack.h"

+#include "x64emu.h"

+#include "x64run.h"

+#include "x64emu_private.h"

+#include "x64run_private.h"

+#include "x64primop.h"

+#include "x64trace.h"

+#include "x87emu_private.h"

+#include "box64context.h"

+//#include "my_cpuid.h"

+#include "bridge.h"

+//#include "signals.h"

+#ifdef DYNAREC

+#include "../dynarec/arm_lock_helper.h"

+#endif

+

+#include "modrm.h"

+

+int Run66D9(x64emu_t *emu, rex_t rex)

+{

+    uint8_t nextop;

+    reg64_t *oped;

+

+    nextop = F8;

+    switch (nextop) {

+        case 0xC0:

+        case 0xC1:

+        case 0xC2:

+        case 0xC3:

+        case 0xC4:

+        case 0xC5:

+        case 0xC6:

+        case 0xC7:

+        case 0xC8:

+        case 0xC9:

+        case 0xCA:

+        case 0xCB:

+        case 0xCC:

+        case 0xCD:

+        case 0xCE:

+        case 0xCF:

+        case 0xD0:

+        case 0xE0:

+        case 0xE5:

+        case 0xE8:

+        case 0xE9:

+        case 0xEA:

+        case 0xEB:

+        case 0xEC:

+        case 0xED:

+        case 0xEE:

+        case 0xFC:

+        case 0xE1:

+        case 0xE4:

+        case 0xF0:

+        case 0xF1:

+        case 0xF2:

+        case 0xF3:

+        case 0xF4:

+        case 0xF5:

+        case 0xF6:

+        case 0xF7:

+        case 0xF8:

+        case 0xF9:

+        case 0xFA:

+        case 0xFB:

+        case 0xFD:

+        case 0xFE:

+        case 0xFF:

+            return 1;

+        default:

+        switch((nextop>>3)&7) {

+            case 4:     /* FLDENV m */

+                // warning, incomplete

+                GETEW(0);

+                fpu_loadenv(emu, (char*)ED, 1);

+                break;

+            case 6:     /* FNSTENV m */

+                // warning, incomplete

+                GETEW(0);

+                fpu_savenv(emu, (char*)ED, 1);

+                break;

+            default:

+                return 1;

+        }

+    }

+    return 0;

+}

diff --git a/src/emu/x64run66dd.c b/src/emu/x64run66dd.c
new file mode 100644
index 00000000..1ef8e93c
--- /dev/null
+++ b/src/emu/x64run66dd.c
@@ -0,0 +1,117 @@
+#define _GNU_SOURCE

+#include <stdint.h>

+#include <stdio.h>

+#include <stdlib.h>

+#include <math.h>

+#include <string.h>

+#include <signal.h>

+#include <sys/types.h>

+#include <unistd.h>

+

+#include "debug.h"

+#include "box64stack.h"

+#include "x64emu.h"

+#include "x64run.h"

+#include "x64emu_private.h"

+#include "x64run_private.h"

+#include "x64primop.h"

+#include "x64trace.h"

+#include "x87emu_private.h"

+#include "box64context.h"

+//#include "my_cpuid.h"

+#include "bridge.h"

+//#include "signals.h"

+#ifdef DYNAREC

+#include "../dynarec/arm_lock_helper.h"

+#endif

+

+#include "modrm.h"

+

+int Run66DD(x64emu_t *emu, rex_t rex)

+{

+    uint8_t nextop;

+    reg64_t *oped;

+

+    nextop = F8;

+    switch (nextop) {

+        case 0xC0:

+        case 0xC1:

+        case 0xC2:

+        case 0xC3:

+        case 0xC4:

+        case 0xC5:

+        case 0xC6:

+        case 0xC7:

+        case 0xC8:

+        case 0xC9:

+        case 0xCA:

+        case 0xCB:

+        case 0xCC:

+        case 0xCD:

+        case 0xCE:

+        case 0xCF:

+        case 0xD0:

+        case 0xE0:

+        case 0xE5:

+        case 0xE8:

+        case 0xE9:

+        case 0xEA:

+        case 0xEB:

+        case 0xEC:

+        case 0xED:

+        case 0xEE:

+        case 0xFC:

+        case 0xE1:

+        case 0xE4:

+        case 0xF0:

+        case 0xF1:

+        case 0xF2:

+        case 0xF3:

+        case 0xF4:

+        case 0xF5:

+        case 0xF6:

+        case 0xF7:

+        case 0xF8:

+        case 0xF9:

+        case 0xFA:

+        case 0xFB:

+        case 0xFD:

+        case 0xFE:

+        case 0xFF:

+            return 1;

+        default:

+        switch((nextop>>3)&7) {

+            case 4: /* FRSTOR m94byte */

+                GETEW(0);

+                fpu_loadenv(emu, (char*)ED, 1);

+                // get the STx

+                {

+                    char* p =(char*)ED;

+                    p += 14;

+                    for (int i=0; i<8; ++i) {

+                        LD2D(p, &ST(i).d);

+                        p+=10;

+                    }

+                }

+                break;

+            case 6: /* FNSAVE m94byte */

+                GETEW(0);

+                // ENV first...

+                fpu_savenv(emu, (char*)ED, 1);

+                // save the STx

+                {

+                    char* p =(char*)ED;

+                    p += 14;

+                    for (int i=0; i<8; ++i) {

+                        D2LD(&ST(i).d, p);

+                        p+=10;

+                    }

+                }

+                reset_fpu(emu);

+                break;

+            default:

+                return 1;

+        }

+    }

+    return 0;

+}

diff --git a/src/emu/x64run_private.h b/src/emu/x64run_private.h
index 7eb9a194..b1d798f0 100755
--- a/src/emu/x64run_private.h
+++ b/src/emu/x64run_private.h
@@ -100,9 +100,12 @@ int Run64(x64emu_t *emu, rex_t rex);
 int Run66(x64emu_t *emu, rex_t rex);
 int Run660F(x64emu_t *emu, rex_t rex);
 int Run6664(x64emu_t *emu, rex_t rex);
+int Run66D9(x64emu_t *emu, rex_t rex);
+int Run66DD(x64emu_t *emu, rex_t rex);
 int Run67(x64emu_t *emu, rex_t rex);
 int RunD8(x64emu_t *emu, rex_t rex);
 int RunD9(x64emu_t *emu, rex_t rex);
+int RunDA(x64emu_t *emu, rex_t rex);
 int RunDB(x64emu_t *emu, rex_t rex);
 int RunDD(x64emu_t *emu, rex_t rex);
 int RunDF(x64emu_t *emu, rex_t rex);
diff --git a/src/emu/x64runda.c b/src/emu/x64runda.c
new file mode 100644
index 00000000..65115b0c
--- /dev/null
+++ b/src/emu/x64runda.c
@@ -0,0 +1,139 @@
+#define _GNU_SOURCE

+#include <stdint.h>

+#include <stdio.h>

+#include <stdlib.h>

+#include <math.h>

+#include <string.h>

+#include <signal.h>

+#include <sys/types.h>

+#include <unistd.h>

+

+#include "debug.h"

+#include "box64stack.h"

+#include "x64emu.h"

+#include "x64run.h"

+#include "x64emu_private.h"

+#include "x64run_private.h"

+#include "x64primop.h"

+#include "x64trace.h"

+#include "x87emu_private.h"

+#include "box64context.h"

+#include "bridge.h"

+#ifdef DYNAREC

+#include "../dynarec/arm_lock_helper.h"

+#endif

+

+#include "modrm.h"

+

+int RunDA(x64emu_t *emu, rex_t rex)

+{

+    uint8_t nextop;

+    reg64_t *oped;

+

+    nextop = F8;

+    switch (nextop) {

+    case 0xC0:      /* FCMOVB ST(0), ST(i) */

+    case 0xC1:

+    case 0xC2:

+    case 0xC3:

+    case 0xC4:

+    case 0xC5:

+    case 0xC6:

+    case 0xC7:

+        CHECK_FLAGS(emu);

+        if(ACCESS_FLAG(F_CF))

+            ST0.q = ST(nextop&7).q;

+        break;

+    case 0xC8:      /* FCMOVE ST(0), ST(i) */

+    case 0xC9:

+    case 0xCA:

+    case 0xCB:

+    case 0xCC:

+    case 0xCD:

+    case 0xCE:

+    case 0xCF:

+        CHECK_FLAGS(emu);

+        if(ACCESS_FLAG(F_ZF))

+            ST0.q = ST(nextop&7).q;

+        break;

+    case 0xD0:      /* FCMOVBE ST(0), ST(i) */

+    case 0xD1:

+    case 0xD2:

+    case 0xD3:

+    case 0xD4:

+    case 0xD5:

+    case 0xD6:

+    case 0xD7:

+        CHECK_FLAGS(emu);

+        if(ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF))

+            ST0.q = ST(nextop&7).q;

+        break;

+    case 0xD8:      /* FCMOVU ST(0), ST(i) */

+    case 0xD9:

+    case 0xDA:

+    case 0xDB:

+    case 0xDC:

+    case 0xDD:

+    case 0xDE:

+    case 0xDF:

+        CHECK_FLAGS(emu);

+        if(ACCESS_FLAG(F_PF))

+            ST0.q = ST(nextop&7).q;

+        break;

+    

+    case 0xE9:      /* FUCOMPP */

+        fpu_fcom(emu, ST1.d);   // bad, should handle QNaN and IA interrupt

+        fpu_do_pop(emu);

+        fpu_do_pop(emu);

+        break;

+

+    case 0xE4:

+    case 0xF0:

+    case 0xF1:

+    case 0xF4:

+    case 0xF5:

+    case 0xF6:

+    case 0xF7:

+    case 0xF8:

+    case 0xF9:

+    case 0xFD:

+        return 1;

+    default:

+        switch((nextop>>3)&7) {

+            case 0:     /* FIADD ST0, Ed int */

+                GETED(0);

+                ST0.d += ED->sdword[0];

+                break;

+            case 1:     /* FIMUL ST0, Ed int */

+                GETED(0);

+                ST0.d *= ED->sdword[0];

+                break;

+            case 2:     /* FICOM ST0, Ed int */

+                GETED(0);

+                fpu_fcom(emu, ED->sdword[0]);

+                break;

+            case 3:     /* FICOMP ST0, Ed int */

+                GETED(0);

+                fpu_fcom(emu, ED->sdword[0]);

+                fpu_do_pop(emu);

+                break;

+            case 4:     /* FISUB ST0, Ed int */

+                GETED(0);

+                ST0.d -= ED->sdword[0];

+                break;

+            case 5:     /* FISUBR ST0, Ed int */

+                GETED(0);

+                ST0.d = (double)ED->sdword[0] - ST0.d;

+                break;

+            case 6:     /* FIDIV ST0, Ed int */

+                GETED(0);

+                ST0.d /= ED->sdword[0];

+                break;

+            case 7:     /* FIDIVR ST0, Ed int */

+                GETED(0);

+                ST0.d = (double)ED->sdword[0] / ST0.d;

+                break;

+        }

+   }

+   return 0;

+}
\ No newline at end of file
diff --git a/src/emu/x64rundd.c b/src/emu/x64rundd.c
index 8c5228c9..73678e2b 100644
--- a/src/emu/x64rundd.c
+++ b/src/emu/x64rundd.c
@@ -150,7 +150,6 @@ int RunDD(x64emu_t *emu, rex_t rex)
                 }

                 fpu_do_pop(emu);

                 break;

-            #if 0

             case 4: /* FRSTOR m108byte */

                 GETED(0);

                 fpu_loadenv(emu, (char*)ED, 0);

@@ -180,7 +179,6 @@ int RunDD(x64emu_t *emu, rex_t rex)
                 }

                 reset_fpu(emu);

                 break;

-            #endif

             case 7: /* FNSTSW m2byte */

                 GETED(0);

                 emu->sw.f.F87_TOP = emu->top&7;

diff --git a/src/emu/x64rundf.c b/src/emu/x64rundf.c
index a382169c..40186287 100644
--- a/src/emu/x64rundf.c
+++ b/src/emu/x64rundf.c
@@ -31,6 +31,7 @@ int RunDF(x64emu_t *emu, rex_t rex)
 {

     uint8_t nextop;

     int16_t tmp16s;

+    int64_t tmp64s;

     reg64_t *oped;

 

     nextop = F8;

@@ -146,7 +147,6 @@ int RunDF(x64emu_t *emu, rex_t rex)
                 EW->sword[0] = fpu_round(emu, ST0.d);

             fpu_do_pop(emu);

             break;

-        #if 0

         case 4: /* FBLD ST0, tbytes */

             GETED(0);

             fpu_do_push(emu);

@@ -154,11 +154,11 @@ int RunDF(x64emu_t *emu, rex_t rex)
             break;

         case 5: /* FILD ST0, Gq */

             GETED(0);

-            tmp64s = *(int64_t*)ED;

+            tmp64s = ED->sq[0];

             fpu_do_push(emu);

             ST0.d = tmp64s;

             STll(0).ll = tmp64s;

-            STll(0).ref = ST0.ll;

+            STll(0).ref = ST0.q;

             break;

         case 6: /* FBSTP tbytes, ST0 */

             GETED(0);

@@ -167,31 +167,16 @@ int RunDF(x64emu_t *emu, rex_t rex)
             break;

         case 7: /* FISTP i64 */

             GETED(0);

-            if((uintptr_t)ED & 0x7) {

-                // un-aligned!

-                if(STll(0).ref==ST(0).ll)

-                    memcpy(ED, &STll(0).ll, sizeof(int64_t));

-                else {

-                    int64_t i64;

-                    if(isgreater(ST0.d, (double)(int64_t)0x7fffffffffffffffLL) || isless(ST0.d, -(double)(int64_t)0x7fffffffffffffffLL) || !isfinite(ST0.d))

-                        i64 = 0x8000000000000000LL;

-                    else

-                        i64 = fpu_round(emu, ST0.d);

-                    memcpy(ED, &i64, sizeof(int64_t));

-                }

-            } else {

-                if(STll(0).ref==ST(0).ll)

-                    *(int64_t*)ED = STll(0).ll;

-                else {

-                    if(isgreater(ST0.d, (double)(int64_t)0x7fffffffffffffffLL) || isless(ST0.d, -(double)(int64_t)0x7fffffffffffffffLL) || !isfinite(ST0.d))

-                        *(int64_t*)ED = 0x8000000000000000LL;

-                    else

-                        *(int64_t*)ED = fpu_round(emu, ST0.d);

-                }

+            if(STll(0).ref==ST(0).q)

+                ED->sq[0] = STll(0).ll;

+            else {

+                if(isgreater(ST0.d, (double)(int64_t)0x7fffffffffffffffLL) || isless(ST0.d, -(double)(int64_t)0x7fffffffffffffffLL) || !isfinite(ST0.d))

+                    ED->sq[0] = 0x8000000000000000LL;

+                else

+                    ED->sq[0] = fpu_round(emu, ST0.d);

             }

             fpu_do_pop(emu);

             break;

-        #endif

         default:

             return 1;

         }