about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2025-04-27 15:51:17 +0200
committerptitSeb <sebastien.chev@gmail.com>2025-04-27 15:51:17 +0200
commitb7ae6ebc27ee7a2511400740e800ef1c67816c03 (patch)
treeefdf342d5f6227722904365266f1f42b7503f661 /src
parent9b904c622a321397fa0a4aed2c975c005d39ae46 (diff)
downloadbox64-b7ae6ebc27ee7a2511400740e800ef1c67816c03.tar.gz
box64-b7ae6ebc27ee7a2511400740e800ef1c67816c03.zip
[INTERP] More work on UD flags
Diffstat (limited to 'src')
-rw-r--r--src/emu/modrm.h2
-rw-r--r--src/emu/x64run0f.c25
-rw-r--r--src/emu/x64run660f.c26
-rw-r--r--src/emu/x64run66f30f.c13
-rw-r--r--src/emu/x64runf30f.c12
5 files changed, 65 insertions, 13 deletions
diff --git a/src/emu/modrm.h b/src/emu/modrm.h
index cd2c3636..bbad2e81 100644
--- a/src/emu/modrm.h
+++ b/src/emu/modrm.h
@@ -10,6 +10,8 @@
 #define F64     *(uint64_t*)(addr+=8, addr-8)

 #define F64S    *(int64_t*)(addr+=8, addr-8)

 #define PK(a)   *(uint8_t*)(addr+a)

+#define PARITY(x)   (((emu->x64emu_parity_tab[(x) / 32] >> ((x) % 32)) & 1) == 0)

+

 #ifdef DYNAREC

 #define STEP  CheckExec(emu, addr); if(step && !ACCESS_FLAG(F_TF)) return 0;

 #define STEP2 CheckExec(emu, addr); if(step && !ACCESS_FLAG(F_TF)) {R_RIP = addr; return 0;}

diff --git a/src/emu/x64run0f.c b/src/emu/x64run0f.c
index 61fa11f4..bc182097 100644
--- a/src/emu/x64run0f.c
+++ b/src/emu/x64run0f.c
@@ -1590,26 +1590,32 @@ uintptr_t Run0F(x64emu_t *emu, rex_t rex, uintptr_t addr, int *step)
             nextop = F8;

             GETED(0);

             GETGD;

+            tmp8u = 0;

             if(rex.w) {

                 tmp64u = ED->q[0];

                 if(tmp64u) {

                     CLEAR_FLAG(F_ZF);

-                    tmp8u = 0;

                     while(!(tmp64u&(1LL<<tmp8u))) ++tmp8u;

-                    GD->q[0] = tmp8u;

                 } else {

                     SET_FLAG(F_ZF);

                 }

+                GD->q[0] = tmp8u;

             } else {

                 tmp32u = ED->dword[0];

                 if(tmp32u) {

                     CLEAR_FLAG(F_ZF);

-                    tmp8u = 0;

                     while(!(tmp32u&(1<<tmp8u))) ++tmp8u;

-                    GD->q[0] = tmp8u;

                 } else {

                     SET_FLAG(F_ZF);

                 }

+                GD->q[0] = tmp8u;

+            }

+            if(!BOX64ENV(cputype)) {

+                CONDITIONAL_SET_FLAG(PARITY(tmp8u), F_PF);

+                CLEAR_FLAG(F_CF);

+                CLEAR_FLAG(F_AF);

+                CLEAR_FLAG(F_SF);

+                CLEAR_FLAG(F_OF);

             }

             break;

         case 0xBD:                      /* BSR Ed,Gd */

@@ -1617,16 +1623,17 @@ uintptr_t Run0F(x64emu_t *emu, rex_t rex, uintptr_t addr, int *step)
             nextop = F8;

             GETED(0);

             GETGD;

+            tmp8u = 0;

             if(rex.w) {

                 tmp64u = ED->q[0];

                 if(tmp64u) {

                     CLEAR_FLAG(F_ZF);

                     tmp8u = 63;

                     while(!(tmp64u&(1LL<<tmp8u))) --tmp8u;

-                    GD->q[0] = tmp8u;

                 } else {

                     SET_FLAG(F_ZF);

                 }

+                GD->q[0] = tmp8u;

             } else {

                 tmp32u = ED->dword[0];

                 if(tmp32u) {

@@ -1636,8 +1643,16 @@ uintptr_t Run0F(x64emu_t *emu, rex_t rex, uintptr_t addr, int *step)
                     GD->q[0] = tmp8u;

                 } else {

                     SET_FLAG(F_ZF);

+                    GD->q[0] = tmp8u;

                 }

             }

+            if(!BOX64ENV(cputype)) {

+                CONDITIONAL_SET_FLAG(PARITY(tmp8u), F_PF);

+                CLEAR_FLAG(F_CF);

+                CLEAR_FLAG(F_AF);

+                CLEAR_FLAG(F_SF);

+                CLEAR_FLAG(F_OF);

+            }

             break;

         case 0xBE:                      /* MOVSX Gd,Eb */

             nextop = F8;

diff --git a/src/emu/x64run660f.c b/src/emu/x64run660f.c
index 001a9aa4..8bb00f52 100644
--- a/src/emu/x64run660f.c
+++ b/src/emu/x64run660f.c
@@ -2115,26 +2115,32 @@ uintptr_t Run660F(x64emu_t *emu, rex_t rex, uintptr_t addr)
         nextop = F8;

         GETEW(0);

         GETGW;

+        tmp8u = 0;

         if(rex.w) {

             tmp64u = EW->q[0];

             if(tmp64u) {

                 CLEAR_FLAG(F_ZF);

-                tmp8u = 0;

                 while(!(tmp64u&(1LL<<tmp8u))) ++tmp8u;

-                GW->q[0] = tmp8u;

             } else {

                 SET_FLAG(F_ZF);

             }

+            GW->q[0] = tmp8u;

         } else {

             tmp16u = EW->word[0];

             if(tmp16u) {

                 CLEAR_FLAG(F_ZF);

-                tmp8u = 0;

                 while(!(tmp16u&(1<<tmp8u))) ++tmp8u;

-                GW->word[0] = tmp8u;

             } else {

                 SET_FLAG(F_ZF);

             }

+            GW->word[0] = tmp8u;

+        }

+        if(!BOX64ENV(cputype)) {

+            CONDITIONAL_SET_FLAG(PARITY(tmp8u), F_PF);

+            CLEAR_FLAG(F_CF);

+            CLEAR_FLAG(F_AF);

+            CLEAR_FLAG(F_SF);

+            CLEAR_FLAG(F_OF);

         }

         break;

     case 0xBD:                      /* BSR Ew,Gw */

@@ -2142,26 +2148,34 @@ uintptr_t Run660F(x64emu_t *emu, rex_t rex, uintptr_t addr)
         nextop = F8;

         GETEW(0);

         GETGW;

+        tmp8u = 0;

         if(rex.w) {

             tmp64u = EW->q[0];

             if(tmp64u) {

                 CLEAR_FLAG(F_ZF);

                 tmp8u = 63;

                 while(!(tmp64u&(1LL<<tmp8u))) --tmp8u;

-                GW->q[0] = tmp8u;

             } else {

                 SET_FLAG(F_ZF);

             }

+            GW->q[0] = tmp8u;

         } else {

             tmp16u = EW->word[0];

             if(tmp16u) {

                 CLEAR_FLAG(F_ZF);

                 tmp8u = 15;

                 while(!(tmp16u&(1<<tmp8u))) --tmp8u;

-                GW->word[0] = tmp8u;

             } else {

                 SET_FLAG(F_ZF);

             }

+            GW->word[0] = tmp8u;

+        }

+        if(!BOX64ENV(cputype)) {

+            CONDITIONAL_SET_FLAG(PARITY(tmp8u), F_PF);

+            CLEAR_FLAG(F_CF);

+            CLEAR_FLAG(F_AF);

+            CLEAR_FLAG(F_SF);

+            CLEAR_FLAG(F_OF);

         }

         break;

     case 0xBE:                      /* MOVSX Gw,Eb */

diff --git a/src/emu/x64run66f30f.c b/src/emu/x64run66f30f.c
index 9e56e94d..00cd6cca 100644
--- a/src/emu/x64run66f30f.c
+++ b/src/emu/x64run66f30f.c
@@ -87,6 +87,11 @@ uintptr_t Run66F30F(x64emu_t *emu, rex_t rex, uintptr_t addr)
                 GD->word[0] = 16;
             }
         }
+        CLEAR_FLAG(F_AF);
+        CLEAR_FLAG(F_SF);
+        CLEAR_FLAG(F_PF);
+        if(!BOX64ENV(cputype))
+            CLEAR_FLAG(F_OF);
         break;
     case 0xBD:  /* LZCNT Ed,Gd */
         CHECK_FLAGS(emu);
@@ -98,13 +103,19 @@ uintptr_t Run66F30F(x64emu_t *emu, rex_t rex, uintptr_t addr)
             tmp8u = (tmp64u)?__builtin_clzl(tmp64u):64;
             CONDITIONAL_SET_FLAG(tmp8u==0, F_ZF);
             CONDITIONAL_SET_FLAG(tmp8u==64, F_CF);
+            GD->q[0] = tmp8u;
         } else {
             tmp32u = EW->word[0];
             tmp8u = (tmp32u)?__builtin_clz(tmp32u<<16):16;
             CONDITIONAL_SET_FLAG(tmp8u==0, F_ZF);
             CONDITIONAL_SET_FLAG(tmp8u==16, F_CF);
+            GD->word[0] = tmp8u;
         }
-        GD->q[0] = tmp8u;
+        CLEAR_FLAG(F_AF);
+        CLEAR_FLAG(F_SF);
+        CLEAR_FLAG(F_PF);
+        if(!BOX64ENV(cputype))
+            CLEAR_FLAG(F_OF);
         break;
 
     case 0xB8:  /* POPCNT Gd,Ed */
diff --git a/src/emu/x64runf30f.c b/src/emu/x64runf30f.c
index 38ef2ad4..ea31cf01 100644
--- a/src/emu/x64runf30f.c
+++ b/src/emu/x64runf30f.c
@@ -388,7 +388,12 @@ uintptr_t RunF30F(x64emu_t *emu, rex_t rex, uintptr_t addr)
                 GD->q[0] = 32;

             }

         }

-        break;

+        CLEAR_FLAG(F_AF);

+        CLEAR_FLAG(F_SF);

+        CLEAR_FLAG(F_PF);

+        if(!BOX64ENV(cputype))

+            CLEAR_FLAG(F_OF);

+    break;

     case 0xBD:  /* LZCNT Ed,Gd */

         CHECK_FLAGS(emu);

         nextop = F8;

@@ -406,6 +411,11 @@ uintptr_t RunF30F(x64emu_t *emu, rex_t rex, uintptr_t addr)
             CONDITIONAL_SET_FLAG(tmp8u==32, F_CF);

         }

         GD->q[0] = tmp8u;

+        CLEAR_FLAG(F_PF);

+        CLEAR_FLAG(F_AF);

+        CLEAR_FLAG(F_SF);

+        if(!BOX64ENV(cputype))

+            CLEAR_FLAG(F_OF);

         break;

 

     case 0xC2:  /* CMPSS Gx, Ex, Ib */