diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2024-05-27 14:51:08 +0200 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2024-05-27 14:51:08 +0200 |
| commit | 0131958136419fb3035510aa4af5938ad38711a3 (patch) | |
| tree | aac490bd22fb6bffdedc1b9f3a17b86c3be70c71 /src | |
| parent | 9f70767acf00dd93eec4db70cdc520e442e48636 (diff) | |
| download | box64-0131958136419fb3035510aa4af5938ad38711a3.tar.gz box64-0131958136419fb3035510aa4af5938ad38711a3.zip | |
[INTERPRETER] Added more avx opcodes
Diffstat (limited to 'src')
| -rw-r--r-- | src/emu/x64runavx0f.c | 133 | ||||
| -rw-r--r-- | src/emu/x64runavx660f.c | 26 | ||||
| -rw-r--r-- | src/emu/x64runavx660f38.c | 2 | ||||
| -rw-r--r-- | src/emu/x64runavx660f3a.c | 41 | ||||
| -rw-r--r-- | src/emu/x64runavxf30f.c | 28 |
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); |