diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2024-05-28 18:27:32 +0200 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2024-05-28 18:27:32 +0200 |
| commit | a77db3c6a5d35140fbfb9ad717b4b36ba30f2972 (patch) | |
| tree | 2d744e94c0be164487332790b33c7eff37bf45fe /src | |
| parent | 4e0889469af7784edff2d102e4bfcb1165f81898 (diff) | |
| download | box64-a77db3c6a5d35140fbfb9ad717b4b36ba30f2972.tar.gz box64-a77db3c6a5d35140fbfb9ad717b4b36ba30f2972.zip | |
[INTERPRETER] Even more avx/avx2 opcodes, all the mov and more
Diffstat (limited to 'src')
| -rw-r--r-- | src/emu/x64run660f.c | 1 | ||||
| -rw-r--r-- | src/emu/x64runavx.c | 2 | ||||
| -rw-r--r-- | src/emu/x64runavx0f.c | 121 | ||||
| -rw-r--r-- | src/emu/x64runavx660f.c | 177 | ||||
| -rw-r--r-- | src/emu/x64runavx660f38.c | 15 | ||||
| -rw-r--r-- | src/emu/x64runavxf20f.c | 44 | ||||
| -rw-r--r-- | src/emu/x64runavxf30f.c | 74 |
7 files changed, 428 insertions, 6 deletions
diff --git a/src/emu/x64run660f.c b/src/emu/x64run660f.c index b602d997..7c14a969 100644 --- a/src/emu/x64run660f.c +++ b/src/emu/x64run660f.c @@ -1387,7 +1387,6 @@ uintptr_t Run660F(x64emu_t *emu, rex_t rex, uintptr_t addr) if (isnan(GX->d[1]) || isnan(EX->d[1]) || isgreater(EX->d[1], GX->d[1])) GX->d[1] = EX->d[1]; break; - case 0x60: /* PUNPCKLBW Gx,Ex */ nextop = F8; GETEX(0); diff --git a/src/emu/x64runavx.c b/src/emu/x64runavx.c index 9d15e803..8b4b9871 100644 --- a/src/emu/x64runavx.c +++ b/src/emu/x64runavx.c @@ -76,7 +76,7 @@ uintptr_t RunAVX(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step) else addr = 0; if(!addr) - printf_log(LOG_NONE, "Unimplemented AVX opcode prefix %s map %s opcode %X ", avx_prefix_string(vex.p), avx_map_string(vex.m), opcode); + printf_log(LOG_NONE, "Unimplemented AVX opcode size %d prefix %s map %s opcode %X ", 128<<vex.l, avx_prefix_string(vex.p), avx_map_string(vex.m), opcode); return addr; } diff --git a/src/emu/x64runavx0f.c b/src/emu/x64runavx0f.c index 8fec79f9..1644836a 100644 --- a/src/emu/x64runavx0f.c +++ b/src/emu/x64runavx0f.c @@ -30,6 +30,11 @@ #include "modrm.h" +#ifdef __clang__ +extern int isinff(float); +extern int isnanf(float); +#endif + #ifdef TEST_INTERPRETER uintptr_t TestAVX_0F(x64test_t *test, vex_t vex, uintptr_t addr, int *step) #else @@ -85,7 +90,25 @@ uintptr_t RunAVX_0F(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step) EY->q[1] = GY->q[1]; } break; - + case 0x12: + nextop = F8; + GETEX(0); + GETGX; + GETVX; + if(MODREG) /* VMOVHLPS Gx, Vx, Ex */ + GX->q[0] = EX->q[1]; + else + GX->q[0] = EX->q[0]; /* VMOVLPS Gx, Vx, Ex */ + GX->q[1] = VX->q[1]; + GETGY; + GY->u128 = 0; + break; + case 0x13: /* VMOVLPS Ex, Gx */ + nextop = F8; + GETEX(0); + GETGX; + EX->q[0] = GX->q[0]; + break; case 0x14: /* VUNPCKLPS Gx, Vx, Ex */ nextop = F8; GETEX(0); @@ -107,6 +130,27 @@ uintptr_t RunAVX_0F(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step) GY->u128 = 0; break; + case 0x16: + nextop = F8; + GETEX(0); + GETGX; + GETVX; + GETGY; + if(MODREG) { /* VMOVLHPS Gx, Vx, Ex */ + GX->q[1] = EX->q[0]; + } else { + GX->q[1] = EX->q[0]; /* MOVHPS Gx,Ex */ + } + GX->q[0] = VX->q[0]; + GY->u128 = 0; + break; + case 0x17: /* VMOVHPS Ex,Gx */ + nextop = F8; + GETEX(0); + GETGX; + EX->q[0] = GX->q[1]; + break; + case 0x28: /* VMOVAPS Gx, Ex */ nextop = F8; GETEX(0); @@ -135,7 +179,21 @@ uintptr_t RunAVX_0F(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step) EY->q[1] = GY->q[1]; } break; - + + case 0x2B: /* VMOVNTPS 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 0x2F: /* VCOMISS Gx, Ex */ RESET_FLAGS(emu); nextop = F8; @@ -153,6 +211,20 @@ uintptr_t RunAVX_0F(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step) CLEAR_FLAG(F_OF); CLEAR_FLAG(F_AF); CLEAR_FLAG(F_SF); break; + case 0x50: /* VMOVMSKPS Gd, Ex */ + nextop = F8; + GETEX(0); + GETGD; + GD->q[0] = 0; + for(int i=0; i<4; ++i) + GD->dword[0] |= ((EX->ud[i]>>31)&1)<<i; + if(vex.l) { + GETEY; + for(int i=0; i<4; ++i) + GD->dword[0] |= ((EY->ud[i]>>31)&1)<<(i+4); + } + break; + case 0x52: /* VRSQRTPS Gx, Ex */ nextop = F8; GETEX(0); @@ -316,7 +388,28 @@ uintptr_t RunAVX_0F(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step) } else GY->u128 = 0; break; - + case 0x5D: /* VMINPS Gx, Vx, Ex */ + nextop = F8; + GETEX(0); + GETGX; + GETVX; + GETGY; + for(int i=0; i<4; ++i) + if (isnanf(VX->f[i]) || isnanf(EX->f[i]) || isgreater(VX->f[i], EX->f[i])) + GX->f[i] = EX->f[i]; + else + GX->f[i] = VX->f[i]; + if(vex.l) { + GETEY; + GETVY; + for(int i=0; i<4; ++i) + if (isnanf(VY->f[i]) || isnanf(EY->f[i]) || isgreater(VY->f[i], EY->f[i])) + GY->f[i] = EY->f[i]; + else + GY->f[i] = VY->f[i]; + } else + GY->u128 = 0; + break; case 0x5E: /* VDIVPS Gx, Ex */ nextop = F8; GETEX(0); @@ -333,6 +426,28 @@ uintptr_t RunAVX_0F(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step) } else GY->u128 = 0; break; + case 0x5F: /* VMAXPS Gx, Vx, Ex */ + nextop = F8; + GETEX(0); + GETGX; + GETVX; + GETGY; + for(int i=0; i<4; ++i) + if (isnanf(VX->f[i]) || isnanf(EX->f[i]) || isgreater(EX->f[i], VX->f[i])) + GX->f[i] = EX->f[i]; + else + GX->f[i] = VX->f[i]; + if(vex.l) { + GETEY; + GETVY; + for(int i=0; i<4; ++i) + if (isnanf(VY->f[i]) || isnanf(EY->f[i]) || isgreater(EY->f[i], VY->f[i])) + GY->f[i] = EY->f[i]; + else + GY->f[i] = VY->f[i]; + } else + GY->u128 = 0; + break; case 0x77: diff --git a/src/emu/x64runavx660f.c b/src/emu/x64runavx660f.c index b851fde4..1539fed6 100644 --- a/src/emu/x64runavx660f.c +++ b/src/emu/x64runavx660f.c @@ -59,6 +59,105 @@ uintptr_t RunAVX_660F(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step) switch(opcode) { + case 0x10: /* MOVUPD Gx, Ex */ + nextop = F8; + GETEX(0); + GETGX; + GETGY; + memcpy(GX, EX, 16); // unaligned... + if(vex.l) { + GETEY; + memcpy(GY, EY, 16); // unaligned... + } else + GY->u128 = 0; + break; + case 0x11: /* MOVUPD Ex, Gx */ + nextop = F8; + GETEX(0); + GETGX; + memcpy(EX, GX, 16); // unaligned... + if(vex.l) { + GETEY; + GETGY; + memcpy(EY, GY, 16); // unaligned... + } + break; + case 0x12: /* VMOVLPD Gx, Vx, Eq */ + nextop = F8; + GETE8(0); + GETGX; + GETVX; + GETGY; + GX->q[0] = ED->q[0]; + GX->q[1] = VX->q[1]; + GY->u128 = 0; + break; + case 0x13: /* VMOVLPD Eq, Gx */ + nextop = F8; + GETE8(0); + GETGX; + ED->q[0] = GX->q[0]; + break; + + case 0x16: /* VMOVHPD Gx, Vx, Ed */ + nextop = F8; + GETE8(0); + GETGX; + GETVX; + GX->q[1] = ED->q[0]; + GX->q[0] = VX->q[0]; + GETGY; + GY->u128 = 0; + break; + case 0x17: /* VMOVHPD Ed, Gx */ + nextop = F8; + GETE8(0); + GETGX; + ED->q[0] = GX->q[1]; + break; + + case 0x28: /* VMOVAPD 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->u128 = 0; + break; + case 0x29: /* VMOVAPD 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 0x2B: /* MOVNTPD Ex, Gx */ + nextop = F8; + GETEX(0); + GETGX; + EX->q[0] = GX->q[0]; + EX->q[1] = GX->q[1]; + if(vex.l) { + GETGY; + GETEY; + EY->q[0] = GY->q[0]; + EY->q[1] = GY->q[1]; + } + break; + case 0x2F: /* VCOMISD Gx, Ex */ RESET_FLAGS(emu); nextop = F8; @@ -76,6 +175,15 @@ uintptr_t RunAVX_660F(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step) CLEAR_FLAG(F_OF); CLEAR_FLAG(F_AF); CLEAR_FLAG(F_SF); break; + case 0x50: /* VMOVMSKPD Gd, Ex */ + nextop = F8; + GETEX(0); + GETGD; + GD->q[0] = 0; + for(int i=0; i<2; ++i) + GD->dword[0] |= ((EX->q[i]>>63)&1)<<i; + break; + case 0x54: /* VANDPD Gx, Vx, Ex */ nextop = F8; GETEX(0); @@ -207,6 +315,28 @@ uintptr_t RunAVX_660F(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step) GY->u128 = 0; break; + case 0x5D: /* VMINPD Gx, Vx, Ex */ + nextop = F8; + GETEX(0); + GETGX; + GETVX; + GETGY; + for(int i=0; i<2; ++i) + if (isnan(VX->d[i]) || isnan(EX->d[i]) || isgreater(VX->d[i], EX->d[i])) + GX->d[i] = EX->d[i]; + else + GX->d[i] = VX->d[i]; + if(vex.l) { + GETEY; + GETVY; + for(int i=0; i<2; ++i) + if (isnan(VY->d[i]) || isnan(EY->d[i]) || isgreater(VY->d[i], EY->d[i])) + GY->d[i] = EY->d[i]; + else + GY->d[i] = VY->d[i]; + } else + GY->u128 = 0; + break; case 0x5E: /* VDIVPD Gx, Vx, Ex */ nextop = F8; GETEX(0); @@ -239,6 +369,28 @@ uintptr_t RunAVX_660F(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step) } else GY->u128 = 0; break; + case 0x5F: /* VMAXPD Gx, Vx, Ex */ + nextop = F8; + GETEX(0); + GETGX; + GETVX; + GETGY; + for(int i=0; i<2; ++i) + if (isnan(VX->d[i]) || isnan(EX->d[i]) || isgreater(EX->d[i], VX->d[i])) + GX->d[i] = EX->d[i]; + else + GX->d[i] = VX->d[i]; + if(vex.l) { + GETEY; + GETVY; + for(int i=0; i<2; ++i) + if (isnan(VY->d[i]) || isnan(EY->d[i]) || isgreater(EY->d[i], VY->d[i])) + GY->d[i] = EY->d[i]; + else + GY->d[i] = VY->d[i]; + } else + GY->u128 = 0; + break; case 0x64: /* VPCMPGTB Gx,Vx, Ex */ nextop = F8; @@ -751,6 +903,18 @@ uintptr_t RunAVX_660F(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step) GY->u128 = 0; break; + case 0xD6: /* VMOVQ Ex, Gx */ + nextop = F8; + GETEX(0); + GETGX; + EX->q[0] = GX->q[0]; + if(MODREG) { + EX->q[1] = 0; + GETEY; + EY->u128 = 0; + } + break; + case 0xDB: /* VPAND Gx, Vx, Ex */ nextop = F8; GETEX(0); @@ -796,6 +960,19 @@ uintptr_t RunAVX_660F(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step) GX->q[1] = 0; GY->u128 = 0; break; + case 0xE7: /* VMOVNTDQ 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 0xEB: /* VPOR Gx, Vx, Ex */ nextop = F8; diff --git a/src/emu/x64runavx660f38.c b/src/emu/x64runavx660f38.c index b6074146..6f46c659 100644 --- a/src/emu/x64runavx660f38.c +++ b/src/emu/x64runavx660f38.c @@ -191,6 +191,21 @@ uintptr_t RunAVX_660F38(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step) GY->u128 = EX->u128; break; + case 0x2A: /* VMOVNTDQA 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->u128 = 0; + break; + case 0x2C: /*VMASKMOVPS Gx, Vx, Ex */ nextop = F8; GETEX(0); diff --git a/src/emu/x64runavxf20f.c b/src/emu/x64runavxf20f.c index 1b0e6291..a3006a7d 100644 --- a/src/emu/x64runavxf20f.c +++ b/src/emu/x64runavxf20f.c @@ -74,7 +74,7 @@ uintptr_t RunAVX_F20F(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step) GETGY; GY->u128 = 0; break; - case 0x11: /* MOVSD Ex Gx */ + case 0x11: /* VMOVSD Ex Gx */ nextop = F8; GETEX(0); GETGX; @@ -86,6 +86,18 @@ uintptr_t RunAVX_F20F(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step) EY->u128 = 0; } break; + case 0x12: /* VMOVDDUP Gx, Ex */ + nextop = F8; + GETEX(0); + GETGX; + GETGY; + GX->q[1] = GX->q[0] = EX->q[0]; + if(vex.l) { + GETEY; + GY->q[1] = GY->q[0] = EY->q[0]; + } else + GY->u128 = 0; + break; case 0x2A: /* VCVTSI2SD Gx, Vx, Ed */ nextop = F8; @@ -196,6 +208,21 @@ uintptr_t RunAVX_F20F(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step) GY->u128 = 0; break; + case 0x5D: /* VMINSD Gx, Vx, Ex */ + nextop = F8; + GETEX(0); + GETGX; + GETVX; + GETGY; + if (VX->d[0] == 0.0 && EX->d[0] == 0.0) + GX->d[0] = EX->d[0]; + else if (isnan(VX->d[0]) || isnan(EX->d[0]) || isgreater(VX->d[0], EX->d[0])) + GX->d[0] = EX->d[0]; + else + GX->d[0] = VX->d[0]; + GX->q[1] = VX->q[1]; + GY->u128 = 0; + break; case 0x5E: /* VDIVSD Gx, Vx, Ex */ nextop = F8; GETEX(0); @@ -213,6 +240,21 @@ uintptr_t RunAVX_F20F(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step) GX->q[1] = VX->q[1]; GY->u128 = 0; break; + case 0x5F: /* VMAXSD Gx, Vx, Ex */ + nextop = F8; + GETEX(0); + GETGX; + GETVX; + GETGY; + if (VX->d[0] == 0.0 && EX->d[0] == 0.0) + GX->d[0] = EX->d[0]; + else if (isnan(VX->d[0]) || isnan(EX->d[0]) || isgreater(EX->d[0], VX->d[0])) + GX->d[0] = EX->d[0]; + else + GX->d[0] = VX->d[0]; + GX->q[1] = VX->q[1]; + GY->u128 = 0; + break; case 0x7C: /* VHADDPS Gx, Vx, Ex */ nextop = F8; diff --git a/src/emu/x64runavxf30f.c b/src/emu/x64runavxf30f.c index 9afef5a8..8aa1506e 100644 --- a/src/emu/x64runavxf30f.c +++ b/src/emu/x64runavxf30f.c @@ -91,6 +91,35 @@ uintptr_t RunAVX_F30F(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step) EY->q[0] = EY->q[1] = 0; } break; + case 0x12: /* VMOVSLDUP Gx, Ex */ + nextop = F8; + GETEX(0); + GETGX; + GETGY; + GX->ud[1] = GX->ud[0] = EX->ud[0]; + GX->ud[3] = GX->ud[2] = EX->ud[2]; + if(vex.l) { + GETEY; + GY->ud[1] = GY->ud[0] = EY->ud[0]; + GY->ud[3] = GY->ud[2] = EY->ud[2]; + } else + GY->u128 = 0; + break; + + case 0x16: /* MOVSHDUP Gx, Ex */ + nextop = F8; + GETEX(0); + GETGX; + GETGY; + GX->ud[1] = GX->ud[0] = EX->ud[1]; + GX->ud[3] = GX->ud[2] = EX->ud[3]; + if(vex.l) { + GETEY; + GY->ud[1] = GY->ud[0] = EY->ud[1]; + GY->ud[3] = GY->ud[2] = EY->ud[3]; + } else + GY->u128 = 0; + break; case 0x2A: /* VCVTSI2SS Gx, Vx, Ed */ nextop = F8; @@ -250,6 +279,24 @@ uintptr_t RunAVX_F30F(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step) GY->u128 = 0; break; + case 0x5D: /* VMINSS Gx, Vx, Ex */ + nextop = F8; + GETEX(0); + GETGX; + GETVX; + GETGY; + if (VX->f[0] == 0.0 && EX->f[0] == 0.0) + GX->f[0] = EX->f[0]; + else if (isnan(VX->f[0]) || isnan(EX->f[0]) || isgreater(VX->f[0], EX->f[0])) + GX->f[0] = EX->f[0]; + else + GX->f[0] = VX->f[0]; + if(GX!=VX) { + GX->ud[1] = VX->ud[1]; + GX->q[1] = VX->q[1]; + } + GY->u128 = 0; + break; case 0x5E: /* VDIVSS Gx, Vx, Ex */ nextop = F8; GETEX(0); @@ -263,6 +310,24 @@ uintptr_t RunAVX_F30F(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step) } GY->u128 = 0; break; + case 0x5F: /* VMAXSS Gx, Vx, Ex */ + nextop = F8; + GETEX(0); + GETGX; + GETVX; + GETGY; + if (VX->f[0] == 0.0 && EX->f[0] == 0.0) + GX->f[0] = EX->f[0]; + else if (isnan(VX->f[0]) || isnan(EX->f[0]) || isgreater(EX->f[0], VX->f[0])) + GX->f[0] = EX->f[0]; + else + GX->f[0] = VX->f[0]; + if(GX!=VX) { + GX->ud[1] = VX->ud[1]; + GX->q[1] = VX->q[1]; + } + GY->u128 = 0; + break; case 0x6F: // VMOVDQU Gx, Ex nextop = F8; @@ -277,6 +342,15 @@ uintptr_t RunAVX_F30F(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step) GY->q[0] = GY->q[1] = 0; break; + case 0x7E: /* MOVQ Gx, Ex */ + nextop = F8; + GETEX(0); + GETGX; + GX->q[0] = EX->q[0]; + GX->q[1] = 0; + GETGY; + GY->u128 = 0; + break; case 0x7F: /* VMOVDQU Ex, Gx */ nextop = F8; GETEX(0); |