summaryrefslogtreecommitdiff
path: root/disasm.c
diff options
context:
space:
mode:
authorJin Kyu Song <jin.kyu.song@intel.com>2014-05-05 13:58:51 -0700
committerJin Kyu Song <jin.kyu.song@intel.com>2014-05-05 13:58:51 -0700
commitabdc8bdea2f2834d442e0ecf8dfdd16d7a17a6f2 (patch)
tree6b19ae08e04e166952b954412b2847341b01f1c0 /disasm.c
parenteb29cf7b31e097237bab41759ecdbe1ed4c7e45d (diff)
downloadnasm-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.c14
1 files changed, 11 insertions, 3 deletions
diff --git a/disasm.c b/disasm.c
index bb53b4c..2f68b1d 100644
--- a/disasm.c
+++ b/disasm.c
@@ -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) {