about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2024-05-27 14:51:08 +0200
committerptitSeb <sebastien.chev@gmail.com>2024-05-27 14:51:08 +0200
commit0131958136419fb3035510aa4af5938ad38711a3 (patch)
treeaac490bd22fb6bffdedc1b9f3a17b86c3be70c71 /src
parent9f70767acf00dd93eec4db70cdc520e442e48636 (diff)
downloadbox64-0131958136419fb3035510aa4af5938ad38711a3.tar.gz
box64-0131958136419fb3035510aa4af5938ad38711a3.zip
[INTERPRETER] Added more avx opcodes
Diffstat (limited to 'src')
-rw-r--r--src/emu/x64runavx0f.c133
-rw-r--r--src/emu/x64runavx660f.c26
-rw-r--r--src/emu/x64runavx660f38.c2
-rw-r--r--src/emu/x64runavx660f3a.c41
-rw-r--r--src/emu/x64runavxf30f.c28
5 files changed, 227 insertions, 3 deletions
diff --git a/src/emu/x64runavx0f.c b/src/emu/x64runavx0f.c
index 0a1a087a..b5a49560 100644
--- a/src/emu/x64runavx0f.c
+++ b/src/emu/x64runavx0f.c
@@ -57,7 +57,103 @@ uintptr_t RunAVX_0F(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step)
 
     switch(opcode) {
 
-        case 0x57:                      /* XORPS Gx, Ex */
+        case 0x10:  /* VMOVUPS 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->q[0] = GY->q[1] = 0;
+            }
+            break;
+        case 0x11:  /* VMOVUPS 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 0x28:  /* VMOVAPS 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->q[0] = GY->q[1] = 0;
+            }
+            break;
+        case 0x29:  /* VMOVAPS 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 0x52:                      /* VRSQRTPS Gx, Ex */
+            nextop = F8;
+            GETEX(0);
+            GETGX;
+            GETGY;
+            for(int i=0; i<4; ++i) {
+                if(EX->f[i]==0)
+                    GX->f[i] = 1.0f/EX->f[i];
+                else if (EX->f[i]<0)
+                    GX->f[i] = NAN;
+                else if (isnan(EX->f[i]))
+                    GX->f[i] = EX->f[i];
+                else if (isinf(EX->f[i]))
+                    GX->f[i] = 0.0;
+                else
+                    GX->f[i] = 1.0f/sqrtf(EX->f[i]);
+            }
+            if(vex.l) {
+                GETEY;
+                for(int i=0; i<4; ++i) {
+                    if(EY->f[i]==0)
+                        GY->f[i] = 1.0f/EY->f[i];
+                    else if (EY->f[i]<0)
+                        GY->f[i] = NAN;
+                    else if (isnan(EY->f[i]))
+                        GY->f[i] = EY->f[i];
+                    else if (isinf(EY->f[i]))
+                        GY->f[i] = 0.0;
+                    else
+                        GY->f[i] = 1.0f/sqrtf(EY->f[i]);
+                }
+            } else
+                GY->q[0] = GY->q[1] = 0;
+            #ifdef TEST_INTERPRETER
+            test->notest = 1;
+            #endif
+            break;
+
+        case 0x57:                      /* XORPS Gx, Vx, Ex */
             nextop = F8;
             GETEX(0);
             GETGX;
@@ -75,6 +171,40 @@ uintptr_t RunAVX_0F(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step)
                 GY->q[0] = GY->q[1] = 0;
             break;
 
+        case 0x59:                      /* VMULPS Gx, Vx, Ex */
+            nextop = F8;
+            GETEX(0);
+            GETGX;
+            GETVX;
+            GETGY;
+            for(int i=0; i<4; ++i)
+                GX->f[i] = VX->f[i] * EX->f[i];
+            if(vex.l) {
+                GETEY;
+                GETVY;
+                for(int i=0; i<4; ++i)
+                    GY->f[i] = VY->f[i] * EY->f[i];
+            } else
+                GY->q[0] = GY->q[1] = 0;
+            break;
+
+        case 0x5C:                      /* VSUBPS Gx, Vx, Ex */
+            nextop = F8;
+            GETEX(0);
+            GETGX;
+            GETVX;
+            GETGY;
+            for(int i=0; i<4; ++i)
+                GX->f[i] = VX->f[i] - EX->f[i];
+            if(vex.l) {
+                GETEY;
+                GETVY;
+                for(int i=0; i<4; ++i)
+                    GY->f[i] = VY->f[i] - EY->f[i];
+            } else
+                GY->q[0] = GY->q[1] = 0;
+            break;
+
         case 0x77:
             if(!vex.l) {    // VZEROUPPER
                 if(vex.v!=0) {
@@ -85,6 +215,7 @@ uintptr_t RunAVX_0F(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step)
             } else
                 return 0;
             break;
+
         default:
             return 0;
     }
diff --git a/src/emu/x64runavx660f.c b/src/emu/x64runavx660f.c
index d796e631..aeb976f1 100644
--- a/src/emu/x64runavx660f.c
+++ b/src/emu/x64runavx660f.c
@@ -141,7 +141,18 @@ uintptr_t RunAVX_660F(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step)
             } else
                 GY->q[0] = GY->q[1] = 0;
             break;
-
+        case 0x6E:                      /* VMOVD GX, Ed */
+            nextop = F8;
+            GETED(0);
+            GETGX;
+            if(rex.w)
+                GX->q[0] = ED->q[0];
+            else
+                GX->q[0] = ED->dword[0];    // zero extended
+            GX->q[1] = 0;
+            GETGY;
+            GY->q[0] = GY->q[1] = 0;
+            break;
         case 0x6F:  // VMOVDQA GX, EX
             nextop = F8;
             GETEX(0);
@@ -328,6 +339,19 @@ uintptr_t RunAVX_660F(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step)
             }
             break;
 
+        case 0x7E:                       /* VMOVD Ed, Gx */
+            nextop = F8;
+            GETED(0);
+            GETGX;
+            if(rex.w)
+                ED->q[0] = GX->q[0];
+            else {
+                if(MODREG)
+                    ED->q[0] = GX->ud[0];
+                else
+                    ED->dword[0] = GX->ud[0];
+            }
+            break;
         case 0x7F:  // VMOVDQA EX, GX
             nextop = F8;
             GETEX(0);
diff --git a/src/emu/x64runavx660f38.c b/src/emu/x64runavx660f38.c
index f77253ba..ab01aba7 100644
--- a/src/emu/x64runavx660f38.c
+++ b/src/emu/x64runavx660f38.c
@@ -81,7 +81,7 @@ uintptr_t RunAVX_660F38(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step)
                     VY = &eay1;
                 }
                 for (int i=0; i<16; ++i) {
-                    if(EX->ub[i]&128)
+                    if(EY->ub[i]&128)
                         GY->ub[i] = 0;
                     else
                         GY->ub[i] = VY->ub[EY->ub[i]&15];
diff --git a/src/emu/x64runavx660f3a.c b/src/emu/x64runavx660f3a.c
index 16a73027..25bc5986 100644
--- a/src/emu/x64runavx660f3a.c
+++ b/src/emu/x64runavx660f3a.c
@@ -56,6 +56,7 @@ uintptr_t RunAVX_660F3A(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step)
     uint64_t tmp64u, tmp64u2;
     int64_t tmp64s;
     reg64_t *oped, *opgd;
+    float tmpf;
     sse_regs_t *opex, *opgx, *opvx, eax1;
     sse_regs_t *opey, *opgy, *opvy, eay1;
 
@@ -101,6 +102,46 @@ uintptr_t RunAVX_660F3A(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step)
                 GY->q[0] = GY->q[1] = 0;
             break;
 
+        case 0x21:  /* VINSRTPS Gx, Vx, Ex, imm8 */
+            nextop = F8;
+            GETGX;
+            GETEX(1);
+            GETVX;
+            GETGY;
+            tmp8u = F8;
+            if(MODREG) {
+                tmp32u = EX->ud[(tmp8u>>6)&3];
+            } else
+                tmp32u = EX->ud[0];
+            for(int i=0; i<4; ++i)
+                GX->ud[i] = (tmp8u&(1<<i))?((i==(tmp8u>>4)&3)?tmp32u:VX->ud[i]):0;
+            GY->q[0] = GY->q[1] = 0;
+            break;
+
+        case 0x40:  /* DPPS Gx, Ex, Ib */
+            nextop = F8;
+            GETEX(1);
+            GETGX;
+            GETVX;
+            GETGY;
+            tmp8u = F8;
+            tmpf = 0.0f;
+            for(int i=0; i<4; ++i)
+                if(tmp8u&(1<<(i+4)))
+                    tmpf += VX->f[i]*EX->f[i];
+            for(int i=0; i<4; ++i)
+                GX->f[i] = (tmp8u&(1<<i))?tmpf:0.0f;
+            if(vex.l) {
+                tmpf = 0.0f;
+                for(int i=0; i<4; ++i)
+                    if(tmp8u&(1<<(i+4)))
+                        tmpf += VY->f[i]*EY->f[i];
+                for(int i=0; i<4; ++i)
+                    GY->f[i] = (tmp8u&(1<<i))?tmpf:0.0f;
+            } else
+                GY->q[0] = GY->q[1] = 0;
+            break;
+
         case 0x44:    /* VPCLMULQDQ Gx, Vx, Ex, imm8 */
             nextop = F8;
             GETGX;
diff --git a/src/emu/x64runavxf30f.c b/src/emu/x64runavxf30f.c
index 6dccb27d..73180d0a 100644
--- a/src/emu/x64runavxf30f.c
+++ b/src/emu/x64runavxf30f.c
@@ -88,6 +88,20 @@ uintptr_t RunAVX_F30F(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step)
             }
             break;
 
+        case 0x58:  /* VADDSS Gx, Vx, Ex */
+            nextop = F8;
+            GETEX(0);
+            GETGX;
+            GETVX;
+            GETGY;
+            GX->f[0] = VX->f[0] + EX->f[0];
+            if(GX!=VX) {
+                GX->ud[1] = VX->ud[1];
+                GX->q[1] = VX->q[1];
+            }
+            GY->q[0] = GY->q[1] = 0;
+            break;
+
         case 0x5A:  /* VCVTSS2SD Gx, Vx, Ex */
             nextop = F8;
             GETEX(0);
@@ -99,6 +113,20 @@ uintptr_t RunAVX_F30F(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step)
             GY->q[0] = GY->q[1] = 0;
             break;
 
+        case 0x5C:  /* VSUBSS Gx, Vx, Ex */
+            nextop = F8;
+            GETEX(0);
+            GETGX;
+            GETVX;
+            GETGY;
+            GX->f[0] = VX->f[0] - EX->f[0];
+            if(GX!=VX) {
+                GX->ud[1] = VX->ud[1];
+                GX->q[1] = VX->q[1];
+            }
+            GY->q[0] = GY->q[1] = 0;
+            break;
+
         case 0x6F:  // VMOVDQU Gx, Ex
             nextop = F8;
             GETEX(0);