public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH 2/2] x86: extend insn decoder to understand xop and evex prefixes
  2014-05-16 18:34 [PATCH 1/2] x86: insn decoder: create artificial 3rd byte for 2-byte VEX Denys Vlasenko
@ 2014-05-16 18:34 ` Denys Vlasenko
  2014-05-17 16:00   ` Masami Hiramatsu
  0 siblings, 1 reply; 7+ messages in thread
From: Denys Vlasenko @ 2014-05-16 18:34 UTC (permalink / raw)
  To: linux-kernel
  Cc: Denys Vlasenko, Masami Hiramatsu, Frank Ch. Eigler,
	Srikar Dronamraju, Ananth N Mavinakayanahalli, Jim Keniston,
	Oleg Nesterov, Andi Kleen, Ingo Molnar

Since xop and evex prefixes are extensions of vex mechanism,
they have similar bit layouts, and they can never be combined
(an instruction can have only one of them),
(ab)use insn->vex_prefix to store data of xop and evex too.

Users will need to conditionalize on insn->vex_prefix.bytes[0]
instead of insn->vex_prefix.nbytes if they want to determine
which of vex(-like) prefixes are there.

Instead of adding more inattr bits for these prefixes, drop
VEX inattr bits and use VEX opcode values directly to detect them.
There is no point in having additional level of indirection here.
(And we are close to running out of inattr bits for prefixes).

Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
Cc: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Cc: Frank Ch. Eigler <fche@redhat.com>
Cc: Srikar Dronamraju <srikar@linux.vnet.ibm.com>
Cc: Ananth N Mavinakayanahalli <ananth@in.ibm.com>
Cc: Jim Keniston <jkenisto@linux.vnet.ibm.com>
Cc: Oleg Nesterov <oleg@redhat.com>
Cc: Andi Kleen <andi@firstfloor.org>
Cc: Ingo Molnar <mingo@kernel.org>
---
 arch/x86/include/asm/inat.h          | 14 -----------
 arch/x86/include/asm/insn.h          |  6 +++++
 arch/x86/lib/insn.c                  | 47 +++++++++++++++++++++++++-----------
 arch/x86/lib/x86-opcode-map.txt      |  4 +--
 arch/x86/tools/gen-insn-attr-x86.awk |  2 --
 5 files changed, 41 insertions(+), 32 deletions(-)

diff --git a/arch/x86/include/asm/inat.h b/arch/x86/include/asm/inat.h
index 74a2e31..5aa6c05 100644
--- a/arch/x86/include/asm/inat.h
+++ b/arch/x86/include/asm/inat.h
@@ -45,9 +45,6 @@
 #define INAT_PFX_ADDRSZ	11	/* 0x67 */
 /* x86-64 REX prefix */
 #define INAT_PFX_REX	12	/* 0x4X */
-/* AVX VEX prefixes */
-#define INAT_PFX_VEX2	13	/* 2-bytes VEX prefix */
-#define INAT_PFX_VEX3	14	/* 3-bytes VEX prefix */
 
 #define INAT_LSTPFX_MAX	3
 #define INAT_LGCPFX_MAX	11
@@ -138,17 +135,6 @@ static inline int inat_last_prefix_id(insn_attr_t attr)
 		return attr & INAT_PFX_MASK;
 }
 
-static inline int inat_is_vex_prefix(insn_attr_t attr)
-{
-	attr &= INAT_PFX_MASK;
-	return attr == INAT_PFX_VEX2 || attr == INAT_PFX_VEX3;
-}
-
-static inline int inat_is_vex3_prefix(insn_attr_t attr)
-{
-	return (attr & INAT_PFX_MASK) == INAT_PFX_VEX3;
-}
-
 static inline int inat_is_escape(insn_attr_t attr)
 {
 	return attr & INAT_ESC_MASK;
diff --git a/arch/x86/include/asm/insn.h b/arch/x86/include/asm/insn.h
index 48eb30a..e098fec 100644
--- a/arch/x86/include/asm/insn.h
+++ b/arch/x86/include/asm/insn.h
@@ -83,6 +83,12 @@ struct insn {
 #define X86_REX_X(rex) ((rex) & 2)
 #define X86_REX_B(rex) ((rex) & 1)
 
+/* VEX and VEX-like multi-byte prefixes */
+#define X86_BYTE_VEX3  0xc4
+#define X86_BYTE_VEX2  0xc5
+#define X86_BYTE_XOP   0x8f
+#define X86_BYTE_EVEX  0x62
+
 /* VEX bit flags  */
 #define X86_VEX_W(vex)	((vex) & 0x80)	/* VEX3 Byte2 */
 #define X86_VEX_R(vex)	((vex) & 0x80)	/* VEX2/3 Byte1 */
diff --git a/arch/x86/lib/insn.c b/arch/x86/lib/insn.c
index 829ca4c..2351977 100644
--- a/arch/x86/lib/insn.c
+++ b/arch/x86/lib/insn.c
@@ -138,31 +138,34 @@ found:
 	}
 	insn->rex_prefix.got = 1;
 
-	/* Decode VEX prefix */
+	/* Decode VEX prefixes et al. Layouts are:
+	 * vex2:     c5    rvvvvLpp
+	 * vex3/xop: c4/8f rxbmmmmm wvvvvLpp
+	 * evex:     62    rxbR00mm wvvvv1pp zllBVaaa
+	 */
 	b = peek_next(insn_byte_t, insn);
-	attr = inat_get_opcode_attribute(b);
-	if (inat_is_vex_prefix(attr)) {
+	if (b == X86_BYTE_VEX2 || b == X86_BYTE_VEX3 ||
+	    b == X86_BYTE_EVEX ||
+	    b == X86_BYTE_XOP) {
 		insn_byte_t b2 = peek_nbyte_next(insn_byte_t, insn, 1);
-		if (!insn->x86_64) {
+		/*
+		 * XOP: If the modrm.reg bits are 000, it's POP reg/mem.
+		 */
+		if (b == X86_BYTE_XOP && X86_MODRM_REG(b2) == 0) {
+			goto vex_end;
+		}
+		else if (!insn->x86_64) {
 			/*
 			 * 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, 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)) {
-			b2 = peek_nbyte_next(insn_byte_t, insn, 2);
-			insn->vex_prefix.bytes[2] = b2;
-			insn->vex_prefix.nbytes = 3;
-			insn->next_byte += 3;
-			if (insn->x86_64 && X86_VEX_W(b2))
-				/* VEX.W overrides opnd_size */
-				insn->opnd_bytes = 8;
-		} else {
+		if (b == X86_BYTE_VEX2) {
 			/*
 			 * For VEX2, fake VEX3-like byte#2.
 			 * Makes it easier to decode vex.W, vex.vvvv,
@@ -171,7 +174,23 @@ found:
 			insn->vex_prefix.bytes[2] = b2 & 0x7f;
 			insn->vex_prefix.nbytes = 2;
 			insn->next_byte += 2;
+			goto vex_end;
+		}
+		b2 = peek_nbyte_next(insn_byte_t, insn, 2);
+		insn->vex_prefix.bytes[2] = b2;
+		if (insn->x86_64 && X86_VEX_W(b2)) {
+			/* VEX.W overrides opnd_size */
+			insn->opnd_bytes = 8;
+		}
+		if (b == X86_BYTE_VEX3 || b == X86_BYTE_XOP) {
+			insn->vex_prefix.nbytes = 3;
+			insn->next_byte += 3;
+			goto vex_end;
 		}
+		b2 = peek_nbyte_next(insn_byte_t, insn, 3);
+		insn->vex_prefix.bytes[3] = b2;
+		insn->vex_prefix.nbytes = 4;
+		insn->next_byte += 4;
 	}
 vex_end:
 	insn->vex_prefix.got = 1;
diff --git a/arch/x86/lib/x86-opcode-map.txt b/arch/x86/lib/x86-opcode-map.txt
index 1a2be7c..9d8a964 100644
--- a/arch/x86/lib/x86-opcode-map.txt
+++ b/arch/x86/lib/x86-opcode-map.txt
@@ -137,7 +137,7 @@ AVXcode:
 # 0x60 - 0x6f
 60: PUSHA/PUSHAD (i64)
 61: POPA/POPAD (i64)
-62: BOUND Gv,Ma (i64)
+62: BOUND Gv,Ma (i64) | EVEX+3byte (Prefix)
 63: ARPL Ew,Gw (i64) | MOVSXD Gv,Ev (o64)
 64: SEG=FS (Prefix)
 65: SEG=GS (Prefix)
@@ -184,7 +184,7 @@ AVXcode:
 8c: MOV Ev,Sw
 8d: LEA Gv,M
 8e: MOV Sw,Ew
-8f: Grp1A (1A) | POP Ev (d64)
+8f: Grp1A (1A) | POP Ev (d64) | XOP+2byte (Prefix)
 # 0x90 - 0x9f
 90: NOP | PAUSE (F3) | XCHG r8,rAX
 91: XCHG rCX/r9,rAX
diff --git a/arch/x86/tools/gen-insn-attr-x86.awk b/arch/x86/tools/gen-insn-attr-x86.awk
index 093a892..b2db5ad 100644
--- a/arch/x86/tools/gen-insn-attr-x86.awk
+++ b/arch/x86/tools/gen-insn-attr-x86.awk
@@ -93,8 +93,6 @@ BEGIN {
 	prefix_num["SEG=GS"] = "INAT_PFX_GS"
 	prefix_num["SEG=SS"] = "INAT_PFX_SS"
 	prefix_num["Address-Size"] = "INAT_PFX_ADDRSZ"
-	prefix_num["VEX+1byte"] = "INAT_PFX_VEX2"
-	prefix_num["VEX+2byte"] = "INAT_PFX_VEX3"
 
 	clear_vars()
 }
-- 
1.8.1.4


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH 2/2] x86: extend insn decoder to understand xop and evex prefixes
  2014-05-16 18:34 ` [PATCH 2/2] x86: extend insn decoder to understand xop and evex prefixes Denys Vlasenko
@ 2014-05-17 16:00   ` Masami Hiramatsu
  2014-05-19 15:04     ` Denys Vlasenko
  0 siblings, 1 reply; 7+ messages in thread
From: Masami Hiramatsu @ 2014-05-17 16:00 UTC (permalink / raw)
  To: Denys Vlasenko
  Cc: linux-kernel, Frank Ch. Eigler, Srikar Dronamraju,
	Ananth N Mavinakayanahalli, Jim Keniston, Oleg Nesterov,
	Andi Kleen, Ingo Molnar

(2014/05/17 3:34), Denys Vlasenko wrote:
> Since xop and evex prefixes are extensions of vex mechanism,
> they have similar bit layouts, and they can never be combined
> (an instruction can have only one of them),
> (ab)use insn->vex_prefix to store data of xop and evex too.
> 
> Users will need to conditionalize on insn->vex_prefix.bytes[0]
> instead of insn->vex_prefix.nbytes if they want to determine
> which of vex(-like) prefixes are there.
> 
> Instead of adding more inattr bits for these prefixes, drop
> VEX inattr bits and use VEX opcode values directly to detect them.
> There is no point in having additional level of indirection here.
> (And we are close to running out of inattr bits for prefixes).

Thank you very much for trying this work :)
But sorry, Nak, I don't like to use the prefix byte directly.
I'd rather like to add additional inattr bits for them.
This is a drawback of what I've done by gen-insn-atter-x86.awk.
It is prefer that x86 instruction information should be hidden
in opcode map and awk decoder.

And also, we should expand x86-opcode-map.txt for new instructions.

> 
> Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
> Cc: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
> Cc: Frank Ch. Eigler <fche@redhat.com>
> Cc: Srikar Dronamraju <srikar@linux.vnet.ibm.com>
> Cc: Ananth N Mavinakayanahalli <ananth@in.ibm.com>
> Cc: Jim Keniston <jkenisto@linux.vnet.ibm.com>
> Cc: Oleg Nesterov <oleg@redhat.com>
> Cc: Andi Kleen <andi@firstfloor.org>
> Cc: Ingo Molnar <mingo@kernel.org>
> ---
>  arch/x86/include/asm/inat.h          | 14 -----------
>  arch/x86/include/asm/insn.h          |  6 +++++
>  arch/x86/lib/insn.c                  | 47 +++++++++++++++++++++++++-----------
>  arch/x86/lib/x86-opcode-map.txt      |  4 +--
>  arch/x86/tools/gen-insn-attr-x86.awk |  2 --
>  5 files changed, 41 insertions(+), 32 deletions(-)
> 
> diff --git a/arch/x86/include/asm/inat.h b/arch/x86/include/asm/inat.h
> index 74a2e31..5aa6c05 100644
> --- a/arch/x86/include/asm/inat.h
> +++ b/arch/x86/include/asm/inat.h
> @@ -45,9 +45,6 @@
>  #define INAT_PFX_ADDRSZ	11	/* 0x67 */
>  /* x86-64 REX prefix */
>  #define INAT_PFX_REX	12	/* 0x4X */
> -/* AVX VEX prefixes */
> -#define INAT_PFX_VEX2	13	/* 2-bytes VEX prefix */
> -#define INAT_PFX_VEX3	14	/* 3-bytes VEX prefix */
>  
>  #define INAT_LSTPFX_MAX	3
>  #define INAT_LGCPFX_MAX	11
> @@ -138,17 +135,6 @@ static inline int inat_last_prefix_id(insn_attr_t attr)
>  		return attr & INAT_PFX_MASK;
>  }
>  
> -static inline int inat_is_vex_prefix(insn_attr_t attr)
> -{
> -	attr &= INAT_PFX_MASK;
> -	return attr == INAT_PFX_VEX2 || attr == INAT_PFX_VEX3;
> -}
> -
> -static inline int inat_is_vex3_prefix(insn_attr_t attr)
> -{
> -	return (attr & INAT_PFX_MASK) == INAT_PFX_VEX3;
> -}
> -
>  static inline int inat_is_escape(insn_attr_t attr)
>  {
>  	return attr & INAT_ESC_MASK;
> diff --git a/arch/x86/include/asm/insn.h b/arch/x86/include/asm/insn.h
> index 48eb30a..e098fec 100644
> --- a/arch/x86/include/asm/insn.h
> +++ b/arch/x86/include/asm/insn.h
> @@ -83,6 +83,12 @@ struct insn {
>  #define X86_REX_X(rex) ((rex) & 2)
>  #define X86_REX_B(rex) ((rex) & 1)
>  
> +/* VEX and VEX-like multi-byte prefixes */
> +#define X86_BYTE_VEX3  0xc4
> +#define X86_BYTE_VEX2  0xc5
> +#define X86_BYTE_XOP   0x8f
> +#define X86_BYTE_EVEX  0x62
> +
>  /* VEX bit flags  */
>  #define X86_VEX_W(vex)	((vex) & 0x80)	/* VEX3 Byte2 */
>  #define X86_VEX_R(vex)	((vex) & 0x80)	/* VEX2/3 Byte1 */
> diff --git a/arch/x86/lib/insn.c b/arch/x86/lib/insn.c
> index 829ca4c..2351977 100644
> --- a/arch/x86/lib/insn.c
> +++ b/arch/x86/lib/insn.c
> @@ -138,31 +138,34 @@ found:
>  	}
>  	insn->rex_prefix.got = 1;
>  
> -	/* Decode VEX prefix */
> +	/* Decode VEX prefixes et al. Layouts are:
> +	 * vex2:     c5    rvvvvLpp
> +	 * vex3/xop: c4/8f rxbmmmmm wvvvvLpp
> +	 * evex:     62    rxbR00mm wvvvv1pp zllBVaaa
> +	 */
>  	b = peek_next(insn_byte_t, insn);
> -	attr = inat_get_opcode_attribute(b);
> -	if (inat_is_vex_prefix(attr)) {
> +	if (b == X86_BYTE_VEX2 || b == X86_BYTE_VEX3 ||
> +	    b == X86_BYTE_EVEX ||
> +	    b == X86_BYTE_XOP) {
>  		insn_byte_t b2 = peek_nbyte_next(insn_byte_t, insn, 1);
> -		if (!insn->x86_64) {
> +		/*
> +		 * XOP: If the modrm.reg bits are 000, it's POP reg/mem.
> +		 */
> +		if (b == X86_BYTE_XOP && X86_MODRM_REG(b2) == 0) {
> +			goto vex_end;
> +		}
> +		else if (!insn->x86_64) {
>  			/*
>  			 * 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, 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)) {
> -			b2 = peek_nbyte_next(insn_byte_t, insn, 2);
> -			insn->vex_prefix.bytes[2] = b2;
> -			insn->vex_prefix.nbytes = 3;
> -			insn->next_byte += 3;
> -			if (insn->x86_64 && X86_VEX_W(b2))
> -				/* VEX.W overrides opnd_size */
> -				insn->opnd_bytes = 8;
> -		} else {
> +		if (b == X86_BYTE_VEX2) {
>  			/*
>  			 * For VEX2, fake VEX3-like byte#2.
>  			 * Makes it easier to decode vex.W, vex.vvvv,
> @@ -171,7 +174,23 @@ found:
>  			insn->vex_prefix.bytes[2] = b2 & 0x7f;
>  			insn->vex_prefix.nbytes = 2;
>  			insn->next_byte += 2;
> +			goto vex_end;
> +		}
> +		b2 = peek_nbyte_next(insn_byte_t, insn, 2);
> +		insn->vex_prefix.bytes[2] = b2;
> +		if (insn->x86_64 && X86_VEX_W(b2)) {
> +			/* VEX.W overrides opnd_size */
> +			insn->opnd_bytes = 8;
> +		}
> +		if (b == X86_BYTE_VEX3 || b == X86_BYTE_XOP) {
> +			insn->vex_prefix.nbytes = 3;
> +			insn->next_byte += 3;
> +			goto vex_end;
>  		}
> +		b2 = peek_nbyte_next(insn_byte_t, insn, 3);
> +		insn->vex_prefix.bytes[3] = b2;
> +		insn->vex_prefix.nbytes = 4;
> +		insn->next_byte += 4;
>  	}
>  vex_end:
>  	insn->vex_prefix.got = 1;
> diff --git a/arch/x86/lib/x86-opcode-map.txt b/arch/x86/lib/x86-opcode-map.txt
> index 1a2be7c..9d8a964 100644
> --- a/arch/x86/lib/x86-opcode-map.txt
> +++ b/arch/x86/lib/x86-opcode-map.txt
> @@ -137,7 +137,7 @@ AVXcode:
>  # 0x60 - 0x6f
>  60: PUSHA/PUSHAD (i64)
>  61: POPA/POPAD (i64)
> -62: BOUND Gv,Ma (i64)
> +62: BOUND Gv,Ma (i64) | EVEX+3byte (Prefix)
>  63: ARPL Ew,Gw (i64) | MOVSXD Gv,Ev (o64)
>  64: SEG=FS (Prefix)
>  65: SEG=GS (Prefix)
> @@ -184,7 +184,7 @@ AVXcode:
>  8c: MOV Ev,Sw
>  8d: LEA Gv,M
>  8e: MOV Sw,Ew
> -8f: Grp1A (1A) | POP Ev (d64)
> +8f: Grp1A (1A) | POP Ev (d64) | XOP+2byte (Prefix)
>  # 0x90 - 0x9f
>  90: NOP | PAUSE (F3) | XCHG r8,rAX
>  91: XCHG rCX/r9,rAX
> diff --git a/arch/x86/tools/gen-insn-attr-x86.awk b/arch/x86/tools/gen-insn-attr-x86.awk
> index 093a892..b2db5ad 100644
> --- a/arch/x86/tools/gen-insn-attr-x86.awk
> +++ b/arch/x86/tools/gen-insn-attr-x86.awk
> @@ -93,8 +93,6 @@ BEGIN {
>  	prefix_num["SEG=GS"] = "INAT_PFX_GS"
>  	prefix_num["SEG=SS"] = "INAT_PFX_SS"
>  	prefix_num["Address-Size"] = "INAT_PFX_ADDRSZ"
> -	prefix_num["VEX+1byte"] = "INAT_PFX_VEX2"
> -	prefix_num["VEX+2byte"] = "INAT_PFX_VEX3"
>  
>  	clear_vars()
>  }
> 


-- 
Masami HIRAMATSU
Software Platform Research Dept. Linux Technology Research Center
Hitachi, Ltd., Yokohama Research Laboratory
E-mail: masami.hiramatsu.pt@hitachi.com



^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH 2/2] x86: extend insn decoder to understand xop and evex prefixes
  2014-05-17 16:00   ` Masami Hiramatsu
@ 2014-05-19 15:04     ` Denys Vlasenko
  2014-05-21  7:40       ` Masami Hiramatsu
  0 siblings, 1 reply; 7+ messages in thread
From: Denys Vlasenko @ 2014-05-19 15:04 UTC (permalink / raw)
  To: Masami Hiramatsu
  Cc: linux-kernel, Frank Ch. Eigler, Srikar Dronamraju,
	Ananth N Mavinakayanahalli, Jim Keniston, Oleg Nesterov,
	Andi Kleen, Ingo Molnar

On 05/17/2014 06:00 PM, Masami Hiramatsu wrote:
> (2014/05/17 3:34), Denys Vlasenko wrote:
>> Since xop and evex prefixes are extensions of vex mechanism,
>> they have similar bit layouts, and they can never be combined
>> (an instruction can have only one of them),
>> (ab)use insn->vex_prefix to store data of xop and evex too.
>>
>> Users will need to conditionalize on insn->vex_prefix.bytes[0]
>> instead of insn->vex_prefix.nbytes if they want to determine
>> which of vex(-like) prefixes are there.
>>
>> Instead of adding more inattr bits for these prefixes, drop
>> VEX inattr bits and use VEX opcode values directly to detect them.
>> There is no point in having additional level of indirection here.
>> (And we are close to running out of inattr bits for prefixes).
> 
> Thank you very much for trying this work :)
> But sorry, Nak, I don't like to use the prefix byte directly.
> I'd rather like to add additional inattr bits for them.

Ok, I'm looking at inat.h and looks like I need to widen
INAT_PFX_BITS, otherwise I have no space for two more bits
for two more prefixes (XOP and EVEX):

/* AVX VEX prefixes */
#define INAT_PFX_VEX2   13      /* 2-bytes VEX prefix */
#define INAT_PFX_VEX3   14      /* 3-bytes VEX prefix */
...

/* Legacy prefix */
#define INAT_PFX_OFFS   0
#define INAT_PFX_BITS   4
#define INAT_PFX_MAX    ((1 << INAT_PFX_BITS) - 1)
#define INAT_PFX_MASK   (INAT_PFX_MAX << INAT_PFX_OFFS)


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH 2/2] x86: extend insn decoder to understand xop and evex prefixes
  2014-05-19 15:04     ` Denys Vlasenko
@ 2014-05-21  7:40       ` Masami Hiramatsu
  0 siblings, 0 replies; 7+ messages in thread
From: Masami Hiramatsu @ 2014-05-21  7:40 UTC (permalink / raw)
  To: Denys Vlasenko
  Cc: linux-kernel, Frank Ch. Eigler, Srikar Dronamraju,
	Ananth N Mavinakayanahalli, Jim Keniston, Oleg Nesterov,
	Andi Kleen, Ingo Molnar

(2014/05/20 0:04), Denys Vlasenko wrote:
> On 05/17/2014 06:00 PM, Masami Hiramatsu wrote:
>> (2014/05/17 3:34), Denys Vlasenko wrote:
>>> Since xop and evex prefixes are extensions of vex mechanism,
>>> they have similar bit layouts, and they can never be combined
>>> (an instruction can have only one of them),
>>> (ab)use insn->vex_prefix to store data of xop and evex too.
>>>
>>> Users will need to conditionalize on insn->vex_prefix.bytes[0]
>>> instead of insn->vex_prefix.nbytes if they want to determine
>>> which of vex(-like) prefixes are there.
>>>
>>> Instead of adding more inattr bits for these prefixes, drop
>>> VEX inattr bits and use VEX opcode values directly to detect them.
>>> There is no point in having additional level of indirection here.
>>> (And we are close to running out of inattr bits for prefixes).
>>
>> Thank you very much for trying this work :)
>> But sorry, Nak, I don't like to use the prefix byte directly.
>> I'd rather like to add additional inattr bits for them.
> 
> Ok, I'm looking at inat.h and looks like I need to widen
> INAT_PFX_BITS, otherwise I have no space for two more bits
> for two more prefixes (XOP and EVEX):

Yes, that's what I look forward! :)

> 
> /* AVX VEX prefixes */
> #define INAT_PFX_VEX2   13      /* 2-bytes VEX prefix */
> #define INAT_PFX_VEX3   14      /* 3-bytes VEX prefix */
> ...
> 
> /* Legacy prefix */
> #define INAT_PFX_OFFS   0
> #define INAT_PFX_BITS   4
> #define INAT_PFX_MAX    ((1 << INAT_PFX_BITS) - 1)
> #define INAT_PFX_MASK   (INAT_PFX_MAX << INAT_PFX_OFFS)
> 
> 


-- 
Masami HIRAMATSU
Software Platform Research Dept. Linux Technology Research Center
Hitachi, Ltd., Yokohama Research Laboratory
E-mail: masami.hiramatsu.pt@hitachi.com



^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH 1/2] x86: insn decoder: create artificial 3rd byte for 2-byte VEX
@ 2014-09-04 12:54 Denys Vlasenko
  2014-09-04 12:54 ` [PATCH 2/2] x86: extend insn decoder to understand xop and evex prefixes Denys Vlasenko
  0 siblings, 1 reply; 7+ messages in thread
From: Denys Vlasenko @ 2014-09-04 12:54 UTC (permalink / raw)
  To: linux-kernel
  Cc: Denys Vlasenko, Masami Hiramatsu, Frank Ch. Eigler,
	Srikar Dronamraju, Ananth N Mavinakayanahalli, Jim Keniston,
	Oleg Nesterov, Andi Kleen, Ingo Molnar

Before this patch, users need to do this to fetch vex.vvvv:

        if (insn->vex_prefix.nbytes == 2) {
                vex_vvvv = ((insn->vex_prefix.bytes[1] >> 3) & 0xf) ^ 0xf;
        }
        if (insn->vex_prefix.nbytes == 3) {
                vex_vvvv = ((insn->vex_prefix.bytes[2] >> 3) & 0xf) ^ 0xf;
        }

Make it so that insn->vex_prefix.bytes[2] always contains vex.wvvvvLpp bits.

Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
Cc: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Cc: Frank Ch. Eigler <fche@redhat.com>
Cc: Srikar Dronamraju <srikar@linux.vnet.ibm.com>
Cc: Ananth N Mavinakayanahalli <ananth@in.ibm.com>
Cc: Jim Keniston <jkenisto@linux.vnet.ibm.com>
Cc: Oleg Nesterov <oleg@redhat.com>
Cc: Andi Kleen <andi@firstfloor.org>
Cc: Ingo Molnar <mingo@kernel.org>
---
 arch/x86/lib/insn.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/arch/x86/lib/insn.c b/arch/x86/lib/insn.c
index 54fcffe..829ca4c 100644
--- a/arch/x86/lib/insn.c
+++ b/arch/x86/lib/insn.c
@@ -163,6 +163,12 @@ found:
 				/* VEX.W overrides opnd_size */
 				insn->opnd_bytes = 8;
 		} else {
+			/*
+			 * For VEX2, fake VEX3-like byte#2.
+			 * Makes it easier to decode vex.W, vex.vvvv,
+			 * vex.L and vex.pp. Masking with 0x7f sets vex.W == 0.
+			 */
+			insn->vex_prefix.bytes[2] = b2 & 0x7f;
 			insn->vex_prefix.nbytes = 2;
 			insn->next_byte += 2;
 		}
-- 
1.8.1.4


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 2/2] x86: extend insn decoder to understand xop and evex prefixes
  2014-09-04 12:54 [PATCH 1/2] x86: insn decoder: create artificial 3rd byte for 2-byte VEX Denys Vlasenko
@ 2014-09-04 12:54 ` Denys Vlasenko
  2014-09-05 12:41   ` Masami Hiramatsu
  0 siblings, 1 reply; 7+ messages in thread
From: Denys Vlasenko @ 2014-09-04 12:54 UTC (permalink / raw)
  To: linux-kernel
  Cc: Denys Vlasenko, Masami Hiramatsu, Frank Ch. Eigler,
	Srikar Dronamraju, Ananth N Mavinakayanahalli, Jim Keniston,
	Oleg Nesterov, Andi Kleen, Ingo Molnar

Since xop and evex prefixes are extensions of vex mechanism,
they have similar bit layouts, and they can never be combined
(an instruction can have only one of them),
(ab)use insn->vex_prefix to store data of xop and evex too.

Users will need to conditionalize on insn->vex_prefix.bytes[0]
instead of insn->vex_prefix.nbytes if they want to determine
which of vex(-like) prefixes are there.

v2: on Masami's request, retained use of inattr bits
for determining prefixes.

Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
Cc: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Cc: Frank Ch. Eigler <fche@redhat.com>
Cc: Srikar Dronamraju <srikar@linux.vnet.ibm.com>
Cc: Ananth N Mavinakayanahalli <ananth@in.ibm.com>
Cc: Jim Keniston <jkenisto@linux.vnet.ibm.com>
Cc: Oleg Nesterov <oleg@redhat.com>
Cc: Andi Kleen <andi@firstfloor.org>
Cc: Ingo Molnar <mingo@kernel.org>
---
 arch/x86/include/asm/inat.h          | 26 +++++++++++++----
 arch/x86/lib/insn.c                  | 54 ++++++++++++++++++++++++------------
 arch/x86/lib/x86-opcode-map.txt      |  4 +--
 arch/x86/tools/gen-insn-attr-x86.awk |  2 ++
 4 files changed, 62 insertions(+), 24 deletions(-)

diff --git a/arch/x86/include/asm/inat.h b/arch/x86/include/asm/inat.h
index 74a2e31..2c7b4cc 100644
--- a/arch/x86/include/asm/inat.h
+++ b/arch/x86/include/asm/inat.h
@@ -48,6 +48,8 @@
 /* AVX VEX prefixes */
 #define INAT_PFX_VEX2	13	/* 2-bytes VEX prefix */
 #define INAT_PFX_VEX3	14	/* 3-bytes VEX prefix */
+#define INAT_PFX_XOP    15      /* 3-bytes XOP prefix */
+#define INAT_PFX_EVEX   16      /* 4-bytes EVEX prefix */
 
 #define INAT_LSTPFX_MAX	3
 #define INAT_LGCPFX_MAX	11
@@ -63,7 +65,7 @@
 
 /* Legacy prefix */
 #define INAT_PFX_OFFS	0
-#define INAT_PFX_BITS	4
+#define INAT_PFX_BITS	5
 #define INAT_PFX_MAX    ((1 << INAT_PFX_BITS) - 1)
 #define INAT_PFX_MASK	(INAT_PFX_MAX << INAT_PFX_OFFS)
 /* Escape opcodes */
@@ -138,15 +140,29 @@ static inline int inat_last_prefix_id(insn_attr_t attr)
 		return attr & INAT_PFX_MASK;
 }
 
+static inline int inat_is_vex3_prefix(insn_attr_t attr)
+{
+	return attr & INAT_PFX_VEX3;
+}
+
+static inline int inat_is_vex2_prefix(insn_attr_t attr)
+{
+	return attr & INAT_PFX_VEX2;
+}
+
+static inline int inat_is_xop_prefix(insn_attr_t attr)
+{
+	return attr & INAT_PFX_XOP;
+}
+
 static inline int inat_is_vex_prefix(insn_attr_t attr)
 {
-	attr &= INAT_PFX_MASK;
-	return attr == INAT_PFX_VEX2 || attr == INAT_PFX_VEX3;
+	return attr & (INAT_PFX_VEX2 | INAT_PFX_VEX3);
 }
 
-static inline int inat_is_vex3_prefix(insn_attr_t attr)
+static inline int inat_is_vex_like_prefix(insn_attr_t attr)
 {
-	return (attr & INAT_PFX_MASK) == INAT_PFX_VEX3;
+	return attr & (INAT_PFX_VEX2 | INAT_PFX_VEX3 | INAT_PFX_XOP | INAT_PFX_EVEX);
 }
 
 static inline int inat_is_escape(insn_attr_t attr)
diff --git a/arch/x86/lib/insn.c b/arch/x86/lib/insn.c
index 829ca4c..def44c8 100644
--- a/arch/x86/lib/insn.c
+++ b/arch/x86/lib/insn.c
@@ -138,40 +138,60 @@ found:
 	}
 	insn->rex_prefix.got = 1;
 
-	/* Decode VEX prefix */
+	/* Decode VEX prefixes et al. Layouts are:
+	 * vex2:     c5    rvvvvLpp
+	 * vex3/xop: c4/8f rxbmmmmm wvvvvLpp
+	 * evex:     62    rxbR00mm wvvvv1pp zllBVaaa
+	 */
 	b = peek_next(insn_byte_t, insn);
 	attr = inat_get_opcode_attribute(b);
-	if (inat_is_vex_prefix(attr)) {
-		insn_byte_t b2 = peek_nbyte_next(insn_byte_t, insn, 1);
-		if (!insn->x86_64) {
+	if (inat_is_vex_like_prefix(attr)) {
+		insn_byte_t b2;
+
+		b2 = peek_nbyte_next(insn_byte_t, insn, 1);
+		if (inat_is_xop_prefix(attr)) {
 			/*
-			 * 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.
+			 * XOP: If modrm.reg bits are 000, it's POP reg/mem.
+			 */
+			if (X86_MODRM_REG(b2) == 0)
+				goto vex_end;
+		}
+		else if (!insn->x86_64) {
+			/*
+			 * [E]VEX: In 32-bits mode, if modrm.mod bits
+			 * are not 11b, it is LDS, 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)) {
-			b2 = peek_nbyte_next(insn_byte_t, insn, 2);
-			insn->vex_prefix.bytes[2] = b2;
-			insn->vex_prefix.nbytes = 3;
-			insn->next_byte += 3;
-			if (insn->x86_64 && X86_VEX_W(b2))
-				/* VEX.W overrides opnd_size */
-				insn->opnd_bytes = 8;
-		} else {
+		if (inat_is_vex2_prefix(attr)) {
 			/*
 			 * For VEX2, fake VEX3-like byte#2.
 			 * Makes it easier to decode vex.W, vex.vvvv,
-			 * vex.L and vex.pp. Masking with 0x7f sets vex.W == 0.
+			 * vex.L and vex.pp. Masking with 0x7f sets vex.W = 0.
 			 */
 			insn->vex_prefix.bytes[2] = b2 & 0x7f;
 			insn->vex_prefix.nbytes = 2;
 			insn->next_byte += 2;
+			goto vex_end;
+		}
+		b2 = peek_nbyte_next(insn_byte_t, insn, 2);
+		insn->vex_prefix.bytes[2] = b2;
+		if (insn->x86_64 && X86_VEX_W(b2)) {
+			/* VEX.W overrides opnd_size */
+			insn->opnd_bytes = 8;
+		}
+		if (inat_is_vex3_prefix(attr) || inat_is_xop_prefix(attr)) {
+			insn->vex_prefix.nbytes = 3;
+			insn->next_byte += 3;
+			goto vex_end;
 		}
+		b2 = peek_nbyte_next(insn_byte_t, insn, 3);
+		insn->vex_prefix.bytes[3] = b2;
+		insn->vex_prefix.nbytes = 4;
+		insn->next_byte += 4;
 	}
 vex_end:
 	insn->vex_prefix.got = 1;
diff --git a/arch/x86/lib/x86-opcode-map.txt b/arch/x86/lib/x86-opcode-map.txt
index 1a2be7c..9d8a964 100644
--- a/arch/x86/lib/x86-opcode-map.txt
+++ b/arch/x86/lib/x86-opcode-map.txt
@@ -137,7 +137,7 @@ AVXcode:
 # 0x60 - 0x6f
 60: PUSHA/PUSHAD (i64)
 61: POPA/POPAD (i64)
-62: BOUND Gv,Ma (i64)
+62: BOUND Gv,Ma (i64) | EVEX+3byte (Prefix)
 63: ARPL Ew,Gw (i64) | MOVSXD Gv,Ev (o64)
 64: SEG=FS (Prefix)
 65: SEG=GS (Prefix)
@@ -184,7 +184,7 @@ AVXcode:
 8c: MOV Ev,Sw
 8d: LEA Gv,M
 8e: MOV Sw,Ew
-8f: Grp1A (1A) | POP Ev (d64)
+8f: Grp1A (1A) | POP Ev (d64) | XOP+2byte (Prefix)
 # 0x90 - 0x9f
 90: NOP | PAUSE (F3) | XCHG r8,rAX
 91: XCHG rCX/r9,rAX
diff --git a/arch/x86/tools/gen-insn-attr-x86.awk b/arch/x86/tools/gen-insn-attr-x86.awk
index 093a892..d288754 100644
--- a/arch/x86/tools/gen-insn-attr-x86.awk
+++ b/arch/x86/tools/gen-insn-attr-x86.awk
@@ -95,6 +95,8 @@ BEGIN {
 	prefix_num["Address-Size"] = "INAT_PFX_ADDRSZ"
 	prefix_num["VEX+1byte"] = "INAT_PFX_VEX2"
 	prefix_num["VEX+2byte"] = "INAT_PFX_VEX3"
+	prefix_num["XOP+2byte"] = "INAT_PFX_XOP"
+	prefix_num["EVEX+3byte"] = "INAT_PFX_EVEX"
 
 	clear_vars()
 }
-- 
1.8.1.4


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH 2/2] x86: extend insn decoder to understand xop and evex prefixes
  2014-09-04 12:54 ` [PATCH 2/2] x86: extend insn decoder to understand xop and evex prefixes Denys Vlasenko
@ 2014-09-05 12:41   ` Masami Hiramatsu
  0 siblings, 0 replies; 7+ messages in thread
From: Masami Hiramatsu @ 2014-09-05 12:41 UTC (permalink / raw)
  To: Denys Vlasenko
  Cc: linux-kernel, Frank Ch. Eigler, Srikar Dronamraju,
	Ananth N Mavinakayanahalli, Jim Keniston, Oleg Nesterov,
	Andi Kleen, Ingo Molnar

Hi Denys,

(2014/09/04 21:54), Denys Vlasenko wrote:
> Since xop and evex prefixes are extensions of vex mechanism,
> they have similar bit layouts, and they can never be combined
> (an instruction can have only one of them),
> (ab)use insn->vex_prefix to store data of xop and evex too.
> 
> Users will need to conditionalize on insn->vex_prefix.bytes[0]
> instead of insn->vex_prefix.nbytes if they want to determine
> which of vex(-like) prefixes are there.

Hmm, this is just a basic support of AVX512, since this doesn't
recognize the instructions which do not support evex prefixes.
We'd better to check Intel's new SDM and clarify which instructions
do really support it or not.

Thank you,

> 
> v2: on Masami's request, retained use of inattr bits
> for determining prefixes.
> 
> Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
> Cc: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
> Cc: Frank Ch. Eigler <fche@redhat.com>
> Cc: Srikar Dronamraju <srikar@linux.vnet.ibm.com>
> Cc: Ananth N Mavinakayanahalli <ananth@in.ibm.com>
> Cc: Jim Keniston <jkenisto@linux.vnet.ibm.com>
> Cc: Oleg Nesterov <oleg@redhat.com>
> Cc: Andi Kleen <andi@firstfloor.org>
> Cc: Ingo Molnar <mingo@kernel.org>
> ---
>  arch/x86/include/asm/inat.h          | 26 +++++++++++++----
>  arch/x86/lib/insn.c                  | 54 ++++++++++++++++++++++++------------
>  arch/x86/lib/x86-opcode-map.txt      |  4 +--
>  arch/x86/tools/gen-insn-attr-x86.awk |  2 ++
>  4 files changed, 62 insertions(+), 24 deletions(-)
> 
> diff --git a/arch/x86/include/asm/inat.h b/arch/x86/include/asm/inat.h
> index 74a2e31..2c7b4cc 100644
> --- a/arch/x86/include/asm/inat.h
> +++ b/arch/x86/include/asm/inat.h
> @@ -48,6 +48,8 @@
>  /* AVX VEX prefixes */
>  #define INAT_PFX_VEX2	13	/* 2-bytes VEX prefix */
>  #define INAT_PFX_VEX3	14	/* 3-bytes VEX prefix */
> +#define INAT_PFX_XOP    15      /* 3-bytes XOP prefix */
> +#define INAT_PFX_EVEX   16      /* 4-bytes EVEX prefix */
>  
>  #define INAT_LSTPFX_MAX	3
>  #define INAT_LGCPFX_MAX	11
> @@ -63,7 +65,7 @@
>  
>  /* Legacy prefix */
>  #define INAT_PFX_OFFS	0
> -#define INAT_PFX_BITS	4
> +#define INAT_PFX_BITS	5
>  #define INAT_PFX_MAX    ((1 << INAT_PFX_BITS) - 1)
>  #define INAT_PFX_MASK	(INAT_PFX_MAX << INAT_PFX_OFFS)
>  /* Escape opcodes */
> @@ -138,15 +140,29 @@ static inline int inat_last_prefix_id(insn_attr_t attr)
>  		return attr & INAT_PFX_MASK;
>  }
>  
> +static inline int inat_is_vex3_prefix(insn_attr_t attr)
> +{
> +	return attr & INAT_PFX_VEX3;
> +}
> +
> +static inline int inat_is_vex2_prefix(insn_attr_t attr)
> +{
> +	return attr & INAT_PFX_VEX2;
> +}
> +
> +static inline int inat_is_xop_prefix(insn_attr_t attr)
> +{
> +	return attr & INAT_PFX_XOP;
> +}
> +
>  static inline int inat_is_vex_prefix(insn_attr_t attr)
>  {
> -	attr &= INAT_PFX_MASK;
> -	return attr == INAT_PFX_VEX2 || attr == INAT_PFX_VEX3;
> +	return attr & (INAT_PFX_VEX2 | INAT_PFX_VEX3);
>  }
>  
> -static inline int inat_is_vex3_prefix(insn_attr_t attr)
> +static inline int inat_is_vex_like_prefix(insn_attr_t attr)
>  {
> -	return (attr & INAT_PFX_MASK) == INAT_PFX_VEX3;
> +	return attr & (INAT_PFX_VEX2 | INAT_PFX_VEX3 | INAT_PFX_XOP | INAT_PFX_EVEX);
>  }
>  
>  static inline int inat_is_escape(insn_attr_t attr)
> diff --git a/arch/x86/lib/insn.c b/arch/x86/lib/insn.c
> index 829ca4c..def44c8 100644
> --- a/arch/x86/lib/insn.c
> +++ b/arch/x86/lib/insn.c
> @@ -138,40 +138,60 @@ found:
>  	}
>  	insn->rex_prefix.got = 1;
>  
> -	/* Decode VEX prefix */
> +	/* Decode VEX prefixes et al. Layouts are:
> +	 * vex2:     c5    rvvvvLpp
> +	 * vex3/xop: c4/8f rxbmmmmm wvvvvLpp
> +	 * evex:     62    rxbR00mm wvvvv1pp zllBVaaa
> +	 */
>  	b = peek_next(insn_byte_t, insn);
>  	attr = inat_get_opcode_attribute(b);
> -	if (inat_is_vex_prefix(attr)) {
> -		insn_byte_t b2 = peek_nbyte_next(insn_byte_t, insn, 1);
> -		if (!insn->x86_64) {
> +	if (inat_is_vex_like_prefix(attr)) {
> +		insn_byte_t b2;
> +
> +		b2 = peek_nbyte_next(insn_byte_t, insn, 1);
> +		if (inat_is_xop_prefix(attr)) {
>  			/*
> -			 * 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.
> +			 * XOP: If modrm.reg bits are 000, it's POP reg/mem.
> +			 */
> +			if (X86_MODRM_REG(b2) == 0)
> +				goto vex_end;
> +		}
> +		else if (!insn->x86_64) {
> +			/*
> +			 * [E]VEX: In 32-bits mode, if modrm.mod bits
> +			 * are not 11b, it is LDS, 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)) {
> -			b2 = peek_nbyte_next(insn_byte_t, insn, 2);
> -			insn->vex_prefix.bytes[2] = b2;
> -			insn->vex_prefix.nbytes = 3;
> -			insn->next_byte += 3;
> -			if (insn->x86_64 && X86_VEX_W(b2))
> -				/* VEX.W overrides opnd_size */
> -				insn->opnd_bytes = 8;
> -		} else {
> +		if (inat_is_vex2_prefix(attr)) {
>  			/*
>  			 * For VEX2, fake VEX3-like byte#2.
>  			 * Makes it easier to decode vex.W, vex.vvvv,
> -			 * vex.L and vex.pp. Masking with 0x7f sets vex.W == 0.
> +			 * vex.L and vex.pp. Masking with 0x7f sets vex.W = 0.
>  			 */
>  			insn->vex_prefix.bytes[2] = b2 & 0x7f;
>  			insn->vex_prefix.nbytes = 2;
>  			insn->next_byte += 2;
> +			goto vex_end;
> +		}
> +		b2 = peek_nbyte_next(insn_byte_t, insn, 2);
> +		insn->vex_prefix.bytes[2] = b2;
> +		if (insn->x86_64 && X86_VEX_W(b2)) {
> +			/* VEX.W overrides opnd_size */
> +			insn->opnd_bytes = 8;
> +		}
> +		if (inat_is_vex3_prefix(attr) || inat_is_xop_prefix(attr)) {
> +			insn->vex_prefix.nbytes = 3;
> +			insn->next_byte += 3;
> +			goto vex_end;
>  		}
> +		b2 = peek_nbyte_next(insn_byte_t, insn, 3);
> +		insn->vex_prefix.bytes[3] = b2;
> +		insn->vex_prefix.nbytes = 4;
> +		insn->next_byte += 4;
>  	}
>  vex_end:
>  	insn->vex_prefix.got = 1;
> diff --git a/arch/x86/lib/x86-opcode-map.txt b/arch/x86/lib/x86-opcode-map.txt
> index 1a2be7c..9d8a964 100644
> --- a/arch/x86/lib/x86-opcode-map.txt
> +++ b/arch/x86/lib/x86-opcode-map.txt
> @@ -137,7 +137,7 @@ AVXcode:
>  # 0x60 - 0x6f
>  60: PUSHA/PUSHAD (i64)
>  61: POPA/POPAD (i64)
> -62: BOUND Gv,Ma (i64)
> +62: BOUND Gv,Ma (i64) | EVEX+3byte (Prefix)
>  63: ARPL Ew,Gw (i64) | MOVSXD Gv,Ev (o64)
>  64: SEG=FS (Prefix)
>  65: SEG=GS (Prefix)
> @@ -184,7 +184,7 @@ AVXcode:
>  8c: MOV Ev,Sw
>  8d: LEA Gv,M
>  8e: MOV Sw,Ew
> -8f: Grp1A (1A) | POP Ev (d64)
> +8f: Grp1A (1A) | POP Ev (d64) | XOP+2byte (Prefix)
>  # 0x90 - 0x9f
>  90: NOP | PAUSE (F3) | XCHG r8,rAX
>  91: XCHG rCX/r9,rAX
> diff --git a/arch/x86/tools/gen-insn-attr-x86.awk b/arch/x86/tools/gen-insn-attr-x86.awk
> index 093a892..d288754 100644
> --- a/arch/x86/tools/gen-insn-attr-x86.awk
> +++ b/arch/x86/tools/gen-insn-attr-x86.awk
> @@ -95,6 +95,8 @@ BEGIN {
>  	prefix_num["Address-Size"] = "INAT_PFX_ADDRSZ"
>  	prefix_num["VEX+1byte"] = "INAT_PFX_VEX2"
>  	prefix_num["VEX+2byte"] = "INAT_PFX_VEX3"
> +	prefix_num["XOP+2byte"] = "INAT_PFX_XOP"
> +	prefix_num["EVEX+3byte"] = "INAT_PFX_EVEX"
>  
>  	clear_vars()
>  }
> 


-- 
Masami HIRAMATSU
Software Platform Research Dept. Linux Technology Research Center
Hitachi, Ltd., Yokohama Research Laboratory
E-mail: masami.hiramatsu.pt@hitachi.com



^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2014-09-05 12:42 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-09-04 12:54 [PATCH 1/2] x86: insn decoder: create artificial 3rd byte for 2-byte VEX Denys Vlasenko
2014-09-04 12:54 ` [PATCH 2/2] x86: extend insn decoder to understand xop and evex prefixes Denys Vlasenko
2014-09-05 12:41   ` Masami Hiramatsu
  -- strict thread matches above, loose matches on Subject: below --
2014-05-16 18:34 [PATCH 1/2] x86: insn decoder: create artificial 3rd byte for 2-byte VEX Denys Vlasenko
2014-05-16 18:34 ` [PATCH 2/2] x86: extend insn decoder to understand xop and evex prefixes Denys Vlasenko
2014-05-17 16:00   ` Masami Hiramatsu
2014-05-19 15:04     ` Denys Vlasenko
2014-05-21  7:40       ` Masami Hiramatsu

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox