Skip to content

Commit

Permalink
[INTERPRETER] Last batch of avx/avx2 opcode
Browse files Browse the repository at this point in the history
  • Loading branch information
ptitSeb committed May 29, 2024
1 parent f6fe84a commit 22bc687
Show file tree
Hide file tree
Showing 6 changed files with 451 additions and 13 deletions.
73 changes: 70 additions & 3 deletions src/emu/x64runavx0f.c
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,23 @@ uintptr_t RunAVX_0F(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step)
} else
GY->u128 = 0;
break;

case 0x15: /* VUNPCKHPS Gx, Vx, Ex */
nextop = F8;
GETEX(0);
GETGX; GETVX; GETGY;
GX->ud[0] = VX->ud[2];
GX->ud[1] = EX->ud[2];
GX->ud[2] = VX->ud[3];
GX->ud[3] = EX->ud[3];
if(vex.l) {
GETEY; GETVY;
GY->ud[0] = VY->ud[2];
GY->ud[1] = EY->ud[2];
GY->ud[2] = VY->ud[3];
GY->ud[3] = EY->ud[3];
} else
GY->u128 = 0;
break;
case 0x16:
nextop = F8;
GETEX(0);
Expand Down Expand Up @@ -194,6 +210,7 @@ uintptr_t RunAVX_0F(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step)
}
break;

case 0x2E: /* VUCOMISS Gx, Ex */
case 0x2F: /* VCOMISS Gx, Ex */
RESET_FLAGS(emu);
nextop = F8;
Expand Down Expand Up @@ -224,7 +241,19 @@ uintptr_t RunAVX_0F(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step)
GD->dword[0] |= ((EY->ud[i]>>31)&1)<<(i+4);
}
break;

case 0x51: /* VSQRTPS Gx, Ex */
nextop = F8;
GETEX(0);
GETGX; GETGY;
for(int i=0; i<4; ++i)
GX->f[i] = (EX->f[i]<0)?(-NAN):sqrtf(EX->f[i]);
if(vex.l) {
GETEY;
for(int i=0; i<4; ++i)
GY->f[i] = (EY->f[i]<0)?(-NAN):sqrtf(EY->f[i]);
} else
GY->u128 = 0;
break;
case 0x52: /* VRSQRTPS Gx, Ex */
nextop = F8;
GETEX(0);
Expand Down Expand Up @@ -262,7 +291,22 @@ uintptr_t RunAVX_0F(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step)
test->notest = 1;
#endif
break;

case 0x53: /* VRCPPS Gx, Ex */
nextop = F8;
GETEX(0);
GETGX; GETGY;
for(int i=0; i<4; ++i)
GX->f[i] = 1.0f/EX->f[i];
if(vex.l) {
GETEY;
for(int i=0; i<4; ++i)
GY->f[i] = 1.0f/EY->f[i];
} else
GY->u128 = 0;
#ifdef TEST_INTERPRETER
test->notest = 1;
#endif
break;
case 0x54: /* VANDPS Gx, Vx, Ex */
nextop = F8;
GETEX(0);
Expand Down Expand Up @@ -475,6 +519,29 @@ uintptr_t RunAVX_0F(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step)
return 0;
break;

case 0xAE: /* Grp Ed (SSE) */
nextop = F8;
if(MODREG)
return 0;
else
switch((nextop>>3)&7) {
case 2: /* VLDMXCSR Md */
GETED(0);
emu->mxcsr.x32 = ED->dword[0];
#ifndef TEST_INTERPRETER
if(box64_sse_flushto0)
applyFlushTo0(emu);
#endif
break;
case 3: /* VSTMXCSR Md */
GETED(0);
ED->dword[0] = emu->mxcsr.x32;
break;
default:
return 0;
}
break;

case 0xC2: /* VCMPPS Gx, Vx, Ex, Ib */
nextop = F8;
GETEX(1);
Expand Down
87 changes: 85 additions & 2 deletions src/emu/x64runavx660f.c
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,32 @@ uintptr_t RunAVX_660F(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step)
GETGX;
ED->q[0] = GX->q[0];
break;

case 0x14: /* VUNPCKLPD Gx, Vx, Ex */
nextop = F8;
GETEX(0);
GETGX; GETVX; GETGY;
GX->q[1] = EX->q[0];
GX->q[0] = VX->q[0];
if(vex.l) {
GETEY; GETVY;
GY->q[1] = EY->q[0];
GY->q[0] = VY->q[0];
} else
GY->u128 = 0;
break;
case 0x15: /* VUNPCKHPD Gx, Vx, Ex */
nextop = F8;
GETEX(0);
GETGX; GETVX; GETGY;
GX->q[0] = VX->q[1];
GX->q[1] = EX->q[1];
if(vex.l) {
GETEY; GETVY;
GY->q[0] = VY->q[1];
GY->q[1] = EY->q[1];
} else
GY->u128 = 0;
break;
case 0x16: /* VMOVHPD Gx, Vx, Ed */
nextop = F8;
GETE8(0);
Expand Down Expand Up @@ -159,6 +184,7 @@ uintptr_t RunAVX_660F(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step)
}
break;

case 0x2E: /* VUCOMISD Gx, Ex */
case 0x2F: /* VCOMISD Gx, Ex */
RESET_FLAGS(emu);
nextop = F8;
Expand All @@ -184,6 +210,31 @@ uintptr_t RunAVX_660F(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step)
for(int i=0; i<2; ++i)
GD->dword[0] |= ((EX->q[i]>>63)&1)<<i;
break;
case 0x51: /* VSQRTPD Gx, Ex */
nextop = F8;
GETEX(0);
GETGX; GETGY;
for (int i=0; i<2; ++i) {
#ifndef NOALIGN
if(EX->d[i]<0.0) // on x86, default nan are negative
GX->d[i] = -NAN; // but input NAN are not touched (so sqrt(+nan) -> +nan)
else
#endif
GX->d[i] = sqrt(EX->d[i]);
}
if(vex.l) {
GETEY;
for (int i=0; i<2; ++i) {
#ifndef NOALIGN
if(EY->d[i]<0.0)
GY->d[i] = -NAN;
else
#endif
GY->d[i] = sqrt(EY->d[i]);
}
} else
GY->u128 = 0;
break;

case 0x54: /* VANDPD Gx, Vx, Ex */
nextop = F8;
Expand Down Expand Up @@ -373,7 +424,23 @@ uintptr_t RunAVX_660F(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step)
} else
GY->u128 = 0;
break;

case 0x5C: /* VSUBPD Gx, Vx, Ex */
nextop = F8;
GETEX(0);
GETGX;
GETVX;
GX->d[0] = VX->d[0] - EX->d[0];
GX->d[1] = VX->d[1] - EX->d[1];
GETGY;
if(vex.l) {
GETEY;
GETVY;
GY->d[0] = VY->d[0] - EY->d[0];
GY->d[1] = VY->d[1] - EY->d[1];
} else {
GY->u128 = 0;
}
break;
case 0x5D: /* VMINPD Gx, Vx, Ex */
nextop = F8;
GETEX(0);
Expand Down Expand Up @@ -1232,6 +1299,22 @@ uintptr_t RunAVX_660F(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step)
tmp8u = F8;
GD->q[0] = EX->uw[tmp8u&7]; // 16bits extract, 0 extended
break;
case 0xC6: /* VSHUFPD Gx, Vx, Ex, Ib */
nextop = F8;
GETEX(1);
GETGX; GETVX; GETGY;
tmp8u = F8;
eax1.q[0] = VX->q[tmp8u&1];
eax1.q[1] = EX->q[(tmp8u>>1)&1];
GX->u128 = eax1.u128;
if(vex.l) {
GETEY; GETVY;
eax1.q[0] = VY->q[(tmp8u>>2)&1];
eax1.q[1] = EY->q[(tmp8u>>3)&1];
GY->u128 = eax1.u128;
} else
GY->u128 = 0;
break;

case 0xD0: /* VADDSUBPD Gx, Vx, Ex */
nextop = F8;
Expand Down
52 changes: 52 additions & 0 deletions src/emu/x64runavx660f38.c
Original file line number Diff line number Diff line change
Expand Up @@ -468,6 +468,58 @@ uintptr_t RunAVX_660F38(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step)
} else
GY->u128 = 0;
break;
case 0x0E: /* VTESTPS Gx, Ex */
nextop = F8;
GETEX(0);
GETGX;
if(vex.l) {GETEY; GETGY;}
// ZF
u8 = 0;
for(int i=0; i<4 && !u8; ++i)
u8 |= ((EX->ud[i]>>31)&(GX->ud[i]>>31));
if(vex.l && !u8)
for(int i=0; i<4 && !u8; ++i)
u8 |= ((EY->ud[i]>>31)&(GY->ud[i]>>31));
CONDITIONAL_SET_FLAG(!u8, F_ZF);
// CF
u8 = 0;
for(int i=0; i<4 && !u8; ++i)
u8 |= ((EX->ud[i]>>31)&((~GX->ud[i])>>31));
if(vex.l && !u8)
for(int i=0; i<4 && !u8; ++i)
u8 |= ((EY->ud[i]>>31)&((~GY->ud[i])>>31));
CONDITIONAL_SET_FLAG(!u8, F_CF);
CLEAR_FLAG(F_AF);
CLEAR_FLAG(F_OF);
CLEAR_FLAG(F_SF);
CLEAR_FLAG(F_PF);
break;
case 0x0F: /* VTESTPD Gx, Ex */
nextop = F8;
GETEX(0);
GETGX;
if(vex.l) {GETEY; GETGY;}
// ZF
u8 = 0;
for(int i=0; i<2 && !u8; ++i)
u8 |= ((EX->q[i]>>63)&(GX->q[i]>>63));
if(vex.l && !u8)
for(int i=0; i<2 && !u8; ++i)
u8 |= ((EY->q[i]>>63)&(GY->q[i]>>63));
CONDITIONAL_SET_FLAG(!u8, F_ZF);
// CF
u8 = 0;
for(int i=0; i<2 && !u8; ++i)
u8 |= ((EX->q[i]>>63)&((~GX->q[i])>>63));
if(vex.l && !u8)
for(int i=0; i<2 && !u8; ++i)
u8 |= ((EY->q[i]>>63)&((~GY->q[i])>>63));
CONDITIONAL_SET_FLAG(!u8, F_CF);
CLEAR_FLAG(F_AF);
CLEAR_FLAG(F_OF);
CLEAR_FLAG(F_SF);
CLEAR_FLAG(F_PF);
break;

case 0x16: /* VPERMPS Gx, Vx, Ex */
// same code as 0x36
Expand Down
Loading

0 comments on commit 22bc687

Please sign in to comment.