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 enum ZydisMaskModes
{ {
ZYDIS_MASKMODE_INVALID, ZYDIS_MASK_MODE_INVALID,
/** /**
* @brief Merge mode. This is the default mode for all EVEX-instructions. * @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. * @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 enum ZydisBroadcastModes
{ {
ZYDIS_BCSTMODE_INVALID, ZYDIS_BROADCAST_MODE_INVALID,
ZYDIS_BCSTMODE_1_TO_2, ZYDIS_BROADCAST_MODE_1_TO_2,
ZYDIS_BCSTMODE_1_TO_4, ZYDIS_BROADCAST_MODE_1_TO_4,
ZYDIS_BCSTMODE_1_TO_8, ZYDIS_BROADCAST_MODE_1_TO_8,
ZYDIS_BCSTMODE_1_TO_16 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 enum ZydisRoundingModes
{ {
ZYDIS_RNDMODE_INVALID, ZYDIS_ROUNDING_MODE_INVALID,
/** /**
* @brief Round to nearest. * @brief Round to nearest.
*/ */
ZYDIS_RNDMODE_RN, ZYDIS_ROUNDING_MODE_RN,
/** /**
* @brief Round down. * @brief Round down.
*/ */
ZYDIS_RNDMODE_RD, ZYDIS_ROUNDING_MODE_RD,
/** /**
* @brief Round up. * @brief Round up.
*/ */
ZYDIS_RNDMODE_RU, ZYDIS_ROUNDING_MODE_RU,
/** /**
* @brief Round towards zero. * @brief Round towards zero.
*/ */
ZYDIS_RNDMODE_RZ, ZYDIS_ROUNDING_MODE_RZ,
/** /**
* @brief Round to nearest and suppress all exceptions. * @brief Round to nearest and suppress all exceptions.
*/ */
ZYDIS_RNDMODE_RN_SAE, ZYDIS_ROUNDING_MODE_RN_SAE,
/** /**
* @brief Round down and suppress all exceptions. * @brief Round down and suppress all exceptions.
*/ */
ZYDIS_RNDMODE_RD_SAE, ZYDIS_ROUNDING_MODE_RD_SAE,
/** /**
* @brief Round up and suppress all exceptions. * @brief Round up and suppress all exceptions.
*/ */
ZYDIS_RNDMODE_RU_SAE, ZYDIS_ROUNDING_MODE_RU_SAE,
/** /**
* @brief Round towards zero and suppress all exceptions. * @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 hasSAE;
ZydisBool hasEvictionHint; ZydisBool hasEvictionHint;
ZydisSwizzleMode swizzleMode;
ZydisConversionMode conversionMode;
} avx; } avx;
/** /**
* @brief Extended info about different instruction-parts like ModRM, SIB or * @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) switch (info->avx.vectorLength)
{ {
case 128: case 128:
info->avx.broadcastMode = ZYDIS_BCSTMODE_1_TO_4; info->avx.broadcastMode = ZYDIS_BROADCAST_MODE_1_TO_4;
break; break;
case 256: case 256:
info->avx.broadcastMode = ZYDIS_BCSTMODE_1_TO_8; info->avx.broadcastMode = ZYDIS_BROADCAST_MODE_1_TO_8;
break; break;
case 512: case 512:
info->avx.broadcastMode = ZYDIS_BCSTMODE_1_TO_16; info->avx.broadcastMode = ZYDIS_BROADCAST_MODE_1_TO_16;
break; break;
default: default:
ZYDIS_UNREACHABLE; ZYDIS_UNREACHABLE;
@ -2241,13 +2241,13 @@ static void ZydisSetAVXInformation(ZydisDecoderContext* context,
switch (info->avx.vectorLength) switch (info->avx.vectorLength)
{ {
case 128: case 128:
info->avx.broadcastMode = ZYDIS_BCSTMODE_1_TO_2; info->avx.broadcastMode = ZYDIS_BROADCAST_MODE_1_TO_2;
break; break;
case 256: case 256:
info->avx.broadcastMode = ZYDIS_BCSTMODE_1_TO_4; info->avx.broadcastMode = ZYDIS_BROADCAST_MODE_1_TO_4;
break; break;
case 512: case 512:
info->avx.broadcastMode = ZYDIS_BCSTMODE_1_TO_8; info->avx.broadcastMode = ZYDIS_BROADCAST_MODE_1_TO_8;
break; break;
default: default:
ZYDIS_UNREACHABLE; ZYDIS_UNREACHABLE;
@ -2286,13 +2286,13 @@ static void ZydisSetAVXInformation(ZydisDecoderContext* context,
switch (info->avx.vectorLength) switch (info->avx.vectorLength)
{ {
case 128: case 128:
info->avx.broadcastMode = ZYDIS_BCSTMODE_1_TO_2; info->avx.broadcastMode = ZYDIS_BROADCAST_MODE_1_TO_2;
break; break;
case 256: case 256:
info->avx.broadcastMode = ZYDIS_BCSTMODE_1_TO_4; info->avx.broadcastMode = ZYDIS_BROADCAST_MODE_1_TO_4;
break; break;
case 512: case 512:
info->avx.broadcastMode = ZYDIS_BCSTMODE_1_TO_8; info->avx.broadcastMode = ZYDIS_BROADCAST_MODE_1_TO_8;
break; break;
default: default:
ZYDIS_UNREACHABLE; ZYDIS_UNREACHABLE;
@ -2478,7 +2478,7 @@ static void ZydisSetAVXInformation(ZydisDecoderContext* context,
// Noting to do here // Noting to do here
break; break;
case ZYDIS_EVEX_FUNC_RC: 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; break;
case ZYDIS_EVEX_FUNC_SAE: case ZYDIS_EVEX_FUNC_SAE:
info->avx.hasSAE = ZYDIS_TRUE; info->avx.hasSAE = ZYDIS_TRUE;
@ -2489,7 +2489,7 @@ static void ZydisSetAVXInformation(ZydisDecoderContext* context,
} }
// Mask mode // Mask mode
info->avx.maskMode = ZYDIS_MASKMODE_MERGE + info->details.evex.z; info->avx.maskMode = ZYDIS_MASK_MODE_MERGE + info->details.evex.z;
break; break;
} }
case ZYDIS_INSTRUCTION_ENCODING_MVEX: case ZYDIS_INSTRUCTION_ENCODING_MVEX:
@ -2497,13 +2497,14 @@ static void ZydisSetAVXInformation(ZydisDecoderContext* context,
const ZydisInstructionDefinitionMVEX* def = const ZydisInstructionDefinitionMVEX* def =
(const ZydisInstructionDefinitionMVEX*)definition; (const ZydisInstructionDefinitionMVEX*)definition;
// Rounding mode, sae, swizzle, convert
switch (def->functionality) switch (def->functionality)
{ {
case ZYDIS_MVEX_FUNC_INVALID: case ZYDIS_MVEX_FUNC_INVALID:
// Nothing to do here // Nothing to do here
break; break;
case ZYDIS_MVEX_FUNC_RC: 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; break;
case ZYDIS_MVEX_FUNC_SAE: case ZYDIS_MVEX_FUNC_SAE:
if (info->details.mvex.SSS >= 4) if (info->details.mvex.SSS >= 4)
@ -2511,9 +2512,135 @@ static void ZydisSetAVXInformation(ZydisDecoderContext* context,
info->avx.hasSAE = ZYDIS_TRUE; info->avx.hasSAE = ZYDIS_TRUE;
} }
break; 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; 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 // Eviction hint