about summary refs log tree commit diff stats
path: root/src/emu/x64runavx660f38.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/emu/x64runavx660f38.c')
-rw-r--r--src/emu/x64runavx660f38.c188
1 files changed, 185 insertions, 3 deletions
diff --git a/src/emu/x64runavx660f38.c b/src/emu/x64runavx660f38.c
index 70d72514..e4de81c2 100644
--- a/src/emu/x64runavx660f38.c
+++ b/src/emu/x64runavx660f38.c
@@ -376,7 +376,62 @@ uintptr_t RunAVX_660F38(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step)
             } else
                 GY->u128 = 0;
             break;
-
+        case 0x08:  /* VPSIGNB Gx, Vx, Ex */
+            nextop = F8;
+            GETEX(0);
+            GETGX; GETVX; GETGY;
+            for (int i=0; i<16; ++i)
+                GX->sb[i] = VX->sb[i] * ((EX->sb[i]<0)?-1:((EX->sb[i]>0)?1:0));
+            if(vex.l) {
+                GETEY; GETVY;
+                for (int i=0; i<16; ++i)
+                    GY->sb[i] = VY->sb[i] * ((EY->sb[i]<0)?-1:((EY->sb[i]>0)?1:0));
+            } else
+                GY->u128 = 0;
+            break;
+        case 0x09:  /* VPSIGNW Gx, Vx, Ex */
+            nextop = F8;
+            GETEX(0);
+            GETGX; GETVX; GETGY;
+            for (int i=0; i<8; ++i)
+                GX->sw[i] = VX->sw[i] * ((EX->sw[i]<0)?-1:((EX->sw[i]>0)?1:0));
+            if(vex.l) {
+                GETEY; GETVY;
+                for (int i=0; i<8; ++i)
+                    GY->sw[i] = VY->sw[i] * ((EY->sw[i]<0)?-1:((EY->sw[i]>0)?1:0));
+            } else
+                GY->u128 = 0;
+            break;
+        case 0x0A:  /* VPSIGND Gx, Vx, Ex */
+            nextop = F8;
+            GETEX(0);
+            GETGX; GETVX; GETGY;
+            for (int i=0; i<4; ++i)
+                GX->sd[i] = VX->sd[i] * ((EX->sd[i]<0)?-1:((EX->sd[i]>0)?1:0));
+            if(vex.l) {
+                GETEY; GETVY;
+                for (int i=0; i<4; ++i)
+                    GY->sd[i] = VY->sd[i] * ((EY->sd[i]<0)?-1:((EY->sd[i]>0)?1:0));
+            } else
+                GY->u128 = 0;
+            break;
+        case 0x0B:  /* VPMULHRSW Gx, Vx, Ex */
+            nextop = F8;
+            GETEX(0);
+            GETGX; GETVX; GETGY;
+            for (int i=0; i<8; ++i) {
+                tmp32s = ((((int32_t)(VX->sw[i])*(int32_t)(EX->sw[i]))>>14) + 1)>>1;
+                GX->uw[i] = tmp32s&0xffff;
+            }
+            if(vex.l) {
+                GETEY; GETVY;
+                for (int i=0; i<8; ++i) {
+                    tmp32s = ((((int32_t)(VY->sw[i])*(int32_t)(EY->sw[i]))>>14) + 1)>>1;
+                    GY->uw[i] = tmp32s&0xffff;
+                }
+            } else
+                GY->u128 = 0;
+            break;
         case 0x0C:  /* VPERMILPS Gx, Vx, Ex */
             nextop = F8;
             GETEX(0);
@@ -445,7 +500,24 @@ uintptr_t RunAVX_660F38(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step)
                 GY->ud[i] = (u8>3)?EY->ud[u8&3]:EX->ud[u8];
             }
             break;
-
+        case 0x17:      // VPTEST GX, EX
+            nextop = F8;
+            GETEX(0);
+            GETGX;
+            RESET_FLAGS(emu);
+            if(vex.l) {
+                GETEY; GETGY;
+                CONDITIONAL_SET_FLAG(!(GY->u128&EY->u128), F_ZF);
+                CONDITIONAL_SET_FLAG(!((~GY->u128)&EY->u128), F_CF);
+            } else {
+                CONDITIONAL_SET_FLAG(!(GX->u128&EX->u128), F_ZF);
+                CONDITIONAL_SET_FLAG(!((~GX->u128)&EX->u128), F_CF);
+            }
+            CLEAR_FLAG(F_AF);
+            CLEAR_FLAG(F_OF);
+            CLEAR_FLAG(F_SF);
+            CLEAR_FLAG(F_PF);
+            break;
         case 0x18:  /* VBROADCASTSS Gx, Ex */
             nextop = F8;
             GETEX(0);
@@ -611,6 +683,21 @@ uintptr_t RunAVX_660F38(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step)
                 GX->sq[i] = EX->sd[i];
             break;
 
+        case 0x28:  /* VPMULDQ Gx, Vx, Ex */
+            nextop = F8;
+            GETEX(0);
+            GETGX;
+            GETVX;
+            GETGY;
+            GX->sq[1] = ((int64_t)VX->sd[2])*(int64_t)EX->sd[2];
+            GX->sq[0] = ((int64_t)VX->sd[0])*(int64_t)EX->sd[0];
+            if(vex.l) {
+                GETEY; GETVY;
+                GY->sq[1] = ((int64_t)VY->sd[2])*(int64_t)EY->sd[2];
+                GY->sq[0] = ((int64_t)VY->sd[0])*(int64_t)EY->sd[0];
+            } else
+                GY->u128 = 0;
+            break;
         case 0x29:  /* VPCMPEQQ Gx, Vx, Ex */
             nextop = F8;
             GETEX(0);
@@ -982,7 +1069,19 @@ uintptr_t RunAVX_660F38(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step)
             } else
                 GY->u128 = 0;
             break;
-
+        case 0x40:  /* VPMULLD Gx, Vx, Ex */
+            nextop = F8;
+            GETEX(0);
+            GETGX; GETVX; GETGY;
+            for(int i=0; i<4; ++i)
+                GX->ud[i] = VX->ud[i] * EX->ud[i];
+            if(vex.l) {
+                GETEY; GETVY;
+                for(int i=0; i<4; ++i)
+                    GY->ud[i] = VY->ud[i] * EY->ud[i];
+            } else
+                GY->u128 = 0;
+            break;
         case 0x41:  /* PHMINPOSUW Gx, Ex */
             nextop = F8;
             GETEX(0);
@@ -1003,6 +1102,89 @@ uintptr_t RunAVX_660F38(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step)
             GY->u128 = 0;
             break;
 
+        case 0x45:  /* VPSLRVD/Q Gx, Vx, Ex */
+            nextop = F8;
+            GETEX(0);
+            GETGX; GETVX; GETGY;
+            if(rex.w) {
+                for(int i=0; i<2; ++i) {
+                    tmp64u = EX->q[i];
+                    GX->q[i] = (tmp64u<64)?(VX->q[i]>>tmp64u):0;
+                }
+                if(vex.l) {
+                    GETEY; GETVY;
+                    for(int i=0; i<2; ++i) {
+                        tmp64u = EY->q[i];
+                        GY->q[i] = (tmp64u<64)?(VY->q[i]>>tmp64u):0;
+                    }
+                }
+            } else {
+                for(int i=0; i<4; ++i) {
+                    tmp32u = EX->ud[i];
+                    GX->ud[i] = (tmp32u<32)?(VX->ud[i]>>tmp32u):0;
+                }
+                if(vex.l) {
+                    GETEY; GETVY;
+                    for(int i=0; i<4; ++i) {
+                        tmp32u = EY->ud[i];
+                        GY->ud[i] = (tmp32u<32)?(VY->ud[i]>>tmp32u):0;
+                    }
+                }
+            }
+            if(!vex.l)
+                GY->u128=0;
+            break;
+        case 0x46:  /* VPSRAVD Gx, Vx, Ex */
+            nextop = F8;
+            GETEX(0);
+            GETGX; GETVX; GETGY;
+            if(rex.w) return 0;
+            for(int i=0; i<4; ++i) {
+                tmp32u = EX->ud[i]; if(tmp32u>31) tmp32u=31;
+                GX->sd[i] = VX->sd[i]>>tmp32u;
+            }
+            if(vex.l) {
+                GETEY; GETVY;
+                for(int i=0; i<4; ++i) {
+                    tmp32u = EY->ud[i]; if(tmp32u>31) tmp32u=31;
+                    GY->sd[i] = VY->sd[i]>>tmp32u;
+                }
+            } else
+                GY->u128=0;
+            break;
+        case 0x47:  /* VPSLLVD/Q Gx, Vx, Ex */
+            nextop = F8;
+            GETEX(0);
+            GETGX; GETVX; GETGY;
+            if(rex.w) {
+                for(int i=0; i<2; ++i) {
+                    tmp64u = EX->q[i];
+                    GX->q[i] = (tmp64u<64)?(VX->q[i]<<tmp64u):0;
+                }
+                if(vex.l) {
+                    GETEY; GETVY;
+                    for(int i=0; i<2; ++i) {
+                        tmp64u = EY->q[i];
+                        GY->q[i] = (tmp64u<64)?(VY->q[i]<<tmp64u):0;
+                    }
+                }
+            } else {
+                for(int i=0; i<4; ++i) {
+                    tmp32u = EX->ud[i];
+                    GX->ud[i] = (tmp32u<32)?(VX->ud[i]<<tmp32u):0;
+                }
+                if(vex.l) {
+                    GETEY; GETVY;
+                    for(int i=0; i<4; ++i) {
+                        tmp32u = EY->ud[i];
+                        GY->ud[i] = (tmp32u<32)?(VY->ud[i]<<tmp32u):0;
+                    }
+                }
+            }
+            if(!vex.l)
+                GY->u128=0;
+            break;
+
         case 0x58:  /* VPBROADCASTD Gx, Ex */
             nextop = F8;
             GETEX(0);