Commit 674d2d69 authored by Ingo Molnar's avatar Ingo Molnar

Merge tag 'perf-core-for-mingo-20160725' of...

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: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: default avatarIngo Molnar <mingo@kernel.org>
parents 5048c2af 4e3ba8af
...@@ -55,7 +55,7 @@ VDSO_LDFLAGS_vdso.lds = -m64 -Wl,-soname=linux-vdso.so.1 \ ...@@ -55,7 +55,7 @@ VDSO_LDFLAGS_vdso.lds = -m64 -Wl,-soname=linux-vdso.so.1 \
$(obj)/vdso64.so.dbg: $(src)/vdso.lds $(vobjs) FORCE $(obj)/vdso64.so.dbg: $(src)/vdso.lds $(vobjs) FORCE
$(call if_changed,vdso) $(call if_changed,vdso)
HOST_EXTRACFLAGS += -I$(srctree)/tools/include -I$(srctree)/include/uapi -I$(srctree)/arch/x86/include/uapi HOST_EXTRACFLAGS += -I$(srctree)/tools/include -I$(srctree)/include/uapi -I$(srctree)/arch/$(SUBARCH)/include/uapi
hostprogs-y += vdso2c hostprogs-y += vdso2c
quiet_cmd_vdso2c = VDSO2C $@ quiet_cmd_vdso2c = VDSO2C $@
......
...@@ -48,6 +48,7 @@ ...@@ -48,6 +48,7 @@
/* AVX VEX prefixes */ /* AVX VEX prefixes */
#define INAT_PFX_VEX2 13 /* 2-bytes VEX prefix */ #define INAT_PFX_VEX2 13 /* 2-bytes VEX prefix */
#define INAT_PFX_VEX3 14 /* 3-bytes VEX prefix */ #define INAT_PFX_VEX3 14 /* 3-bytes VEX prefix */
#define INAT_PFX_EVEX 15 /* EVEX prefix */
#define INAT_LSTPFX_MAX 3 #define INAT_LSTPFX_MAX 3
#define INAT_LGCPFX_MAX 11 #define INAT_LGCPFX_MAX 11
...@@ -89,6 +90,7 @@ ...@@ -89,6 +90,7 @@
#define INAT_VARIANT (1 << (INAT_FLAG_OFFS + 4)) #define INAT_VARIANT (1 << (INAT_FLAG_OFFS + 4))
#define INAT_VEXOK (1 << (INAT_FLAG_OFFS + 5)) #define INAT_VEXOK (1 << (INAT_FLAG_OFFS + 5))
#define INAT_VEXONLY (1 << (INAT_FLAG_OFFS + 6)) #define INAT_VEXONLY (1 << (INAT_FLAG_OFFS + 6))
#define INAT_EVEXONLY (1 << (INAT_FLAG_OFFS + 7))
/* Attribute making macros for attribute tables */ /* Attribute making macros for attribute tables */
#define INAT_MAKE_PREFIX(pfx) (pfx << INAT_PFX_OFFS) #define INAT_MAKE_PREFIX(pfx) (pfx << INAT_PFX_OFFS)
#define INAT_MAKE_ESCAPE(esc) (esc << INAT_ESC_OFFS) #define INAT_MAKE_ESCAPE(esc) (esc << INAT_ESC_OFFS)
...@@ -141,7 +143,13 @@ static inline int inat_last_prefix_id(insn_attr_t attr) ...@@ -141,7 +143,13 @@ static inline int inat_last_prefix_id(insn_attr_t attr)
static inline int inat_is_vex_prefix(insn_attr_t attr) static inline int inat_is_vex_prefix(insn_attr_t attr)
{ {
attr &= INAT_PFX_MASK; attr &= INAT_PFX_MASK;
return attr == INAT_PFX_VEX2 || attr == INAT_PFX_VEX3; return attr == INAT_PFX_VEX2 || attr == INAT_PFX_VEX3 ||
attr == INAT_PFX_EVEX;
}
static inline int inat_is_evex_prefix(insn_attr_t attr)
{
return (attr & INAT_PFX_MASK) == INAT_PFX_EVEX;
} }
static inline int inat_is_vex3_prefix(insn_attr_t attr) static inline int inat_is_vex3_prefix(insn_attr_t attr)
...@@ -216,6 +224,11 @@ static inline int inat_accept_vex(insn_attr_t attr) ...@@ -216,6 +224,11 @@ static inline int inat_accept_vex(insn_attr_t attr)
static inline int inat_must_vex(insn_attr_t attr) static inline int inat_must_vex(insn_attr_t attr)
{ {
return attr & INAT_VEXONLY; return attr & (INAT_VEXONLY | INAT_EVEXONLY);
}
static inline int inat_must_evex(insn_attr_t attr)
{
return attr & INAT_EVEXONLY;
} }
#endif #endif
...@@ -91,6 +91,7 @@ struct insn { ...@@ -91,6 +91,7 @@ struct insn {
#define X86_VEX_B(vex) ((vex) & 0x20) /* VEX3 Byte1 */ #define X86_VEX_B(vex) ((vex) & 0x20) /* VEX3 Byte1 */
#define X86_VEX_L(vex) ((vex) & 0x04) /* VEX3 Byte2, VEX2 Byte1 */ #define X86_VEX_L(vex) ((vex) & 0x04) /* VEX3 Byte2, VEX2 Byte1 */
/* VEX bit fields */ /* VEX bit fields */
#define X86_EVEX_M(vex) ((vex) & 0x03) /* EVEX Byte1 */
#define X86_VEX3_M(vex) ((vex) & 0x1f) /* VEX3 Byte1 */ #define X86_VEX3_M(vex) ((vex) & 0x1f) /* VEX3 Byte1 */
#define X86_VEX2_M 1 /* VEX2.M always 1 */ #define X86_VEX2_M 1 /* VEX2.M always 1 */
#define X86_VEX_V(vex) (((vex) & 0x78) >> 3) /* VEX3 Byte2, VEX2 Byte1 */ #define X86_VEX_V(vex) (((vex) & 0x78) >> 3) /* VEX3 Byte2, VEX2 Byte1 */
...@@ -133,6 +134,13 @@ static inline int insn_is_avx(struct insn *insn) ...@@ -133,6 +134,13 @@ static inline int insn_is_avx(struct insn *insn)
return (insn->vex_prefix.value != 0); return (insn->vex_prefix.value != 0);
} }
static inline int insn_is_evex(struct insn *insn)
{
if (!insn->prefixes.got)
insn_get_prefixes(insn);
return (insn->vex_prefix.nbytes == 4);
}
/* Ensure this instruction is decoded completely */ /* Ensure this instruction is decoded completely */
static inline int insn_complete(struct insn *insn) static inline int insn_complete(struct insn *insn)
{ {
...@@ -144,8 +152,10 @@ static inline insn_byte_t insn_vex_m_bits(struct insn *insn) ...@@ -144,8 +152,10 @@ static inline insn_byte_t insn_vex_m_bits(struct insn *insn)
{ {
if (insn->vex_prefix.nbytes == 2) /* 2 bytes VEX */ if (insn->vex_prefix.nbytes == 2) /* 2 bytes VEX */
return X86_VEX2_M; return X86_VEX2_M;
else else if (insn->vex_prefix.nbytes == 3) /* 3 bytes VEX */
return X86_VEX3_M(insn->vex_prefix.bytes[1]); return X86_VEX3_M(insn->vex_prefix.bytes[1]);
else /* EVEX */
return X86_EVEX_M(insn->vex_prefix.bytes[1]);
} }
static inline insn_byte_t insn_vex_p_bits(struct insn *insn) static inline insn_byte_t insn_vex_p_bits(struct insn *insn)
......
...@@ -155,14 +155,24 @@ void insn_get_prefixes(struct insn *insn) ...@@ -155,14 +155,24 @@ void insn_get_prefixes(struct insn *insn)
/* /*
* In 32-bits mode, if the [7:6] bits (mod bits of * In 32-bits mode, if the [7:6] bits (mod bits of
* ModRM) on the second byte are not 11b, it is * ModRM) on the second byte are not 11b, it is
* LDS or LES. * LDS or LES or BOUND.
*/ */
if (X86_MODRM_MOD(b2) != 3) if (X86_MODRM_MOD(b2) != 3)
goto vex_end; goto vex_end;
} }
insn->vex_prefix.bytes[0] = b; insn->vex_prefix.bytes[0] = b;
insn->vex_prefix.bytes[1] = b2; 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); b2 = peek_nbyte_next(insn_byte_t, insn, 2);
insn->vex_prefix.bytes[2] = b2; insn->vex_prefix.bytes[2] = b2;
insn->vex_prefix.nbytes = 3; insn->vex_prefix.nbytes = 3;
...@@ -221,7 +231,9 @@ void insn_get_opcode(struct insn *insn) ...@@ -221,7 +231,9 @@ void insn_get_opcode(struct insn *insn)
m = insn_vex_m_bits(insn); m = insn_vex_m_bits(insn);
p = insn_vex_p_bits(insn); p = insn_vex_p_bits(insn);
insn->attr = inat_get_avx_attribute(op, m, p); 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 */ insn->attr = 0; /* This instruction is bad */
goto end; /* VEX has only 1 byte for opcode */ goto end; /* VEX has only 1 byte for opcode */
} }
......
This diff is collapsed.
...@@ -72,12 +72,14 @@ BEGIN { ...@@ -72,12 +72,14 @@ BEGIN {
lprefix_expr = "\\((66|F2|F3)\\)" lprefix_expr = "\\((66|F2|F3)\\)"
max_lprefix = 4 max_lprefix = 4
# All opcodes starting with lower-case 'v' or with (v1) superscript # All opcodes starting with lower-case 'v', 'k' or with (v1) superscript
# accepts VEX prefix # accepts VEX prefix
vexok_opcode_expr = "^v.*" vexok_opcode_expr = "^[vk].*"
vexok_expr = "\\(v1\\)" vexok_expr = "\\(v1\\)"
# All opcodes with (v) superscript supports *only* VEX prefix # All opcodes with (v) superscript supports *only* VEX prefix
vexonly_expr = "\\(v\\)" vexonly_expr = "\\(v\\)"
# All opcodes with (ev) superscript supports *only* EVEX prefix
evexonly_expr = "\\(ev\\)"
prefix_expr = "\\(Prefix\\)" prefix_expr = "\\(Prefix\\)"
prefix_num["Operand-Size"] = "INAT_PFX_OPNDSZ" prefix_num["Operand-Size"] = "INAT_PFX_OPNDSZ"
...@@ -95,6 +97,7 @@ BEGIN { ...@@ -95,6 +97,7 @@ BEGIN {
prefix_num["Address-Size"] = "INAT_PFX_ADDRSZ" prefix_num["Address-Size"] = "INAT_PFX_ADDRSZ"
prefix_num["VEX+1byte"] = "INAT_PFX_VEX2" prefix_num["VEX+1byte"] = "INAT_PFX_VEX2"
prefix_num["VEX+2byte"] = "INAT_PFX_VEX3" prefix_num["VEX+2byte"] = "INAT_PFX_VEX3"
prefix_num["EVEX"] = "INAT_PFX_EVEX"
clear_vars() clear_vars()
} }
...@@ -319,7 +322,9 @@ function convert_operands(count,opnd, i,j,imm,mod) ...@@ -319,7 +322,9 @@ function convert_operands(count,opnd, i,j,imm,mod)
flags = add_flags(flags, "INAT_MODRM") flags = add_flags(flags, "INAT_MODRM")
# check VEX codes # check VEX codes
if (match(ext, vexonly_expr)) if (match(ext, evexonly_expr))
flags = add_flags(flags, "INAT_VEXOK | INAT_EVEXONLY")
else if (match(ext, vexonly_expr))
flags = add_flags(flags, "INAT_VEXOK | INAT_VEXONLY") flags = add_flags(flags, "INAT_VEXOK | INAT_VEXONLY")
else if (match(ext, vexok_expr) || match(opcode, vexok_opcode_expr)) else if (match(ext, vexok_expr) || match(opcode, vexok_opcode_expr))
flags = add_flags(flags, "INAT_VEXOK") flags = add_flags(flags, "INAT_VEXOK")
......
objtool-y += arch/$(ARCH)/ objtool-y += arch/$(SRCARCH)/
objtool-y += builtin-check.o objtool-y += builtin-check.o
objtool-y += elf.o objtool-y += elf.o
objtool-y += special.o objtool-y += special.o
......
include ../scripts/Makefile.include include ../scripts/Makefile.include
include ../scripts/Makefile.arch
ifndef ($(ARCH))
ARCH ?= $(shell uname -m)
ifeq ($(ARCH),x86_64) ifeq ($(ARCH),x86_64)
ARCH := x86 ARCH := x86
endif endif
endif
# always use the host compiler # always use the host compiler
CC = gcc CC = gcc
...@@ -26,7 +24,7 @@ OBJTOOL_IN := $(OBJTOOL)-in.o ...@@ -26,7 +24,7 @@ OBJTOOL_IN := $(OBJTOOL)-in.o
all: $(OBJTOOL) all: $(OBJTOOL)
INCLUDES := -I$(srctree)/tools/include -I$(srctree)/tools/arch/$(ARCH)/include/uapi INCLUDES := -I$(srctree)/tools/include -I$(srctree)/tools/arch/$(HOSTARCH)/include/uapi
CFLAGS += -Wall -Werror $(EXTRA_WARNINGS) -fomit-frame-pointer -O2 -g $(INCLUDES) CFLAGS += -Wall -Werror $(EXTRA_WARNINGS) -fomit-frame-pointer -O2 -g $(INCLUDES)
LDFLAGS += -lelf $(LIBSUBCMD) LDFLAGS += -lelf $(LIBSUBCMD)
...@@ -35,7 +33,7 @@ elfshdr := $(shell echo '\#include <libelf.h>' | $(CC) $(CFLAGS) -x c -E - | gre ...@@ -35,7 +33,7 @@ elfshdr := $(shell echo '\#include <libelf.h>' | $(CC) $(CFLAGS) -x c -E - | gre
CFLAGS += $(if $(elfshdr),,-DLIBELF_USE_DEPRECATED) CFLAGS += $(if $(elfshdr),,-DLIBELF_USE_DEPRECATED)
AWK = awk AWK = awk
export srctree OUTPUT CFLAGS ARCH AWK export srctree OUTPUT CFLAGS SRCARCH AWK
include $(srctree)/tools/build/Makefile.include include $(srctree)/tools/build/Makefile.include
$(OBJTOOL_IN): fixdep FORCE $(OBJTOOL_IN): fixdep FORCE
......
This diff is collapsed.
This diff is collapsed.
#include <stdbool.h> #include <stdbool.h>
#include <stdlib.h>
#include "tests.h" #include "tests.h"
#include "dso.h" #include "dso.h"
#include "debug.h" #include "debug.h"
......
...@@ -8,7 +8,6 @@ ...@@ -8,7 +8,6 @@
#include "map.h" #include "map.h"
#include "build-id.h" #include "build-id.h"
#include "perf_regs.h" #include "perf_regs.h"
#include <asm/perf_regs.h>
struct mmap_event { struct mmap_event {
struct perf_event_header header; struct perf_event_header header;
......
...@@ -72,12 +72,14 @@ BEGIN { ...@@ -72,12 +72,14 @@ BEGIN {
lprefix_expr = "\\((66|F2|F3)\\)" lprefix_expr = "\\((66|F2|F3)\\)"
max_lprefix = 4 max_lprefix = 4
# All opcodes starting with lower-case 'v' or with (v1) superscript # All opcodes starting with lower-case 'v', 'k' or with (v1) superscript
# accepts VEX prefix # accepts VEX prefix
vexok_opcode_expr = "^v.*" vexok_opcode_expr = "^[vk].*"
vexok_expr = "\\(v1\\)" vexok_expr = "\\(v1\\)"
# All opcodes with (v) superscript supports *only* VEX prefix # All opcodes with (v) superscript supports *only* VEX prefix
vexonly_expr = "\\(v\\)" vexonly_expr = "\\(v\\)"
# All opcodes with (ev) superscript supports *only* EVEX prefix
evexonly_expr = "\\(ev\\)"
prefix_expr = "\\(Prefix\\)" prefix_expr = "\\(Prefix\\)"
prefix_num["Operand-Size"] = "INAT_PFX_OPNDSZ" prefix_num["Operand-Size"] = "INAT_PFX_OPNDSZ"
...@@ -95,6 +97,7 @@ BEGIN { ...@@ -95,6 +97,7 @@ BEGIN {
prefix_num["Address-Size"] = "INAT_PFX_ADDRSZ" prefix_num["Address-Size"] = "INAT_PFX_ADDRSZ"
prefix_num["VEX+1byte"] = "INAT_PFX_VEX2" prefix_num["VEX+1byte"] = "INAT_PFX_VEX2"
prefix_num["VEX+2byte"] = "INAT_PFX_VEX3" prefix_num["VEX+2byte"] = "INAT_PFX_VEX3"
prefix_num["EVEX"] = "INAT_PFX_EVEX"
clear_vars() clear_vars()
} }
...@@ -319,7 +322,9 @@ function convert_operands(count,opnd, i,j,imm,mod) ...@@ -319,7 +322,9 @@ function convert_operands(count,opnd, i,j,imm,mod)
flags = add_flags(flags, "INAT_MODRM") flags = add_flags(flags, "INAT_MODRM")
# check VEX codes # check VEX codes
if (match(ext, vexonly_expr)) if (match(ext, evexonly_expr))
flags = add_flags(flags, "INAT_VEXOK | INAT_EVEXONLY")
else if (match(ext, vexonly_expr))
flags = add_flags(flags, "INAT_VEXOK | INAT_VEXONLY") flags = add_flags(flags, "INAT_VEXOK | INAT_VEXONLY")
else if (match(ext, vexok_expr) || match(opcode, vexok_opcode_expr)) else if (match(ext, vexok_expr) || match(opcode, vexok_opcode_expr))
flags = add_flags(flags, "INAT_VEXOK") flags = add_flags(flags, "INAT_VEXOK")
......
...@@ -48,6 +48,7 @@ ...@@ -48,6 +48,7 @@
/* AVX VEX prefixes */ /* AVX VEX prefixes */
#define INAT_PFX_VEX2 13 /* 2-bytes VEX prefix */ #define INAT_PFX_VEX2 13 /* 2-bytes VEX prefix */
#define INAT_PFX_VEX3 14 /* 3-bytes VEX prefix */ #define INAT_PFX_VEX3 14 /* 3-bytes VEX prefix */
#define INAT_PFX_EVEX 15 /* EVEX prefix */
#define INAT_LSTPFX_MAX 3 #define INAT_LSTPFX_MAX 3
#define INAT_LGCPFX_MAX 11 #define INAT_LGCPFX_MAX 11
...@@ -89,6 +90,7 @@ ...@@ -89,6 +90,7 @@
#define INAT_VARIANT (1 << (INAT_FLAG_OFFS + 4)) #define INAT_VARIANT (1 << (INAT_FLAG_OFFS + 4))
#define INAT_VEXOK (1 << (INAT_FLAG_OFFS + 5)) #define INAT_VEXOK (1 << (INAT_FLAG_OFFS + 5))
#define INAT_VEXONLY (1 << (INAT_FLAG_OFFS + 6)) #define INAT_VEXONLY (1 << (INAT_FLAG_OFFS + 6))
#define INAT_EVEXONLY (1 << (INAT_FLAG_OFFS + 7))
/* Attribute making macros for attribute tables */ /* Attribute making macros for attribute tables */
#define INAT_MAKE_PREFIX(pfx) (pfx << INAT_PFX_OFFS) #define INAT_MAKE_PREFIX(pfx) (pfx << INAT_PFX_OFFS)
#define INAT_MAKE_ESCAPE(esc) (esc << INAT_ESC_OFFS) #define INAT_MAKE_ESCAPE(esc) (esc << INAT_ESC_OFFS)
...@@ -141,7 +143,13 @@ static inline int inat_last_prefix_id(insn_attr_t attr) ...@@ -141,7 +143,13 @@ static inline int inat_last_prefix_id(insn_attr_t attr)
static inline int inat_is_vex_prefix(insn_attr_t attr) static inline int inat_is_vex_prefix(insn_attr_t attr)
{ {
attr &= INAT_PFX_MASK; attr &= INAT_PFX_MASK;
return attr == INAT_PFX_VEX2 || attr == INAT_PFX_VEX3; return attr == INAT_PFX_VEX2 || attr == INAT_PFX_VEX3 ||
attr == INAT_PFX_EVEX;
}
static inline int inat_is_evex_prefix(insn_attr_t attr)
{
return (attr & INAT_PFX_MASK) == INAT_PFX_EVEX;
} }
static inline int inat_is_vex3_prefix(insn_attr_t attr) static inline int inat_is_vex3_prefix(insn_attr_t attr)
...@@ -216,6 +224,11 @@ static inline int inat_accept_vex(insn_attr_t attr) ...@@ -216,6 +224,11 @@ static inline int inat_accept_vex(insn_attr_t attr)
static inline int inat_must_vex(insn_attr_t attr) static inline int inat_must_vex(insn_attr_t attr)
{ {
return attr & INAT_VEXONLY; return attr & (INAT_VEXONLY | INAT_EVEXONLY);
}
static inline int inat_must_evex(insn_attr_t attr)
{
return attr & INAT_EVEXONLY;
} }
#endif #endif
...@@ -155,14 +155,24 @@ void insn_get_prefixes(struct insn *insn) ...@@ -155,14 +155,24 @@ void insn_get_prefixes(struct insn *insn)
/* /*
* In 32-bits mode, if the [7:6] bits (mod bits of * In 32-bits mode, if the [7:6] bits (mod bits of
* ModRM) on the second byte are not 11b, it is * ModRM) on the second byte are not 11b, it is
* LDS or LES. * LDS or LES or BOUND.
*/ */
if (X86_MODRM_MOD(b2) != 3) if (X86_MODRM_MOD(b2) != 3)
goto vex_end; goto vex_end;
} }
insn->vex_prefix.bytes[0] = b; insn->vex_prefix.bytes[0] = b;
insn->vex_prefix.bytes[1] = b2; 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); b2 = peek_nbyte_next(insn_byte_t, insn, 2);
insn->vex_prefix.bytes[2] = b2; insn->vex_prefix.bytes[2] = b2;
insn->vex_prefix.nbytes = 3; insn->vex_prefix.nbytes = 3;
...@@ -221,7 +231,9 @@ void insn_get_opcode(struct insn *insn) ...@@ -221,7 +231,9 @@ void insn_get_opcode(struct insn *insn)
m = insn_vex_m_bits(insn); m = insn_vex_m_bits(insn);
p = insn_vex_p_bits(insn); p = insn_vex_p_bits(insn);
insn->attr = inat_get_avx_attribute(op, m, p); 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 */ insn->attr = 0; /* This instruction is bad */
goto end; /* VEX has only 1 byte for opcode */ goto end; /* VEX has only 1 byte for opcode */
} }
......
...@@ -91,6 +91,7 @@ struct insn { ...@@ -91,6 +91,7 @@ struct insn {
#define X86_VEX_B(vex) ((vex) & 0x20) /* VEX3 Byte1 */ #define X86_VEX_B(vex) ((vex) & 0x20) /* VEX3 Byte1 */
#define X86_VEX_L(vex) ((vex) & 0x04) /* VEX3 Byte2, VEX2 Byte1 */ #define X86_VEX_L(vex) ((vex) & 0x04) /* VEX3 Byte2, VEX2 Byte1 */
/* VEX bit fields */ /* VEX bit fields */
#define X86_EVEX_M(vex) ((vex) & 0x03) /* EVEX Byte1 */
#define X86_VEX3_M(vex) ((vex) & 0x1f) /* VEX3 Byte1 */ #define X86_VEX3_M(vex) ((vex) & 0x1f) /* VEX3 Byte1 */
#define X86_VEX2_M 1 /* VEX2.M always 1 */ #define X86_VEX2_M 1 /* VEX2.M always 1 */
#define X86_VEX_V(vex) (((vex) & 0x78) >> 3) /* VEX3 Byte2, VEX2 Byte1 */ #define X86_VEX_V(vex) (((vex) & 0x78) >> 3) /* VEX3 Byte2, VEX2 Byte1 */
...@@ -133,6 +134,13 @@ static inline int insn_is_avx(struct insn *insn) ...@@ -133,6 +134,13 @@ static inline int insn_is_avx(struct insn *insn)
return (insn->vex_prefix.value != 0); return (insn->vex_prefix.value != 0);
} }
static inline int insn_is_evex(struct insn *insn)
{
if (!insn->prefixes.got)
insn_get_prefixes(insn);
return (insn->vex_prefix.nbytes == 4);
}
/* Ensure this instruction is decoded completely */ /* Ensure this instruction is decoded completely */
static inline int insn_complete(struct insn *insn) static inline int insn_complete(struct insn *insn)
{ {
...@@ -144,8 +152,10 @@ static inline insn_byte_t insn_vex_m_bits(struct insn *insn) ...@@ -144,8 +152,10 @@ static inline insn_byte_t insn_vex_m_bits(struct insn *insn)
{ {
if (insn->vex_prefix.nbytes == 2) /* 2 bytes VEX */ if (insn->vex_prefix.nbytes == 2) /* 2 bytes VEX */
return X86_VEX2_M; return X86_VEX2_M;
else else if (insn->vex_prefix.nbytes == 3) /* 3 bytes VEX */
return X86_VEX3_M(insn->vex_prefix.bytes[1]); return X86_VEX3_M(insn->vex_prefix.bytes[1]);
else /* EVEX */
return X86_EVEX_M(insn->vex_prefix.bytes[1]);
} }
static inline insn_byte_t insn_vex_p_bits(struct insn *insn) static inline insn_byte_t insn_vex_p_bits(struct insn *insn)
......
ifndef ARCH HOSTARCH := $(shell uname -m | sed -e s/i.86/x86/ -e s/x86_64/x86/ \
ARCH := $(shell uname -m 2>/dev/null || echo not)
endif
ARCH := $(shell echo $(ARCH) | sed -e s/i.86/x86/ -e s/x86_64/x86/ \
-e s/sun4u/sparc/ -e s/sparc64/sparc/ \ -e s/sun4u/sparc/ -e s/sparc64/sparc/ \
-e /arm64/!s/arm.*/arm/ -e s/sa110/arm/ \ -e /arm64/!s/arm.*/arm/ -e s/sa110/arm/ \
-e s/s390x/s390/ -e s/parisc64/parisc/ \ -e s/s390x/s390/ -e s/parisc64/parisc/ \
...@@ -10,6 +6,41 @@ ARCH := $(shell echo $(ARCH) | sed -e s/i.86/x86/ -e s/x86_64/x86/ \ ...@@ -10,6 +6,41 @@ ARCH := $(shell echo $(ARCH) | sed -e s/i.86/x86/ -e s/x86_64/x86/ \
-e s/sh[234].*/sh/ -e s/aarch64.*/arm64/ \ -e s/sh[234].*/sh/ -e s/aarch64.*/arm64/ \
-e s/tile.*/tile/ ) -e s/tile.*/tile/ )
ifndef ARCH
ARCH := $(HOSTARCH)
endif
SRCARCH := $(ARCH)
# Additional ARCH settings for x86
ifeq ($(ARCH),i386)
SRCARCH := x86
endif
ifeq ($(ARCH),x86_64)
SRCARCH := x86
endif
# Additional ARCH settings for sparc
ifeq ($(ARCH),sparc32)
SRCARCH := sparc
endif
ifeq ($(ARCH),sparc64)
SRCARCH := sparc
endif
# Additional ARCH settings for sh
ifeq ($(ARCH),sh64)
SRCARCH := sh
endif
# Additional ARCH settings for tile
ifeq ($(ARCH),tilepro)
SRCARCH := tile
endif
ifeq ($(ARCH),tilegx)
SRCARCH := tile
endif
LP64 := $(shell echo __LP64__ | ${CC} ${CFLAGS} -E -x c - | tail -n 1) LP64 := $(shell echo __LP64__ | ${CC} ${CFLAGS} -E -x c - | tail -n 1)
ifeq ($(LP64), 1) ifeq ($(LP64), 1)
IS_64_BIT := 1 IS_64_BIT := 1
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment