diff options
author | Jin Kyu Song <jin.kyu.song@intel.com> | 2014-05-05 13:58:51 -0700 |
---|---|---|
committer | Jin Kyu Song <jin.kyu.song@intel.com> | 2014-05-05 13:58:51 -0700 |
commit | abdc8bdea2f2834d442e0ecf8dfdd16d7a17a6f2 (patch) | |
tree | 6b19ae08e04e166952b954412b2847341b01f1c0 /disasm.c | |
parent | eb29cf7b31e097237bab41759ecdbe1ed4c7e45d (diff) | |
download | nasm-abdc8bdea2f2834d442e0ecf8dfdd16d7a17a6f2.tar.gz nasm-abdc8bdea2f2834d442e0ecf8dfdd16d7a17a6f2.tar.bz2 nasm-abdc8bdea2f2834d442e0ecf8dfdd16d7a17a6f2.zip |
ndisasm: Match vector length with EVEX.b set
With broadcasting, EVEX.L'L should be matched even when EVEX.b is set.
Only in a case of embedded rounding, EVEX.L'L is ignored in matching
function since it becomes EVEX.RC.
Signed-off-by: Jin Kyu Song <jin.kyu.song@intel.com>
Diffstat (limited to 'disasm.c')
-rw-r--r-- | disasm.c | 14 |
1 files changed, 11 insertions, 3 deletions
@@ -726,7 +726,9 @@ static int matches(const struct itemplate *t, uint8_t *data, { uint8_t evexm = *r++; uint8_t evexwlp = *r++; + uint8_t modrm, valid_mask; ins->evex_tuple = *r++ - 0300; + modrm = *(origdata + 1); ins->rex |= REX_EV; if ((prefix->rex & (REX_EV|REX_V|REX_P)) != REX_EV) @@ -752,9 +754,15 @@ static int matches(const struct itemplate *t, uint8_t *data, break; } - /* If EVEX.b is set, EVEX.L'L can be rounding control bits */ - if ((evexwlp ^ prefix->vex_lp) & - ((prefix->evex[2] & EVEX_P2B) ? 0x03 : 0x0f)) + /* If EVEX.b is set with reg-reg op, + * EVEX.L'L contains embedded rounding control info + */ + if ((prefix->evex[2] & EVEX_P2B) && ((modrm >> 6) == 3)) { + valid_mask = 0x3; /* prefix only */ + } else { + valid_mask = 0xf; /* vector length and prefix */ + } + if ((evexwlp ^ prefix->vex_lp) & valid_mask) return false; if (c == 0250) { |