about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorYang Liu <liuyang22@iscas.ac.cn>2025-03-27 17:21:34 +0800
committerGitHub <noreply@github.com>2025-03-27 10:21:34 +0100
commitec385c8e75ba47fc42345cf796cef5ce274571cc (patch)
tree8dcf7a0449a5500229537a63b2342ee7297d0008 /src
parent3aed03273865a3301a1d01ed8a04f951e1d0d715 (diff)
downloadbox64-ec385c8e75ba47fc42345cf796cef5ce274571cc.tar.gz
box64-ec385c8e75ba47fc42345cf796cef5ce274571cc.zip
[INTERP] Fixed Interpreter to have new test30 running on RISC-V (#2470)
Diffstat (limited to 'src')
-rw-r--r--src/emu/x64runavx0f.c112
-rw-r--r--src/emu/x64runavxf20f.c101
2 files changed, 123 insertions, 90 deletions
diff --git a/src/emu/x64runavx0f.c b/src/emu/x64runavx0f.c
index 6d5de569..49786f8b 100644
--- a/src/emu/x64runavx0f.c
+++ b/src/emu/x64runavx0f.c
@@ -246,12 +246,18 @@ uintptr_t RunAVX_0F(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step)
             nextop = F8;
             GETEX(0);
             GETGX; GETGY;
-            for(int i=0; i<4; ++i)
-                GX->f[i] = (EX->f[i]<0)?(-NAN):sqrtf(EX->f[i]);
+            for (int i = 0; i < 4; ++i)
+                if (isnan(EX->f[i]))
+                    GX->f[i] = EX->f[i];
+                else
+                    GX->f[i] = (EX->f[i] < 0) ? (-NAN) : sqrtf(EX->f[i]);
             if(vex.l) {
                 GETEY;
-                for(int i=0; i<4; ++i)
-                    GY->f[i] = (EY->f[i]<0)?(-NAN):sqrtf(EY->f[i]);
+                for (int i = 0; i < 4; ++i)
+                    if (isnan(EY->f[i]))
+                        GY->f[i] = EY->f[i];
+                    else
+                        GY->f[i] = (EY->f[i] < 0) ? (-NAN) : sqrtf(EY->f[i]);
             } else
                 GY->u128 = 0;
             break;
@@ -261,7 +267,9 @@ uintptr_t RunAVX_0F(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step)
             GETGX;
             GETGY;
             for(int i=0; i<4; ++i) {
-                if(EX->f[i]==0)
+                if (isnan(EX->f[i]))
+                    GX->f[i] = EX->f[i];
+                else if (EX->f[i] == 0)
                     GX->f[i] = 1.0f/EX->f[i];
                 else if (EX->f[i]<0)
                     GX->f[i] = -NAN;
@@ -275,7 +283,9 @@ uintptr_t RunAVX_0F(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step)
             if(vex.l) {
                 GETEY;
                 for(int i=0; i<4; ++i) {
-                    if(EY->f[i]==0)
+                    if (isnan(EY->f[i]))
+                        GY->f[i] = EY->f[i];
+                    else if (EY->f[i] == 0)
                         GY->f[i] = 1.0f/EY->f[i];
                     else if (EY->f[i]<0)
                         GY->f[i] = -NAN;
@@ -294,11 +304,17 @@ uintptr_t RunAVX_0F(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step)
             GETEX(0);
             GETGX; GETGY;
             for(int i=0; i<4; ++i)
-                GX->f[i] = 1.0f/EX->f[i];
+                if (isnan(EX->f[i]))
+                    GX->f[i] = EX->f[i];
+                else
+                    GX->f[i] = 1.0f / EX->f[i];
             if(vex.l) {
                 GETEY;
                 for(int i=0; i<4; ++i)
-                    GY->f[i] = 1.0f/EY->f[i];
+                    if (isnan(EY->f[i]))
+                        GY->f[i] = EY->f[i];
+                    else
+                        GY->f[i] = 1.0f / EY->f[i];
             } else
                 GY->u128 = 0;
             break;
@@ -368,17 +384,29 @@ uintptr_t RunAVX_0F(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step)
             GETVX;
             GETGY;
             for(int i=0; i<4; ++i) {
-                maskps[i] = isnanf(VX->f[i]) || isnanf(EX->f[i]);
+                if (isnan(VX->f[i]) || isnan(EX->f[i])) {
+                    if (isnan(VX->f[i]))
+                        GX->f[i] = VX->f[i];
+                    else
+                        GX->f[i] = EX->f[i];
+                    continue;
+                }
                 GX->f[i] = VX->f[i] + EX->f[i];
-                if(isnanf(GX->f[i]) && !maskps[i]) GX->ud[i] |= 0x80000000;
+                if (isnan(GX->f[i])) GX->ud[i] |= 0x80000000;
             }
             if(vex.l) {
                 GETEY;
                 GETVY;
                 for(int i=0; i<4; ++i) {
-                    maskps[i] = isnanf(VY->f[i]) || isnanf(EY->f[i]);
+                    if (isnan(VY->f[i]) || isnan(EY->f[i])) {
+                        if (isnan(VY->f[i]))
+                            GY->f[i] = VY->f[i];
+                        else
+                            GY->f[i] = EY->f[i];
+                        continue;
+                    }
                     GY->f[i] = VY->f[i] + EY->f[i];
-                    if(isnanf(GY->f[i]) && !maskps[i]) GY->ud[i] |= 0x80000000;
+                    if (isnan(GY->f[i])) GY->ud[i] |= 0x80000000;
                 }
             } else
                 GY->u128 = 0;
@@ -390,17 +418,29 @@ uintptr_t RunAVX_0F(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step)
             GETVX;
             GETGY;
             for(int i=0; i<4; ++i) {
-                maskps[i] = isnanf(VX->f[i]) || isnanf(EX->f[i]);
+                if (isnan(VX->f[i]) || isnan(EX->f[i])) {
+                    if (isnan(VX->f[i]))
+                        GX->f[i] = VX->f[i];
+                    else
+                        GX->f[i] = EX->f[i];
+                    continue;
+                }
                 GX->f[i] = VX->f[i] * EX->f[i];
-                if(isnanf(GX->f[i]) && !maskps[i]) GX->ud[i] |= 0x80000000;
+                if (isnan(GX->f[i])) GX->ud[i] |= 0x80000000;
             }
             if(vex.l) {
                 GETEY;
                 GETVY;
                 for(int i=0; i<4; ++i) {
-                    maskps[i] = isnanf(VY->f[i]) || isnanf(EY->f[i]);
+                    if (isnan(VY->f[i]) || isnan(EY->f[i])) {
+                        if (isnan(VY->f[i]))
+                            GY->f[i] = VY->f[i];
+                        else
+                            GY->f[i] = EY->f[i];
+                        continue;
+                    }
                     GY->f[i] = VY->f[i] * EY->f[i];
-                    if(isnanf(GY->f[i]) && !maskps[i]) GY->ud[i] |= 0x80000000;
+                    if (isnan(GY->f[i])) GY->ud[i] |= 0x80000000;
                 }
             } else
                 GY->u128 = 0;
@@ -444,17 +484,29 @@ uintptr_t RunAVX_0F(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step)
             GETVX;
             GETGY;
             for(int i=0; i<4; ++i) {
-                maskps[i] = isnanf(VX->f[i]) || isnanf(EX->f[i]);
+                if (isnan(VX->f[i]) || isnan(EX->f[i])) {
+                    if (isnan(VX->f[i]))
+                        GX->f[i] = VX->f[i];
+                    else
+                        GX->f[i] = EX->f[i];
+                    continue;
+                }
                 GX->f[i] = VX->f[i] - EX->f[i];
-                if(isnanf(GX->f[i]) && !maskps[i]) GX->ud[i] |= 0x80000000;
+                if (isnan(GX->f[i])) GX->ud[i] |= 0x80000000;
             }
             if(vex.l) {
                 GETEY;
                 GETVY;
                 for(int i=0; i<4; ++i) {
-                    maskps[i] = isnanf(VY->f[i]) || isnanf(EY->f[i]);
+                    if (isnan(VY->f[i]) || isnan(EY->f[i])) {
+                        if (isnan(VY->f[i]))
+                            GY->f[i] = VY->f[i];
+                        else
+                            GY->f[i] = EY->f[i];
+                        continue;
+                    }
                     GY->f[i] = VY->f[i] - EY->f[i];
-                    if(isnanf(GY->f[i]) && !maskps[i]) GY->ud[i] |= 0x80000000;
+                    if (isnan(GY->f[i])) GY->ud[i] |= 0x80000000;
                 }
             } else
                 GY->u128 = 0;
@@ -488,17 +540,29 @@ uintptr_t RunAVX_0F(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step)
             GETVX;
             GETGY;
             for(int i=0; i<4; ++i) {
-                maskps[i] = isnanf(VX->f[i]) || isnanf(EX->f[i]);
+                if (isnan(VX->f[i]) || isnan(EX->f[i])) {
+                    if (isnan(VX->f[i]))
+                        GX->f[i] = VX->f[i];
+                    else
+                        GX->f[i] = EX->f[i];
+                    continue;
+                }
                 GX->f[i] = VX->f[i] / EX->f[i];
-                if(isnanf(GX->f[i]) && !maskps[i]) GX->ud[i] |= 0x80000000;
+                if (isnan(GX->f[i])) GX->ud[i] |= 0x80000000;
             }
             if(vex.l) {
                 GETEY;
                 GETVY;
                 for(int i=0; i<4; ++i) {
-                    maskps[i] = isnanf(VY->f[i]) || isnanf(EY->f[i]);
+                    if (isnan(VY->f[i]) || isnan(EY->f[i])) {
+                        if (isnan(VY->f[i]))
+                            GY->f[i] = VY->f[i];
+                        else
+                            GY->f[i] = EY->f[i];
+                        continue;
+                    }
                     GY->f[i] = VY->f[i] / EY->f[i];
-                    if(isnanf(GY->f[i]) && !maskps[i]) GY->ud[i] |= 0x80000000;
+                    if (isnan(GY->f[i])) GY->ud[i] |= 0x80000000;
                 }
             } else
                 GY->u128 = 0;
diff --git a/src/emu/x64runavxf20f.c b/src/emu/x64runavxf20f.c
index 34280a00..9dc26b01 100644
--- a/src/emu/x64runavxf20f.c
+++ b/src/emu/x64runavxf20f.c
@@ -49,9 +49,7 @@ uintptr_t RunAVX_F20F(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step)
     sse_regs_t *opex, *opgx, *opvx, eax1;
     sse_regs_t *opey, *opgy, *opvy, eay1;
     int is_nan;
-    #ifndef NOALIGN
     int nan_mask[4];
-    #endif
 
 
 #ifdef TEST_INTERPRETER
@@ -336,62 +334,46 @@ uintptr_t RunAVX_F20F(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step)
                 eax1 = *EX;
                 EX = &eax1;
             }
-            #ifndef NOALIGN
             nan_mask[0] = isnanf(VX->f[0]) || isnanf(VX->f[1]);
             nan_mask[1] = isnanf(VX->f[2]) || isnanf(VX->f[3]);
-            #endif
-            GX->f[0] = VX->f[0] + VX->f[1];
-            GX->f[1] = VX->f[2] + VX->f[3];
+            GX->f[0] = isnan(VX->f[0]) ? VX->f[0] : (isnan(VX->f[1]) ? VX->f[1] : (VX->f[0] + VX->f[1]));
+            GX->f[1] = isnan(VX->f[2]) ? VX->f[2] : (isnan(VX->f[3]) ? VX->f[3] : (VX->f[2] + VX->f[3]));
             if(EX==VX) {
                 GX->f[2] = GX->f[0];
                 GX->f[3] = GX->f[1];
-                #ifndef NOALIGN
                 nan_mask[2] = nan_mask[0];
                 nan_mask[3] = nan_mask[1];
-                #endif
             } else {
-                #ifndef NOALIGN
                 nan_mask[2] = isnanf(EX->f[0]) || isnanf(EX->f[1]);
                 nan_mask[3] = isnanf(EX->f[2]) || isnanf(EX->f[3]);
-                #endif
-                GX->f[2] = EX->f[0] + EX->f[1];
-                GX->f[3] = EX->f[2] + EX->f[3];
+                GX->f[2] = isnan(EX->f[0]) ? EX->f[0] : (isnan(EX->f[1]) ? EX->f[1] : (EX->f[0] + EX->f[1]));
+                GX->f[3] = isnan(EX->f[2]) ? EX->f[2] : (isnan(EX->f[3]) ? EX->f[3] : (EX->f[2] + EX->f[3]));
             }
-            #ifndef NOALIGN
             for(int i=0; i<4; ++i)
-                if(!nan_mask[i] && isnanf(GX->f[i])) GX->ud[i] |= 0x80000000;
-            #endif
+                if (!nan_mask[i] && isnanf(GX->f[i])) GX->ud[i] |= 0x80000000;
             if(vex.l) {
                 if(GY==EY) {
                     eay1 = *EY;
                     EY = &eay1;
                 }
                 GETVY;
-                #ifndef NOALIGN
                 nan_mask[0] = isnanf(VY->f[0]) || isnanf(VY->f[1]);
                 nan_mask[1] = isnanf(VY->f[2]) || isnanf(VY->f[3]);
-                #endif
-                GY->f[0] = VY->f[0] + VY->f[1];
-                GY->f[1] = VY->f[2] + VY->f[3];
+                GY->f[0] = isnan(VY->f[0]) ? VY->f[0] : (isnan(VY->f[1]) ? VY->f[1] : (VY->f[0] + VY->f[1]));
+                GY->f[1] = isnan(VY->f[2]) ? VY->f[2] : (isnan(VY->f[3]) ? VY->f[3] : (VY->f[2] + VY->f[3]));
                 if(EY==VY) {
                     GY->f[2] = GY->f[0];
                     GY->f[3] = GY->f[1];
-                    #ifndef NOALIGN
                     nan_mask[2] = nan_mask[0];
                     nan_mask[3] = nan_mask[1];
-                    #endif
                 } else {
-                    #ifndef NOALIGN
                     nan_mask[2] = isnanf(EY->f[0]) || isnanf(EY->f[1]);
                     nan_mask[3] = isnanf(EY->f[2]) || isnanf(EY->f[3]);
-                    #endif
-                    GY->f[2] = EY->f[0] + EY->f[1];
-                    GY->f[3] = EY->f[2] + EY->f[3];
+                    GY->f[2] = isnan(EY->f[0]) ? EY->f[0] : (isnan(EY->f[1]) ? EY->f[1] : (EY->f[0] + EY->f[1]));
+                    GY->f[3] = isnan(EY->f[2]) ? EY->f[2] : (isnan(EY->f[3]) ? EY->f[3] : (EY->f[2] + EY->f[3]));
                 }
-                #ifndef NOALIGN
                 for(int i=0; i<4; ++i)
-                    if(!nan_mask[i] && isnanf(GY->f[i])) GY->ud[i] |= 0x80000000;
-                #endif
+                    if (!nan_mask[i] && isnanf(GY->f[i])) GY->ud[i] |= 0x80000000;
             } else
                 GY->u128 = 0;
             break;
@@ -402,66 +384,53 @@ uintptr_t RunAVX_F20F(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step)
             GETVX;
             GETGY;
             GETEY;
-            if(GX==EX) {
+            if (GX == EX) {
                 eax1 = *EX;
                 EX = &eax1;
             }
-            #ifndef NOALIGN
             nan_mask[0] = isnanf(VX->f[0]) || isnanf(VX->f[1]);
             nan_mask[1] = isnanf(VX->f[2]) || isnanf(VX->f[3]);
-            #endif
-            GX->f[0] = VX->f[0] - VX->f[1];
-            GX->f[1] = VX->f[2] - VX->f[3];
-            if(EX==VX) {
+            GX->f[0] = isnan(VX->f[0]) ? VX->f[0] : (isnan(VX->f[1]) ? VX->f[1] : (VX->f[0] - VX->f[1]));
+            GX->f[1] = isnan(VX->f[2]) ? VX->f[2] : (isnan(VX->f[3]) ? VX->f[3] : (VX->f[2] - VX->f[3]));
+            if (EX == VX) {
                 GX->f[2] = GX->f[0];
                 GX->f[3] = GX->f[1];
-                #ifndef NOALIGN
                 nan_mask[2] = nan_mask[0];
                 nan_mask[3] = nan_mask[1];
-                #endif
             } else {
-                #ifndef NOALIGN
                 nan_mask[2] = isnanf(EX->f[0]) || isnanf(EX->f[1]);
                 nan_mask[3] = isnanf(EX->f[2]) || isnanf(EX->f[3]);
-                #endif
-                GX->f[2] = EX->f[0] - EX->f[1];
-                GX->f[3] = EX->f[2] - EX->f[3];
+                GX->f[2] = isnan(EX->f[0]) ? EX->f[0] : (isnan(EX->f[1]) ? EX->f[1] : (EX->f[0] - EX->f[1]));
+                GX->f[3] = isnan(EX->f[2]) ? EX->f[2] : (isnan(EX->f[3]) ? EX->f[3] : (EX->f[2] - EX->f[3]));
             }
-            if(vex.l) {
-                if(GY==EY) {
+            for (int i = 0; i < 4; ++i)
+                if (!nan_mask[i] && isnanf(GX->f[i])) GX->ud[i] |= 0x80000000;
+            if (vex.l) {
+                if (GY == EY) {
                     eay1 = *EY;
                     EY = &eay1;
                 }
                 GETVY;
-                #ifndef NOALIGN
                 nan_mask[0] = isnanf(VY->f[0]) || isnanf(VY->f[1]);
                 nan_mask[1] = isnanf(VY->f[2]) || isnanf(VY->f[3]);
-                #endif
-                GY->f[0] = VY->f[0] - VY->f[1];
-                GY->f[1] = VY->f[2] - VY->f[3];
-                if(EY==VY) {
+                GY->f[0] = isnan(VY->f[0]) ? VY->f[0] : (isnan(VY->f[1]) ? VY->f[1] : (VY->f[0] - VY->f[1]));
+                GY->f[1] = isnan(VY->f[2]) ? VY->f[2] : (isnan(VY->f[3]) ? VY->f[3] : (VY->f[2] - VY->f[3]));
+                if (EY == VY) {
                     GY->f[2] = GY->f[0];
                     GY->f[3] = GY->f[1];
-                    #ifndef NOALIGN
                     nan_mask[2] = nan_mask[0];
                     nan_mask[3] = nan_mask[1];
-                    #endif
                 } else {
-                    #ifndef NOALIGN
                     nan_mask[2] = isnanf(EY->f[0]) || isnanf(EY->f[1]);
                     nan_mask[3] = isnanf(EY->f[2]) || isnanf(EY->f[3]);
-                    #endif
-                    GY->f[2] = EY->f[0] - EY->f[1];
-                    GY->f[3] = EY->f[2] - EY->f[3];
+                    GY->f[2] = isnan(EY->f[0]) ? EY->f[0] : (isnan(EY->f[1]) ? EY->f[1] : (EY->f[0] - EY->f[1]));
+                    GY->f[3] = isnan(EY->f[2]) ? EY->f[2] : (isnan(EY->f[3]) ? EY->f[3] : (EY->f[2] - EY->f[3]));
                 }
-                #ifndef NOALIGN
-                for(int i=0; i<4; ++i)
-                    if(!nan_mask[i] && isnanf(GY->f[i])) GY->ud[i] |= 0x80000000;
-                #endif
+                for (int i = 0; i < 4; ++i)
+                    if (!nan_mask[i] && isnanf(GY->f[i])) GY->ud[i] |= 0x80000000;
             } else
                 GY->u128 = 0;
             break;
-
         case 0xC2:  /* VCMPSD Gx, Vx, Ex, Ib */
             nextop = F8;
             GETEX(1);
@@ -501,17 +470,17 @@ uintptr_t RunAVX_F20F(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step)
             GETGX;
             GETVX;
             GETGY;
-            GX->f[0] = VX->f[0] - EX->f[0];
-            GX->f[1] = VX->f[1] + EX->f[1];
-            GX->f[2] = VX->f[2] - EX->f[2];
-            GX->f[3] = VX->f[3] + EX->f[3];
+            GX->f[0] = isnan(VX->f[0]) ? VX->f[0] : (isnan(EX->f[0]) ? EX->f[0] : (VX->f[0] - EX->f[0]));
+            GX->f[1] = isnan(VX->f[1]) ? VX->f[1] : (isnan(EX->f[1]) ? EX->f[1] : (VX->f[1] + EX->f[1]));
+            GX->f[2] = isnan(VX->f[2]) ? VX->f[2] : (isnan(EX->f[2]) ? EX->f[2] : (VX->f[2] - EX->f[2]));
+            GX->f[3] = isnan(VX->f[3]) ? VX->f[3] : (isnan(EX->f[3]) ? EX->f[3] : (VX->f[3] + EX->f[3]));
             if(vex.l) {
                 GETEY;
                 GETVY;
-                GY->f[0] = VY->f[0] - EY->f[0];
-                GY->f[1] = VY->f[1] + EY->f[1];
-                GY->f[2] = VY->f[2] - EY->f[2];
-                GY->f[3] = VY->f[3] + EY->f[3];
+                GY->f[0] = isnan(VY->f[0]) ? VY->f[0] : (isnan(EY->f[0]) ? EY->f[0] : (VY->f[0] - EY->f[0]));
+                GY->f[1] = isnan(VY->f[1]) ? VY->f[1] : (isnan(EY->f[1]) ? EY->f[1] : (VY->f[1] + EY->f[1]));
+                GY->f[2] = isnan(VY->f[2]) ? VY->f[2] : (isnan(EY->f[2]) ? EY->f[2] : (VY->f[2] - EY->f[2]));
+                GY->f[3] = isnan(VY->f[3]) ? VY->f[3] : (isnan(EY->f[3]) ? EY->f[3] : (VY->f[3] + EY->f[3]));
             } else
                 GY->u128 = 0;
             break;