about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/emu/x64emu.c5
-rw-r--r--src/emu/x64runavx660f.c135
-rw-r--r--src/emu/x64runavx660f38.c36
-rw-r--r--src/emu/x64runavx660f3a.c18
-rw-r--r--src/emu/x64runavxf20f.c90
-rw-r--r--src/emu/x64runavxf30f.c5
6 files changed, 285 insertions, 4 deletions
diff --git a/src/emu/x64emu.c b/src/emu/x64emu.c
index f19b6e73..10507768 100644
--- a/src/emu/x64emu.c
+++ b/src/emu/x64emu.c
@@ -428,7 +428,10 @@ const char* DumpCPURegs(x64emu_t* emu, uintptr_t ip, int is32bits)
                 }
                 strcat(buff, tmp);
             }
-            if ((i&3)==3) strcat(buff, "\n"); else strcat(buff, " ");
+            if(box64_avx)
+                if ((i&1)==1) strcat(buff, "\n"); else strcat(buff, " ");
+            else
+                if ((i&3)==3) strcat(buff, "\n"); else strcat(buff, " ");
         }
     }
 #endif
diff --git a/src/emu/x64runavx660f.c b/src/emu/x64runavx660f.c
index c8f23596..b851fde4 100644
--- a/src/emu/x64runavx660f.c
+++ b/src/emu/x64runavx660f.c
@@ -545,6 +545,126 @@ uintptr_t RunAVX_660F(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step)
             }
             break;
 
+        case 0x7C:  /* VHADDPD Gx, Vx, Ex */
+            nextop = F8;
+            GETEX(0);
+            GETGX;
+            GETVX;
+            GETGY;
+            GETEY;
+            if(GX==EX) {
+                eax1 = *EX;
+                EX = &eax1;
+            }
+            #ifndef NOALIGN
+            is_nan = isnan(VX->d[0]) || isnan(VX->d[1]);
+            #endif
+            GX->d[0] = VX->d[0] + VX->d[1];
+            #ifndef NOALIGN
+            if(!is_nan && isnan(GX->d[0]))
+                GX->d[0] = -NAN;
+            #endif
+            if(EX==VX) {
+                GX->d[1] = GX->d[0];
+            } else {
+                #ifndef NOALIGN
+                is_nan = isnan(EX->d[0]) || isnan(EX->d[1]);
+                #endif
+                GX->d[1] = EX->d[0] + EX->d[1];
+                #ifndef NOALIGN
+                if(!is_nan && isnan(GX->d[1]))
+                    GX->d[1] = -NAN;
+                #endif
+            }
+            if(vex.l) {
+                if(GY==EY) {
+                    eay1 = *EY;
+                    EY = &eay1;
+                }
+                GETVY;
+                #ifndef NOALIGN
+                is_nan = isnan(VY->d[0]) || isnan(VY->d[1]);
+                #endif
+                GY->d[0] = VY->d[0] + VY->d[1];
+                #ifndef NOALIGN
+                if(!is_nan && isnan(GY->d[0]))
+                    GY->d[0] = -NAN;
+                #endif
+                if(EY==VY) {
+                    GY->d[1] = GY->d[0];
+                } else {
+                    #ifndef NOALIGN
+                    is_nan = isnan(EY->d[0]) || isnan(EY->d[1]);
+                    #endif
+                    GY->d[1] = EY->d[0] + EY->d[1];
+                    #ifndef NOALIGN
+                    if(!is_nan && isnan(GY->d[1]))
+                        GY->d[1] = -NAN;
+                    #endif
+                }
+            } else
+                GY->u128 = 0;
+            break;
+        case 0x7D:  /* VHSUBPD Gx, Vx, Ex */
+            nextop = F8;
+            GETEX(0);
+            GETGX;
+            GETVX;
+            GETGY;
+            GETEY;
+            if(GX==EX) {
+                eax1 = *EX;
+                EX = &eax1;
+            }
+            #ifndef NOALIGN
+            is_nan = isnan(VX->d[0]) || isnan(VX->d[1]);
+            #endif
+            GX->d[0] = VX->d[0] - VX->d[1];
+            #ifndef NOALIGN
+            if(!is_nan && isnan(GX->d[0]))
+                GX->d[0] = -NAN;
+            #endif
+            if(EX==VX) {
+                GX->d[1] = GX->d[0];
+            } else {
+                #ifndef NOALIGN
+                is_nan = isnan(EX->d[0]) || isnan(EX->d[1]);
+                #endif
+                GX->d[1] = EX->d[0] - EX->d[1];
+                #ifndef NOALIGN
+                if(!is_nan && isnan(GX->d[1]))
+                    GX->d[1] = -NAN;
+                #endif
+            }
+            if(vex.l) {
+                if(GY==EY) {
+                    eay1 = *EY;
+                    EY = &eay1;
+                }
+                GETVY;
+                #ifndef NOALIGN
+                is_nan = isnan(VY->d[0]) || isnan(VY->d[1]);
+                #endif
+                GY->d[0] = VY->d[0] - VY->d[1];
+                #ifndef NOALIGN
+                if(!is_nan && isnan(GY->d[0]))
+                    GY->d[0] = -NAN;
+                #endif
+                if(EY==VY) {
+                    GY->d[1] = GY->d[0];
+                } else {
+                    #ifndef NOALIGN
+                    is_nan = isnan(EY->d[0]) || isnan(EY->d[1]);
+                    #endif
+                    GY->d[1] = EY->d[0] - EY->d[1];
+                    #ifndef NOALIGN
+                    if(!is_nan && isnan(GY->d[1]))
+                        GY->d[1] = -NAN;
+                    #endif
+                }
+            } else
+                GY->u128 = 0;
+            break;
         case 0x7E:                       /* VMOVD Ed, Gx */
             nextop = F8;
             GETED(0);
@@ -714,6 +834,21 @@ uintptr_t RunAVX_660F(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step)
 
             break;
 
+        case 0xF7:  /* VMASKMOVDQU Gx, Ex */
+            nextop = F8;
+            if(vex.l) {
+                emit_signal(emu, SIGILL, (void*)R_RIP, 0);
+            }
+            GETEX(0);
+            GETGX;
+            VX = (sse_regs_t *)(R_RDI);
+            for (int i=0; i<16; ++i) {
+                if(EX->ub[i]&0x80)
+                    VX->ub[i] = GX->ub[i];
+            }
+            // no raz of upper ymm
+            break;
+
         default:
             return 0;
     }
diff --git a/src/emu/x64runavx660f38.c b/src/emu/x64runavx660f38.c
index ae6d1cbf..b6074146 100644
--- a/src/emu/x64runavx660f38.c
+++ b/src/emu/x64runavx660f38.c
@@ -207,20 +207,50 @@ uintptr_t RunAVX_660F38(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step)
             } else
                 GY->u128 = 0;
             break;
-
+        case 0x2D:  /*VMASKMOVPD Gx, Vx, Ex */
+            nextop = F8;
+            GETEX(0);
+            GETGX;
+            GETVX;
+            GETGY;
+            for(int i=0; i<2; ++i)
+                GX->q[i] = (VX->q[i]>>63)?EX->q[i]:0;
+            if(vex.l) {
+                GETEY;
+                GETVY;
+                for(int i=0; i<2; ++i)
+                    GY->q[i] = (VY->q[i]>>63)?EY->q[i]:0;
+            } else
+                GY->u128 = 0;
+            break;
         case 0x2E:  /*VMASKMOVPS Ex, Vx, Gx */
             nextop = F8;
             GETEX(0);
             GETGX;
             GETVX;
             for(int i=0; i<4; ++i)
-                EX->ud[i] = (VX->ud[i]>>31)?GX->ud[i]:0;
+                if(VX->ud[i]>>31) EX->ud[i] = GX->ud[i];
             if(vex.l) {
                 GETGY;
                 GETEY;
                 GETVY;
                 for(int i=0; i<4; ++i)
-                    EY->ud[i] = (VY->ud[i]>>31)?GY->ud[i]:0;
+                    if(VY->ud[i]>>31) EY->ud[i] = GY->ud[i];
+            }
+            break;
+        case 0x2F:  /*VMASKMOVPD Ex, Vx, Gx */
+            nextop = F8;
+            GETEX(0);
+            GETGX;
+            GETVX;
+            for(int i=0; i<2; ++i)
+                if(VX->q[i]>>63) EX->q[i] = GX->q[i];
+            if(vex.l) {
+                GETGY;
+                GETEY;
+                GETVY;
+                for(int i=0; i<2; ++i)
+                    if(VY->q[i]>>63) EY->q[i] = GY->q[i];
             }
             break;
 
diff --git a/src/emu/x64runavx660f3a.c b/src/emu/x64runavx660f3a.c
index e09de6bf..63125974 100644
--- a/src/emu/x64runavx660f3a.c
+++ b/src/emu/x64runavx660f3a.c
@@ -226,6 +226,24 @@ uintptr_t RunAVX_660F3A(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step)
             GY->u128 = 0;
             break;
 
+        case 0x38:  /* VINSERTI128 Gx, Ex, imm8 */
+            nextop = F8;
+            GETEX(1);
+            GETGX;
+            GETVX;
+            GETGY;
+            GETVY;
+            tmp8u = F8;
+            if(tmp8u&1) {
+                GY->u128 = EX->u128;
+                if(GX!=VX);
+                    GX->u128 = VX->u128;
+            } else {
+                GX->u128 = EX->u128;
+                if(GY!=VY)
+                    GY->u128 = VY->u128;
+            }
+            break;
         case 0x39:  /* VEXTRACTI128 Ex, Gx, Ib */
             nextop = F8;
             GETGX;
diff --git a/src/emu/x64runavxf20f.c b/src/emu/x64runavxf20f.c
index fc51a3a4..1b0e6291 100644
--- a/src/emu/x64runavxf20f.c
+++ b/src/emu/x64runavxf20f.c
@@ -214,6 +214,83 @@ uintptr_t RunAVX_F20F(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step)
             GY->u128 = 0;
             break;
 
+        case 0x7C:  /* VHADDPS Gx, Vx, Ex */
+            nextop = F8;
+            GETEX(0);
+            GETGX;
+            GETVX;
+            GETGY;
+            GETEY;
+            if(GX==EX) {
+                eax1 = *EX;
+                EX = &eax1;
+            }
+            GX->f[0] = VX->f[0] + VX->f[1];
+            GX->f[1] = VX->f[2] + VX->f[3];
+            if(EX==VX) {
+                GX->f[2] = GX->f[0];
+                GX->f[3] = GX->f[1];
+            } else {
+                GX->f[2] = EX->f[0] + EX->f[1];
+                GX->f[3] = EX->f[2] + EX->f[3];
+            }
+            if(vex.l) {
+                if(GY==EY) {
+                    eay1 = *EY;
+                    EY = &eay1;
+                }
+                GETVY;
+                GY->f[0] = VY->f[0] + VY->f[1];
+                GY->f[1] = VY->f[2] + VY->f[3];
+                if(EY==VY) {
+                    GY->f[2] = GY->f[0];
+                    GY->f[3] = GY->f[1];
+                } else {
+                    GY->f[2] = EY->f[0] + EY->f[1];
+                    GY->f[3] = EY->f[2] + EY->f[3];
+                }
+            } else
+                GY->u128 = 0;
+            break;
+        case 0x7D:  /* VHSUBPS Gx, Vx, Ex */
+            nextop = F8;
+            GETEX(0);
+            GETGX;
+            GETVX;
+            GETGY;
+            GETEY;
+            if(GX==EX) {
+                eax1 = *EX;
+                EX = &eax1;
+            }
+            GX->f[0] = VX->f[0] - VX->f[1];
+            GX->f[1] = VX->f[2] - VX->f[3];
+            if(EX==VX) {
+                GX->f[2] = GX->f[0];
+                GX->f[3] = GX->f[1];
+            } else {
+                GX->f[2] = EX->f[0] - EX->f[1];
+                GX->f[3] = EX->f[2] - EX->f[3];
+            }
+            if(vex.l) {
+                if(GY==EY) {
+                    eay1 = *EY;
+                    EY = &eay1;
+                }
+                GETVY;
+                GY->f[0] = VY->f[0] - VY->f[1];
+                GY->f[1] = VY->f[2] - VY->f[3];
+                if(EY==VY) {
+                    GY->f[2] = GY->f[0];
+                    GY->f[3] = GY->f[1];
+                } else {
+                    GY->f[2] = EY->f[0] - EY->f[1];
+                    GY->f[3] = EY->f[2] - EY->f[3];
+                }
+            } else
+                GY->u128 = 0;
+            break;
+
         case 0xC2:  /* VCMPSD Gx, Vx, Ex, Ib */
             nextop = F8;
             GETEX(1);
@@ -334,6 +411,19 @@ uintptr_t RunAVX_F20F(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step)
             GY->u128 = 0;
             break;
 
+        case 0xF0:  /* VLDDQU Gx, Ex */
+            nextop = F8;
+            GETEX(0);
+            GETGX;
+            GETGY;
+            memcpy(GX, EX, 16);
+            if(vex.l) {
+                GETEY;
+                memcpy(GY, EY, 16);
+            } else
+                GY->u128 = 0;
+            break;
+
         default:
             return 0;
     }
diff --git a/src/emu/x64runavxf30f.c b/src/emu/x64runavxf30f.c
index 9afb1c10..9afef5a8 100644
--- a/src/emu/x64runavxf30f.c
+++ b/src/emu/x64runavxf30f.c
@@ -30,6 +30,11 @@
 
 #include "modrm.h"
 
+#ifdef __clang__
+extern int isinff(float);
+extern int isnanf(float);
+#endif
+
 #ifdef TEST_INTERPRETER
 uintptr_t TestAVX_F30F(x64test_t *test, vex_t vex, uintptr_t addr, int *step)
 #else