summaryrefslogtreecommitdiffstats
path: root/tools/perf/util/intel-pt-decoder/insn.c
diff options
context:
space:
mode:
authorIngo Molnar <mingo@kernel.org>2016-07-25 19:48:41 +0200
committerIngo Molnar <mingo@kernel.org>2016-07-25 19:48:41 +0200
commit674d2d69b14f677a771ceec4b48bfade94a0c5f1 (patch)
tree1413429fd703b57aaf9f5b7fdab4b283b32b13cd /tools/perf/util/intel-pt-decoder/insn.c
parent5048c2af078d5976895d521262a8802ea791f3b0 (diff)
parent4e3ba8af21b00b91b451e7c4a9fa3a63b025dd56 (diff)
downloadlinux-674d2d69b14f677a771ceec4b48bfade94a0c5f1.tar.bz2
Merge tag 'perf-core-for-mingo-20160725' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/core
Pull perf/core improvements and fixes from Arnaldo Carvalho de Melo: - Add AVX-512 support to the instruction decoder, used by Intel PT, fix vcvtph2ps instruction decoding (Adrian Hunter) - Make objtool and vdso2c use the right arch header search path (Stephen Rothwell, Josh Poimboeuf, Arnaldo Carvalho de Melo) Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'tools/perf/util/intel-pt-decoder/insn.c')
-rw-r--r--tools/perf/util/intel-pt-decoder/insn.c18
1 files changed, 15 insertions, 3 deletions
diff --git a/tools/perf/util/intel-pt-decoder/insn.c b/tools/perf/util/intel-pt-decoder/insn.c
index 9f26eae6c9f0..ca983e2bea8b 100644
--- a/tools/perf/util/intel-pt-decoder/insn.c
+++ b/tools/perf/util/intel-pt-decoder/insn.c
@@ -155,14 +155,24 @@ found:
/*
* In 32-bits mode, if the [7:6] bits (mod bits of
* ModRM) on the second byte are not 11b, it is
- * LDS or LES.
+ * LDS or LES or BOUND.
*/
if (X86_MODRM_MOD(b2) != 3)
goto vex_end;
}
insn->vex_prefix.bytes[0] = b;
insn->vex_prefix.bytes[1] = b2;
- if (inat_is_vex3_prefix(attr)) {
+ if (inat_is_evex_prefix(attr)) {
+ b2 = peek_nbyte_next(insn_byte_t, insn, 2);
+ insn->vex_prefix.bytes[2] = b2;
+ b2 = peek_nbyte_next(insn_byte_t, insn, 3);
+ insn->vex_prefix.bytes[3] = b2;
+ insn->vex_prefix.nbytes = 4;
+ insn->next_byte += 4;
+ if (insn->x86_64 && X86_VEX_W(b2))
+ /* VEX.W overrides opnd_size */
+ insn->opnd_bytes = 8;
+ } else if (inat_is_vex3_prefix(attr)) {
b2 = peek_nbyte_next(insn_byte_t, insn, 2);
insn->vex_prefix.bytes[2] = b2;
insn->vex_prefix.nbytes = 3;
@@ -221,7 +231,9 @@ void insn_get_opcode(struct insn *insn)
m = insn_vex_m_bits(insn);
p = insn_vex_p_bits(insn);
insn->attr = inat_get_avx_attribute(op, m, p);
- if (!inat_accept_vex(insn->attr) && !inat_is_group(insn->attr))
+ if ((inat_must_evex(insn->attr) && !insn_is_evex(insn)) ||
+ (!inat_accept_vex(insn->attr) &&
+ !inat_is_group(insn->attr)))
insn->attr = 0; /* This instruction is bad */
goto end; /* VEX has only 1 byte for opcode */
}