diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2024-06-02 17:26:26 +0200 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2024-06-02 17:26:26 +0200 |
| commit | 9e5df7957e786ba71d3aea720e8be5b4afd04e14 (patch) | |
| tree | b6b8ac63d90de2ee3fb078fb0c17afb2b70dc4e3 /src | |
| parent | ca63389ea395a0f2baafa50ec7d6a2c71d041602 (diff) | |
| download | box64-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.c | 168 |
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; |