diff --git a/libudis86/decode.c b/libudis86/decode.c index 2e147de..e179a36 100644 --- a/libudis86/decode.c +++ b/libudis86/decode.c @@ -277,21 +277,23 @@ modrm(struct ud * u) static unsigned int -resolve_operand_size( const struct ud * u, unsigned int s ) +resolve_operand_size(const struct ud* u, enum ud_operand_size osize) { - switch ( s ) - { - case SZ_V: - return ( u->opr_mode ); - case SZ_Z: - return ( u->opr_mode == 16 ) ? 16 : 32; - case SZ_Y: - return ( u->opr_mode == 16 ) ? 32 : u->opr_mode; - case SZ_RDQ: - return ( u->dis_mode == 64 ) ? 64 : 32; - default: - return s; - } + switch (osize) { + case SZ_V: + return u->opr_mode; + case SZ_Z: + return u->opr_mode == 16 ? 16 : 32; + case SZ_Y: + return u->opr_mode == 16 ? 32 : u->opr_mode; + case SZ_RDQ: + return u->dis_mode == 64 ? 64 : 32; + case SZ_X: + UD_ASSERT(u->vex_op != 0); + return (P_VEXL(u->itab_entry->prefix) && vex_l(u)) ? SZ_QQ : SZ_DQ; + default: + return osize; + } } @@ -391,8 +393,7 @@ decode_reg(struct ud *u, case REGCLASS_GPR : reg = decode_gpr(u, size, num); break; case REGCLASS_MMX : reg = UD_R_MM0 + (num & 7); break; case REGCLASS_XMM : - reg = ((u->vex_op != 0 && P_VEXL(u->itab_entry->prefix) && vex_l(u)) - ? UD_R_YMM0 : UD_R_XMM0) + num; + reg = num + (size == SZ_QQ ? UD_R_YMM0 : UD_R_XMM0); break; case REGCLASS_CR : reg = UD_R_CR0 + num; break; case REGCLASS_DB : reg = UD_R_DR0 + num; break; diff --git a/libudis86/decode.h b/libudis86/decode.h index 1d3c07d..338ab26 100644 --- a/libudis86/decode.h +++ b/libudis86/decode.h @@ -119,8 +119,11 @@ enum ud_operand_size { SZ_Q = 64, SZ_T = 80, SZ_O = 128, + SZ_DQ = 128, /* double quad */ + SZ_QQ = 256, /* quad quad */ SZ_Y = 17, + SZ_X = 18, /* * complex size types, that encode sizes for operands