Replaced `EVEX.z` filter by `acceptsZeroMask` attribute

This commit is contained in:
flobernd 2017-07-14 22:54:22 +02:00
parent 5bdc173649
commit 53e89b0800
10 changed files with 10087 additions and 11234 deletions

View File

@ -546,11 +546,12 @@ enum ZydisMaskModes
{
ZYDIS_MASK_MODE_INVALID,
/**
* @brief Merge mode. This is the default mode for all EVEX-instructions.
* @brief The embedded mask register is used as a merge-mask. This is the default mode for
* all EVEX/MVEX-instructions.
*/
ZYDIS_MASK_MODE_MERGE,
/**
* @brief The zeroing mode is enabled for this instruction.
* @brief The embedded mask register is used as a zero-mask.
*/
ZYDIS_MASK_MODE_ZERO
};
@ -705,6 +706,10 @@ typedef struct ZydisDecodedInstruction_
* @brief The effective operand size.
*/
uint8_t operandSize;
/**
* @brief The stack width.
*/
uint8_t stackWidth;
/**
* @brief The effective address width.
*/
@ -756,9 +761,23 @@ typedef struct ZydisDecodedInstruction_
*/
ZydisVectorLength vectorLength;
/**
* @brief The AVX mask-mode.
* @brief Info about the embedded writemask-register.
*/
ZydisMaskMode maskMode;
struct
{
/**
* @brief The masking mode.
*/
ZydisMaskMode mode;
/**
* @brief The mask register.
*/
ZydisRegister reg;
/**
* @brief Signals, if the mask-register is used as a control mask.
*/
ZydisBool isControlMask;
} mask;
/**
* @brief Contains info about the AVX broadcast-factor.
*/

View File

@ -1936,7 +1936,7 @@ FinalizeOperand:
// Fix operand-action for EVEX instructions with merge-mask
if (((instruction->encoding == ZYDIS_INSTRUCTION_ENCODING_EVEX) ||
(instruction->encoding == ZYDIS_INSTRUCTION_ENCODING_MVEX)) &&
(instruction->avx.maskMode == ZYDIS_MASK_MODE_MERGE) &&
(instruction->avx.mask.mode == ZYDIS_MASK_MODE_MERGE) &&
(instruction->operandCount >= 3) &&
(instruction->operands[1].type == ZYDIS_OPERAND_TYPE_REGISTER) &&
(instruction->operands[1].reg >= ZYDIS_REGISTER_K1) &&
@ -2180,6 +2180,9 @@ static void ZydisSetAccessedFlags(ZydisDecodedInstruction* instruction,
{
const ZydisAccessedFlags* flags;
ZydisGetAccessedFlags(definition, &flags);
ZYDIS_ASSERT(ZYDIS_ARRAY_SIZE(instruction->flags) == ZYDIS_ARRAY_SIZE(flags->action));
memcpy(&instruction->flags, &flags->action, ZYDIS_ARRAY_SIZE(flags->action));
}
@ -2666,8 +2669,10 @@ static void ZydisSetAVXInformation(ZydisDecoderContext* context,
}
}
// Mask mode
instruction->avx.maskMode = ZYDIS_MASK_MODE_MERGE + instruction->raw.evex.z;
// Mask
instruction->avx.mask.mode = ZYDIS_MASK_MODE_MERGE + instruction->raw.evex.z;
instruction->avx.mask.reg = ZYDIS_REGISTER_K0 + instruction->raw.evex.aaa;
instruction->avx.mask.isControlMask = def->isControlMask;
break;
}
@ -2963,8 +2968,9 @@ static void ZydisSetAVXInformation(ZydisDecoderContext* context,
instruction->avx.hasEvictionHint = ZYDIS_TRUE;
}
// Mask mode
instruction->avx.maskMode = ZYDIS_MASK_MODE_MERGE;
// Mask
instruction->avx.mask.mode = ZYDIS_MASK_MODE_MERGE;
instruction->avx.mask.reg = ZYDIS_REGISTER_K0 + instruction->raw.mvex.kkk;
break;
}
@ -3922,17 +3928,6 @@ static ZydisStatus ZydisNodeHandlerEvexB(ZydisDecodedInstruction* instruction, u
return ZYDIS_STATUS_SUCCESS;
}
static ZydisStatus ZydisNodeHandlerEvexZ(ZydisDecodedInstruction* instruction, uint16_t* index)
{
ZYDIS_ASSERT(instruction);
ZYDIS_ASSERT(index);
ZYDIS_ASSERT(instruction->encoding == ZYDIS_INSTRUCTION_ENCODING_EVEX);
ZYDIS_ASSERT(instruction->raw.evex.isDecoded);
*index = instruction->raw.evex.z;
return ZYDIS_STATUS_SUCCESS;
}
static ZydisStatus ZydisNodeHandlerMvexE(ZydisDecodedInstruction* instruction, uint16_t* index)
{
ZYDIS_ASSERT(instruction);
@ -3998,6 +3993,13 @@ static ZydisStatus ZydisCheckErrorConditions(ZydisDecoderContext* context,
hasNDSNDDOperand = def->hasNDSNDDOperand;
hasVSIB = def->hasVSIB;
maskPolicy = def->maskPolicy;
// Check for invalid zero-mask
if ((instruction->raw.evex.z) && (!def->acceptsZeroMask))
{
return ZYDIS_STATUS_INVALID_MASK; // TODO: Dedicated status code
}
break;
}
case ZYDIS_INSTRUCTION_ENCODING_MVEX:
@ -4215,9 +4217,6 @@ static ZydisStatus ZydisDecodeInstruction(ZydisDecoderContext* context,
case ZYDIS_NODETYPE_FILTER_EVEX_B:
status = ZydisNodeHandlerEvexB(instruction, &index);
break;
case ZYDIS_NODETYPE_FILTER_EVEX_Z:
status = ZydisNodeHandlerEvexZ(instruction, &index);
break;
case ZYDIS_NODETYPE_FILTER_MVEX_E:
status = ZydisNodeHandlerMvexE(instruction, &index);
break;
@ -4271,7 +4270,12 @@ static ZydisStatus ZydisDecodeInstruction(ZydisDecoderContext* context,
break;
}
ZYDIS_CHECK(ZydisDecodeOperands(context, instruction, definition));
ZydisSetAccessedFlags(instruction, definition);
ZydisRegister reg = instruction->operands[instruction->operandCount - 1].reg;
if ((reg == ZYDIS_REGISTER_FLAGS ) || (reg == ZYDIS_REGISTER_EFLAGS) ||
(reg == ZYDIS_REGISTER_RFLAGS))
{
ZydisSetAccessedFlags(instruction, definition);
}
}
return ZYDIS_STATUS_SUCCESS;
@ -4355,6 +4359,7 @@ ZydisStatus ZydisDecoderDecodeBuffer(const ZydisDecoder* decoder, const void* bu
void* userData = instruction->userData;
memset(instruction, 0, sizeof(*instruction));
instruction->machineMode = decoder->machineMode;
instruction->stackWidth = decoder->addressWidth;
instruction->encoding = ZYDIS_INSTRUCTION_ENCODING_DEFAULT;
instruction->instrAddress = instructionPointer;
instruction->userData = userData;

View File

@ -228,13 +228,6 @@ extern const ZydisDecoderTreeNode filtersREXB[][2];
*/
extern const ZydisDecoderTreeNode filtersEVEXB[][2];
/**
* @brief Contains all EVEX.z filters.
*
* Indexed by the numeric value of the EVEX.z field.
*/
extern const ZydisDecoderTreeNode filtersEVEXZ[][2];
/**
* @brief Contains all MVEX.E filters.
*
@ -337,9 +330,6 @@ const ZydisDecoderTreeNode* ZydisDecoderTreeGetChildNode(const ZydisDecoderTreeN
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];

View File

@ -133,14 +133,10 @@ enum ZydisDecoderTreeNodeTypes
* @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 = 0x13,
ZYDIS_NODETYPE_FILTER_MVEX_E = 0x12
};
/* ---------------------------------------------------------------------------------------------- */

View File

@ -73,7 +73,6 @@ typedef struct ZydisEncodableInstruction_
uint8_t rexW ZYDIS_BITFIELD( 1);
uint8_t rexB ZYDIS_BITFIELD( 2);
uint8_t evexB ZYDIS_BITFIELD( 1);
uint8_t evexZ ZYDIS_BITFIELD( 2);
uint8_t mvexE ZYDIS_BITFIELD( 2);
} ZydisEncodableInstruction;

View File

@ -507,6 +507,8 @@ static ZydisStatus ZydisFormatterPrintOperandSizeIntel(const ZydisFormatter* for
return ZYDIS_STATUS_INVALID_PARAMETER;
}
// TODO: refactor
uint32_t typecast = 0;
if (formatter->flags & ZYDIS_FMTFLAG_FORCE_OPERANDSIZE)
{
@ -656,7 +658,7 @@ static ZydisStatus ZydisFormatterPrintDecoratorIntel(const ZydisFormatter* forma
}
ZYDIS_CHECK(ZydisStringBufferAppendFormat(
buffer, bufEnd - *buffer, ZYDIS_APPENDMODE, " {%s}", reg));
if (instruction->avx.maskMode == ZYDIS_MASK_MODE_ZERO)
if (instruction->avx.mask.mode == ZYDIS_MASK_MODE_ZERO)
{
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {z}"));
@ -914,52 +916,48 @@ static ZydisStatus ZydisFormatterFormatInstrIntel(const ZydisFormatter* formatte
if ((instruction->encoding == ZYDIS_INSTRUCTION_ENCODING_EVEX) ||
(instruction->encoding == ZYDIS_INSTRUCTION_ENCODING_MVEX))
{
if (i == 0)
if ((i == 0) &&
(instruction->operands[i + 1].encoding == ZYDIS_OPERAND_ENCODING_MASK))
{
if (instruction->operands[i + 1].encoding == ZYDIS_OPERAND_ENCODING_MASK)
ZYDIS_CHECK(formatter->funcPrintDecorator(formatter, buffer,
bufEnd - *buffer, instruction, &instruction->operands[i],
ZYDIS_DECORATOR_TYPE_MASK, instruction->operands[i + 1].reg));
}
if (instruction->operands[i].type == ZYDIS_OPERAND_TYPE_MEMORY)
{
ZYDIS_CHECK(formatter->funcPrintDecorator(formatter, buffer,
bufEnd - *buffer, instruction, &instruction->operands[i],
ZYDIS_DECORATOR_TYPE_BROADCAST, ZYDIS_REGISTER_NONE));
if (instruction->encoding == ZYDIS_INSTRUCTION_ENCODING_MVEX)
{
ZYDIS_CHECK(formatter->funcPrintDecorator(formatter, buffer,
bufEnd - *buffer, instruction, &instruction->operands[i],
ZYDIS_DECORATOR_TYPE_MASK, instruction->operands[i + 1].reg));
ZYDIS_DECORATOR_TYPE_CONVERSION, ZYDIS_REGISTER_NONE));
ZYDIS_CHECK(formatter->funcPrintDecorator(formatter, buffer,
bufEnd - *buffer, instruction, &instruction->operands[i],
ZYDIS_DECORATOR_TYPE_EVICTION_HINT, ZYDIS_REGISTER_NONE));
}
} else
{
if (instruction->operands[i].type == ZYDIS_OPERAND_TYPE_MEMORY)
{
ZYDIS_CHECK(formatter->funcPrintDecorator(formatter, buffer,
bufEnd - *buffer, instruction, &instruction->operands[i],
ZYDIS_DECORATOR_TYPE_BROADCAST, ZYDIS_REGISTER_NONE));
if ((i == (instruction->operandCount - 1)) ||
(instruction->operands[i + 1].type == ZYDIS_OPERAND_TYPE_IMMEDIATE))
{
if (instruction->encoding == ZYDIS_INSTRUCTION_ENCODING_MVEX)
{
ZYDIS_CHECK(formatter->funcPrintDecorator(formatter, buffer,
bufEnd - *buffer, instruction, &instruction->operands[i],
ZYDIS_DECORATOR_TYPE_CONVERSION, ZYDIS_REGISTER_NONE));
ZYDIS_DECORATOR_TYPE_SWIZZLE, ZYDIS_REGISTER_NONE));
}
if (instruction->avx.roundingMode)
{
ZYDIS_CHECK(formatter->funcPrintDecorator(formatter, buffer,
bufEnd - *buffer, instruction, &instruction->operands[i],
ZYDIS_DECORATOR_TYPE_EVICTION_HINT, ZYDIS_REGISTER_NONE));
}
} else
{
if ((i == (instruction->operandCount - 1)) ||
(instruction->operands[i + 1].type == ZYDIS_OPERAND_TYPE_IMMEDIATE))
{
if (instruction->encoding == ZYDIS_INSTRUCTION_ENCODING_MVEX)
{
ZYDIS_CHECK(formatter->funcPrintDecorator(formatter, buffer,
bufEnd - *buffer, instruction, &instruction->operands[i],
ZYDIS_DECORATOR_TYPE_SWIZZLE, ZYDIS_REGISTER_NONE));
}
if (instruction->avx.roundingMode)
{
ZYDIS_CHECK(formatter->funcPrintDecorator(formatter, buffer,
bufEnd - *buffer, instruction, &instruction->operands[i],
ZYDIS_DECORATOR_TYPE_ROUNDING_CONTROL, ZYDIS_REGISTER_NONE));
} else
{
ZYDIS_CHECK(formatter->funcPrintDecorator(formatter, buffer,
bufEnd - *buffer, instruction, &instruction->operands[i],
ZYDIS_DECORATOR_TYPE_SAE, ZYDIS_REGISTER_NONE));
}
ZYDIS_DECORATOR_TYPE_ROUNDING_CONTROL, ZYDIS_REGISTER_NONE));
} else
{
ZYDIS_CHECK(formatter->funcPrintDecorator(formatter, buffer,
bufEnd - *buffer, instruction, &instruction->operands[i],
ZYDIS_DECORATOR_TYPE_SAE, ZYDIS_REGISTER_NONE));
}
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -603,6 +603,8 @@ typedef struct ZydisInstructionDefinitionEVEX_
ZydisInternalElementSize elementSize ZYDIS_BITFIELD( 4);
ZydisEVEXFunctionality functionality ZYDIS_BITFIELD( 2);
ZydisMaskPolicy maskPolicy ZYDIS_BITFIELD( 2);
ZydisBool acceptsZeroMask ZYDIS_BITFIELD( 1);
ZydisBool isControlMask ZYDIS_BITFIELD( 1);
ZydisEVEXStaticBroadcast broadcast ZYDIS_BITFIELD( 4);
} ZydisInstructionDefinitionEVEX;