diff --git a/assemble.c b/assemble.c index c5f8172e..245aea44 100644 --- a/assemble.c +++ b/assemble.c @@ -64,9 +64,11 @@ * VEX prefixes are followed by the sequence: * \mm\wlp where mm is the M field; and wlp is: * 00 0ww lpp - * ww = 0 for W = 0 - * ww = 1 for W = 1 - * ww = 2 for W used as REX.W + * [w0] ww = 0 for W = 0 + * [w1] ww = 1 for W = 1 + * [wx] ww = 2 for W don't care (always assembled as 0) + * [ww] ww = 3 for W used as REX.W + * * * \310 - indicates fixed 16-bit address size, i.e. optional 0x67. * \311 - indicates fixed 32-bit address size, i.e. optional 0x67. @@ -1159,13 +1161,14 @@ static int64_t calcsize(int32_t segment, int64_t offset, int bits, } switch (ins->vex_wlp & 030) { case 000: + case 020: ins->rex &= ~REX_W; break; case 010: ins->rex |= REX_W; bad32 &= ~REX_W; break; - default: + case 030: /* Follow REX_W */ break; } diff --git a/disasm.c b/disasm.c index 33cdfd42..77b87b03 100644 --- a/disasm.c +++ b/disasm.c @@ -709,9 +709,13 @@ static int matches(const struct itemplate *t, uint8_t *data, case 010: if (!(prefix->rex & REX_W)) return false; + ins->rex &= ~REX_W; + break; + case 020: /* VEX.W is a don't care */ + ins->rex &= ~REX_W; + break; + case 030: break; - default: - break; /* XXX: Need to do anything special here? */ } if ((vexwlp & 007) != prefix->vex_lp) diff --git a/insns.pl b/insns.pl index 7d667786..36a82e69 100644 --- a/insns.pl +++ b/insns.pl @@ -611,6 +611,10 @@ sub byte_code_compile($) { $w = 0; } elsif ($oq eq 'w1') { $w = 1; + } elsif ($oq eq 'wx') { + $w = 2; + } elsif ($oq eq 'ww') { + $w = 3; } elsif ($oq eq '66') { $p = 1; } elsif ($oq eq 'f3') {