Added decoding of MVEX swizzle/conversion and rounding-control values

This commit is contained in:
flobernd 2017-06-22 02:42:16 +02:00
parent 15f89dc4ea
commit 2a0525925f
2 changed files with 209 additions and 31 deletions

View File

@ -800,15 +800,15 @@ typedef uint8_t ZydisMaskMode;
*/
enum ZydisMaskModes
{
ZYDIS_MASKMODE_INVALID,
ZYDIS_MASK_MODE_INVALID,
/**
* @brief Merge mode. This is the default mode for all EVEX-instructions.
*/
ZYDIS_MASKMODE_MERGE,
ZYDIS_MASK_MODE_MERGE,
/**
* @brief The zeroing mode is enabled for this instruction.
*/
ZYDIS_MASKMODE_ZERO
ZYDIS_MASK_MODE_ZERO
};
/* ---------------------------------------------------------------------------------------------- */
@ -825,11 +825,13 @@ typedef uint16_t ZydisBroadcastMode;
*/
enum ZydisBroadcastModes
{
ZYDIS_BCSTMODE_INVALID,
ZYDIS_BCSTMODE_1_TO_2,
ZYDIS_BCSTMODE_1_TO_4,
ZYDIS_BCSTMODE_1_TO_8,
ZYDIS_BCSTMODE_1_TO_16
ZYDIS_BROADCAST_MODE_INVALID,
ZYDIS_BROADCAST_MODE_1_TO_2,
ZYDIS_BROADCAST_MODE_1_TO_4,
ZYDIS_BROADCAST_MODE_1_TO_8,
ZYDIS_BROADCAST_MODE_1_TO_16,
ZYDIS_BROADCAST_MODE_4_TO_8,
ZYDIS_BROADCAST_MODE_4_TO_16
};
/* ---------------------------------------------------------------------------------------------- */
@ -846,39 +848,86 @@ typedef uint8_t ZydisRoundingMode;
*/
enum ZydisRoundingModes
{
ZYDIS_RNDMODE_INVALID,
ZYDIS_ROUNDING_MODE_INVALID,
/**
* @brief Round to nearest.
*/
ZYDIS_RNDMODE_RN,
ZYDIS_ROUNDING_MODE_RN,
/**
* @brief Round down.
*/
ZYDIS_RNDMODE_RD,
ZYDIS_ROUNDING_MODE_RD,
/**
* @brief Round up.
*/
ZYDIS_RNDMODE_RU,
ZYDIS_ROUNDING_MODE_RU,
/**
* @brief Round towards zero.
*/
ZYDIS_RNDMODE_RZ,
ZYDIS_ROUNDING_MODE_RZ,
/**
* @brief Round to nearest and suppress all exceptions.
*/
ZYDIS_RNDMODE_RN_SAE,
ZYDIS_ROUNDING_MODE_RN_SAE,
/**
* @brief Round down and suppress all exceptions.
*/
ZYDIS_RNDMODE_RD_SAE,
ZYDIS_ROUNDING_MODE_RD_SAE,
/**
* @brief Round up and suppress all exceptions.
*/
ZYDIS_RNDMODE_RU_SAE,
ZYDIS_ROUNDING_MODE_RU_SAE,
/**
* @brief Round towards zero and suppress all exceptions.
*/
ZYDIS_RNDMODE_RZ_SAE
ZYDIS_ROUNDING_MODE_RZ_SAE
};
/* ---------------------------------------------------------------------------------------------- */
/* KNC swizzle-mode */
/* ---------------------------------------------------------------------------------------------- */
/**
* @brief Defines the @c ZydisSwizzleMode datatype.
*/
typedef uint16_t ZydisSwizzleMode;
/**
* @brief Values that represent swizzle-modes.
*/
enum ZydisSwizzleModes
{
ZYDIS_SWIZZLE_MODE_INVALID,
ZYDIS_SWIZZLE_MODE_DCBA,
ZYDIS_SWIZZLE_MODE_CDAB,
ZYDIS_SWIZZLE_MODE_BADC,
ZYDIS_SWIZZLE_MODE_DACB,
ZYDIS_SWIZZLE_MODE_AAAA,
ZYDIS_SWIZZLE_MODE_BBBB,
ZYDIS_SWIZZLE_MODE_CCCC,
ZYDIS_SWIZZLE_MODE_DDDD
};
/* ---------------------------------------------------------------------------------------------- */
/* KNC conversion-mode */
/* ---------------------------------------------------------------------------------------------- */
/**
* @brief Defines the @c ZydisConversionMode datatype.
*/
typedef uint16_t ZydisConversionMode;
/**
* @brief Values that represent conversion-modes.
*/
enum ZydisConversionModes
{
ZYDIS_CONVERSION_MODE_INVALID,
ZYDIS_CONVERSION_MODE_FLOAT16,
ZYDIS_CONVERSION_MODE_SINT8,
ZYDIS_CONVERSION_MODE_UINT8,
ZYDIS_CONVERSION_MODE_SINT16,
ZYDIS_CONVERSION_MODE_UINT16
};
/* ---------------------------------------------------------------------------------------------- */
@ -986,6 +1035,8 @@ typedef struct ZydisInstructionInfo_
ZydisBool hasSAE;
ZydisBool hasEvictionHint;
ZydisSwizzleMode swizzleMode;
ZydisConversionMode conversionMode;
} avx;
/**
* @brief Extended info about different instruction-parts like ModRM, SIB or

View File

@ -2223,13 +2223,13 @@ static void ZydisSetAVXInformation(ZydisDecoderContext* context,
switch (info->avx.vectorLength)
{
case 128:
info->avx.broadcastMode = ZYDIS_BCSTMODE_1_TO_4;
info->avx.broadcastMode = ZYDIS_BROADCAST_MODE_1_TO_4;
break;
case 256:
info->avx.broadcastMode = ZYDIS_BCSTMODE_1_TO_8;
info->avx.broadcastMode = ZYDIS_BROADCAST_MODE_1_TO_8;
break;
case 512:
info->avx.broadcastMode = ZYDIS_BCSTMODE_1_TO_16;
info->avx.broadcastMode = ZYDIS_BROADCAST_MODE_1_TO_16;
break;
default:
ZYDIS_UNREACHABLE;
@ -2241,13 +2241,13 @@ static void ZydisSetAVXInformation(ZydisDecoderContext* context,
switch (info->avx.vectorLength)
{
case 128:
info->avx.broadcastMode = ZYDIS_BCSTMODE_1_TO_2;
info->avx.broadcastMode = ZYDIS_BROADCAST_MODE_1_TO_2;
break;
case 256:
info->avx.broadcastMode = ZYDIS_BCSTMODE_1_TO_4;
info->avx.broadcastMode = ZYDIS_BROADCAST_MODE_1_TO_4;
break;
case 512:
info->avx.broadcastMode = ZYDIS_BCSTMODE_1_TO_8;
info->avx.broadcastMode = ZYDIS_BROADCAST_MODE_1_TO_8;
break;
default:
ZYDIS_UNREACHABLE;
@ -2286,13 +2286,13 @@ static void ZydisSetAVXInformation(ZydisDecoderContext* context,
switch (info->avx.vectorLength)
{
case 128:
info->avx.broadcastMode = ZYDIS_BCSTMODE_1_TO_2;
info->avx.broadcastMode = ZYDIS_BROADCAST_MODE_1_TO_2;
break;
case 256:
info->avx.broadcastMode = ZYDIS_BCSTMODE_1_TO_4;
info->avx.broadcastMode = ZYDIS_BROADCAST_MODE_1_TO_4;
break;
case 512:
info->avx.broadcastMode = ZYDIS_BCSTMODE_1_TO_8;
info->avx.broadcastMode = ZYDIS_BROADCAST_MODE_1_TO_8;
break;
default:
ZYDIS_UNREACHABLE;
@ -2478,7 +2478,7 @@ static void ZydisSetAVXInformation(ZydisDecoderContext* context,
// Noting to do here
break;
case ZYDIS_EVEX_FUNC_RC:
info->avx.roundingMode = ZYDIS_RNDMODE_RN_SAE + context->cache.LL;
info->avx.roundingMode = ZYDIS_ROUNDING_MODE_RN_SAE + context->cache.LL;
break;
case ZYDIS_EVEX_FUNC_SAE:
info->avx.hasSAE = ZYDIS_TRUE;
@ -2489,7 +2489,7 @@ static void ZydisSetAVXInformation(ZydisDecoderContext* context,
}
// Mask mode
info->avx.maskMode = ZYDIS_MASKMODE_MERGE + info->details.evex.z;
info->avx.maskMode = ZYDIS_MASK_MODE_MERGE + info->details.evex.z;
break;
}
case ZYDIS_INSTRUCTION_ENCODING_MVEX:
@ -2497,13 +2497,14 @@ static void ZydisSetAVXInformation(ZydisDecoderContext* context,
const ZydisInstructionDefinitionMVEX* def =
(const ZydisInstructionDefinitionMVEX*)definition;
// Rounding mode, sae, swizzle, convert
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;
info->avx.roundingMode = ZYDIS_ROUNDING_MODE_RN + info->details.mvex.SSS;
break;
case ZYDIS_MVEX_FUNC_SAE:
if (info->details.mvex.SSS >= 4)
@ -2511,9 +2512,135 @@ static void ZydisSetAVXInformation(ZydisDecoderContext* context,
info->avx.hasSAE = ZYDIS_TRUE;
}
break;
default:
case ZYDIS_MVEX_FUNC_REG_SWIZZLE_32:
case ZYDIS_MVEX_FUNC_REG_SWIZZLE_64:
info->avx.swizzleMode = ZYDIS_SWIZZLE_MODE_DCBA + info->details.mvex.SSS;
break;
//ZYDIS_UNREACHABLE;
case ZYDIS_MVEX_FUNC_FLOAT_UCONV_LOAD_32:
switch (info->details.mvex.SSS)
{
case 0:
break;
case 1:
info->avx.broadcastMode = ZYDIS_BROADCAST_MODE_1_TO_16;
break;
case 2:
info->avx.broadcastMode = ZYDIS_BROADCAST_MODE_4_TO_16;
break;
case 3:
info->avx.conversionMode = ZYDIS_CONVERSION_MODE_FLOAT16;
break;
case 4:
info->avx.conversionMode = ZYDIS_CONVERSION_MODE_UINT8;
break;
case 6:
info->avx.conversionMode = ZYDIS_CONVERSION_MODE_UINT16;
break;
case 7:
info->avx.conversionMode = ZYDIS_CONVERSION_MODE_SINT16;
break;
default:
ZYDIS_UNREACHABLE;
}
break;
case ZYDIS_MVEX_FUNC_FLOAT_UCONV_LOAD_64:
case ZYDIS_MVEX_FUNC_INT_UCONV_LOAD_64:
switch (info->details.mvex.SSS)
{
case 0:
break;
case 1:
info->avx.broadcastMode = ZYDIS_BROADCAST_MODE_1_TO_8;
break;
case 2:
info->avx.broadcastMode = ZYDIS_BROADCAST_MODE_4_TO_8;
break;
default:
ZYDIS_UNREACHABLE;
}
break;
case ZYDIS_MVEX_FUNC_INT_UCONV_LOAD_32:
switch (info->details.mvex.SSS)
{
case 0:
break;
case 1:
info->avx.broadcastMode = ZYDIS_BROADCAST_MODE_1_TO_16;
break;
case 2:
info->avx.broadcastMode = ZYDIS_BROADCAST_MODE_4_TO_16;
break;
case 4:
info->avx.conversionMode = ZYDIS_CONVERSION_MODE_UINT8;
break;
case 5:
info->avx.conversionMode = ZYDIS_CONVERSION_MODE_SINT8;
break;
case 6:
info->avx.conversionMode = ZYDIS_CONVERSION_MODE_UINT16;
break;
case 7:
info->avx.conversionMode = ZYDIS_CONVERSION_MODE_SINT16;
break;
default:
ZYDIS_UNREACHABLE;
}
break;
case ZYDIS_MVEX_FUNC_FLOAT_UCONV_32:
case ZYDIS_MVEX_FUNC_FLOAT_DCONV_32:
switch (info->details.mvex.SSS)
{
case 0:
break;
case 3:
info->avx.conversionMode = ZYDIS_CONVERSION_MODE_FLOAT16;
break;
case 4:
info->avx.conversionMode = ZYDIS_CONVERSION_MODE_UINT8;
break;
case 5:
info->avx.conversionMode = ZYDIS_CONVERSION_MODE_SINT8;
break;
case 6:
info->avx.conversionMode = ZYDIS_CONVERSION_MODE_UINT16;
break;
case 7:
info->avx.conversionMode = ZYDIS_CONVERSION_MODE_SINT16;
break;
default:
ZYDIS_UNREACHABLE;
}
break;
case ZYDIS_MVEX_FUNC_FLOAT_UCONV_64:
case ZYDIS_MVEX_FUNC_FLOAT_DCONV_64:
break;
case ZYDIS_MVEX_FUNC_INT_UCONV_32:
case ZYDIS_MVEX_FUNC_INT_DCONV_32:
switch (info->details.mvex.SSS)
{
case 0:
break;
case 4:
info->avx.conversionMode = ZYDIS_CONVERSION_MODE_UINT8;
break;
case 5:
info->avx.conversionMode = ZYDIS_CONVERSION_MODE_SINT8;
break;
case 6:
info->avx.conversionMode = ZYDIS_CONVERSION_MODE_UINT16;
break;
case 7:
info->avx.conversionMode = ZYDIS_CONVERSION_MODE_SINT16;
break;
default:
ZYDIS_UNREACHABLE;
}
break;
case ZYDIS_MVEX_FUNC_INT_UCONV_64:
case ZYDIS_MVEX_FUNC_INT_DCONV_64:
break;
default:
ZYDIS_UNREACHABLE;
}
// Eviction hint