@@ -603,7 +603,7 @@ static ZyanStatus ZydisDecodeEVEX(const ZydisDecoder* decoder, ZydisDecoderConte
603
603
instruction -> raw .evex .mmm = (data [1 ] >> 0 ) & 0x07 ;
604
604
605
605
const ZyanBool is_apx = ZYDIS_DECODER_MODE_ACTIVE (decoder , ZYDIS_DECODER_MODE_APX );
606
- if (!is_apx && (data [ 1 ] & 0x08 )) // TODO: This condition might have to as well consider AVX 10.2 besides APX
606
+ if (!is_apx && (instruction -> raw . evex . B4 != 0 )) // TODO: This condition might have to as well consider AVX 10.2 besides APX
607
607
{
608
608
// Invalid according to the intel documentation
609
609
return ZYDIS_STATUS_MALFORMED_EVEX ;
@@ -4315,14 +4315,23 @@ static ZyanStatus ZydisNodeHandlerEvexU(const ZydisDecoderState* state,
4315
4315
ZYAN_ASSERT (instruction -> encoding == ZYDIS_INSTRUCTION_ENCODING_EVEX );
4316
4316
ZYAN_ASSERT (instruction -> attributes & ZYDIS_ATTRIB_HAS_EVEX );
4317
4317
4318
- // TODO: Reevaluate this condition when adding AVX10.2 support.
4319
- ZYAN_ASSERT (ZYDIS_DECODER_MODE_ACTIVE (state -> decoder , ZYDIS_DECODER_MODE_APX ));
4318
+ * index = instruction -> raw .evex .U ;
4320
4319
4321
- // The `evex.u` filter requires a preceding `modrm.mod == 3` filter.
4322
- ZYAN_ASSERT (instruction -> attributes & ZYDIS_ATTRIB_HAS_MODRM );
4323
- ZYAN_ASSERT (instruction -> raw .modrm .mod == 3 );
4320
+ if (!ZYDIS_DECODER_MODE_ACTIVE (state -> decoder , ZYDIS_DECODER_MODE_APX )) // TODO: AVX10.2
4321
+ {
4322
+ return ZYAN_STATUS_SUCCESS ;
4323
+ }
4324
4324
4325
- * index = instruction -> raw .evex .U ;
4325
+ if ((instruction -> attributes & ZYDIS_ATTRIB_HAS_MODRM ) && (instruction -> raw .modrm .mod != 3 ))
4326
+ {
4327
+ // APX reinterprets `EVEX.U` as `EVEX.X4` for instructions with memory operands
4328
+ // (`modrm.mod != 3`).
4329
+
4330
+ // We don't care about the actual value of `EVEX.U` in this case and force it to `1` to
4331
+ // emulate legacy `EVEX` instruction behavior.
4332
+
4333
+ * index = 1 ;
4334
+ }
4326
4335
4327
4336
return ZYAN_STATUS_SUCCESS ;
4328
4337
}
@@ -4668,11 +4677,14 @@ static ZyanStatus ZydisPopulateRegisterIds(ZydisDecoderContext* context,
4668
4677
4669
4678
// Assign to context
4670
4679
4680
+ const ZyanBool has_base = !is_mod_reg && !(instruction -> raw .modrm .mod == 0 && id_base == 5 );
4681
+ const ZyanBool has_index = has_sib && (instruction -> raw .sib .index != 4 );
4682
+
4671
4683
context -> reg_info .id_reg = def_reg ? id_reg : -1 ;
4672
4684
context -> reg_info .id_rm = def_rm && is_mod_reg ? id_rm : -1 ;
4673
4685
context -> reg_info .id_ndsndd = def_vvvv ? id_vvvv : -1 ;
4674
- context -> reg_info .id_base = ! is_mod_reg ? id_base : -1 ;
4675
- context -> reg_info .id_index = ! is_mod_reg ? id_index : -1 ;
4686
+ context -> reg_info .id_base = has_base ? id_base : -1 ;
4687
+ context -> reg_info .id_index = has_index ? id_index : -1 ;
4676
4688
4677
4689
// Update APX info
4678
4690
@@ -4684,9 +4696,8 @@ static ZyanStatus ZydisPopulateRegisterIds(ZydisDecoderContext* context,
4684
4696
const ZyanBool has_egpr_reg = (def_reg == ZYDIS_REGKIND_GPR ) && (id_reg >= 16 );
4685
4697
const ZyanBool has_egpr_rm = is_mod_reg && (def_rm == ZYDIS_REGKIND_GPR ) && (id_rm >= 16 );
4686
4698
const ZyanBool has_egpr_vvvv = (def_vvvv == ZYDIS_REGKIND_GPR ) && (id_vvvv >= 16 );
4687
- const ZyanBool has_egpr_base = !is_mod_reg && (id_base >= 16 ) &&
4688
- ((instruction -> raw .modrm .mod != 0 ) || (instruction -> raw .modrm .rm != 5 ));
4689
- const ZyanBool has_egpr_index = !is_mod_reg && !has_vsib && (id_index >= 16 );
4699
+ const ZyanBool has_egpr_base = has_base && (id_base >= 16 );
4700
+ const ZyanBool has_egpr_index = has_index && !has_vsib && (id_index >= 16 );
4690
4701
4691
4702
if (has_egpr_reg || has_egpr_rm || has_egpr_vvvv || has_egpr_base || has_egpr_index )
4692
4703
{
0 commit comments