about summary refs log tree commit diff stats
path: root/src/emu
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2022-09-29 11:24:42 +0200
committerptitSeb <sebastien.chev@gmail.com>2022-09-29 11:24:42 +0200
commit32c229215aa438bf5a087c2e9a97462fd26208ad (patch)
treea775056684e36404726f7253b860eae0d4600762 /src/emu
parent9c5cc38c9a11c87ae2ef845879cb479f52b9de00 (diff)
downloadbox64-32c229215aa438bf5a087c2e9a97462fd26208ad.tar.gz
box64-32c229215aa438bf5a087c2e9a97462fd26208ad.zip
Improved signal handling and x87 flags (with tests backported from box86)
Diffstat (limited to 'src/emu')
-rwxr-xr-xsrc/emu/x64emu.c3
-rwxr-xr-xsrc/emu/x64emu_private.h3
-rw-r--r--src/emu/x64rund9.c5
-rwxr-xr-xsrc/emu/x87emu_private.c14
-rwxr-xr-xsrc/emu/x87emu_private.h2
5 files changed, 12 insertions, 15 deletions
diff --git a/src/emu/x64emu.c b/src/emu/x64emu.c
index a91fe04b..9e4fc7e0 100755
--- a/src/emu/x64emu.c
+++ b/src/emu/x64emu.c
@@ -224,10 +224,9 @@ void CloneEmu(x64emu_t *newemu, const x64emu_t* emu)
     memcpy(newemu->fpu_ll, emu->fpu_ll, sizeof(emu->fpu_ll));
 	memcpy(newemu->p_regs, emu->p_regs, sizeof(emu->p_regs));
 	newemu->cw = emu->cw;
-	memcpy(&newemu->sw, &emu->sw, sizeof(emu->sw));
+	newemu->sw = emu->sw;
 	newemu->top = emu->top;
     newemu->fpu_stack = emu->fpu_stack;
-	memcpy(&newemu->round, &emu->round, sizeof(emu->round));
     memcpy(newemu->xmm, emu->xmm, sizeof(emu->xmm));
     newemu->mxcsr = emu->mxcsr;
     newemu->quit = emu->quit;
diff --git a/src/emu/x64emu_private.h b/src/emu/x64emu_private.h
index 1ffdd1fa..093706bf 100755
--- a/src/emu/x64emu_private.h
+++ b/src/emu/x64emu_private.h
@@ -35,12 +35,11 @@ typedef struct x64emu_s {
     // fpu / mmx
 	mmx87_regs_t x87[8];
 	mmx87_regs_t mmx[8];
-	uint16_t    cw;
+	x87control_t cw;
 	x87flags_t  sw;
 	uint32_t    top;        // top is part of sw, but it's faster to have it separatly
     int         fpu_stack;
     uint32_t    mxcsr;
-	fpu_round_t round;
     fpu_ld_t    fpu_ld[8]; // for long double emulation / 80bits fld fst
     fpu_ll_t    fpu_ll[8]; // for 64bits fild / fist sequence
 	fpu_p_reg_t p_regs[8];
diff --git a/src/emu/x64rund9.c b/src/emu/x64rund9.c
index 34e29879..301f2852 100644
--- a/src/emu/x64rund9.c
+++ b/src/emu/x64rund9.c
@@ -265,9 +265,8 @@ uintptr_t RunD9(x64emu_t *emu, rex_t rex, uintptr_t addr)
                 break;

             case 5:     /* FLDCW Ew */

                 GETEW(0);

-                emu->cw = EW->word[0];

+                emu->cw.x16 = EW->word[0];

                 // do something with cw?

-                emu->round = (fpu_round_t)((emu->cw >> 10) & 3);

                 break;

             case 6:     /* FNSTENV m */

                 // warning, incomplete

@@ -279,7 +278,7 @@ uintptr_t RunD9(x64emu_t *emu, rex_t rex, uintptr_t addr)
                 break;

             case 7: /* FNSTCW Ew */

                 GETEW(0);

-                EW->word[0] = emu->cw;

+                EW->word[0] = emu->cw.x16;

                 break;

             default:

                 return 0;

diff --git a/src/emu/x87emu_private.c b/src/emu/x87emu_private.c
index f151ee45..846016c8 100755
--- a/src/emu/x87emu_private.c
+++ b/src/emu/x87emu_private.c
@@ -23,7 +23,7 @@ void reset_fpu(x64emu_t* emu)
 {
     memset(emu->x87, 0, sizeof(emu->x87));
     memset(emu->fpu_ld, 0, sizeof(emu->fpu_ld));
-    emu->cw = 0x37F;
+    emu->cw.x16 = 0x37F;
     emu->sw.x16 = 0x0000;
     emu->top = 0;
     emu->fpu_stack = 0;
@@ -223,7 +223,7 @@ long double LD2localLD(void* ld)
 
 void fpu_loadenv(x64emu_t* emu, char* p, int b16)
 {
-    emu->cw = *(uint16_t*)p;
+    emu->cw.x16 = *(uint16_t*)p;
     p+=(b16)?2:4;
     emu->sw.x16 = *(uint16_t*)p;
     emu->top = emu->sw.f.F87_TOP;
@@ -241,7 +241,7 @@ void fpu_loadenv(x64emu_t* emu, char* p, int b16)
 void fpu_savenv(x64emu_t* emu, char* p, int b16)
 {
     emu->sw.f.F87_TOP = emu->top&7;
-    *(uint16_t*)p = emu->cw;
+    *(uint16_t*)p = emu->cw.x16;
     p+=2;
     if(!b16) {*(uint16_t*)p = 0; p+=2;}
     *(uint16_t*)p = emu->sw.x16;
@@ -299,7 +299,7 @@ void fpu_fxsave32(x64emu_t* emu, void* ed)
     if(top==0)  // check if stack is full or empty, based on tag[0]
         stack = (emu->p_regs[0].tag)?8:0;
     emu->sw.f.F87_TOP = top;
-    p->ControlWord = emu->cw;
+    p->ControlWord = emu->cw.x16;
     p->StatusWord = emu->sw.x16;
     uint8_t tags = 0;
     for (int i=0; i<8; ++i)
@@ -328,7 +328,7 @@ void fpu_fxsave64(x64emu_t* emu, void* ed)
     if(top==0)  // check if stack is full or empty, based on tag[0]
         stack = (emu->p_regs[0].tag)?8:0;
     emu->sw.f.F87_TOP = top;
-    p->ControlWord = emu->cw;
+    p->ControlWord = emu->cw.x16;
     p->StatusWord = emu->sw.x16;
     uint8_t tags = 0;
     for (int i=0; i<8; ++i)
@@ -349,7 +349,7 @@ void fpu_fxsave64(x64emu_t* emu, void* ed)
 void fpu_fxrstor32(x64emu_t* emu, void* ed)
 {
     xsave32_t *p = (xsave32_t*)ed;
-    emu->cw = p->ControlWord;
+    emu->cw.x16 = p->ControlWord;
     emu->sw.x16 = p->StatusWord;
     emu->top = emu->sw.f.F87_TOP;
     uint8_t tags = p->TagWord;
@@ -369,7 +369,7 @@ void fpu_fxrstor32(x64emu_t* emu, void* ed)
 void fpu_fxrstor64(x64emu_t* emu, void* ed)
 {
     xsave64_t *p = (xsave64_t*)ed;
-    emu->cw = p->ControlWord;
+    emu->cw.x16 = p->ControlWord;
     emu->sw.x16 = p->StatusWord;
     emu->top = emu->sw.f.F87_TOP;
     uint8_t tags = p->TagWord;
diff --git a/src/emu/x87emu_private.h b/src/emu/x87emu_private.h
index 7d64bf27..a2287059 100755
--- a/src/emu/x87emu_private.h
+++ b/src/emu/x87emu_private.h
@@ -107,7 +107,7 @@ static inline void fpu_fcomi(x64emu_t* emu, double b)
 static inline double fpu_round(x64emu_t* emu, double d) {
     if (!isfinite(d))
         return d;
-    switch(emu->round) {
+    switch(emu->cw.f.C87_RD) {
         case ROUND_Nearest:
             return nearbyint(d);
         case ROUND_Down: