mirror of https://github.com/x64dbg/zydis
Reimplemented decoding of 3DNOW instructions and improved EVEX decoding
This commit is contained in:
parent
702f6b8d53
commit
6caa68b674
|
@ -711,14 +711,14 @@ enum ZydisVectorLengths
|
|||
/* ---------------------------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* @brief Defines the @c ZydisEVEXTupleType datatype.
|
||||
* @brief Defines the @c ZydisTupleType datatype.
|
||||
*/
|
||||
typedef uint8_t ZydisEVEXTupleType;
|
||||
typedef uint8_t ZydisTupleType;
|
||||
|
||||
/**
|
||||
* @brief Values that represent EVEX tuple-types.
|
||||
*/
|
||||
enum ZydisEVEXTupleTypes
|
||||
enum ZydisTupleTypes
|
||||
{
|
||||
ZYDIS_TUPLETYPE_INVALID,
|
||||
/**
|
||||
|
@ -779,6 +779,31 @@ enum ZydisEVEXTupleTypes
|
|||
ZYDIS_TUPLETYPE_DUP
|
||||
};
|
||||
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
/* AVX mask mode */
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* @brief Defines the @c ZydisMaskMode datatype.
|
||||
*/
|
||||
typedef uint8_t ZydisMaskMode;
|
||||
|
||||
/**
|
||||
* @brief Values that represent AVX mask-modes.
|
||||
*/
|
||||
enum ZydisMaskModes
|
||||
{
|
||||
ZYDIS_MASKMODE_INVALID,
|
||||
/**
|
||||
* @brief Merge mode. This is the default mode for all EVEX-instructions.
|
||||
*/
|
||||
ZYDIS_MASKMODE_MERGE,
|
||||
/**
|
||||
* @brief The zeroing mode is enabled for this instruction.
|
||||
*/
|
||||
ZYDIS_MASKMODE_ZERO
|
||||
};
|
||||
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
/* AVX broadcast-mode */
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
|
@ -800,6 +825,55 @@ enum ZydisBroadcastModes
|
|||
ZYDIS_BROADCAST_MODE_1_TO_16
|
||||
};
|
||||
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
/* AVX rounding-mode */
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* @brief Defines the @c ZydisRoundingMode datatype.
|
||||
*/
|
||||
typedef uint8_t ZydisRoundingMode;
|
||||
|
||||
/**
|
||||
* @brief Values that represent AVX rounding-modes.
|
||||
*/
|
||||
enum ZydisRoundingModes
|
||||
{
|
||||
ZYDIS_RNDMODE_INVALID,
|
||||
/**
|
||||
* @brief Round to nearest.
|
||||
*/
|
||||
ZYDIS_RNDMODE_RN,
|
||||
/**
|
||||
* @brief Round down.
|
||||
*/
|
||||
ZYDIS_RNDMODE_RD,
|
||||
/**
|
||||
* @brief Round up.
|
||||
*/
|
||||
ZYDIS_RNDMODE_RU,
|
||||
/**
|
||||
* @brief Round towards zero.
|
||||
*/
|
||||
ZYDIS_RNDMODE_RZ,
|
||||
/**
|
||||
* @brief Round to nearest and suppress all exceptions.
|
||||
*/
|
||||
ZYDIS_RNDMODE_RN_SAE,
|
||||
/**
|
||||
* @brief Round down and suppress all exceptions.
|
||||
*/
|
||||
ZYDIS_RNDMODE_RD_SAE,
|
||||
/**
|
||||
* @brief Round up and suppress all exceptions.
|
||||
*/
|
||||
ZYDIS_RNDMODE_RU_SAE,
|
||||
/**
|
||||
* @brief Round towards zero and suppress all exceptions.
|
||||
*/
|
||||
ZYDIS_RNDMODE_RZ_SAE
|
||||
};
|
||||
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
/* Instruction info */
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
|
@ -874,11 +948,34 @@ typedef struct ZydisInstructionInfo_
|
|||
*/
|
||||
struct
|
||||
{
|
||||
/**
|
||||
* @brief The AVX vector-length.
|
||||
*/
|
||||
ZydisVectorLength vectorLength;
|
||||
ZydisEVEXTupleType tupleType;
|
||||
/**
|
||||
* @brief The AVX tuple-type (EVEX only).
|
||||
*/
|
||||
ZydisTupleType tupleType;
|
||||
/**
|
||||
* @brief The AVX element-size.
|
||||
*/
|
||||
uint8_t elementSize;
|
||||
/**
|
||||
* @brief The scale-factor for compressed 8-bit displacement values.
|
||||
*/
|
||||
uint8_t compressedDisp8Scale;
|
||||
/**
|
||||
* @brief The AVX mask-mode.
|
||||
*/
|
||||
ZydisMaskMode maskMode;
|
||||
/**
|
||||
* @brief The AVX broadcast-mode.
|
||||
*/
|
||||
ZydisBroadcastMode broadcastMode;
|
||||
/**
|
||||
* @brief The AVX rounding-mode.
|
||||
*/
|
||||
ZydisRoundingMode roundingMode;
|
||||
} avx;
|
||||
/**
|
||||
* @brief Extended info about different instruction-parts like ModRM, SIB or
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -151,10 +151,14 @@ enum ZydisInstructionTreeNodeTypes
|
|||
* @brief Reference to an EVEX.b filter.
|
||||
*/
|
||||
ZYDIS_NODETYPE_FILTER_EVEX_B = 0x11,
|
||||
/**
|
||||
* @brief Reference to an EVEX.z filter.
|
||||
*/
|
||||
ZYDIS_NODETYPE_FILTER_EVEX_Z = 0x12,
|
||||
/**
|
||||
* @brief Reference to an MVEX.E filter.
|
||||
*/
|
||||
ZYDIS_NODETYPE_FILTER_MVEX_E = 0x12,
|
||||
ZYDIS_NODETYPE_FILTER_MVEX_E = 0x13,
|
||||
};
|
||||
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
|
@ -230,6 +234,61 @@ typedef struct ZydisOperandDefinition_
|
|||
/* Instruction definition */
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* @brief Defines the @c ZydisEVEXFunctionality datatype.
|
||||
*/
|
||||
typedef uint8_t ZydisEVEXFunctionality;
|
||||
|
||||
/**
|
||||
* @brief Values that represent EVEX-functionalities.
|
||||
*/
|
||||
enum ZydisEVEXFunctionalities
|
||||
{
|
||||
ZYDIS_EVEX_FUNC_INVALID,
|
||||
/**
|
||||
* @brief @c EVEX.b enables broadcast functionality.
|
||||
*/
|
||||
ZYDIS_EVEX_FUNC_BC,
|
||||
/**
|
||||
* @brief @c EVEX.b enables embedded-rounding functionality.
|
||||
*/
|
||||
ZYDIS_EVEX_FUNC_RC,
|
||||
/**
|
||||
* @brief @c EVEX.b enables sae functionality.
|
||||
*/
|
||||
ZYDIS_EVEX_FUNC_SAE
|
||||
};
|
||||
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* @brief Defines the @c ZydisMaskPolicy datatype.
|
||||
*/
|
||||
typedef uint8_t ZydisMaskPolicy;
|
||||
|
||||
/**
|
||||
* @brief Values that represent AVX mask policies.
|
||||
*/
|
||||
enum ZydisMaskPolicies
|
||||
{
|
||||
ZYDIS_MASK_POLICY_INVALID,
|
||||
/**
|
||||
* @brief The instruction accepts mask-registers other than the default-mask (K0), but
|
||||
* does not require them.
|
||||
*/
|
||||
ZYDIS_MASK_POLICY_ALLOWED,
|
||||
/**
|
||||
* @brief The instruction requires a mask-register other than the default-mask (K0).
|
||||
*/
|
||||
ZYDIS_MASK_POLICY_REQUIRED,
|
||||
/**
|
||||
* @brief The instruction does not allow a mask-register other than the default-mask (K0).
|
||||
*/
|
||||
ZYDIS_MASK_POLICY_FORBIDDEN
|
||||
};
|
||||
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
|
||||
#define ZYDIS_INSTRUCTION_DEFINITION_BASE \
|
||||
ZydisInstructionMnemonic mnemonic : 11; \
|
||||
uint8_t operandCount : 4; \
|
||||
|
@ -277,8 +336,10 @@ typedef struct ZydisInstructionDefinitionVEX_
|
|||
typedef struct ZydisInstructionDefinitionEVEX_
|
||||
{
|
||||
ZYDIS_INSTRUCTION_DEFINITION_BASE;
|
||||
ZydisEVEXTupleType tupleType : 4;
|
||||
ZydisTupleType tupleType : 4;
|
||||
uint8_t elementSize : 7;
|
||||
ZydisEVEXFunctionality functionality : 2;
|
||||
ZydisMaskPolicy maskPolicy : 2;
|
||||
} ZydisInstructionDefinitionEVEX;
|
||||
|
||||
typedef struct ZydisInstructionDefinitionMVEX_
|
||||
|
|
|
@ -117,13 +117,6 @@ enum ZydisStatusCode
|
|||
ZYDIS_STATUS_INVALID_MASK,
|
||||
ZYDIS_STATUS_INVALID_VSIB,
|
||||
|
||||
/* ------------------------------------------------------------------------------------------ */
|
||||
/* Encoder */
|
||||
/* ------------------------------------------------------------------------------------------ */
|
||||
|
||||
// TODO:
|
||||
ZYDIS_STATUS_IMPOSSIBLE_INSTRUCTION,
|
||||
|
||||
/* ------------------------------------------------------------------------------------------ */
|
||||
/* Formatter */
|
||||
/* ------------------------------------------------------------------------------------------ */
|
||||
|
|
459
src/Decoder.c
459
src/Decoder.c
|
@ -1791,15 +1791,111 @@ static void ZydisSetAVXInformation(ZydisDecoderContext* context,
|
|||
(const ZydisInstructionDefinitionEVEX*)definition;
|
||||
|
||||
info->avx.tupleType = def->tupleType;
|
||||
info->avx.elementSize = def->elementSize;
|
||||
ZYDIS_ASSERT((def->elementSize == 8) || (def->elementSize == 16) ||
|
||||
(def->elementSize == 32) || (def->elementSize == 64));
|
||||
switch (info->avx.tupleType)
|
||||
if (info->avx.tupleType)
|
||||
{
|
||||
case ZYDIS_TUPLETYPE_FV:
|
||||
switch (info->details.evex.b)
|
||||
ZYDIS_ASSERT(info->details.modrm.mod != 3);
|
||||
ZYDIS_ASSERT((def->elementSize == 8) || (def->elementSize == 16) ||
|
||||
(def->elementSize == 32) || (def->elementSize == 64));
|
||||
info->avx.elementSize = def->elementSize;
|
||||
|
||||
// Compressed disp8 scale and broadcast-factor
|
||||
switch (info->avx.tupleType)
|
||||
{
|
||||
case 0:
|
||||
case ZYDIS_TUPLETYPE_FV:
|
||||
switch (info->details.evex.b)
|
||||
{
|
||||
case 0:
|
||||
switch (info->avx.vectorLength)
|
||||
{
|
||||
case 128:
|
||||
info->avx.compressedDisp8Scale = 16;
|
||||
break;
|
||||
case 256:
|
||||
info->avx.compressedDisp8Scale = 32;
|
||||
break;
|
||||
case 512:
|
||||
info->avx.compressedDisp8Scale = 64;
|
||||
break;
|
||||
default:
|
||||
ZYDIS_UNREACHABLE;
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
ZYDIS_ASSERT(def->functionality == ZYDIS_EVEX_FUNC_BC);
|
||||
switch (context->cache.W)
|
||||
{
|
||||
case 0:
|
||||
ZYDIS_ASSERT(info->avx.elementSize == 32);
|
||||
info->avx.compressedDisp8Scale = 4;
|
||||
switch (info->avx.vectorLength)
|
||||
{
|
||||
case 128:
|
||||
info->avx.broadcastMode = ZYDIS_BROADCAST_MODE_1_TO_4;
|
||||
break;
|
||||
case 256:
|
||||
info->avx.broadcastMode = ZYDIS_BROADCAST_MODE_1_TO_8;
|
||||
break;
|
||||
case 512:
|
||||
info->avx.broadcastMode = ZYDIS_BROADCAST_MODE_1_TO_16;
|
||||
break;
|
||||
default:
|
||||
ZYDIS_UNREACHABLE;
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
ZYDIS_ASSERT(info->avx.elementSize == 64);
|
||||
info->avx.compressedDisp8Scale = 8;
|
||||
switch (info->avx.vectorLength)
|
||||
{
|
||||
case 128:
|
||||
info->avx.broadcastMode = ZYDIS_BROADCAST_MODE_1_TO_2;
|
||||
break;
|
||||
case 256:
|
||||
info->avx.broadcastMode = ZYDIS_BROADCAST_MODE_1_TO_4;
|
||||
break;
|
||||
case 512:
|
||||
info->avx.broadcastMode = ZYDIS_BROADCAST_MODE_1_TO_8;
|
||||
break;
|
||||
default:
|
||||
ZYDIS_UNREACHABLE;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
ZYDIS_UNREACHABLE;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
ZYDIS_UNREACHABLE;
|
||||
}
|
||||
break;
|
||||
case ZYDIS_TUPLETYPE_HV:
|
||||
ZYDIS_ASSERT(info->avx.elementSize == 32);
|
||||
switch (info->details.evex.b)
|
||||
{
|
||||
case 0:
|
||||
switch (info->avx.vectorLength)
|
||||
{
|
||||
case 128:
|
||||
info->avx.compressedDisp8Scale = 8;
|
||||
break;
|
||||
case 256:
|
||||
info->avx.compressedDisp8Scale = 16;
|
||||
break;
|
||||
case 512:
|
||||
info->avx.compressedDisp8Scale = 32;
|
||||
break;
|
||||
default:
|
||||
ZYDIS_UNREACHABLE;
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
info->avx.compressedDisp8Scale = 4;
|
||||
break;
|
||||
default:
|
||||
ZYDIS_UNREACHABLE;
|
||||
}
|
||||
break;
|
||||
case ZYDIS_TUPLETYPE_FVM:
|
||||
switch (info->avx.vectorLength)
|
||||
{
|
||||
case 128:
|
||||
|
@ -1815,58 +1911,77 @@ static void ZydisSetAVXInformation(ZydisDecoderContext* context,
|
|||
ZYDIS_UNREACHABLE;
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
switch (context->cache.W)
|
||||
case ZYDIS_TUPLETYPE_T1S:
|
||||
info->avx.compressedDisp8Scale = info->avx.elementSize / 8;
|
||||
break;
|
||||
case ZYDIS_TUPLETYPE_T1F:
|
||||
switch (info->avx.elementSize)
|
||||
{
|
||||
case 0:
|
||||
ZYDIS_ASSERT(info->avx.elementSize == 32);
|
||||
case 32:
|
||||
info->avx.compressedDisp8Scale = 4;
|
||||
switch (info->avx.vectorLength)
|
||||
{
|
||||
case 128:
|
||||
info->avx.broadcastMode = ZYDIS_BROADCAST_MODE_1_TO_4;
|
||||
break;
|
||||
case 256:
|
||||
info->avx.broadcastMode = ZYDIS_BROADCAST_MODE_1_TO_8;
|
||||
break;
|
||||
case 512:
|
||||
info->avx.broadcastMode = ZYDIS_BROADCAST_MODE_1_TO_16;
|
||||
break;
|
||||
default:
|
||||
ZYDIS_UNREACHABLE;
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
ZYDIS_ASSERT(info->avx.elementSize == 64);
|
||||
case 64:
|
||||
info->avx.compressedDisp8Scale = 8;
|
||||
switch (info->avx.vectorLength)
|
||||
{
|
||||
case 128:
|
||||
info->avx.broadcastMode = ZYDIS_BROADCAST_MODE_1_TO_2;
|
||||
break;
|
||||
case 256:
|
||||
info->avx.broadcastMode = ZYDIS_BROADCAST_MODE_1_TO_4;
|
||||
break;
|
||||
case 512:
|
||||
info->avx.broadcastMode = ZYDIS_BROADCAST_MODE_1_TO_8;
|
||||
break;
|
||||
default:
|
||||
ZYDIS_UNREACHABLE;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
ZYDIS_UNREACHABLE;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
ZYDIS_UNREACHABLE;
|
||||
}
|
||||
break;
|
||||
case ZYDIS_TUPLETYPE_HV:
|
||||
ZYDIS_ASSERT(info->avx.elementSize == 32);
|
||||
switch (info->details.evex.b)
|
||||
{
|
||||
case 0:
|
||||
case ZYDIS_TUPLETYPE_GSCAT:
|
||||
switch (context->cache.W)
|
||||
{
|
||||
case 0:
|
||||
ZYDIS_ASSERT(info->avx.elementSize == 32);
|
||||
info->avx.compressedDisp8Scale = 4;
|
||||
break;
|
||||
case 1:
|
||||
ZYDIS_ASSERT(info->avx.elementSize == 64);
|
||||
info->avx.compressedDisp8Scale = 8;
|
||||
break;
|
||||
default:
|
||||
ZYDIS_UNREACHABLE;
|
||||
}
|
||||
break;
|
||||
case ZYDIS_TUPLETYPE_T2:
|
||||
switch (context->cache.W)
|
||||
{
|
||||
case 0:
|
||||
ZYDIS_ASSERT(info->avx.elementSize == 32);
|
||||
info->avx.compressedDisp8Scale = 8;
|
||||
break;
|
||||
case 1:
|
||||
ZYDIS_ASSERT(info->avx.elementSize == 64);
|
||||
ZYDIS_ASSERT((info->avx.vectorLength == 256) || (info->avx.vectorLength == 512));
|
||||
info->avx.compressedDisp8Scale = 16;
|
||||
break;
|
||||
default:
|
||||
ZYDIS_UNREACHABLE;
|
||||
}
|
||||
break;
|
||||
case ZYDIS_TUPLETYPE_T4:
|
||||
switch (context->cache.W)
|
||||
{
|
||||
case 0:
|
||||
ZYDIS_ASSERT(info->avx.elementSize == 32);
|
||||
ZYDIS_ASSERT((info->avx.vectorLength == 256) || (info->avx.vectorLength == 512));
|
||||
info->avx.compressedDisp8Scale = 16;
|
||||
break;
|
||||
case 1:
|
||||
ZYDIS_ASSERT(info->avx.elementSize == 64);
|
||||
ZYDIS_ASSERT(info->avx.vectorLength == 512);
|
||||
info->avx.compressedDisp8Scale = 32;
|
||||
break;
|
||||
default:
|
||||
ZYDIS_UNREACHABLE;
|
||||
}
|
||||
break;
|
||||
case ZYDIS_TUPLETYPE_T8:
|
||||
ZYDIS_ASSERT(!context->cache.W);
|
||||
ZYDIS_ASSERT(info->avx.vectorLength == 512);
|
||||
ZYDIS_ASSERT(info->avx.elementSize == 32);
|
||||
info->avx.compressedDisp8Scale = 32;
|
||||
break;
|
||||
case ZYDIS_TUPLETYPE_HVM:
|
||||
switch (info->avx.vectorLength)
|
||||
{
|
||||
case 128:
|
||||
|
@ -1882,171 +1997,74 @@ static void ZydisSetAVXInformation(ZydisDecoderContext* context,
|
|||
ZYDIS_UNREACHABLE;
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
info->avx.compressedDisp8Scale = 4;
|
||||
case ZYDIS_TUPLETYPE_QVM:
|
||||
switch (info->avx.vectorLength)
|
||||
{
|
||||
case 128:
|
||||
info->avx.compressedDisp8Scale = 4;
|
||||
break;
|
||||
case 256:
|
||||
info->avx.compressedDisp8Scale = 8;
|
||||
break;
|
||||
case 512:
|
||||
info->avx.compressedDisp8Scale = 16;
|
||||
break;
|
||||
default:
|
||||
ZYDIS_UNREACHABLE;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
ZYDIS_UNREACHABLE;
|
||||
}
|
||||
break;
|
||||
case ZYDIS_TUPLETYPE_FVM:
|
||||
switch (info->avx.vectorLength)
|
||||
{
|
||||
case 128:
|
||||
case ZYDIS_TUPLETYPE_OVM:
|
||||
switch (info->avx.vectorLength)
|
||||
{
|
||||
case 128:
|
||||
info->avx.compressedDisp8Scale = 2;
|
||||
break;
|
||||
case 256:
|
||||
info->avx.compressedDisp8Scale = 4;
|
||||
break;
|
||||
case 512:
|
||||
info->avx.compressedDisp8Scale = 8;
|
||||
break;
|
||||
default:
|
||||
ZYDIS_UNREACHABLE;
|
||||
}
|
||||
break;
|
||||
case ZYDIS_TUPLETYPE_M128:
|
||||
info->avx.compressedDisp8Scale = 16;
|
||||
break;
|
||||
case 256:
|
||||
info->avx.compressedDisp8Scale = 32;
|
||||
break;
|
||||
case 512:
|
||||
info->avx.compressedDisp8Scale = 64;
|
||||
case ZYDIS_TUPLETYPE_DUP:
|
||||
switch (info->avx.vectorLength)
|
||||
{
|
||||
case 128:
|
||||
info->avx.compressedDisp8Scale = 8;
|
||||
break;
|
||||
case 256:
|
||||
info->avx.compressedDisp8Scale = 32;
|
||||
break;
|
||||
case 512:
|
||||
info->avx.compressedDisp8Scale = 64;
|
||||
break;
|
||||
default:
|
||||
ZYDIS_UNREACHABLE;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
ZYDIS_UNREACHABLE;
|
||||
}
|
||||
break;
|
||||
case ZYDIS_TUPLETYPE_T1S:
|
||||
info->avx.compressedDisp8Scale = info->avx.elementSize / 8;
|
||||
break;
|
||||
case ZYDIS_TUPLETYPE_T1F:
|
||||
switch (info->avx.elementSize)
|
||||
{
|
||||
case 32:
|
||||
info->avx.compressedDisp8Scale = 4;
|
||||
break;
|
||||
case 64:
|
||||
info->avx.compressedDisp8Scale = 8;
|
||||
break;
|
||||
default:
|
||||
ZYDIS_UNREACHABLE;
|
||||
}
|
||||
break;
|
||||
case ZYDIS_TUPLETYPE_GSCAT:
|
||||
switch (context->cache.W)
|
||||
{
|
||||
case 0:
|
||||
ZYDIS_ASSERT(info->avx.elementSize == 32);
|
||||
info->avx.compressedDisp8Scale = 4;
|
||||
break;
|
||||
case 1:
|
||||
ZYDIS_ASSERT(info->avx.elementSize == 64);
|
||||
info->avx.compressedDisp8Scale = 8;
|
||||
break;
|
||||
default:
|
||||
ZYDIS_UNREACHABLE;
|
||||
}
|
||||
break;
|
||||
case ZYDIS_TUPLETYPE_T2:
|
||||
switch (context->cache.W)
|
||||
{
|
||||
case 0:
|
||||
ZYDIS_ASSERT(info->avx.elementSize == 32);
|
||||
info->avx.compressedDisp8Scale = 8;
|
||||
break;
|
||||
case 1:
|
||||
ZYDIS_ASSERT(info->avx.elementSize == 64);
|
||||
ZYDIS_ASSERT((info->avx.vectorLength == 256) || (info->avx.vectorLength == 512));
|
||||
info->avx.compressedDisp8Scale = 16;
|
||||
break;
|
||||
default:
|
||||
ZYDIS_UNREACHABLE;
|
||||
}
|
||||
break;
|
||||
case ZYDIS_TUPLETYPE_T4:
|
||||
switch (context->cache.W)
|
||||
{
|
||||
case 0:
|
||||
ZYDIS_ASSERT(info->avx.elementSize == 32);
|
||||
ZYDIS_ASSERT((info->avx.vectorLength == 256) || (info->avx.vectorLength == 512));
|
||||
info->avx.compressedDisp8Scale = 16;
|
||||
break;
|
||||
case 1:
|
||||
ZYDIS_ASSERT(info->avx.elementSize == 64);
|
||||
ZYDIS_ASSERT(info->avx.vectorLength == 512);
|
||||
info->avx.compressedDisp8Scale = 32;
|
||||
break;
|
||||
default:
|
||||
ZYDIS_UNREACHABLE;
|
||||
}
|
||||
break;
|
||||
case ZYDIS_TUPLETYPE_T8:
|
||||
ZYDIS_ASSERT(!context->cache.W);
|
||||
ZYDIS_ASSERT(info->avx.vectorLength == 512);
|
||||
ZYDIS_ASSERT(info->avx.elementSize == 32);
|
||||
info->avx.compressedDisp8Scale = 32;
|
||||
break;
|
||||
case ZYDIS_TUPLETYPE_HVM:
|
||||
switch (info->avx.vectorLength)
|
||||
{
|
||||
case 128:
|
||||
info->avx.compressedDisp8Scale = 8;
|
||||
break;
|
||||
case 256:
|
||||
info->avx.compressedDisp8Scale = 16;
|
||||
break;
|
||||
case 512:
|
||||
info->avx.compressedDisp8Scale = 32;
|
||||
break;
|
||||
default:
|
||||
ZYDIS_UNREACHABLE;
|
||||
}
|
||||
break;
|
||||
case ZYDIS_TUPLETYPE_QVM:
|
||||
switch (info->avx.vectorLength)
|
||||
{
|
||||
case 128:
|
||||
info->avx.compressedDisp8Scale = 4;
|
||||
break;
|
||||
case 256:
|
||||
info->avx.compressedDisp8Scale = 8;
|
||||
break;
|
||||
case 512:
|
||||
info->avx.compressedDisp8Scale = 16;
|
||||
break;
|
||||
default:
|
||||
ZYDIS_UNREACHABLE;
|
||||
}
|
||||
break;
|
||||
case ZYDIS_TUPLETYPE_OVM:
|
||||
switch (info->avx.vectorLength)
|
||||
{
|
||||
case 128:
|
||||
info->avx.compressedDisp8Scale = 2;
|
||||
break;
|
||||
case 256:
|
||||
info->avx.compressedDisp8Scale = 4;
|
||||
break;
|
||||
case 512:
|
||||
info->avx.compressedDisp8Scale = 8;
|
||||
break;
|
||||
default:
|
||||
ZYDIS_UNREACHABLE;
|
||||
}
|
||||
break;
|
||||
case ZYDIS_TUPLETYPE_M128:
|
||||
info->avx.compressedDisp8Scale = 16;
|
||||
break;
|
||||
case ZYDIS_TUPLETYPE_DUP:
|
||||
switch (info->avx.vectorLength)
|
||||
{
|
||||
case 128:
|
||||
info->avx.compressedDisp8Scale = 8;
|
||||
break;
|
||||
case 256:
|
||||
info->avx.compressedDisp8Scale = 32;
|
||||
break;
|
||||
case 512:
|
||||
info->avx.compressedDisp8Scale = 64;
|
||||
break;
|
||||
default:
|
||||
ZYDIS_UNREACHABLE;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
ZYDIS_UNREACHABLE;
|
||||
} else
|
||||
{
|
||||
// TODO: Add tuple type
|
||||
ZYDIS_ASSERT(info->details.modrm.mod == 3);
|
||||
}
|
||||
|
||||
// TODO: Set Mask Mode
|
||||
// Rounding mode
|
||||
if (def->functionality == ZYDIS_EVEX_FUNC_RC)
|
||||
{
|
||||
info->avx.roundingMode = ZYDIS_RNDMODE_RN_SAE + context->cache.LL;
|
||||
}
|
||||
|
||||
// Mask mode
|
||||
info->avx.maskMode = ZYDIS_MASKMODE_MERGE + info->details.evex.z;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2566,6 +2584,17 @@ static ZydisStatus ZydisNodeHandlerEvexB(ZydisInstructionInfo* info, uint16_t* i
|
|||
return ZYDIS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static ZydisStatus ZydisNodeHandlerEvexZ(ZydisInstructionInfo* info, uint16_t* index)
|
||||
{
|
||||
ZYDIS_ASSERT(info);
|
||||
ZYDIS_ASSERT(index);
|
||||
|
||||
ZYDIS_ASSERT(info->encoding == ZYDIS_INSTRUCTION_ENCODING_EVEX);
|
||||
ZYDIS_ASSERT(info->details.evex.isDecoded);
|
||||
*index = info->details.evex.z;
|
||||
return ZYDIS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static ZydisStatus ZydisNodeHandlerMvexE(ZydisInstructionInfo* info, uint16_t* index)
|
||||
{
|
||||
ZYDIS_ASSERT(info);
|
||||
|
@ -2655,7 +2684,10 @@ static ZydisStatus ZydisDecodeInstruction(ZydisDecoderContext* context, ZydisIns
|
|||
break;
|
||||
case ZYDIS_NODETYPE_FILTER_EVEX_B:
|
||||
status = ZydisNodeHandlerEvexB(info, &index);
|
||||
break;
|
||||
break;
|
||||
case ZYDIS_NODETYPE_FILTER_EVEX_Z:
|
||||
status = ZydisNodeHandlerEvexZ(info, &index);
|
||||
break;
|
||||
case ZYDIS_NODETYPE_FILTER_MVEX_E:
|
||||
status = ZydisNodeHandlerMvexE(info, &index);
|
||||
break;
|
||||
|
@ -2674,7 +2706,18 @@ static ZydisStatus ZydisDecodeInstruction(ZydisDecoderContext* context, ZydisIns
|
|||
if (info->encoding == ZYDIS_INSTRUCTION_ENCODING_3DNOW)
|
||||
{
|
||||
ZYDIS_CHECK(ZydisInputNext(context, info, &info->opcode));
|
||||
// TODO: Load new instruction definition
|
||||
node = ZydisInstructionTreeGetRootNode();
|
||||
node = ZydisInstructionTreeGetChildNode(node, 0x0F);
|
||||
node = ZydisInstructionTreeGetChildNode(node, 0x0F);
|
||||
node = ZydisInstructionTreeGetChildNode(node, info->opcode);
|
||||
if (node->type == ZYDIS_NODETYPE_INVALID)
|
||||
{
|
||||
return ZYDIS_STATUS_DECODING_ERROR;
|
||||
}
|
||||
ZYDIS_ASSERT(node->type == ZYDIS_NODETYPE_FILTER_MODRM_MOD_COMPACT);
|
||||
node = ZydisInstructionTreeGetChildNode(
|
||||
node, (info->details.modrm.mod == 0x3) ? 0 : 1);
|
||||
ZydisGetInstructionDefinition(node, &definition);
|
||||
}
|
||||
|
||||
info->mnemonic = definition->mnemonic;
|
||||
|
|
|
@ -229,6 +229,13 @@ extern const ZydisInstructionTreeNode filtersREXB[][2];
|
|||
*/
|
||||
extern const ZydisInstructionTreeNode filtersEVEXB[][2];
|
||||
|
||||
/**
|
||||
* @brief Contains all EVEX.z filters.
|
||||
*
|
||||
* Indexed by the numeric value of the EVEX.z field.
|
||||
*/
|
||||
extern const ZydisInstructionTreeNode filtersEVEXZ[][2];
|
||||
|
||||
/**
|
||||
* @brief Contains all MVEX.E filters.
|
||||
*
|
||||
|
@ -383,6 +390,9 @@ const ZydisInstructionTreeNode* ZydisInstructionTreeGetChildNode(
|
|||
case ZYDIS_NODETYPE_FILTER_EVEX_B:
|
||||
ZYDIS_ASSERT(index < 2);
|
||||
return &filtersEVEXB[parent->value][index];
|
||||
case ZYDIS_NODETYPE_FILTER_EVEX_Z:
|
||||
ZYDIS_ASSERT(index < 2);
|
||||
return &filtersEVEXZ[parent->value][index];
|
||||
case ZYDIS_NODETYPE_FILTER_MVEX_E:
|
||||
ZYDIS_ASSERT(index < 2);
|
||||
return &filtersMVEXE[parent->value][index];
|
||||
|
|
Loading…
Reference in New Issue