about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2024-06-02 17:26:26 +0200
committerptitSeb <sebastien.chev@gmail.com>2024-06-02 17:26:26 +0200
commit9e5df7957e786ba71d3aea720e8be5b4afd04e14 (patch)
treeb6b8ac63d90de2ee3fb078fb0c17afb2b70dc4e3 /src
parentca63389ea395a0f2baafa50ec7d6a2c71d041602 (diff)
downloadbox64-9e5df7957e786ba71d3aea720e8be5b4afd04e14.tar.gz
box64-9e5df7957e786ba71d3aea720e8be5b4afd04e14.zip
[INTERPRETER] Added missing FMA opcodes, and fixed some existing ones
Diffstat (limited to 'src')
-rw-r--r--src/emu/x64runavx660f38.c168
1 files changed, 156 insertions, 12 deletions
diff --git a/src/emu/x64runavx660f38.c b/src/emu/x64runavx660f38.c
index 922e4a1a..5cae3e33 100644
--- a/src/emu/x64runavx660f38.c
+++ b/src/emu/x64runavx660f38.c
@@ -1491,6 +1491,54 @@ uintptr_t RunAVX_660F38(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step)
             }
             break;
 
+        case 0x96:  /* VFMADDSUB132PS/D Gx, Vx, Ex */
+            nextop = F8;
+            GETEX(0);
+            GETGX;
+            GETVX;
+            GETGY;
+            if(rex.w) {
+                for(int i=0; i<2; ++i)
+                    GX->d[i] = GX->d[i]*EX->d[i] + ((i&1)?VX->d[i]:(-VX->d[i]));
+            } else {
+                for(int i=0; i<4; ++i)
+                    GX->f[i] = GX->f[i]*EX->f[i] + ((i&1)?VX->f[i]:(-VX->f[i]));
+            }
+            if(vex.l) {
+                GETEY; GETVY;
+                if(rex.w) {
+                    for(int i=0; i<2; ++i)
+                        GY->d[i] = GY->d[i]*EY->d[i] + ((i&1)?VY->d[i]:(-VY->d[i]));
+                } else {
+                    for(int i=0; i<4; ++i)
+                        GY->f[i] = GY->f[i]*EY->f[i] + ((i&1)?VY->f[i]:(-VY->f[i]));
+                }
+            } else GY->u128 = 0;
+            break;
+        case 0x97:  /* VFMSUBADD132PS/D Gx, Vx, Ex */
+            nextop = F8;
+            GETEX(0);
+            GETGX;
+            GETVX;
+            GETGY;
+            if(rex.w) {
+                for(int i=0; i<2; ++i)
+                    GX->d[i] = GX->d[i]*EX->d[i] + ((i&1)?(-VX->d[i]):VX->d[i]);
+            } else {
+                for(int i=0; i<4; ++i)
+                    GX->f[i] = GX->f[i]*EX->f[i] + ((i&1)?(-VX->f[i]):VX->f[i]);
+            }
+            if(vex.l) {
+                GETEY; GETVY;
+                if(rex.w) {
+                    for(int i=0; i<2; ++i)
+                        GY->d[i] = GY->d[i]*EY->d[i] + ((i&1)?(-VY->d[i]):VY->d[i]);
+                } else {
+                    for(int i=0; i<4; ++i)
+                        GY->f[i] = GY->f[i]*EY->f[i] + ((i&1)?(-VY->f[i]):VY->f[i]);
+                }
+            } else GY->u128 = 0;
+            break;
         case 0x98:  /* VFMADD132PS/D Gx, Vx, Ex */
             nextop = F8;
             GETEX(0);
@@ -1640,6 +1688,54 @@ uintptr_t RunAVX_660F38(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step)
             GY->u128 = 0;
             break;
 
+        case 0xA6:  /* VFMADDSUB213PS/D Gx, Vx, Ex */
+            nextop = F8;
+            GETEX(0);
+            GETGX;
+            GETVX;
+            GETGY;
+            if(rex.w) {
+                for(int i=0; i<2; ++i)
+                    GX->d[i] = VX->d[i]*GX->d[i] + ((i&1)?EX->d[i]:(-EX->d[i]));
+            } else {
+                for(int i=0; i<4; ++i)
+                    GX->f[i] = VX->f[i]*GX->f[i] + ((i&1)?EX->f[i]:(-EX->f[i]));
+            }
+            if(vex.l) {
+                GETEY; GETVY;
+                if(rex.w) {
+                    for(int i=0; i<2; ++i)
+                        GY->d[i] = VY->d[i]*GY->d[i] + ((i&1)?EY->d[i]:(-EY->d[i]));
+                } else {
+                    for(int i=0; i<4; ++i)
+                        GY->f[i] = VY->f[i]*GY->f[i] + ((i&1)?EY->f[i]:(-EY->f[i]));
+                }
+            } else GY->u128 = 0;
+            break;
+        case 0xA7:  /* VFMSUBADD213PS/D Gx, Vx, Ex */
+            nextop = F8;
+            GETEX(0);
+            GETGX;
+            GETVX;
+            GETGY;
+            if(rex.w) {
+                for(int i=0; i<2; ++i)
+                    GX->d[i] = VX->d[i]*GX->d[i] + ((i&1)?(-EX->d[i]):EX->d[i]);
+            } else {
+                for(int i=0; i<4; ++i)
+                    GX->f[i] = VX->f[i]*GX->f[i] + ((i&1)?(-EX->f[i]):EX->f[i]);
+            }
+            if(vex.l) {
+                GETEY; GETVY;
+                if(rex.w) {
+                    for(int i=0; i<2; ++i)
+                        GY->d[i] = VY->d[i]*GY->d[i] + ((i&1)?(-EY->d[i]):EY->d[i]);
+                } else {
+                    for(int i=0; i<4; ++i)
+                        GY->f[i] = VY->f[i]*GY->f[i] + ((i&1)?(-EY->f[i]):EY->f[i]);
+                }
+            } else GY->u128 = 0;
+            break;
         case 0xA8:  /* VFMADD213PS/D Gx, Vx, Ex */
             nextop = F8;
             GETEX(0);
@@ -1789,6 +1885,54 @@ uintptr_t RunAVX_660F38(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step)
             GY->u128 = 0;
             break;
 
+        case 0xB6:  /* VFMADDSUB231PS/D Gx, Vx, Ex */
+            nextop = F8;
+            GETEX(0);
+            GETGX;
+            GETVX;
+            GETGY;
+            if(rex.w) {
+                for(int i=0; i<2; ++i)
+                    GX->d[i] = VX->d[i]*EX->d[i] + ((i&1)?GX->d[i]:(-GX->d[i]));
+            } else {
+                for(int i=0; i<4; ++i)
+                    GX->f[i] = VX->f[i]*EX->f[i] + ((i&1)?GX->f[i]:(-GX->f[i]));
+            }
+            if(vex.l) {
+                GETEY; GETVY;
+                if(rex.w) {
+                    for(int i=0; i<2; ++i)
+                        GY->d[i] = VY->d[i]*EY->d[i] + ((i&1)?GY->d[i]:(-GY->d[i]));
+                } else {
+                    for(int i=0; i<4; ++i)
+                        GY->f[i] = VY->f[i]*EY->f[i] + ((i&1)?GY->f[i]:(-GY->f[i]));
+                }
+            } else GY->u128 = 0;
+            break;
+        case 0xB7:  /* VFMSUBADD231PS/D Gx, Vx, Ex */
+            nextop = F8;
+            GETEX(0);
+            GETGX;
+            GETVX;
+            GETGY;
+            if(rex.w) {
+                for(int i=0; i<2; ++i)
+                    GX->d[i] = VX->d[i]*EX->d[i] + ((i&1)?(-GX->d[i]):GX->d[i]);
+            } else {
+                for(int i=0; i<4; ++i)
+                    GX->f[i] = VX->f[i]*EX->f[i] + ((i&1)?(-GX->f[i]):GX->f[i]);
+            }
+            if(vex.l) {
+                GETEY; GETVY;
+                if(rex.w) {
+                    for(int i=0; i<2; ++i)
+                        GY->d[i] = VY->d[i]*EY->d[i] + ((i&1)?(-GY->d[i]):GY->d[i]);
+                } else {
+                    for(int i=0; i<4; ++i)
+                        GY->f[i] = VY->f[i]*EY->f[i] + ((i&1)?(-GY->f[i]):GY->f[i]);
+                }
+            } else GY->u128 = 0;
+            break;
         case 0xB8:  /* VFMADD231PS/D Gx, Vx, Ex */
             nextop = F8;
             GETEX(0);
@@ -1800,7 +1944,7 @@ uintptr_t RunAVX_660F38(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step)
                     GX->d[i] = VX->d[i]*EX->d[i] + GX->d[i];
             } else {
                 for(int i=0; i<4; ++i)
-                    GX->f[i] = VX->f[i]*EX->f[i] + GX->d[i];
+                    GX->f[i] = VX->f[i]*EX->f[i] + GX->f[i];
             }
             if(vex.l) {
                 GETEY; GETVY;
@@ -1809,7 +1953,7 @@ uintptr_t RunAVX_660F38(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step)
                         GY->d[i] = VY->d[i]*EY->d[i] + GY->d[i];
                 } else {
                     for(int i=0; i<4; ++i)
-                        GY->f[i] = VY->f[i]*EY->f[i] + GY->d[i];
+                        GY->f[i] = VY->f[i]*EY->f[i] + GY->f[i];
                 }
             } else GY->u128 = 0;
             break;
@@ -1822,7 +1966,7 @@ uintptr_t RunAVX_660F38(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step)
             if(rex.w) {
                 GX->d[0] = VX->d[0]*EX->d[0] + GX->d[0];
             } else {
-                GX->f[0] = VX->f[0]*EX->f[0] + GX->d[0];
+                GX->f[0] = VX->f[0]*EX->f[0] + GX->f[0];
             }
             GY->u128 = 0;
             break;
@@ -1837,7 +1981,7 @@ uintptr_t RunAVX_660F38(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step)
                     GX->d[i] = VX->d[i]*EX->d[i] - GX->d[i];
             } else {
                 for(int i=0; i<4; ++i)
-                    GX->f[i] = VX->f[i]*EX->f[i] - GX->d[i];
+                    GX->f[i] = VX->f[i]*EX->f[i] - GX->f[i];
             }
             if(vex.l) {
                 GETEY; GETVY;
@@ -1846,7 +1990,7 @@ uintptr_t RunAVX_660F38(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step)
                         GY->d[i] = VY->d[i]*EY->d[i] - GY->d[i];
                 } else {
                     for(int i=0; i<4; ++i)
-                        GY->f[i] = VY->f[i]*EY->f[i] - GY->d[i];
+                        GY->f[i] = VY->f[i]*EY->f[i] - GY->f[i];
                 }
             } else GY->u128 = 0;
             break;
@@ -1859,7 +2003,7 @@ uintptr_t RunAVX_660F38(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step)
             if(rex.w) {
                 GX->d[0] = VX->d[0]*EX->d[0] - GX->d[0];
             } else {
-                GX->f[0] = VX->f[0]*EX->f[0] - GX->d[0];
+                GX->f[0] = VX->f[0]*EX->f[0] - GX->f[0];
             }
             GY->u128 = 0;
             break;
@@ -1874,7 +2018,7 @@ uintptr_t RunAVX_660F38(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step)
                     GX->d[i] = -VX->d[i]*EX->d[i] + GX->d[i];
             } else {
                 for(int i=0; i<4; ++i)
-                    GX->f[i] = -VX->f[i]*EX->f[i] + GX->d[i];
+                    GX->f[i] = -VX->f[i]*EX->f[i] + GX->f[i];
             }
             if(vex.l) {
                 GETEY; GETVY;
@@ -1883,7 +2027,7 @@ uintptr_t RunAVX_660F38(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step)
                         GY->d[i] = -VY->d[i]*EY->d[i] + GY->d[i];
                 } else {
                     for(int i=0; i<4; ++i)
-                        GY->f[i] = -VY->f[i]*EY->f[i] + GY->d[i];
+                        GY->f[i] = -VY->f[i]*EY->f[i] + GY->f[i];
                 }
             } else GY->u128 = 0;
             break;
@@ -1896,7 +2040,7 @@ uintptr_t RunAVX_660F38(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step)
             if(rex.w) {
                 GX->d[0] = -VX->d[0]*EX->d[0] + GX->d[0];
             } else {
-                GX->f[0] = -VX->f[0]*EX->f[0] + GX->d[0];
+                GX->f[0] = -VX->f[0]*EX->f[0] + GX->f[0];
             }
             GY->u128 = 0;
             break;
@@ -1911,7 +2055,7 @@ uintptr_t RunAVX_660F38(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step)
                     GX->d[i] = -VX->d[i]*EX->d[i] - GX->d[i];
             } else {
                 for(int i=0; i<4; ++i)
-                    GX->f[i] = -VX->f[i]*EX->f[i] - GX->d[i];
+                    GX->f[i] = -VX->f[i]*EX->f[i] - GX->f[i];
             }
             if(vex.l) {
                 GETEY; GETVY;
@@ -1920,7 +2064,7 @@ uintptr_t RunAVX_660F38(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step)
                         GY->d[i] = -VY->d[i]*EY->d[i] - GY->d[i];
                 } else {
                     for(int i=0; i<4; ++i)
-                        GY->f[i] = -VY->f[i]*EY->f[i] - GY->d[i];
+                        GY->f[i] = -VY->f[i]*EY->f[i] - GY->f[i];
                 }
             } else GY->u128 = 0;
             break;
@@ -1933,7 +2077,7 @@ uintptr_t RunAVX_660F38(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step)
             if(rex.w) {
                 GX->d[0] = -VX->d[0]*EX->d[0] - GX->d[0];
             } else {
-                GX->f[0] = -VX->f[0]*EX->f[0] - GX->d[0];
+                GX->f[0] = -VX->f[0]*EX->f[0] - GX->f[0];
             }
             GY->u128 = 0;
             break;