From dce4de037ddd1a59bd7d42ab30a662b142e2deba Mon Sep 17 00:00:00 2001 From: Florian Bernd Date: Thu, 31 Oct 2024 13:29:48 +0100 Subject: [PATCH] Add `uses_egpr` APX info --- include/Zydis/DecoderTypes.h | 4 ++++ src/Decoder.c | 17 +++++++++++++++-- tools/ZydisInfo.c | 5 +++-- 3 files changed, 22 insertions(+), 4 deletions(-) diff --git a/include/Zydis/DecoderTypes.h b/include/Zydis/DecoderTypes.h index 3c7a3312..f4179872 100644 --- a/include/Zydis/DecoderTypes.h +++ b/include/Zydis/DecoderTypes.h @@ -1215,6 +1215,10 @@ typedef struct ZydisDecodedInstructionAvx_ */ typedef struct ZydisDecodedInstructionApx_ { + /** + * Signals, if the instruction uses the extended GRP registers (R16..R31). + */ + ZyanBool uses_egpr; /** * Signals, if the APX `no flags` functionality enabled for the instruction. */ diff --git a/src/Decoder.c b/src/Decoder.c index 5098016f..621e2eaf 100644 --- a/src/Decoder.c +++ b/src/Decoder.c @@ -4450,7 +4450,7 @@ static ZyanStatus ZydisNodeHandlerMvexE(const ZydisDecodedInstruction* instructi * - `def_vvvv` -> `ZydisRegisterKind` */ static ZyanStatus ZydisPopulateRegisterIds(ZydisDecoderContext* context, - const ZydisDecodedInstruction* instruction, ZyanU8 def_reg, ZyanU8 def_rm, ZyanU8 def_vvvv) + ZydisDecodedInstruction* instruction, ZyanU8 def_reg, ZyanU8 def_rm, ZyanU8 def_vvvv) { ZYAN_ASSERT(context); ZYAN_ASSERT(instruction); @@ -4673,6 +4673,19 @@ static ZyanStatus ZydisPopulateRegisterIds(ZydisDecoderContext* context, context->reg_info.id_base = !is_mod_reg ? id_base : -1; context->reg_info.id_index = !is_mod_reg ? id_index : -1; + // Update APX info + + const ZyanBool has_egpr_reg = (def_reg == ZYDIS_REGKIND_GPR) && (id_reg >= 16); + const ZyanBool has_egpr_rm = is_mod_reg && (def_rm == ZYDIS_REGKIND_GPR) && (id_rm >= 16); + const ZyanBool has_egpr_vvvv = (def_vvvv == ZYDIS_REGKIND_GPR) && (id_vvvv >= 16); + const ZyanBool has_egpr_base = !is_mod_reg && (id_base >= 16); + const ZyanBool has_egpr_index = !is_mod_reg && !has_vsib && (id_index >= 16); + + if (has_egpr_reg || has_egpr_rm || has_egpr_vvvv || has_egpr_base || has_egpr_index) + { + instruction->apx.uses_egpr = ZYAN_TRUE; + } + return ZYAN_STATUS_SUCCESS; } @@ -4688,7 +4701,7 @@ static ZyanStatus ZydisPopulateRegisterIds(ZydisDecoderContext* context, * This function is called immediately after a valid instruction-definition was found. */ static ZyanStatus ZydisCheckErrorConditions(ZydisDecoderState* state, - const ZydisDecodedInstruction* instruction, const ZydisInstructionDefinition* definition) + ZydisDecodedInstruction* instruction, const ZydisInstructionDefinition* definition) { ZYAN_ASSERT(state); ZYAN_ASSERT(instruction); diff --git a/tools/ZydisInfo.c b/tools/ZydisInfo.c index 8a81e6ab..ad265819 100644 --- a/tools/ZydisInfo.c +++ b/tools/ZydisInfo.c @@ -863,8 +863,9 @@ static void PrintAPXInfo(const ZydisDecodedInstruction* instruction) PrintSectionHeader("APX"); - PRINT_VALUE_B("NF", "%s", instruction->apx.has_nf ? "Y" : "N"); - PRINT_VALUE_B("ZU", "%s", instruction->apx.has_zu ? "Y" : "N"); + PRINT_VALUE_B("USES_EGPR", "%s", instruction->apx.uses_egpr ? "Y" : "N"); + PRINT_VALUE_B("HAS_NF", "%s", instruction->apx.has_nf ? "Y" : "N"); + PRINT_VALUE_B("HAS_ZU", "%s", instruction->apx.has_zu ? "Y" : "N"); PRINT_VALUE_B("SCC", "%s", strings_scc[instruction->apx.scc]); }