From 5bd81b7f1cc9bb273b4a5231822a75693865b676 Mon Sep 17 00:00:00 2001 From: flobernd Date: Thu, 22 Jun 2017 01:38:41 +0200 Subject: [PATCH] Fixed sign-extension of displacement values --- include/Zydis/InstructionInfo.h | 3 + .../Zydis/Internal/InstructionDefinitions.inc | 48 +++++------ include/Zydis/Internal/InstructionTable.h | 6 +- src/Decoder.c | 80 ++++++++++++++++--- 4 files changed, 101 insertions(+), 36 deletions(-) diff --git a/include/Zydis/InstructionInfo.h b/include/Zydis/InstructionInfo.h index c395e5f..1417fe6 100644 --- a/include/Zydis/InstructionInfo.h +++ b/include/Zydis/InstructionInfo.h @@ -983,6 +983,9 @@ typedef struct ZydisInstructionInfo_ * @brief The AVX rounding-mode. */ ZydisRoundingMode roundingMode; + + ZydisBool hasSAE; + ZydisBool hasEvictionHint; } avx; /** * @brief Extended info about different instruction-parts like ModRM, SIB or diff --git a/include/Zydis/Internal/InstructionDefinitions.inc b/include/Zydis/Internal/InstructionDefinitions.inc index b155011..3f3f69e 100644 --- a/include/Zydis/Internal/InstructionDefinitions.inc +++ b/include/Zydis/Internal/InstructionDefinitions.inc @@ -6542,49 +6542,49 @@ const ZydisInstructionDefinitionMVEX instructionDefinitionsMVEX[] = /*001E*/ { ZYDIS_MNEMONIC_VBROADCASTSS, 3, 0x0894, 0x00, ZYDIS_MVEX_FUNC_FLOAT_UCONV_LOAD_32, ZYDIS_MASK_POLICY_ALLOWED }, /*001F*/ { ZYDIS_MNEMONIC_VCMPPD, 5, 0x03A0, 0x00, ZYDIS_MVEX_FUNC_FLOAT_UCONV_64, ZYDIS_MASK_POLICY_ALLOWED }, /*0020*/ { ZYDIS_MNEMONIC_VCMPPD, 5, 0x03A5, 0x00, ZYDIS_MVEX_FUNC_REG_SWIZZLE_64, ZYDIS_MASK_POLICY_ALLOWED }, - /*0021*/ { ZYDIS_MNEMONIC_VCMPPD, 5, 0x03A5, 0x00, ZYDIS_MVEX_FUNC_RC, ZYDIS_MASK_POLICY_ALLOWED }, + /*0021*/ { ZYDIS_MNEMONIC_VCMPPD, 5, 0x03A5, 0x00, ZYDIS_MVEX_FUNC_SAE, ZYDIS_MASK_POLICY_ALLOWED }, /*0022*/ { ZYDIS_MNEMONIC_VCMPPS, 5, 0x03AA, 0x00, ZYDIS_MVEX_FUNC_FLOAT_UCONV_32, ZYDIS_MASK_POLICY_ALLOWED }, /*0023*/ { ZYDIS_MNEMONIC_VCMPPS, 5, 0x03AF, 0x00, ZYDIS_MVEX_FUNC_REG_SWIZZLE_64, ZYDIS_MASK_POLICY_ALLOWED }, - /*0024*/ { ZYDIS_MNEMONIC_VCMPPS, 5, 0x03AF, 0x00, ZYDIS_MVEX_FUNC_RC, ZYDIS_MASK_POLICY_ALLOWED }, + /*0024*/ { ZYDIS_MNEMONIC_VCMPPS, 5, 0x03AF, 0x00, ZYDIS_MVEX_FUNC_SAE, ZYDIS_MASK_POLICY_ALLOWED }, /*0025*/ { ZYDIS_MNEMONIC_VCVTDQ2PD, 3, 0x08B8, 0x00, ZYDIS_MVEX_FUNC_INVALID, ZYDIS_MASK_POLICY_ALLOWED }, /*0026*/ { ZYDIS_MNEMONIC_VCVTDQ2PD, 3, 0x08BC, 0x00, ZYDIS_MVEX_FUNC_REG_SWIZZLE_32, ZYDIS_MASK_POLICY_ALLOWED }, /*0027*/ { ZYDIS_MNEMONIC_VCVTDQ2PD, 3, 0x08BC, 0x00, ZYDIS_MVEX_FUNC_INVALID, ZYDIS_MASK_POLICY_ALLOWED }, /*0028*/ { ZYDIS_MNEMONIC_VCVTFXPNTDQ2PS, 4, 0x0894, 0x00, ZYDIS_MVEX_FUNC_INT_UCONV_32, ZYDIS_MASK_POLICY_ALLOWED }, /*0029*/ { ZYDIS_MNEMONIC_VCVTFXPNTDQ2PS, 4, 0x0898, 0x00, ZYDIS_MVEX_FUNC_REG_SWIZZLE_32, ZYDIS_MASK_POLICY_ALLOWED }, - /*002A*/ { ZYDIS_MNEMONIC_VCVTFXPNTDQ2PS, 4, 0x0898, 0x00, ZYDIS_MVEX_FUNC_RC, ZYDIS_MASK_POLICY_ALLOWED }, + /*002A*/ { ZYDIS_MNEMONIC_VCVTFXPNTDQ2PS, 4, 0x0898, 0x00, ZYDIS_MVEX_FUNC_SAE, ZYDIS_MASK_POLICY_ALLOWED }, /*002B*/ { ZYDIS_MNEMONIC_VCVTFXPNTPD2DQ, 4, 0x089C, 0x00, ZYDIS_MVEX_FUNC_FLOAT_UCONV_64, ZYDIS_MASK_POLICY_ALLOWED }, /*002C*/ { ZYDIS_MNEMONIC_VCVTFXPNTPD2DQ, 4, 0x08A0, 0x00, ZYDIS_MVEX_FUNC_REG_SWIZZLE_64, ZYDIS_MASK_POLICY_ALLOWED }, - /*002D*/ { ZYDIS_MNEMONIC_VCVTFXPNTPD2DQ, 4, 0x08A0, 0x00, ZYDIS_MVEX_FUNC_RC, ZYDIS_MASK_POLICY_ALLOWED }, + /*002D*/ { ZYDIS_MNEMONIC_VCVTFXPNTPD2DQ, 4, 0x08A0, 0x00, ZYDIS_MVEX_FUNC_SAE, ZYDIS_MASK_POLICY_ALLOWED }, /*002E*/ { ZYDIS_MNEMONIC_VCVTFXPNTPD2UDQ, 4, 0x08A4, 0x00, ZYDIS_MVEX_FUNC_FLOAT_UCONV_64, ZYDIS_MASK_POLICY_ALLOWED }, - /*002F*/ { ZYDIS_MNEMONIC_VCVTFXPNTPD2UDQ, 4, 0x08A8, 0x00, ZYDIS_MVEX_FUNC_RC, ZYDIS_MASK_POLICY_ALLOWED }, + /*002F*/ { ZYDIS_MNEMONIC_VCVTFXPNTPD2UDQ, 4, 0x08A8, 0x00, ZYDIS_MVEX_FUNC_SAE, ZYDIS_MASK_POLICY_ALLOWED }, /*0030*/ { ZYDIS_MNEMONIC_VCVTFXPNTPD2UDQ, 4, 0x08A8, 0x00, ZYDIS_MVEX_FUNC_REG_SWIZZLE_64, ZYDIS_MASK_POLICY_ALLOWED }, /*0031*/ { ZYDIS_MNEMONIC_VCVTFXPNTPS2DQ, 4, 0x089C, 0x00, ZYDIS_MVEX_FUNC_FLOAT_UCONV_32, ZYDIS_MASK_POLICY_ALLOWED }, - /*0032*/ { ZYDIS_MNEMONIC_VCVTFXPNTPS2DQ, 4, 0x08AC, 0x00, ZYDIS_MVEX_FUNC_RC, ZYDIS_MASK_POLICY_ALLOWED }, + /*0032*/ { ZYDIS_MNEMONIC_VCVTFXPNTPS2DQ, 4, 0x08AC, 0x00, ZYDIS_MVEX_FUNC_SAE, ZYDIS_MASK_POLICY_ALLOWED }, /*0033*/ { ZYDIS_MNEMONIC_VCVTFXPNTPS2DQ, 4, 0x08AC, 0x00, ZYDIS_MVEX_FUNC_REG_SWIZZLE_32, ZYDIS_MASK_POLICY_ALLOWED }, /*0034*/ { ZYDIS_MNEMONIC_VCVTFXPNTPS2UDQ, 4, 0x08A4, 0x00, ZYDIS_MVEX_FUNC_FLOAT_UCONV_32, ZYDIS_MASK_POLICY_ALLOWED }, - /*0035*/ { ZYDIS_MNEMONIC_VCVTFXPNTPS2UDQ, 4, 0x08B0, 0x00, ZYDIS_MVEX_FUNC_RC, ZYDIS_MASK_POLICY_ALLOWED }, + /*0035*/ { ZYDIS_MNEMONIC_VCVTFXPNTPS2UDQ, 4, 0x08B0, 0x00, ZYDIS_MVEX_FUNC_SAE, ZYDIS_MASK_POLICY_ALLOWED }, /*0036*/ { ZYDIS_MNEMONIC_VCVTFXPNTPS2UDQ, 4, 0x08B0, 0x00, ZYDIS_MVEX_FUNC_REG_SWIZZLE_32, ZYDIS_MASK_POLICY_ALLOWED }, /*0037*/ { ZYDIS_MNEMONIC_VCVTFXPNTUDQ2PS, 4, 0x0894, 0x00, ZYDIS_MVEX_FUNC_INT_UCONV_32, ZYDIS_MASK_POLICY_ALLOWED }, /*0038*/ { ZYDIS_MNEMONIC_VCVTFXPNTUDQ2PS, 4, 0x08B4, 0x00, ZYDIS_MVEX_FUNC_REG_SWIZZLE_32, ZYDIS_MASK_POLICY_ALLOWED }, - /*0039*/ { ZYDIS_MNEMONIC_VCVTFXPNTUDQ2PS, 4, 0x08B4, 0x00, ZYDIS_MVEX_FUNC_RC, ZYDIS_MASK_POLICY_ALLOWED }, + /*0039*/ { ZYDIS_MNEMONIC_VCVTFXPNTUDQ2PS, 4, 0x08B4, 0x00, ZYDIS_MVEX_FUNC_SAE, ZYDIS_MASK_POLICY_ALLOWED }, /*003A*/ { ZYDIS_MNEMONIC_VCVTPD2PS, 3, 0x0894, 0x00, ZYDIS_MVEX_FUNC_FLOAT_UCONV_64, ZYDIS_MASK_POLICY_ALLOWED }, /*003B*/ { ZYDIS_MNEMONIC_VCVTPD2PS, 3, 0x11B7, 0x00, ZYDIS_MVEX_FUNC_REG_SWIZZLE_64, ZYDIS_MASK_POLICY_ALLOWED }, /*003C*/ { ZYDIS_MNEMONIC_VCVTPD2PS, 3, 0x11B7, 0x00, ZYDIS_MVEX_FUNC_RC, ZYDIS_MASK_POLICY_ALLOWED }, /*003D*/ { ZYDIS_MNEMONIC_VCVTPS2PD, 3, 0x08B8, 0x00, ZYDIS_MVEX_FUNC_INVALID, ZYDIS_MASK_POLICY_ALLOWED }, /*003E*/ { ZYDIS_MNEMONIC_VCVTPS2PD, 3, 0x11BA, 0x00, ZYDIS_MVEX_FUNC_REG_SWIZZLE_32, ZYDIS_MASK_POLICY_ALLOWED }, - /*003F*/ { ZYDIS_MNEMONIC_VCVTPS2PD, 3, 0x11BA, 0x00, ZYDIS_MVEX_FUNC_RC, ZYDIS_MASK_POLICY_ALLOWED }, + /*003F*/ { ZYDIS_MNEMONIC_VCVTPS2PD, 3, 0x11BA, 0x00, ZYDIS_MVEX_FUNC_SAE, ZYDIS_MASK_POLICY_ALLOWED }, /*0040*/ { ZYDIS_MNEMONIC_VCVTUDQ2PD, 3, 0x08B8, 0x00, ZYDIS_MVEX_FUNC_INVALID, ZYDIS_MASK_POLICY_ALLOWED }, /*0041*/ { ZYDIS_MNEMONIC_VCVTUDQ2PD, 3, 0x08BC, 0x00, ZYDIS_MVEX_FUNC_REG_SWIZZLE_32, ZYDIS_MASK_POLICY_ALLOWED }, /*0042*/ { ZYDIS_MNEMONIC_VCVTUDQ2PD, 3, 0x08BC, 0x00, ZYDIS_MVEX_FUNC_INVALID, ZYDIS_MASK_POLICY_ALLOWED }, /*0043*/ { ZYDIS_MNEMONIC_VEXP223PS, 3, 0x08CC, 0x00, ZYDIS_MVEX_FUNC_INVALID, ZYDIS_MASK_POLICY_ALLOWED }, - /*0044*/ { ZYDIS_MNEMONIC_VEXP223PS, 3, 0x08D0, 0x00, ZYDIS_MVEX_FUNC_RC, ZYDIS_MASK_POLICY_ALLOWED }, + /*0044*/ { ZYDIS_MNEMONIC_VEXP223PS, 3, 0x08D0, 0x00, ZYDIS_MVEX_FUNC_SAE, ZYDIS_MASK_POLICY_ALLOWED }, /*0045*/ { ZYDIS_MNEMONIC_VEXP223PS, 3, 0x08D0, 0x00, ZYDIS_MVEX_FUNC_INVALID, ZYDIS_MASK_POLICY_ALLOWED }, /*0046*/ { ZYDIS_MNEMONIC_VFIXUPNANPD, 4, 0x0880, 0x00, ZYDIS_MVEX_FUNC_INT_UCONV_64, ZYDIS_MASK_POLICY_ALLOWED }, /*0047*/ { ZYDIS_MNEMONIC_VFIXUPNANPD, 4, 0x0884, 0x00, ZYDIS_MVEX_FUNC_REG_SWIZZLE_64, ZYDIS_MASK_POLICY_ALLOWED }, - /*0048*/ { ZYDIS_MNEMONIC_VFIXUPNANPD, 4, 0x0884, 0x00, ZYDIS_MVEX_FUNC_RC, ZYDIS_MASK_POLICY_ALLOWED }, + /*0048*/ { ZYDIS_MNEMONIC_VFIXUPNANPD, 4, 0x0884, 0x00, ZYDIS_MVEX_FUNC_SAE, ZYDIS_MASK_POLICY_ALLOWED }, /*0049*/ { ZYDIS_MNEMONIC_VFIXUPNANPS, 4, 0x0888, 0x00, ZYDIS_MVEX_FUNC_INT_UCONV_32, ZYDIS_MASK_POLICY_ALLOWED }, /*004A*/ { ZYDIS_MNEMONIC_VFIXUPNANPS, 4, 0x039B, 0x00, ZYDIS_MVEX_FUNC_REG_SWIZZLE_32, ZYDIS_MASK_POLICY_ALLOWED }, - /*004B*/ { ZYDIS_MNEMONIC_VFIXUPNANPS, 4, 0x039B, 0x00, ZYDIS_MVEX_FUNC_RC, ZYDIS_MASK_POLICY_ALLOWED }, + /*004B*/ { ZYDIS_MNEMONIC_VFIXUPNANPS, 4, 0x039B, 0x00, ZYDIS_MVEX_FUNC_SAE, ZYDIS_MASK_POLICY_ALLOWED }, /*004C*/ { ZYDIS_MNEMONIC_VFMADD132PD, 4, 0x0880, 0x00, ZYDIS_MVEX_FUNC_FLOAT_UCONV_64, ZYDIS_MASK_POLICY_ALLOWED }, /*004D*/ { ZYDIS_MNEMONIC_VFMADD132PD, 4, 0x0884, 0x00, ZYDIS_MVEX_FUNC_REG_SWIZZLE_64, ZYDIS_MASK_POLICY_ALLOWED }, /*004E*/ { ZYDIS_MNEMONIC_VFMADD132PD, 4, 0x0884, 0x00, ZYDIS_MVEX_FUNC_RC, ZYDIS_MASK_POLICY_ALLOWED }, @@ -6668,28 +6668,28 @@ const ZydisInstructionDefinitionMVEX instructionDefinitionsMVEX[] = /*009C*/ { ZYDIS_MNEMONIC_VGATHERPF1DPS, 2, 0x16C8, 0x00, ZYDIS_MVEX_FUNC_FLOAT_UCONV_LOAD_32, ZYDIS_MASK_POLICY_ALLOWED }, /*009D*/ { ZYDIS_MNEMONIC_VGETEXPPD, 3, 0x08B8, 0x00, ZYDIS_MVEX_FUNC_FLOAT_UCONV_64, ZYDIS_MASK_POLICY_ALLOWED }, /*009E*/ { ZYDIS_MNEMONIC_VGETEXPPD, 3, 0x08BC, 0x00, ZYDIS_MVEX_FUNC_REG_SWIZZLE_64, ZYDIS_MASK_POLICY_ALLOWED }, - /*009F*/ { ZYDIS_MNEMONIC_VGETEXPPD, 3, 0x08BC, 0x00, ZYDIS_MVEX_FUNC_RC, ZYDIS_MASK_POLICY_ALLOWED }, + /*009F*/ { ZYDIS_MNEMONIC_VGETEXPPD, 3, 0x08BC, 0x00, ZYDIS_MVEX_FUNC_SAE, ZYDIS_MASK_POLICY_ALLOWED }, /*00A0*/ { ZYDIS_MNEMONIC_VGETEXPPS, 3, 0x08B8, 0x00, ZYDIS_MVEX_FUNC_FLOAT_UCONV_32, ZYDIS_MASK_POLICY_ALLOWED }, /*00A1*/ { ZYDIS_MNEMONIC_VGETEXPPS, 3, 0x11BA, 0x00, ZYDIS_MVEX_FUNC_REG_SWIZZLE_32, ZYDIS_MASK_POLICY_ALLOWED }, - /*00A2*/ { ZYDIS_MNEMONIC_VGETEXPPS, 3, 0x11BA, 0x00, ZYDIS_MVEX_FUNC_RC, ZYDIS_MASK_POLICY_ALLOWED }, + /*00A2*/ { ZYDIS_MNEMONIC_VGETEXPPS, 3, 0x11BA, 0x00, ZYDIS_MVEX_FUNC_SAE, ZYDIS_MASK_POLICY_ALLOWED }, /*00A3*/ { ZYDIS_MNEMONIC_VGETMANTPD, 4, 0x08B8, 0x00, ZYDIS_MVEX_FUNC_FLOAT_UCONV_64, ZYDIS_MASK_POLICY_ALLOWED }, - /*00A4*/ { ZYDIS_MNEMONIC_VGETMANTPD, 4, 0x08BC, 0x00, ZYDIS_MVEX_FUNC_RC, ZYDIS_MASK_POLICY_ALLOWED }, + /*00A4*/ { ZYDIS_MNEMONIC_VGETMANTPD, 4, 0x08BC, 0x00, ZYDIS_MVEX_FUNC_SAE, ZYDIS_MASK_POLICY_ALLOWED }, /*00A5*/ { ZYDIS_MNEMONIC_VGETMANTPD, 4, 0x08BC, 0x00, ZYDIS_MVEX_FUNC_REG_SWIZZLE_64, ZYDIS_MASK_POLICY_ALLOWED }, /*00A6*/ { ZYDIS_MNEMONIC_VGETMANTPS, 4, 0x0894, 0x00, ZYDIS_MVEX_FUNC_FLOAT_UCONV_32, ZYDIS_MASK_POLICY_ALLOWED }, - /*00A7*/ { ZYDIS_MNEMONIC_VGETMANTPS, 4, 0x08C0, 0x00, ZYDIS_MVEX_FUNC_RC, ZYDIS_MASK_POLICY_ALLOWED }, + /*00A7*/ { ZYDIS_MNEMONIC_VGETMANTPS, 4, 0x08C0, 0x00, ZYDIS_MVEX_FUNC_SAE, ZYDIS_MASK_POLICY_ALLOWED }, /*00A8*/ { ZYDIS_MNEMONIC_VGETMANTPS, 4, 0x08C0, 0x00, ZYDIS_MVEX_FUNC_REG_SWIZZLE_32, ZYDIS_MASK_POLICY_ALLOWED }, /*00A9*/ { ZYDIS_MNEMONIC_VGMAXABSPS, 4, 0x0888, 0x00, ZYDIS_MVEX_FUNC_FLOAT_UCONV_32, ZYDIS_MASK_POLICY_ALLOWED }, /*00AA*/ { ZYDIS_MNEMONIC_VGMAXABSPS, 4, 0x039B, 0x00, ZYDIS_MVEX_FUNC_REG_SWIZZLE_32, ZYDIS_MASK_POLICY_ALLOWED }, - /*00AB*/ { ZYDIS_MNEMONIC_VGMAXABSPS, 4, 0x039B, 0x00, ZYDIS_MVEX_FUNC_RC, ZYDIS_MASK_POLICY_ALLOWED }, + /*00AB*/ { ZYDIS_MNEMONIC_VGMAXABSPS, 4, 0x039B, 0x00, ZYDIS_MVEX_FUNC_SAE, ZYDIS_MASK_POLICY_ALLOWED }, /*00AC*/ { ZYDIS_MNEMONIC_VGMAXPD, 4, 0x0880, 0x00, ZYDIS_MVEX_FUNC_FLOAT_UCONV_64, ZYDIS_MASK_POLICY_ALLOWED }, /*00AD*/ { ZYDIS_MNEMONIC_VGMAXPD, 4, 0x0884, 0x00, ZYDIS_MVEX_FUNC_REG_SWIZZLE_64, ZYDIS_MASK_POLICY_ALLOWED }, - /*00AE*/ { ZYDIS_MNEMONIC_VGMAXPD, 4, 0x0884, 0x00, ZYDIS_MVEX_FUNC_RC, ZYDIS_MASK_POLICY_ALLOWED }, + /*00AE*/ { ZYDIS_MNEMONIC_VGMAXPD, 4, 0x0884, 0x00, ZYDIS_MVEX_FUNC_SAE, ZYDIS_MASK_POLICY_ALLOWED }, /*00AF*/ { ZYDIS_MNEMONIC_VGMAXPS, 4, 0x0888, 0x00, ZYDIS_MVEX_FUNC_FLOAT_UCONV_32, ZYDIS_MASK_POLICY_ALLOWED }, /*00B0*/ { ZYDIS_MNEMONIC_VGMAXPS, 4, 0x039B, 0x00, ZYDIS_MVEX_FUNC_REG_SWIZZLE_32, ZYDIS_MASK_POLICY_ALLOWED }, /*00B1*/ { ZYDIS_MNEMONIC_VGMAXPS, 4, 0x039B, 0x00, ZYDIS_MVEX_FUNC_RC, ZYDIS_MASK_POLICY_ALLOWED }, /*00B2*/ { ZYDIS_MNEMONIC_VGMINPD, 4, 0x0880, 0x00, ZYDIS_MVEX_FUNC_FLOAT_UCONV_64, ZYDIS_MASK_POLICY_ALLOWED }, /*00B3*/ { ZYDIS_MNEMONIC_VGMINPD, 4, 0x0884, 0x00, ZYDIS_MVEX_FUNC_REG_SWIZZLE_64, ZYDIS_MASK_POLICY_ALLOWED }, - /*00B4*/ { ZYDIS_MNEMONIC_VGMINPD, 4, 0x0884, 0x00, ZYDIS_MVEX_FUNC_RC, ZYDIS_MASK_POLICY_ALLOWED }, + /*00B4*/ { ZYDIS_MNEMONIC_VGMINPD, 4, 0x0884, 0x00, ZYDIS_MVEX_FUNC_SAE, ZYDIS_MASK_POLICY_ALLOWED }, /*00B5*/ { ZYDIS_MNEMONIC_VGMINPS, 4, 0x0888, 0x00, ZYDIS_MVEX_FUNC_FLOAT_UCONV_32, ZYDIS_MASK_POLICY_ALLOWED }, /*00B6*/ { ZYDIS_MNEMONIC_VGMINPS, 4, 0x039B, 0x00, ZYDIS_MVEX_FUNC_REG_SWIZZLE_32, ZYDIS_MASK_POLICY_ALLOWED }, /*00B7*/ { ZYDIS_MNEMONIC_VGMINPS, 4, 0x039B, 0x00, ZYDIS_MVEX_FUNC_RC, ZYDIS_MASK_POLICY_ALLOWED }, @@ -6702,7 +6702,7 @@ const ZydisInstructionDefinitionMVEX instructionDefinitionsMVEX[] = /*00BE*/ { ZYDIS_MNEMONIC_VLOADUNPACKLPS, 3, 0x0894, 0x00, ZYDIS_MVEX_FUNC_FLOAT_UCONV_LOAD_32, ZYDIS_MASK_POLICY_ALLOWED }, /*00BF*/ { ZYDIS_MNEMONIC_VLOADUNPACKLQ, 3, 0x11B4, 0x00, ZYDIS_MVEX_FUNC_INT_UCONV_LOAD_64, ZYDIS_MASK_POLICY_ALLOWED }, /*00C0*/ { ZYDIS_MNEMONIC_VLOG2PS, 3, 0x08CC, 0x00, ZYDIS_MVEX_FUNC_INVALID, ZYDIS_MASK_POLICY_ALLOWED }, - /*00C1*/ { ZYDIS_MNEMONIC_VLOG2PS, 3, 0x08D0, 0x00, ZYDIS_MVEX_FUNC_RC, ZYDIS_MASK_POLICY_ALLOWED }, + /*00C1*/ { ZYDIS_MNEMONIC_VLOG2PS, 3, 0x08D0, 0x00, ZYDIS_MVEX_FUNC_SAE, ZYDIS_MASK_POLICY_ALLOWED }, /*00C2*/ { ZYDIS_MNEMONIC_VLOG2PS, 3, 0x08D0, 0x00, ZYDIS_MVEX_FUNC_INVALID, ZYDIS_MASK_POLICY_ALLOWED }, /*00C3*/ { ZYDIS_MNEMONIC_VMOVAPD, 3, 0x08B8, 0x00, ZYDIS_MVEX_FUNC_FLOAT_UCONV_LOAD_64, ZYDIS_MASK_POLICY_ALLOWED }, /*00C4*/ { ZYDIS_MNEMONIC_VMOVAPD, 3, 0x08BC, 0x00, ZYDIS_MVEX_FUNC_REG_SWIZZLE_64, ZYDIS_MASK_POLICY_ALLOWED }, @@ -6884,16 +6884,16 @@ const ZydisInstructionDefinitionMVEX instructionDefinitionsMVEX[] = /*0174*/ { ZYDIS_MNEMONIC_VPXORQ, 4, 0x0884, 0x00, ZYDIS_MVEX_FUNC_REG_SWIZZLE_64, ZYDIS_MASK_POLICY_ALLOWED }, /*0175*/ { ZYDIS_MNEMONIC_VPXORQ, 4, 0x0884, 0x00, ZYDIS_MVEX_FUNC_INVALID, ZYDIS_MASK_POLICY_ALLOWED }, /*0176*/ { ZYDIS_MNEMONIC_VRCP23PS, 3, 0x08CC, 0x00, ZYDIS_MVEX_FUNC_INVALID, ZYDIS_MASK_POLICY_ALLOWED }, - /*0177*/ { ZYDIS_MNEMONIC_VRCP23PS, 3, 0x08D0, 0x00, ZYDIS_MVEX_FUNC_RC, ZYDIS_MASK_POLICY_ALLOWED }, + /*0177*/ { ZYDIS_MNEMONIC_VRCP23PS, 3, 0x08D0, 0x00, ZYDIS_MVEX_FUNC_SAE, ZYDIS_MASK_POLICY_ALLOWED }, /*0178*/ { ZYDIS_MNEMONIC_VRCP23PS, 3, 0x08D0, 0x00, ZYDIS_MVEX_FUNC_INVALID, ZYDIS_MASK_POLICY_ALLOWED }, /*0179*/ { ZYDIS_MNEMONIC_VRNDFXPNTPD, 4, 0x08B8, 0x00, ZYDIS_MVEX_FUNC_FLOAT_UCONV_64, ZYDIS_MASK_POLICY_ALLOWED }, - /*017A*/ { ZYDIS_MNEMONIC_VRNDFXPNTPD, 4, 0x08BC, 0x00, ZYDIS_MVEX_FUNC_RC, ZYDIS_MASK_POLICY_ALLOWED }, + /*017A*/ { ZYDIS_MNEMONIC_VRNDFXPNTPD, 4, 0x08BC, 0x00, ZYDIS_MVEX_FUNC_SAE, ZYDIS_MASK_POLICY_ALLOWED }, /*017B*/ { ZYDIS_MNEMONIC_VRNDFXPNTPD, 4, 0x08BC, 0x00, ZYDIS_MVEX_FUNC_REG_SWIZZLE_64, ZYDIS_MASK_POLICY_ALLOWED }, /*017C*/ { ZYDIS_MNEMONIC_VRNDFXPNTPS, 4, 0x0894, 0x00, ZYDIS_MVEX_FUNC_FLOAT_UCONV_32, ZYDIS_MASK_POLICY_ALLOWED }, - /*017D*/ { ZYDIS_MNEMONIC_VRNDFXPNTPS, 4, 0x08C0, 0x00, ZYDIS_MVEX_FUNC_RC, ZYDIS_MASK_POLICY_ALLOWED }, + /*017D*/ { ZYDIS_MNEMONIC_VRNDFXPNTPS, 4, 0x08C0, 0x00, ZYDIS_MVEX_FUNC_SAE, ZYDIS_MASK_POLICY_ALLOWED }, /*017E*/ { ZYDIS_MNEMONIC_VRNDFXPNTPS, 4, 0x08C0, 0x00, ZYDIS_MVEX_FUNC_REG_SWIZZLE_32, ZYDIS_MASK_POLICY_ALLOWED }, /*017F*/ { ZYDIS_MNEMONIC_VRSQRT23PS, 3, 0x08CC, 0x00, ZYDIS_MVEX_FUNC_INVALID, ZYDIS_MASK_POLICY_ALLOWED }, - /*0180*/ { ZYDIS_MNEMONIC_VRSQRT23PS, 3, 0x08D0, 0x00, ZYDIS_MVEX_FUNC_RC, ZYDIS_MASK_POLICY_ALLOWED }, + /*0180*/ { ZYDIS_MNEMONIC_VRSQRT23PS, 3, 0x08D0, 0x00, ZYDIS_MVEX_FUNC_SAE, ZYDIS_MASK_POLICY_ALLOWED }, /*0181*/ { ZYDIS_MNEMONIC_VRSQRT23PS, 3, 0x08D0, 0x00, ZYDIS_MVEX_FUNC_INVALID, ZYDIS_MASK_POLICY_ALLOWED }, /*0182*/ { ZYDIS_MNEMONIC_VSCALEPS, 4, 0x0888, 0x00, ZYDIS_MVEX_FUNC_INT_UCONV_32, ZYDIS_MASK_POLICY_ALLOWED }, /*0183*/ { ZYDIS_MNEMONIC_VSCALEPS, 4, 0x039B, 0x00, ZYDIS_MVEX_FUNC_REG_SWIZZLE_32, ZYDIS_MASK_POLICY_ALLOWED }, diff --git a/include/Zydis/Internal/InstructionTable.h b/include/Zydis/Internal/InstructionTable.h index 714cef1..ac5cea2 100644 --- a/include/Zydis/Internal/InstructionTable.h +++ b/include/Zydis/Internal/InstructionTable.h @@ -367,9 +367,13 @@ enum ZydisMVEXFunctionalities { ZYDIS_MVEX_FUNC_INVALID, /** - * @brief @c MVEX.SSS controls embedded-rounding and sae functionality. + * @brief @c MVEX.SSS controls embedded-rounding functionality. */ ZYDIS_MVEX_FUNC_RC, + /** + * @brief @c MVEX.SSS controls sae functionality. + */ + ZYDIS_MVEX_FUNC_SAE, /** * @brief @c MVEX.SSS controls register swizzle 32-bit functionality. */ diff --git a/src/Decoder.c b/src/Decoder.c index f3b2190..e371bbf 100644 --- a/src/Decoder.c +++ b/src/Decoder.c @@ -547,7 +547,7 @@ static ZydisStatus ZydisReadDisplacement(ZydisDecoderContext* context, ZydisInst { uint8_t value; ZYDIS_CHECK(ZydisInputNext(context, info, &value)); - info->details.disp.value.sbyte = (int8_t)value; + info->details.disp.value.sqword = (int8_t)value; break; } case 16: @@ -555,7 +555,7 @@ static ZydisStatus ZydisReadDisplacement(ZydisDecoderContext* context, ZydisInst uint16_t data[2] = { 0, 0 }; ZYDIS_CHECK(ZydisInputNext(context, info, (uint8_t*)&data[1])); ZYDIS_CHECK(ZydisInputNext(context, info, (uint8_t*)&data[0])); - info->details.disp.value.sword = (data[0] << 8) | data[1]; + info->details.disp.value.sqword = (int16_t)((data[0] << 8) | data[1]); break; } case 32: @@ -565,8 +565,8 @@ static ZydisStatus ZydisReadDisplacement(ZydisDecoderContext* context, ZydisInst { ZYDIS_CHECK(ZydisInputNext(context, info, (uint8_t*)&data[i - 1])); } - info->details.disp.value.sdword = - (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3]; + info->details.disp.value.sqword = + (int32_t)((data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3]); break; } case 64: @@ -577,8 +577,8 @@ static ZydisStatus ZydisReadDisplacement(ZydisDecoderContext* context, ZydisInst ZYDIS_CHECK(ZydisInputNext(context, info, (uint8_t*)&data[i - 1])); } info->details.disp.value.sqword = - (data[0] << 56) | (data[1] << 48) | (data[2] << 40) | (data[3] << 32) | - (data[4] << 24) | (data[5] << 16) | (data[6] << 8) | data[7]; + (int64_t)((data[0] << 56) | (data[1] << 48) | (data[2] << 40) | (data[3] << 32) | + (data[4] << 24) | (data[5] << 16) | (data[6] << 8) | data[7]); break; } default: @@ -1453,6 +1453,9 @@ static ZydisStatus ZydisDecodeOperands(ZydisDecoderContext* context, ZydisInstru uint8_t immId = 0; const ZydisOperandDefinition* operand; info->operandCount = ZydisGetOperandDefinitions(definition, &operand); + + ZYDIS_ASSERT(info->operandCount < ZYDIS_ARRAY_SIZE(info->operands)); + for (uint8_t i = 0; i < info->operandCount; ++i) { info->operands[i].id = i; @@ -2135,7 +2138,9 @@ static void ZydisSetAVXInformation(ZydisDecoderContext* context, ZYDIS_ASSERT(info); ZYDIS_ASSERT(definition); - if (info->encoding == ZYDIS_INSTRUCTION_ENCODING_EVEX) + switch (info->encoding) + { + case ZYDIS_INSTRUCTION_ENCODING_EVEX: { const ZydisInstructionDefinitionEVEX* def = (const ZydisInstructionDefinitionEVEX*)definition; @@ -2463,14 +2468,65 @@ static void ZydisSetAVXInformation(ZydisDecoderContext* context, ZYDIS_ASSERT(info->details.modrm.mod == 3); } - // Rounding mode - if (def->functionality == ZYDIS_EVEX_FUNC_RC) + // Rounding mode and SAE + if (info->details.evex.b) { - info->avx.roundingMode = ZYDIS_RNDMODE_RN_SAE + context->cache.LL; + switch (def->functionality) + { + case ZYDIS_EVEX_FUNC_INVALID: + case ZYDIS_EVEX_FUNC_BC: + // Noting to do here + break; + case ZYDIS_EVEX_FUNC_RC: + info->avx.roundingMode = ZYDIS_RNDMODE_RN_SAE + context->cache.LL; + break; + case ZYDIS_EVEX_FUNC_SAE: + info->avx.hasSAE = ZYDIS_TRUE; + break; + default: + ZYDIS_UNREACHABLE; + } } // Mask mode info->avx.maskMode = ZYDIS_MASKMODE_MERGE + info->details.evex.z; + break; + } + case ZYDIS_INSTRUCTION_ENCODING_MVEX: + { + const ZydisInstructionDefinitionMVEX* def = + (const ZydisInstructionDefinitionMVEX*)definition; + + switch (def->functionality) + { + case ZYDIS_MVEX_FUNC_INVALID: + // Nothing to do here + break; + case ZYDIS_MVEX_FUNC_RC: + info->avx.roundingMode = ZYDIS_RNDMODE_INVALID + info->details.mvex.SSS; + break; + case ZYDIS_MVEX_FUNC_SAE: + if (info->details.mvex.SSS >= 4) + { + info->avx.hasSAE = ZYDIS_TRUE; + } + break; + default: + break; + //ZYDIS_UNREACHABLE; + } + + // Eviction hint + if ((info->details.modrm.mod != 3) && info->details.mvex.E) + { + info->avx.hasEvictionHint = ZYDIS_TRUE; + } + + break; + } + default: + // Nothing to do here + break; } } @@ -3157,12 +3213,14 @@ static ZydisStatus ZydisDecodeInstruction(ZydisDecoderContext* context, ZydisIns maskPolicy = def->maskPolicy; // Check for invalid MVEX.SSS values - static const uint8_t lookup[16][8] = + static const uint8_t lookup[17][8] = { // ZYDIS_MVEX_FUNC_INVALID { 0, 0, 0, 0, 0, 0, 0, 0 }, // ZYDIS_MVEX_FUNC_RC { 1, 1, 1, 1, 1, 1, 1, 1 }, + // ZYDIS_MVEX_FUNC_SAE + { 1, 1, 1, 1, 1, 1, 1, 1 }, // ZYDIS_MVEX_FUNC_REG_SWIZZLE_32 { 1, 1, 1, 1, 1, 1, 1, 1 }, // ZYDIS_MVEX_FUNC_REG_SWIZZLE_64