Skip to content

Commit

Permalink
APX progress
Browse files Browse the repository at this point in the history
- Add `EVEX.U` filter (required for AVX 10.2 in the future)
- Add `avx.has_apx_nf` and `avx.has_apx_zu` flags
- Rename `avx.scc` to `avx.apx_scc`
- Rename certain enum default case elements from `_INVALID` to `_NONE`
  • Loading branch information
flobernd committed Oct 30, 2024
1 parent 2031c37 commit fa5240c
Show file tree
Hide file tree
Showing 12 changed files with 7,013 additions and 6,247 deletions.
34 changes: 26 additions & 8 deletions include/Zydis/DecoderTypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -566,7 +566,7 @@ typedef enum ZydisExceptionClass_
*/
typedef enum ZydisMaskMode_
{
ZYDIS_MASK_MODE_INVALID,
ZYDIS_MASK_MODE_NONE,
/**
* Masking is disabled for the current instruction (`K0` register is used).
*/
Expand Down Expand Up @@ -607,7 +607,7 @@ typedef enum ZydisMaskMode_
*/
typedef enum ZydisBroadcastMode_
{
ZYDIS_BROADCAST_MODE_INVALID,
ZYDIS_BROADCAST_MODE_NONE,
ZYDIS_BROADCAST_MODE_1_TO_2,
ZYDIS_BROADCAST_MODE_1_TO_4,
ZYDIS_BROADCAST_MODE_1_TO_8,
Expand Down Expand Up @@ -640,7 +640,7 @@ typedef enum ZydisBroadcastMode_
*/
typedef enum ZydisRoundingMode_
{
ZYDIS_ROUNDING_MODE_INVALID,
ZYDIS_ROUNDING_MODE_NONE,
/**
* Round to nearest.
*/
Expand Down Expand Up @@ -677,7 +677,7 @@ typedef enum ZydisRoundingMode_
*/
typedef enum ZydisSwizzleMode_
{
ZYDIS_SWIZZLE_MODE_INVALID,
ZYDIS_SWIZZLE_MODE_NONE,
ZYDIS_SWIZZLE_MODE_DCBA,
ZYDIS_SWIZZLE_MODE_CDAB,
ZYDIS_SWIZZLE_MODE_BADC,
Expand Down Expand Up @@ -706,7 +706,7 @@ typedef enum ZydisSwizzleMode_
*/
typedef enum ZydisConversionMode_
{
ZYDIS_CONVERSION_MODE_INVALID,
ZYDIS_CONVERSION_MODE_NONE,
ZYDIS_CONVERSION_MODE_FLOAT16,
ZYDIS_CONVERSION_MODE_SINT8,
ZYDIS_CONVERSION_MODE_UINT8,
Expand All @@ -732,7 +732,7 @@ typedef enum ZydisConversionMode_
*/
typedef enum ZydisSourceConditionCode_
{
ZYDIS_SCC_INVALID,
ZYDIS_SCC_NONE,
ZYDIS_SCC_O,
ZYDIS_SCC_NO,
ZYDIS_SCC_B,
Expand Down Expand Up @@ -1019,6 +1019,10 @@ typedef struct ZydisDecodedInstructionRawEvex_
* (inverted).
*/
ZyanU8 vvvv;
/**
* The `U`-bit.
*/
ZyanU8 U;
/**
* High-16 register specifier modifier for the `SIB.index/vidx` field (inverted).
*/
Expand All @@ -1040,7 +1044,7 @@ typedef struct ZydisDecodedInstructionRawEvex_
*/
ZyanU8 L;
/**
* Broadcast/RC/SAE context.
* Broadcast/RC/SAE control.
*/
ZyanU8 b;
/**
Expand Down Expand Up @@ -1206,7 +1210,21 @@ typedef struct ZydisDecodedInstructionAvx_
/**
* The AVX-512 APX source condition code.
*/
ZydisSourceConditionCode scc;
ZydisSourceConditionCode apx_scc;
/**
* Signals, if the APX `no flags` functionality enabled for the instruction.
*/
ZyanBool has_apx_nf;
/**
* Signals, if the APX `zero upper` functionality enabled for the instruction.
*/
ZyanBool has_apx_zu;
/**
* Signals, if the APX push/pop performance-hint (`PPX`) is enabled for the instruction.
*
* This flag is only valid for `push2` and `pop2`.
*/
ZyanBool has_apx_ppx;
// TODO: publish EVEX tuple-type and MVEX functionality
} ZydisDecodedInstructionAvx;

Expand Down
6 changes: 5 additions & 1 deletion include/Zydis/Internal/DecoderData.h
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,11 @@ enum ZydisDecoderTreeNodeTypes
/**
* Reference to a REX2-prefix filter.
*/
ZYDIS_NODETYPE_FILTER_REX2_PREFIX = 0x22
ZYDIS_NODETYPE_FILTER_REX2_PREFIX = 0x22,
/**
* Reference to a EVEX.U filter.
*/
ZYDIS_NODETYPE_FILTER_EVEX_U = 0x23
};

/* ---------------------------------------------------------------------------------------------- */
Expand Down
4 changes: 2 additions & 2 deletions include/Zydis/Internal/SharedData.h
Original file line number Diff line number Diff line change
Expand Up @@ -860,8 +860,8 @@ typedef struct ZydisInstructionDefinitionEVEX_
ZyanU8 broadcast ZYAN_BITFIELD(ZYDIS_EVEX_STATIC_BROADCAST_REQUIRED_BITS);
#endif
ZyanU8 is_eevex ZYAN_BITFIELD( 1);
/*ZyanU8 accepts_zu ZYAN_BITFIELD( 1);
ZyanU8 accepts_nf ZYAN_BITFIELD( 1);*/
ZyanU8 has_apx_nf ZYAN_BITFIELD(1);
ZyanU8 has_apx_zu ZYAN_BITFIELD( 1);
} ZydisInstructionDefinitionEVEX;
#endif

Expand Down
8 changes: 1 addition & 7 deletions include/Zydis/SharedTypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -727,16 +727,10 @@ typedef ZyanU64 ZydisInstructionAttributes;
* The instruction has the `REX2` prefix.
*/
#define ZYDIS_ATTRIB_HAS_REX2 (1ULL << 46) // TODO: rebase
/**
* The instruction uses the APX source condition code.
*/
#define ZYDIS_ATTRIB_HAS_SCC (1ULL << 47)
/**
* The instruction has the `EEVEX` (extended `EVEX`) prefix.
*/
#define ZYDIS_ATTRIB_HAS_EEVEX (1ULL << 48) // TODO: rebase

// TODO: PPX Hint
#define ZYDIS_ATTRIB_HAS_EEVEX (1ULL << 47) // TODO: rebase

/**
* @}
Expand Down
74 changes: 44 additions & 30 deletions src/Decoder.c
Original file line number Diff line number Diff line change
Expand Up @@ -618,14 +618,11 @@ static ZyanStatus ZydisDecodeEVEX(const ZydisDecoder* decoder, ZydisDecoderConte

instruction->raw.evex.W = (data[2] >> 7) & 0x01;
instruction->raw.evex.vvvv = (data[2] >> 3) & 0x0F;
instruction->raw.evex.X4 = (data[2] >> 2) & 0x01;
// instruction->raw.evex.DFV = (data[2] >> 3) & 0x0F; // uses same bits as 'vvvv'
instruction->raw.evex.U = (data[2] >> 2) & 0x01;
instruction->raw.evex.X4 = (data[2] >> 2) & 0x01; // uses same bit as 'U'
instruction->raw.evex.pp = (data[2] >> 0) & 0x03;

if (!is_apx && (instruction->raw.evex.X4 != 0x01))
{
return ZYDIS_STATUS_MALFORMED_EVEX;
}

instruction->raw.evex.z = (data[3] >> 7) & 0x01;
instruction->raw.evex.L2 = (data[3] >> 6) & 0x01;
instruction->raw.evex.L = (data[3] >> 5) & 0x01;
Expand Down Expand Up @@ -1138,7 +1135,7 @@ static void ZydisSetOperandSizeAndElementInfo(const ZydisDecoderContext* context

switch (instruction->avx.conversion.mode)
{
case ZYDIS_CONVERSION_MODE_INVALID:
case ZYDIS_CONVERSION_MODE_NONE:
operand->size = 512;
switch (context->mvex.functionality)
{
Expand Down Expand Up @@ -1213,7 +1210,7 @@ static void ZydisSetOperandSizeAndElementInfo(const ZydisDecoderContext* context

switch (instruction->avx.broadcast.mode)
{
case ZYDIS_BROADCAST_MODE_INVALID:
case ZYDIS_BROADCAST_MODE_NONE:
// Nothing to do here
break;
case ZYDIS_BROADCAST_MODE_1_TO_8:
Expand Down Expand Up @@ -2413,7 +2410,7 @@ static void ZydisSetAVXInformation(ZydisDecoderContext* context,
instruction->avx.broadcast.is_static = ZYAN_TRUE;
static ZydisBroadcastMode broadcasts[ZYDIS_VEX_STATIC_BROADCAST_MAX_VALUE + 1] =
{
ZYDIS_BROADCAST_MODE_INVALID,
ZYDIS_BROADCAST_MODE_NONE,
ZYDIS_BROADCAST_MODE_1_TO_2,
ZYDIS_BROADCAST_MODE_1_TO_4,
ZYDIS_BROADCAST_MODE_1_TO_8,
Expand Down Expand Up @@ -2485,21 +2482,21 @@ static void ZydisSetAVXInformation(ZydisDecoderContext* context,
{
/*16*/
{
ZYDIS_BROADCAST_MODE_INVALID,
ZYDIS_BROADCAST_MODE_INVALID,
ZYDIS_BROADCAST_MODE_INVALID
ZYDIS_BROADCAST_MODE_NONE,
ZYDIS_BROADCAST_MODE_NONE,
ZYDIS_BROADCAST_MODE_NONE
},
/*32*/
{
ZYDIS_BROADCAST_MODE_INVALID,
ZYDIS_BROADCAST_MODE_INVALID,
ZYDIS_BROADCAST_MODE_INVALID
ZYDIS_BROADCAST_MODE_NONE,
ZYDIS_BROADCAST_MODE_NONE,
ZYDIS_BROADCAST_MODE_NONE
},
/*64*/
{
ZYDIS_BROADCAST_MODE_INVALID,
ZYDIS_BROADCAST_MODE_INVALID,
ZYDIS_BROADCAST_MODE_INVALID
ZYDIS_BROADCAST_MODE_NONE,
ZYDIS_BROADCAST_MODE_NONE,
ZYDIS_BROADCAST_MODE_NONE
}
},
/*B1*/
Expand Down Expand Up @@ -2552,15 +2549,15 @@ static void ZydisSetAVXInformation(ZydisDecoderContext* context,
{
/*16*/
{
ZYDIS_BROADCAST_MODE_INVALID,
ZYDIS_BROADCAST_MODE_INVALID,
ZYDIS_BROADCAST_MODE_INVALID
ZYDIS_BROADCAST_MODE_NONE,
ZYDIS_BROADCAST_MODE_NONE,
ZYDIS_BROADCAST_MODE_NONE
},
/*32*/
{
ZYDIS_BROADCAST_MODE_INVALID,
ZYDIS_BROADCAST_MODE_INVALID,
ZYDIS_BROADCAST_MODE_INVALID
ZYDIS_BROADCAST_MODE_NONE,
ZYDIS_BROADCAST_MODE_NONE,
ZYDIS_BROADCAST_MODE_NONE
}
},
/*B1*/
Expand Down Expand Up @@ -2741,9 +2738,9 @@ static void ZydisSetAVXInformation(ZydisDecoderContext* context,
{
/*B0*/
{
ZYDIS_BROADCAST_MODE_INVALID,
ZYDIS_BROADCAST_MODE_INVALID,
ZYDIS_BROADCAST_MODE_INVALID
ZYDIS_BROADCAST_MODE_NONE,
ZYDIS_BROADCAST_MODE_NONE,
ZYDIS_BROADCAST_MODE_NONE
},
/*B1*/
{
Expand Down Expand Up @@ -2772,7 +2769,7 @@ static void ZydisSetAVXInformation(ZydisDecoderContext* context,
instruction->avx.broadcast.is_static = ZYAN_TRUE;
static const ZydisBroadcastMode broadcasts[ZYDIS_EVEX_STATIC_BROADCAST_MAX_VALUE + 1] =
{
ZYDIS_BROADCAST_MODE_INVALID,
ZYDIS_BROADCAST_MODE_NONE,
ZYDIS_BROADCAST_MODE_1_TO_2,
ZYDIS_BROADCAST_MODE_1_TO_4,
ZYDIS_BROADCAST_MODE_1_TO_8,
Expand Down Expand Up @@ -4320,6 +4317,18 @@ static ZyanStatus ZydisNodeHandlerRexB(const ZydisDecoderContext* context,
}

#ifndef ZYDIS_DISABLE_AVX512

static ZyanStatus ZydisNodeHandlerEvexU(const ZydisDecodedInstruction* instruction, ZyanU16* index)
{
ZYAN_ASSERT(instruction);
ZYAN_ASSERT(index);

ZYAN_ASSERT(instruction->encoding == ZYDIS_INSTRUCTION_ENCODING_EVEX);
ZYAN_ASSERT(instruction->attributes & ZYDIS_ATTRIB_HAS_EVEX);
*index = instruction->raw.evex.U;
return ZYAN_STATUS_SUCCESS;
}

static ZyanStatus ZydisNodeHandlerEvexB(const ZydisDecodedInstruction* instruction, ZyanU16* index)
{
ZYAN_ASSERT(instruction);
Expand Down Expand Up @@ -4400,8 +4409,7 @@ static ZyanStatus ZydisNodeHandlerEvexSCC(ZydisDecoderContext* context,
context->vector_unified.vvvv = (~context->vector_unified.vvvv) & 0x0F;
context->vector_unified.V4 = 0;

instruction->attributes |= ZYDIS_ATTRIB_HAS_SCC;
instruction->avx.scc = ZYDIS_SCC_O + instruction->raw.evex.SCC;
instruction->avx.apx_scc = ZYDIS_SCC_O + instruction->raw.evex.SCC;

*index = instruction->raw.evex.SCC;
return ZYAN_STATUS_SUCCESS;
Expand Down Expand Up @@ -5108,6 +5116,9 @@ static ZyanStatus ZydisDecodeInstruction(ZydisDecoderState* state,
status = ZydisNodeHandlerRexB(state->context, instruction, &index);
break;
#ifndef ZYDIS_DISABLE_AVX512
case ZYDIS_NODETYPE_FILTER_EVEX_U:
status = ZydisNodeHandlerEvexU(instruction, &index);
break;
case ZYDIS_NODETYPE_FILTER_EVEX_B:
status = ZydisNodeHandlerEvexB(instruction, &index);
break;
Expand Down Expand Up @@ -5200,6 +5211,9 @@ static ZyanStatus ZydisDecodeInstruction(ZydisDecoderState* state,
{
instruction->attributes |= ZYDIS_ATTRIB_HAS_EEVEX;
}

instruction->avx.has_apx_nf = evex_definition->has_apx_nf;
instruction->avx.has_apx_zu = evex_definition->has_apx_zu;
}

instruction->mnemonic = definition->mnemonic;
Expand Down
3 changes: 3 additions & 0 deletions src/DecoderData.c
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,9 @@ const ZydisDecoderTreeNode* ZydisDecoderTreeGetChildNode(const ZydisDecoderTreeN
case ZYDIS_NODETYPE_FILTER_REX2_PREFIX:
ZYAN_ASSERT(index < 2);
return &FILTERS_REX2_PREFIX[parent->value][index];
case ZYDIS_NODETYPE_FILTER_EVEX_U:
ZYAN_ASSERT(index < 2);
return &FILTERS_EVEX_U[parent->value][index];
default:
ZYAN_UNREACHABLE;
}
Expand Down
Loading

0 comments on commit fa5240c

Please sign in to comment.