about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2024-05-28 18:27:32 +0200
committerptitSeb <sebastien.chev@gmail.com>2024-05-28 18:27:32 +0200
commita77db3c6a5d35140fbfb9ad717b4b36ba30f2972 (patch)
tree2d744e94c0be164487332790b33c7eff37bf45fe /src
parent4e0889469af7784edff2d102e4bfcb1165f81898 (diff)
downloadbox64-a77db3c6a5d35140fbfb9ad717b4b36ba30f2972.tar.gz
box64-a77db3c6a5d35140fbfb9ad717b4b36ba30f2972.zip
[INTERPRETER] Even more avx/avx2 opcodes, all the mov and more
Diffstat (limited to 'src')
-rw-r--r--src/emu/x64run660f.c1
-rw-r--r--src/emu/x64runavx.c2
-rw-r--r--src/emu/x64runavx0f.c121
-rw-r--r--src/emu/x64runavx660f.c177
-rw-r--r--src/emu/x64runavx660f38.c15
-rw-r--r--src/emu/x64runavxf20f.c44
-rw-r--r--src/emu/x64runavxf30f.c74
7 files changed, 428 insertions, 6 deletions
diff --git a/src/emu/x64run660f.c b/src/emu/x64run660f.c
index b602d997..7c14a969 100644
--- a/src/emu/x64run660f.c
+++ b/src/emu/x64run660f.c
@@ -1387,7 +1387,6 @@ uintptr_t Run660F(x64emu_t *emu, rex_t rex, uintptr_t addr)
         if (isnan(GX->d[1]) || isnan(EX->d[1]) || isgreater(EX->d[1], GX->d[1]))

             GX->d[1] = EX->d[1];

         break;

-

     case 0x60:  /* PUNPCKLBW Gx,Ex */

         nextop = F8;

         GETEX(0);

diff --git a/src/emu/x64runavx.c b/src/emu/x64runavx.c
index 9d15e803..8b4b9871 100644
--- a/src/emu/x64runavx.c
+++ b/src/emu/x64runavx.c
@@ -76,7 +76,7 @@ uintptr_t RunAVX(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step)
     else addr = 0;
 
     if(!addr)
-        printf_log(LOG_NONE, "Unimplemented AVX opcode prefix %s map %s opcode %X ", avx_prefix_string(vex.p), avx_map_string(vex.m), opcode);
+        printf_log(LOG_NONE, "Unimplemented AVX opcode size %d prefix %s map %s opcode %X ", 128<<vex.l, avx_prefix_string(vex.p), avx_map_string(vex.m), opcode);
 
     return addr;
 }
diff --git a/src/emu/x64runavx0f.c b/src/emu/x64runavx0f.c
index 8fec79f9..1644836a 100644
--- a/src/emu/x64runavx0f.c
+++ b/src/emu/x64runavx0f.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_0F(x64test_t *test, vex_t vex, uintptr_t addr, int *step)
 #else
@@ -85,7 +90,25 @@ uintptr_t RunAVX_0F(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step)
                 EY->q[1] = GY->q[1];
             }
             break;
-
+        case 0x12:
+            nextop = F8;
+            GETEX(0);
+            GETGX;
+            GETVX;
+            if(MODREG)    /* VMOVHLPS Gx, Vx, Ex */
+                GX->q[0] = EX->q[1];
+            else
+                GX->q[0] = EX->q[0];    /* VMOVLPS Gx, Vx, Ex */
+            GX->q[1] = VX->q[1];
+            GETGY;
+            GY->u128 = 0;
+            break;
+        case 0x13:                      /* VMOVLPS Ex, Gx */
+            nextop = F8;
+            GETEX(0);
+            GETGX;
+            EX->q[0] = GX->q[0];
+            break;
         case 0x14:  /* VUNPCKLPS Gx, Vx, Ex */
             nextop = F8;
             GETEX(0);
@@ -107,6 +130,27 @@ uintptr_t RunAVX_0F(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step)
                 GY->u128 = 0;
             break;
 
+        case 0x16:
+            nextop = F8;               
+            GETEX(0);
+            GETGX;
+            GETVX;
+            GETGY;
+            if(MODREG) {                /* VMOVLHPS Gx, Vx, Ex */
+                GX->q[1] = EX->q[0];
+            } else {
+                GX->q[1] = EX->q[0];    /* MOVHPS Gx,Ex */
+            }
+            GX->q[0] = VX->q[0];
+            GY->u128 = 0;
+            break;
+        case 0x17:                      /* VMOVHPS Ex,Gx */
+            nextop = F8;
+            GETEX(0);
+            GETGX;
+            EX->q[0] = GX->q[1];
+            break;
+
         case 0x28:  /* VMOVAPS Gx, Ex */
             nextop = F8;
             GETEX(0);
@@ -135,7 +179,21 @@ uintptr_t RunAVX_0F(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step)
                 EY->q[1] = GY->q[1];
             }
             break;
-            
+
+        case 0x2B:                      /* VMOVNTPS Ex,Gx */
+            nextop = F8;
+            GETEX(0);
+            GETGX;
+            EX->q[0] = GX->q[0];
+            EX->q[1] = GX->q[1];
+            if(vex.l) {
+                GETEY;
+                GETGY;
+                EY->q[0] = GY->q[0];
+                EY->q[1] = GY->q[1];
+            }
+            break;
+
         case 0x2F:                      /* VCOMISS Gx, Ex */
             RESET_FLAGS(emu);
             nextop = F8;
@@ -153,6 +211,20 @@ uintptr_t RunAVX_0F(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step)
             CLEAR_FLAG(F_OF); CLEAR_FLAG(F_AF); CLEAR_FLAG(F_SF);
             break;
 
+        case 0x50:                      /* VMOVMSKPS Gd, Ex */
+            nextop = F8;
+            GETEX(0);
+            GETGD;
+            GD->q[0] = 0;
+            for(int i=0; i<4; ++i)
+                GD->dword[0] |= ((EX->ud[i]>>31)&1)<<i;
+            if(vex.l) {
+                GETEY;
+                for(int i=0; i<4; ++i)
+                    GD->dword[0] |= ((EY->ud[i]>>31)&1)<<(i+4);
+            }
+            break;
+
         case 0x52:                      /* VRSQRTPS Gx, Ex */
             nextop = F8;
             GETEX(0);
@@ -316,7 +388,28 @@ uintptr_t RunAVX_0F(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step)
             } else
                 GY->u128 = 0;
             break;
-
+        case 0x5D:                      /* VMINPS Gx, Vx, Ex */
+            nextop = F8;
+            GETEX(0);
+            GETGX;
+            GETVX;
+            GETGY;
+            for(int i=0; i<4; ++i)
+                if (isnanf(VX->f[i]) || isnanf(EX->f[i]) || isgreater(VX->f[i], EX->f[i]))
+                    GX->f[i] = EX->f[i];
+                else
+                    GX->f[i] = VX->f[i];
+            if(vex.l) {
+                GETEY;
+                GETVY;
+                for(int i=0; i<4; ++i)
+                    if (isnanf(VY->f[i]) || isnanf(EY->f[i]) || isgreater(VY->f[i], EY->f[i]))
+                        GY->f[i] = EY->f[i];
+                    else
+                        GY->f[i] = VY->f[i];
+            } else
+                GY->u128 = 0;
+            break;
         case 0x5E:                      /* VDIVPS Gx, Ex */
             nextop = F8;
             GETEX(0);
@@ -333,6 +426,28 @@ uintptr_t RunAVX_0F(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step)
             } else
                 GY->u128 = 0;
             break;
+        case 0x5F:                      /* VMAXPS Gx, Vx, Ex */
+            nextop = F8;
+            GETEX(0);
+            GETGX;
+            GETVX;
+            GETGY;
+            for(int i=0; i<4; ++i)
+                if (isnanf(VX->f[i]) || isnanf(EX->f[i]) || isgreater(EX->f[i], VX->f[i]))
+                    GX->f[i] = EX->f[i];
+                else
+                    GX->f[i] = VX->f[i];
+            if(vex.l) {
+                GETEY;
+                GETVY;
+                for(int i=0; i<4; ++i)
+                    if (isnanf(VY->f[i]) || isnanf(EY->f[i]) || isgreater(EY->f[i], VY->f[i]))
+                        GY->f[i] = EY->f[i];
+                    else
+                        GY->f[i] = VY->f[i];
+            } else
+                GY->u128 = 0;
+            break;
 
 
         case 0x77:
diff --git a/src/emu/x64runavx660f.c b/src/emu/x64runavx660f.c
index b851fde4..1539fed6 100644
--- a/src/emu/x64runavx660f.c
+++ b/src/emu/x64runavx660f.c
@@ -59,6 +59,105 @@ uintptr_t RunAVX_660F(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step)
 
     switch(opcode) {
 
+        case 0x10:                      /* MOVUPD Gx, Ex */
+            nextop = F8;
+            GETEX(0);
+            GETGX;
+            GETGY;
+            memcpy(GX, EX, 16); // unaligned...
+            if(vex.l) {
+                GETEY;
+                memcpy(GY, EY, 16); // unaligned...
+            } else
+                GY->u128 = 0;
+            break;
+        case 0x11:                      /* MOVUPD Ex, Gx */
+            nextop = F8;
+            GETEX(0);
+            GETGX;
+            memcpy(EX, GX, 16); // unaligned...
+            if(vex.l) {
+                GETEY;
+                GETGY;
+                memcpy(EY, GY, 16); // unaligned...
+            }
+            break;
+        case 0x12:                      /* VMOVLPD Gx, Vx, Eq */
+            nextop = F8;
+            GETE8(0);
+            GETGX;
+            GETVX;
+            GETGY;
+            GX->q[0] = ED->q[0];
+            GX->q[1] = VX->q[1];
+            GY->u128 = 0;
+            break;
+        case 0x13:                      /* VMOVLPD Eq, Gx */
+            nextop = F8;
+            GETE8(0);
+            GETGX;
+            ED->q[0] = GX->q[0];
+            break;
+
+        case 0x16:                      /* VMOVHPD Gx, Vx, Ed */
+            nextop = F8;
+            GETE8(0);
+            GETGX;
+            GETVX;
+            GX->q[1] = ED->q[0];
+            GX->q[0] = VX->q[0];
+            GETGY;
+            GY->u128 = 0;
+            break;
+        case 0x17:                      /* VMOVHPD Ed, Gx */
+            nextop = F8;
+            GETE8(0);
+            GETGX;
+            ED->q[0] = GX->q[1];
+            break;
+
+        case 0x28:                      /* VMOVAPD Gx, Ex */
+            nextop = F8;
+            GETEX(0);
+            GETGX;
+            GETGY;
+            GX->q[0] = EX->q[0];
+            GX->q[1] = EX->q[1];
+            if(vex.l) {
+                GETEY;
+                GY->q[0] = EY->q[0];
+                GY->q[1] = EY->q[1];
+            } else
+                GY->u128 = 0;
+            break;
+        case 0x29:                      /* VMOVAPD Ex, Gx */
+            nextop = F8;
+            GETEX(0);
+            GETGX;
+            EX->q[0] = GX->q[0];
+            EX->q[1] = GX->q[1];
+            if(vex.l) {
+                GETEY;
+                GETGY;
+                EY->q[0] = GY->q[0];
+                EY->q[1] = GY->q[1];
+            }
+            break;
+
+        case 0x2B:                      /* MOVNTPD Ex, Gx */
+            nextop = F8;
+            GETEX(0);
+            GETGX;
+            EX->q[0] = GX->q[0];
+            EX->q[1] = GX->q[1];
+            if(vex.l) {
+                GETGY;
+                GETEY;
+                EY->q[0] = GY->q[0];
+                EY->q[1] = GY->q[1];
+            }
+            break;
+
         case 0x2F:                      /* VCOMISD Gx, Ex */
             RESET_FLAGS(emu);
             nextop = F8;
@@ -76,6 +175,15 @@ uintptr_t RunAVX_660F(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step)
             CLEAR_FLAG(F_OF); CLEAR_FLAG(F_AF); CLEAR_FLAG(F_SF);
             break;
 
+        case 0x50:  /* VMOVMSKPD Gd, Ex */
+            nextop = F8;
+            GETEX(0);
+            GETGD;
+            GD->q[0] = 0;
+            for(int i=0; i<2; ++i)
+                GD->dword[0] |= ((EX->q[i]>>63)&1)<<i;
+            break;
+
         case 0x54:  /* VANDPD Gx, Vx, Ex */
             nextop = F8;
             GETEX(0);
@@ -207,6 +315,28 @@ uintptr_t RunAVX_660F(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step)
                 GY->u128 = 0;
             break;
 
+        case 0x5D:                      /* VMINPD Gx, Vx, Ex */
+            nextop = F8;
+            GETEX(0);
+            GETGX;
+            GETVX;
+            GETGY;
+            for(int i=0; i<2; ++i)
+                if (isnan(VX->d[i]) || isnan(EX->d[i]) || isgreater(VX->d[i], EX->d[i]))
+                    GX->d[i] = EX->d[i];
+                else
+                    GX->d[i] = VX->d[i];
+            if(vex.l) {
+                GETEY;
+                GETVY;
+                for(int i=0; i<2; ++i)
+                    if (isnan(VY->d[i]) || isnan(EY->d[i]) || isgreater(VY->d[i], EY->d[i]))
+                        GY->d[i] = EY->d[i];
+                    else
+                        GY->d[i] = VY->d[i];
+            } else
+                GY->u128 = 0;
+            break;
         case 0x5E:  /* VDIVPD Gx, Vx, Ex */
             nextop = F8;
             GETEX(0);
@@ -239,6 +369,28 @@ uintptr_t RunAVX_660F(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step)
             } else
                 GY->u128 = 0;
             break;
+        case 0x5F:                      /* VMAXPD Gx, Vx, Ex */
+            nextop = F8;
+            GETEX(0);
+            GETGX;
+            GETVX;
+            GETGY;
+            for(int i=0; i<2; ++i)
+                if (isnan(VX->d[i]) || isnan(EX->d[i]) || isgreater(EX->d[i], VX->d[i]))
+                    GX->d[i] = EX->d[i];
+                else
+                    GX->d[i] = VX->d[i];
+            if(vex.l) {
+                GETEY;
+                GETVY;
+                for(int i=0; i<2; ++i)
+                    if (isnan(VY->d[i]) || isnan(EY->d[i]) || isgreater(EY->d[i], VY->d[i]))
+                        GY->d[i] = EY->d[i];
+                    else
+                        GY->d[i] = VY->d[i];
+            } else
+                GY->u128 = 0;
+            break;
 
         case 0x64:  /* VPCMPGTB Gx,Vx, Ex */
             nextop = F8;
@@ -751,6 +903,18 @@ uintptr_t RunAVX_660F(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step)
                 GY->u128 = 0;
             break;
 
+        case 0xD6:  /* VMOVQ Ex, Gx */
+            nextop = F8;
+            GETEX(0);
+            GETGX;
+            EX->q[0] = GX->q[0];
+            if(MODREG) {
+                EX->q[1] = 0;
+                GETEY;
+                EY->u128 = 0;
+            }
+            break;
+
         case 0xDB:  /* VPAND Gx, Vx, Ex */
             nextop = F8;
             GETEX(0);
@@ -796,6 +960,19 @@ uintptr_t RunAVX_660F(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step)
                 GX->q[1] = 0;
             GY->u128 = 0;
             break;
+        case 0xE7:   /* VMOVNTDQ Ex, Gx */
+            nextop = F8;
+            GETEX(0);
+            GETGX;
+            EX->q[0] = GX->q[0];
+            EX->q[1] = GX->q[1];
+            if(vex.l) {
+                GETEY;
+                GETGY;
+                EY->q[0] = GY->q[0];
+                EY->q[1] = GY->q[1];
+            }
+            break;
 
         case 0xEB:  /* VPOR Gx, Vx, Ex */
             nextop = F8;
diff --git a/src/emu/x64runavx660f38.c b/src/emu/x64runavx660f38.c
index b6074146..6f46c659 100644
--- a/src/emu/x64runavx660f38.c
+++ b/src/emu/x64runavx660f38.c
@@ -191,6 +191,21 @@ uintptr_t RunAVX_660F38(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step)
             GY->u128 = EX->u128;
             break;
 
+        case 0x2A:  /* VMOVNTDQA Gx, Ex */
+            nextop = F8;
+            GETEX(0);
+            GETGX;
+            GETGY;
+            GX->q[0] = EX->q[0];
+            GX->q[1] = EX->q[1];
+            if(vex.l) {
+                GETEY;
+                GY->q[0] = EY->q[0];
+                GY->q[1] = EY->q[1];
+            } else
+                GY->u128 = 0;
+            break;
+
         case 0x2C:  /*VMASKMOVPS Gx, Vx, Ex */
             nextop = F8;
             GETEX(0);
diff --git a/src/emu/x64runavxf20f.c b/src/emu/x64runavxf20f.c
index 1b0e6291..a3006a7d 100644
--- a/src/emu/x64runavxf20f.c
+++ b/src/emu/x64runavxf20f.c
@@ -74,7 +74,7 @@ uintptr_t RunAVX_F20F(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step)
             GETGY;
             GY->u128 = 0;
             break;
-        case 0x11:  /* MOVSD Ex Gx */
+        case 0x11:  /* VMOVSD Ex Gx */
             nextop = F8;
             GETEX(0);
             GETGX;
@@ -86,6 +86,18 @@ uintptr_t RunAVX_F20F(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step)
                 EY->u128 = 0;
             }
             break;
+        case 0x12:  /* VMOVDDUP Gx, Ex */
+            nextop = F8;
+            GETEX(0);
+            GETGX;
+            GETGY;
+            GX->q[1] = GX->q[0] = EX->q[0];
+            if(vex.l) {
+                GETEY;
+                GY->q[1] = GY->q[0] = EY->q[0];
+            } else
+                GY->u128 = 0;
+            break;
 
         case 0x2A:  /* VCVTSI2SD Gx, Vx, Ed */
             nextop = F8;
@@ -196,6 +208,21 @@ uintptr_t RunAVX_F20F(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step)
             GY->u128 = 0;
             break;
 
+        case 0x5D:  /* VMINSD Gx, Vx, Ex */
+            nextop = F8;
+            GETEX(0);
+            GETGX;
+            GETVX;
+            GETGY;
+            if (VX->d[0] == 0.0 && EX->d[0]  == 0.0)
+                GX->d[0] = EX->d[0];
+            else if (isnan(VX->d[0]) || isnan(EX->d[0]) || isgreater(VX->d[0], EX->d[0]))
+                GX->d[0] = EX->d[0];
+            else
+                GX->d[0] = VX->d[0];
+            GX->q[1] = VX->q[1];
+            GY->u128 = 0;
+            break;
         case 0x5E:  /* VDIVSD Gx, Vx, Ex */
             nextop = F8;
             GETEX(0);
@@ -213,6 +240,21 @@ uintptr_t RunAVX_F20F(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step)
             GX->q[1] = VX->q[1];
             GY->u128 = 0;
             break;
+        case 0x5F:  /* VMAXSD Gx, Vx, Ex */
+            nextop = F8;
+            GETEX(0);
+            GETGX;
+            GETVX;
+            GETGY;
+            if (VX->d[0] == 0.0 && EX->d[0]  == 0.0)
+                GX->d[0] = EX->d[0];
+            else if (isnan(VX->d[0]) || isnan(EX->d[0]) || isgreater(EX->d[0], VX->d[0]))
+                GX->d[0] = EX->d[0];
+            else
+                GX->d[0] = VX->d[0];
+            GX->q[1] = VX->q[1];
+            GY->u128 = 0;
+            break;
 
         case 0x7C:  /* VHADDPS Gx, Vx, Ex */
             nextop = F8;
diff --git a/src/emu/x64runavxf30f.c b/src/emu/x64runavxf30f.c
index 9afef5a8..8aa1506e 100644
--- a/src/emu/x64runavxf30f.c
+++ b/src/emu/x64runavxf30f.c
@@ -91,6 +91,35 @@ uintptr_t RunAVX_F30F(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step)
                 EY->q[0] = EY->q[1] = 0;
             }
             break;
+        case 0x12:  /* VMOVSLDUP Gx, Ex */
+            nextop = F8;
+            GETEX(0);
+            GETGX;
+            GETGY;
+            GX->ud[1] = GX->ud[0] = EX->ud[0];
+            GX->ud[3] = GX->ud[2] = EX->ud[2];
+            if(vex.l) {
+                GETEY;
+                GY->ud[1] = GY->ud[0] = EY->ud[0];
+                GY->ud[3] = GY->ud[2] = EY->ud[2];
+            } else
+                GY->u128 = 0;
+            break;
+
+        case 0x16:  /* MOVSHDUP Gx, Ex */
+            nextop = F8;
+            GETEX(0);
+            GETGX;
+            GETGY;
+            GX->ud[1] = GX->ud[0] = EX->ud[1];
+            GX->ud[3] = GX->ud[2] = EX->ud[3];
+            if(vex.l) {
+                GETEY;
+                GY->ud[1] = GY->ud[0] = EY->ud[1];
+                GY->ud[3] = GY->ud[2] = EY->ud[3];
+            } else
+                GY->u128 = 0;
+            break;
 
         case 0x2A:  /* VCVTSI2SS Gx, Vx, Ed */
             nextop = F8;
@@ -250,6 +279,24 @@ uintptr_t RunAVX_F30F(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step)
             GY->u128 = 0;
             break;
 
+        case 0x5D:  /* VMINSS Gx, Vx, Ex */
+            nextop = F8;
+            GETEX(0);
+            GETGX;
+            GETVX;
+            GETGY;
+            if (VX->f[0] == 0.0 && EX->f[0]  == 0.0)
+                GX->f[0] = EX->f[0];
+            else if (isnan(VX->f[0]) || isnan(EX->f[0]) || isgreater(VX->f[0], EX->f[0]))
+                GX->f[0] = EX->f[0];
+            else
+                GX->f[0] = VX->f[0];
+            if(GX!=VX) {
+                GX->ud[1] = VX->ud[1];
+                GX->q[1] = VX->q[1];
+            }
+            GY->u128 = 0;
+            break;
         case 0x5E:  /* VDIVSS Gx, Vx, Ex */
             nextop = F8;
             GETEX(0);
@@ -263,6 +310,24 @@ uintptr_t RunAVX_F30F(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step)
             }
             GY->u128 = 0;
             break;
+        case 0x5F:  /* VMAXSS Gx, Vx, Ex */
+            nextop = F8;
+            GETEX(0);
+            GETGX;
+            GETVX;
+            GETGY;
+            if (VX->f[0] == 0.0 && EX->f[0]  == 0.0)
+                GX->f[0] = EX->f[0];
+            else if (isnan(VX->f[0]) || isnan(EX->f[0]) || isgreater(EX->f[0], VX->f[0]))
+                GX->f[0] = EX->f[0];
+            else
+                GX->f[0] = VX->f[0];
+            if(GX!=VX) {
+                GX->ud[1] = VX->ud[1];
+                GX->q[1] = VX->q[1];
+            }
+            GY->u128 = 0;
+            break;
 
         case 0x6F:  // VMOVDQU Gx, Ex
             nextop = F8;
@@ -277,6 +342,15 @@ uintptr_t RunAVX_F30F(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step)
                 GY->q[0] = GY->q[1] = 0;
             break;
 
+        case 0x7E:  /* MOVQ Gx, Ex */
+            nextop = F8;
+            GETEX(0);
+            GETGX;
+            GX->q[0] = EX->q[0];
+            GX->q[1] = 0;
+            GETGY;
+            GY->u128 = 0;
+            break;
         case 0x7F:  /* VMOVDQU Ex, Gx */
             nextop = F8;
             GETEX(0);