public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* [PATCH] x86: don't allow invalid operand combinations for VGATHER
@ 2012-07-24 14:19 Jan Beulich
  2012-07-30 16:10 ` H.J. Lu
  0 siblings, 1 reply; 9+ messages in thread
From: Jan Beulich @ 2012-07-24 14:19 UTC (permalink / raw)
  To: binutils

[-- Attachment #1: Type: text/plain, Size: 2841 bytes --]

The VGATHER group of instructions requires that all three involved
xmm/ymm registers are distinct. This patch adds code to check for this,
and at once eliminates a superfluous check for not using PC-relative
addressing for these instructions (the fact that an index register is
required here already excludes valid PC-relative addresses).

Note that this patch depends on the introduction of register_number(),
which is being done by the patch at
http://www.sourceware.org/ml/binutils/2012-07/msg00168.html.

2012-07-24  Jan Beulich <jbeulich@suse.com>

	* config/tc-i386.c (enum i386_error): New enumerator
	'invalid_vector_register_set'.
	(match_template): Handle it.
	(check_VecOperands): Don't special case RIP addressing. Check
	that vSIB operands use distinct vector registers.

--- a/gas/config/tc-i386.c
+++ b/gas/config/tc-i386.c
@@ -221,6 +221,7 @@ enum i386_error
     unsupported_syntax,
     unsupported,
     invalid_vsib_address,
+    invalid_vector_register_set,
     unsupported_vector_index_register
   };
 
@@ -3958,18 +3959,32 @@ check_VecOperands (const insn_template *
       return 1;
     }
 
-  /* For VSIB byte, we need a vector register for index and no PC
-     relative addressing is allowed.  */
-  if (t->opcode_modifier.vecsib
-      && (!i.index_reg
+  /* For VSIB byte, we need a vector register for index, and all vector
+     registers must be distinct.  */
+  if (t->opcode_modifier.vecsib)
+    {
+      if (!i.index_reg
 	  || !((t->opcode_modifier.vecsib == VecSIB128
 		&& i.index_reg->reg_type.bitfield.regxmm)
 	       || (t->opcode_modifier.vecsib == VecSIB256
-		   && i.index_reg->reg_type.bitfield.regymm))
-	  || (i.base_reg && i.base_reg->reg_num == RegRip)))
-    {
-      i.error = invalid_vsib_address;
-      return 1;
+		   && i.index_reg->reg_type.bitfield.regymm)))
+      {
+	i.error = invalid_vsib_address;
+	return 1;
+      }
+
+      gas_assert (i.reg_operands == 2);
+      gas_assert (i.types[0].bitfield.regxmm
+		  || i.types[0].bitfield.regymm);
+      gas_assert (i.types[2].bitfield.regxmm
+		  || i.types[2].bitfield.regymm);
+      if (register_number (i.op[0].regs) == register_number (i.index_reg)
+	  || register_number (i.op[2].regs) == register_number (i.index_reg)
+	  || register_number (i.op[0].regs) == register_number (i.op[2].regs))
+      {
+	i.error = invalid_vector_register_set;
+	return 1;
+      }
     }
 
   return 0;
@@ -4365,6 +4380,9 @@ check_reverse:
 	case invalid_vsib_address:
 	  err_msg = _("invalid VSIB address");
 	  break;
+	case invalid_vector_register_set:
+	  err_msg = _("mask, index, and destination registers must be distinct");
+	  break;
 	case unsupported_vector_index_register:
 	  err_msg = _("unsupported vector index register");
 	  break;




[-- Attachment #2: binutils-mainline-x86-vgather-distinct-regs.patch --]
[-- Type: text/plain, Size: 2835 bytes --]

The VGATHER group of instructions requires that all three involved
xmm/ymm registers are distinct. This patch adds code to check for this,
and at once eliminates a superfluous check for not using PC-relative
addressing for these instructions (the fact that an index register is
required here already excludes valid PC-relative addresses).

Note that this patch depends on the introduction of register_number(),
which is being done by the patch at
http://www.sourceware.org/ml/binutils/2012-07/msg00168.html.

2012-07-24  Jan Beulich <jbeulich@suse.com>

	* config/tc-i386.c (enum i386_error): New enumerator
	'invalid_vector_register_set'.
	(match_template): Handle it.
	(check_VecOperands): Don't special case RIP addressing. Check
	that vSIB operands use distinct vector registers.

--- a/gas/config/tc-i386.c
+++ b/gas/config/tc-i386.c
@@ -221,6 +221,7 @@ enum i386_error
     unsupported_syntax,
     unsupported,
     invalid_vsib_address,
+    invalid_vector_register_set,
     unsupported_vector_index_register
   };
 
@@ -3958,18 +3959,32 @@ check_VecOperands (const insn_template *
       return 1;
     }
 
-  /* For VSIB byte, we need a vector register for index and no PC
-     relative addressing is allowed.  */
-  if (t->opcode_modifier.vecsib
-      && (!i.index_reg
+  /* For VSIB byte, we need a vector register for index, and all vector
+     registers must be distinct.  */
+  if (t->opcode_modifier.vecsib)
+    {
+      if (!i.index_reg
 	  || !((t->opcode_modifier.vecsib == VecSIB128
 		&& i.index_reg->reg_type.bitfield.regxmm)
 	       || (t->opcode_modifier.vecsib == VecSIB256
-		   && i.index_reg->reg_type.bitfield.regymm))
-	  || (i.base_reg && i.base_reg->reg_num == RegRip)))
-    {
-      i.error = invalid_vsib_address;
-      return 1;
+		   && i.index_reg->reg_type.bitfield.regymm)))
+      {
+	i.error = invalid_vsib_address;
+	return 1;
+      }
+
+      gas_assert (i.reg_operands == 2);
+      gas_assert (i.types[0].bitfield.regxmm
+		  || i.types[0].bitfield.regymm);
+      gas_assert (i.types[2].bitfield.regxmm
+		  || i.types[2].bitfield.regymm);
+      if (register_number (i.op[0].regs) == register_number (i.index_reg)
+	  || register_number (i.op[2].regs) == register_number (i.index_reg)
+	  || register_number (i.op[0].regs) == register_number (i.op[2].regs))
+      {
+	i.error = invalid_vector_register_set;
+	return 1;
+      }
     }
 
   return 0;
@@ -4365,6 +4380,9 @@ check_reverse:
 	case invalid_vsib_address:
 	  err_msg = _("invalid VSIB address");
 	  break;
+	case invalid_vector_register_set:
+	  err_msg = _("mask, index, and destination registers must be distinct");
+	  break;
 	case unsupported_vector_index_register:
 	  err_msg = _("unsupported vector index register");
 	  break;

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

* Re: [PATCH] x86: don't allow invalid operand combinations for VGATHER
  2012-07-24 14:19 [PATCH] x86: don't allow invalid operand combinations for VGATHER Jan Beulich
@ 2012-07-30 16:10 ` H.J. Lu
  2012-07-31  7:49   ` Jan Beulich
  0 siblings, 1 reply; 9+ messages in thread
From: H.J. Lu @ 2012-07-30 16:10 UTC (permalink / raw)
  To: Jan Beulich; +Cc: binutils

On Tue, Jul 24, 2012 at 7:18 AM, Jan Beulich <JBeulich@suse.com> wrote:
> The VGATHER group of instructions requires that all three involved
> xmm/ymm registers are distinct. This patch adds code to check for this,
> and at once eliminates a superfluous check for not using PC-relative
> addressing for these instructions (the fact that an index register is
> required here already excludes valid PC-relative addresses).
>

The assembler should only check the operands which can't be
encoded.  It should shouldn't check if operands are functional
correct.  However, I don't mind to issue an error which is controlled
by a command line option.

Thanks.

-- 
H.J.

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

* Re: [PATCH] x86: don't allow invalid operand combinations for VGATHER
  2012-07-30 16:10 ` H.J. Lu
@ 2012-07-31  7:49   ` Jan Beulich
  2012-07-31 15:44     ` H.J. Lu
  0 siblings, 1 reply; 9+ messages in thread
From: Jan Beulich @ 2012-07-31  7:49 UTC (permalink / raw)
  To: H.J. Lu; +Cc: binutils

>>> On 30.07.12 at 18:10, "H.J. Lu" <hjl.tools@gmail.com> wrote:
> On Tue, Jul 24, 2012 at 7:18 AM, Jan Beulich <JBeulich@suse.com> wrote:
>> The VGATHER group of instructions requires that all three involved
>> xmm/ymm registers are distinct. This patch adds code to check for this,
>> and at once eliminates a superfluous check for not using PC-relative
>> addressing for these instructions (the fact that an index register is
>> required here already excludes valid PC-relative addresses).
>>
> 
> The assembler should only check the operands which can't be
> encoded.  It should shouldn't check if operands are functional
> correct.  However, I don't mind to issue an error which is controlled
> by a command line option.

Hmm, not sure. Is there any precedent to such behavior? I as a
programmer would appreciate if the assembler rejected anything
that's invalid.

In the case you stay on that position, would making the new
diagnostic an unconditional warning be acceptable instead?

Jan

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

* Re: [PATCH] x86: don't allow invalid operand combinations for VGATHER
  2012-07-31  7:49   ` Jan Beulich
@ 2012-07-31 15:44     ` H.J. Lu
  2012-07-31 16:24       ` Jan Beulich
  2012-08-07 10:32       ` [PATCH, v2] gas/x86: " Jan Beulich
  0 siblings, 2 replies; 9+ messages in thread
From: H.J. Lu @ 2012-07-31 15:44 UTC (permalink / raw)
  To: Jan Beulich; +Cc: binutils

On Tue, Jul 31, 2012 at 12:49 AM, Jan Beulich <JBeulich@suse.com> wrote:
>>>> On 30.07.12 at 18:10, "H.J. Lu" <hjl.tools@gmail.com> wrote:
>> On Tue, Jul 24, 2012 at 7:18 AM, Jan Beulich <JBeulich@suse.com> wrote:
>>> The VGATHER group of instructions requires that all three involved
>>> xmm/ymm registers are distinct. This patch adds code to check for this,
>>> and at once eliminates a superfluous check for not using PC-relative
>>> addressing for these instructions (the fact that an index register is
>>> required here already excludes valid PC-relative addresses).
>>>
>>
>> The assembler should only check the operands which can't be
>> encoded.  It should shouldn't check if operands are functional
>> correct.  However, I don't mind to issue an error which is controlled
>> by a command line option.
>
> Hmm, not sure. Is there any precedent to such behavior? I as a
> programmer would appreciate if the assembler rejected anything
> that's invalid.
>
> In the case you stay on that position, would making the new
> diagnostic an unconditional warning be acceptable instead?
>

Can you also add a command line option to turn it off and
turn warning into error?

Thanks.

-- 
H.J.

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

* Re: [PATCH] x86: don't allow invalid operand combinations for VGATHER
  2012-07-31 15:44     ` H.J. Lu
@ 2012-07-31 16:24       ` Jan Beulich
  2012-08-07 10:32       ` [PATCH, v2] gas/x86: " Jan Beulich
  1 sibling, 0 replies; 9+ messages in thread
From: Jan Beulich @ 2012-07-31 16:24 UTC (permalink / raw)
  To: H.J. Lu; +Cc: binutils

>>> On 31.07.12 at 17:43, "H.J. Lu" <hjl.tools@gmail.com> wrote:
> On Tue, Jul 31, 2012 at 12:49 AM, Jan Beulich <JBeulich@suse.com> wrote:
>>>>> On 30.07.12 at 18:10, "H.J. Lu" <hjl.tools@gmail.com> wrote:
>>> On Tue, Jul 24, 2012 at 7:18 AM, Jan Beulich <JBeulich@suse.com> wrote:
>>>> The VGATHER group of instructions requires that all three involved
>>>> xmm/ymm registers are distinct. This patch adds code to check for this,
>>>> and at once eliminates a superfluous check for not using PC-relative
>>>> addressing for these instructions (the fact that an index register is
>>>> required here already excludes valid PC-relative addresses).
>>>>
>>>
>>> The assembler should only check the operands which can't be
>>> encoded.  It should shouldn't check if operands are functional
>>> correct.  However, I don't mind to issue an error which is controlled
>>> by a command line option.
>>
>> Hmm, not sure. Is there any precedent to such behavior? I as a
>> programmer would appreciate if the assembler rejected anything
>> that's invalid.
>>
>> In the case you stay on that position, would making the new
>> diagnostic an unconditional warning be acceptable instead?
>>
> 
> Can you also add a command line option to turn it off and
> turn warning into error?

That should be possible, yes.

Jan

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

* [PATCH, v2] gas/x86: don't allow invalid operand combinations for VGATHER
  2012-07-31 15:44     ` H.J. Lu
  2012-07-31 16:24       ` Jan Beulich
@ 2012-08-07 10:32       ` Jan Beulich
  2012-08-07 13:25         ` H.J. Lu
  1 sibling, 1 reply; 9+ messages in thread
From: Jan Beulich @ 2012-08-07 10:32 UTC (permalink / raw)
  To: H.J. Lu; +Cc: binutils

[-- Attachment #1: Type: text/plain, Size: 20143 bytes --]

>>> On 31.07.12 at 17:43, "H.J. Lu" <hjl.tools@gmail.com> wrote:
> On Tue, Jul 31, 2012 at 12:49 AM, Jan Beulich <JBeulich@suse.com> wrote:
>>>>> On 30.07.12 at 18:10, "H.J. Lu" <hjl.tools@gmail.com> wrote:
>>> The assembler should only check the operands which can't be
>>> encoded.  It should shouldn't check if operands are functional
>>> correct.  However, I don't mind to issue an error which is controlled
>>> by a command line option.
>>
>> Hmm, not sure. Is there any precedent to such behavior? I as a
>> programmer would appreciate if the assembler rejected anything
>> that's invalid.
>>
>> In the case you stay on that position, would making the new
>> diagnostic an unconditional warning be acceptable instead?
>>
> 
> Can you also add a command line option to turn it off and
> turn warning into error?

How about this then?

Jan

The VGATHER group of instructions requires that all three involved
xmm/ymm registers are distinct. This patch adds code to check for this,
and at once eliminates a superfluous check for not using PC-relative
addressing for these instructions (the fact that an index register is
required here already excludes valid PC-relative addresses). The
severity of the resulting diagnostics can be controlled via command
line option or directive.

Note that this patch depends on the introduction of register_number(),
which is being done by the patch at
http://www.sourceware.org/ml/binutils/2012-08/msg00119.html.

gas/
2012-08-07  Jan Beulich <jbeulich@suse.com>

	* config/tc-i386.c (set_check): Renamed from set_sse_check.
	Generalize to also handle operand checking option.
	(enum i386_error): New enumerator 'invalid_vector_register_set'.
	(match_template): Handle it.
	(enum check_kind): Give it a tag. Drop sse_ prefixes from
	enumerators.
	(operand_check): New.
	(md_pseudo_table): Add "operand_check".
	(check_VecOperands): Don't special case RIP addressing. Check
	that vSIB operands use distinct vector registers unless no
	checking was requested.
	(OPTION_MOPERAND_CHECK): New.
	(md_parse_option): Handle it.
	(OPTION_MAVXSCALAR, OPTION_X32): Adjust.
	(md_longopts): Add "moperand-check".
	(md_show_usage): Add help text for it.

gas/testsuite/
2012-08-07  Jan Beulich <jbeulich@suse.com>

	* gas/i386/vgather-check-error.{s,l}: New.
	* gas/i386/vgather-check-none.{s,d}: New.
	* gas/i386/vgather-check-warn.{d,e}: New.
	* gas/i386/vgather-check.{s,d}: New.
	* gas/i386/x86-64-vgather-check-error.{s,l}: New.
	* gas/i386/x86-64-vgather-check-none.{s,d}: New.
	* gas/i386/x86-64-vgather-check-warn.{d,e}: New.
	* gas/i386/x86-64-vgather-check.{s,d}: New.
	* gas/i386/i386.exp: Run new tests.

--- 2012-08-07/gas/config/tc-i386.c	2012-07-31 09:45:03.000000000 +0200
+++ 2012-08-07/gas/config/tc-i386.c	2012-08-07 11:53:37.000000000 +0200
@@ -144,7 +144,7 @@ static void set_16bit_gcc_code_flag (int
 static void set_intel_syntax (int);
 static void set_intel_mnemonic (int);
 static void set_allow_index_reg (int);
-static void set_sse_check (int);
+static void set_check (int);
 static void set_cpu_arch (int);
 #ifdef TE_PE
 static void pe_directive_secrel (int);
@@ -221,6 +221,7 @@ enum i386_error
     unsupported_syntax,
     unsupported,
     invalid_vsib_address,
+    invalid_vector_register_set,
     unsupported_vector_index_register
   };
 
@@ -449,13 +450,13 @@ static int allow_naked_reg = 0;
 /* 1 if pseudo index register, eiz/riz, is allowed .  */
 static int allow_index_reg = 0;
 
-static enum
+static enum check_kind
   {
-    sse_check_none = 0,
-    sse_check_warning,
-    sse_check_error
+    check_none = 0,
+    check_warning,
+    check_error
   }
-sse_check;
+sse_check, operand_check = check_warning;
 
 /* Register prefix used for error message.  */
 static const char *register_prefix = "%";
@@ -847,7 +848,8 @@ const pseudo_typeS md_pseudo_table[] =
   {"att_mnemonic", set_intel_mnemonic, 0},
   {"allow_index_reg", set_allow_index_reg, 1},
   {"disallow_index_reg", set_allow_index_reg, 0},
-  {"sse_check", set_sse_check, 0},
+  {"sse_check", set_check, 0},
+  {"operand_check", set_check, 1},
 #if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
   {"largecomm", handle_large_common, 0},
 #else
@@ -2111,8 +2113,22 @@ set_allow_index_reg (int flag)
 }
 
 static void
-set_sse_check (int dummy ATTRIBUTE_UNUSED)
+set_check (int what)
 {
+  enum check_kind *kind;
+  const char *str;
+
+  if (what)
+    {
+      kind = &operand_check;
+      str = "operand";
+    }
+  else
+    {
+      kind = &sse_check;
+      str = "sse";
+    }
+
   SKIP_WHITESPACE ();
 
   if (!is_end_of_line[(unsigned char) *input_line_pointer])
@@ -2121,17 +2137,17 @@ set_sse_check (int dummy ATTRIBUTE_UNUSE
       int e = get_symbol_end ();
 
       if (strcmp (string, "none") == 0)
-	sse_check = sse_check_none;
+	*kind = check_none;
       else if (strcmp (string, "warning") == 0)
-	sse_check = sse_check_warning;
+	*kind = check_warning;
       else if (strcmp (string, "error") == 0)
-	sse_check = sse_check_error;
+	*kind = check_error;
       else
-	as_bad (_("bad argument to sse_check directive."));
+	as_bad (_("bad argument to %s_check directive."), str);
       *input_line_pointer = e;
     }
   else
-    as_bad (_("missing argument for sse_check directive"));
+    as_bad (_("missing argument for %s_check directive"), str);
 
   demand_empty_rest_of_line ();
 }
@@ -3140,7 +3156,7 @@ md_assemble (char *line)
   if (!(t = match_template ()))
     return;
 
-  if (sse_check != sse_check_none
+  if (sse_check != check_none
       && !i.tm.opcode_modifier.noavx
       && (i.tm.cpu_flags.bitfield.cpusse
 	  || i.tm.cpu_flags.bitfield.cpusse2
@@ -3149,7 +3165,7 @@ md_assemble (char *line)
 	  || i.tm.cpu_flags.bitfield.cpusse4_1
 	  || i.tm.cpu_flags.bitfield.cpusse4_2))
     {
-      (sse_check == sse_check_warning
+      (sse_check == check_warning
        ? as_warn
        : as_bad) (_("SSE instruction `%s' is used"), i.tm.name);
     }
@@ -3969,18 +3985,38 @@ check_VecOperands (const insn_template *
       return 1;
     }
 
-  /* For VSIB byte, we need a vector register for index and no PC
-     relative addressing is allowed.  */
-  if (t->opcode_modifier.vecsib
-      && (!i.index_reg
+  /* For VSIB byte, we need a vector register for index, and all vector
+     registers must be distinct.  */
+  if (t->opcode_modifier.vecsib)
+    {
+      if (!i.index_reg
 	  || !((t->opcode_modifier.vecsib == VecSIB128
 		&& i.index_reg->reg_type.bitfield.regxmm)
 	       || (t->opcode_modifier.vecsib == VecSIB256
-		   && i.index_reg->reg_type.bitfield.regymm))
-	  || (i.base_reg && i.base_reg->reg_num == RegRip)))
-    {
-      i.error = invalid_vsib_address;
-      return 1;
+		   && i.index_reg->reg_type.bitfield.regymm)))
+      {
+	i.error = invalid_vsib_address;
+	return 1;
+      }
+
+      gas_assert (i.reg_operands == 2);
+      gas_assert (i.types[0].bitfield.regxmm
+		  || i.types[0].bitfield.regymm);
+      gas_assert (i.types[2].bitfield.regxmm
+		  || i.types[2].bitfield.regymm);
+
+      if (operand_check == check_none)
+	return 0;
+      if (register_number (i.op[0].regs) != register_number (i.index_reg)
+	  && register_number (i.op[2].regs) != register_number (i.index_reg)
+	  && register_number (i.op[0].regs) != register_number (i.op[2].regs))
+	return 0;
+      if (operand_check == check_error)
+	{
+	  i.error = invalid_vector_register_set;
+	  return 1;
+	}
+      as_warn (_("mask, index, and destination registers should be distinct"));
     }
 
   return 0;
@@ -4376,6 +4412,9 @@ check_reverse:
 	case invalid_vsib_address:
 	  err_msg = _("invalid VSIB address");
 	  break;
+	case invalid_vector_register_set:
+	  err_msg = _("mask, index, and destination registers must be distinct");
+	  break;
 	case unsupported_vector_index_register:
 	  err_msg = _("unsupported vector index register");
 	  break;
@@ -8408,8 +8447,9 @@ const char *md_shortopts = "qn";
 #define OPTION_MOLD_GCC (OPTION_MD_BASE + 9)
 #define OPTION_MSSE2AVX (OPTION_MD_BASE + 10)
 #define OPTION_MSSE_CHECK (OPTION_MD_BASE + 11)
-#define OPTION_MAVXSCALAR (OPTION_MD_BASE + 12)
-#define OPTION_X32 (OPTION_MD_BASE + 13)
+#define OPTION_MOPERAND_CHECK (OPTION_MD_BASE + 12)
+#define OPTION_MAVXSCALAR (OPTION_MD_BASE + 13)
+#define OPTION_X32 (OPTION_MD_BASE + 14)
 
 struct option md_longopts[] =
 {
@@ -8431,6 +8471,7 @@ struct option md_longopts[] =
   {"mold-gcc", no_argument, NULL, OPTION_MOLD_GCC},
   {"msse2avx", no_argument, NULL, OPTION_MSSE2AVX},
   {"msse-check", required_argument, NULL, OPTION_MSSE_CHECK},
+  {"moperand-check", required_argument, NULL, OPTION_MOPERAND_CHECK},
   {"mavxscalar", required_argument, NULL, OPTION_MAVXSCALAR},
   {NULL, no_argument, NULL, 0}
 };
@@ -8660,15 +8701,26 @@ md_parse_option (int c, char *arg)
 
     case OPTION_MSSE_CHECK:
       if (strcasecmp (arg, "error") == 0)
-	sse_check = sse_check_error;
+	sse_check = check_error;
       else if (strcasecmp (arg, "warning") == 0)
-	sse_check = sse_check_warning;
+	sse_check = check_warning;
       else if (strcasecmp (arg, "none") == 0)
-	sse_check = sse_check_none;
+	sse_check = check_none;
       else
 	as_fatal (_("invalid -msse-check= option: `%s'"), arg);
       break;
 
+    case OPTION_MOPERAND_CHECK:
+      if (strcasecmp (arg, "error") == 0)
+	operand_check = check_error;
+      else if (strcasecmp (arg, "warning") == 0)
+	operand_check = check_warning;
+      else if (strcasecmp (arg, "none") == 0)
+	operand_check = check_none;
+      else
+	as_fatal (_("invalid -moperand-check= option: `%s'"), arg);
+      break;
+
     case OPTION_MAVXSCALAR:
       if (strcasecmp (arg, "128") == 0)
 	avxscalar = vex128;
@@ -8807,6 +8859,9 @@ md_show_usage (FILE *stream)
   -msse-check=[none|error|warning]\n\
                           check SSE instructions\n"));
   fprintf (stream, _("\
+  -moperand-check=[none|error|warning]\n\
+                          check operand combinations for validity\n"));
+  fprintf (stream, _("\
   -mavxscalar=[128|256]   encode scalar AVX instructions with specific vector\n\
                            length\n"));
   fprintf (stream, _("\
--- 2012-08-07/gas/testsuite/gas/i386/i386.exp	2012-07-24 14:52:59.000000000 +0200
+++ 2012-08-07/gas/testsuite/gas/i386/i386.exp	2012-08-07 11:53:38.000000000 +0200
@@ -160,6 +160,10 @@ if [expr ([istarget "i*86-*-*"] ||  [ist
     run_dump_test "sse-check-none"
     run_dump_test "sse-check-warn"
     run_list_test "sse-check-error" "-msse-check=error -I${srcdir}/$subdir -al"
+    run_dump_test "vgather-check"
+    run_dump_test "vgather-check-none"
+    run_dump_test "vgather-check-warn"
+    run_list_test "vgather-check-error" "-moperand-check=error -I${srcdir}/$subdir"
     run_dump_test "sse-noavx"
     run_dump_test "movbe"
     run_dump_test "movbe-intel"
@@ -402,6 +406,10 @@ if [expr ([istarget "i*86-*-*"] || [ista
     run_dump_test "x86-64-sse-check-none"
     run_dump_test "x86-64-sse-check-warn"
     run_list_test "x86-64-sse-check-error" "-msse-check=error -I${srcdir}/$subdir -al"
+    run_dump_test "x86-64-vgather-check"
+    run_dump_test "x86-64-vgather-check-none"
+    run_dump_test "x86-64-vgather-check-warn"
+    run_list_test "x86-64-vgather-check-error" "-moperand-check=error -I${srcdir}/$subdir"
     run_dump_test "x86-64-sse-noavx"
     run_dump_test "x86-64-movbe"
     run_dump_test "x86-64-movbe-intel"
--- 2012-08-07/gas/testsuite/gas/i386/vgather-check-error.l	1970-01-01 01:00:00.000000000 +0100
+++ 2012-08-07/gas/testsuite/gas/i386/vgather-check-error.l	2012-08-03 16:45:09.000000000 +0200
@@ -0,0 +1,4 @@
+.*: Assembler messages:
+.*:6: Error: .*
+.*:7: Error: .*
+.*:8: Error: .*
--- 2012-08-07/gas/testsuite/gas/i386/vgather-check-error.s	1970-01-01 01:00:00.000000000 +0100
+++ 2012-08-07/gas/testsuite/gas/i386/vgather-check-error.s	2012-08-03 16:24:53.000000000 +0200
@@ -0,0 +1 @@
+.include "vgather-check.s"
--- 2012-08-07/gas/testsuite/gas/i386/vgather-check-none.d	1970-01-01 01:00:00.000000000 +0100
+++ 2012-08-07/gas/testsuite/gas/i386/vgather-check-none.d	2012-08-03 16:51:24.000000000 +0200
@@ -0,0 +1,14 @@
+#as: -moperand-check=error -I${srcdir}/$subdir
+#objdump: -dw
+#name: i386 vgather check (.operand_check none)
+
+.*:     file format .*
+
+Disassembly of section .text:
+
+0+ <vgather>:
+[ 	]*[a-f0-9]+:[ 	]+c4 e2 69 92 04 08[ 	]+vgatherdps %xmm2,\(%eax,%xmm1,1\),%xmm0
+[ 	]*[a-f0-9]+:[ 	]+c4 e2 69 92 14 48[ 	]+vgatherdps %xmm2,\(%eax,%xmm1,2\),%xmm2
+[ 	]*[a-f0-9]+:[ 	]+c4 e2 71 92 04 88[ 	]+vgatherdps %xmm1,\(%eax,%xmm1,4\),%xmm0
+[ 	]*[a-f0-9]+:[ 	]+c4 e2 69 92 0c c8[ 	]+vgatherdps %xmm2,\(%eax,%xmm1,8\),%xmm1
+#pass
--- 2012-08-07/gas/testsuite/gas/i386/vgather-check-none.s	1970-01-01 01:00:00.000000000 +0100
+++ 2012-08-07/gas/testsuite/gas/i386/vgather-check-none.s	2012-08-03 16:24:46.000000000 +0200
@@ -0,0 +1,2 @@
+.operand_check none
+.include "vgather-check.s"
--- 2012-08-07/gas/testsuite/gas/i386/vgather-check-warn.d	1970-01-01 01:00:00.000000000 +0100
+++ 2012-08-07/gas/testsuite/gas/i386/vgather-check-warn.d	2012-08-03 16:46:15.000000000 +0200
@@ -0,0 +1,15 @@
+#source: vgather-check.s
+#stderr: vgather-check-warn.e
+#objdump: -dw
+#name: i386 vgather check (warning)
+
+.*:     file format .*
+
+Disassembly of section .text:
+
+0+ <vgather>:
+[ 	]*[a-f0-9]+:[ 	]+c4 e2 69 92 04 08[ 	]+vgatherdps %xmm2,\(%eax,%xmm1,1\),%xmm0
+[ 	]*[a-f0-9]+:[ 	]+c4 e2 69 92 14 48[ 	]+vgatherdps %xmm2,\(%eax,%xmm1,2\),%xmm2
+[ 	]*[a-f0-9]+:[ 	]+c4 e2 71 92 04 88[ 	]+vgatherdps %xmm1,\(%eax,%xmm1,4\),%xmm0
+[ 	]*[a-f0-9]+:[ 	]+c4 e2 69 92 0c c8[ 	]+vgatherdps %xmm2,\(%eax,%xmm1,8\),%xmm1
+#pass
--- 2012-08-07/gas/testsuite/gas/i386/vgather-check-warn.e	1970-01-01 01:00:00.000000000 +0100
+++ 2012-08-07/gas/testsuite/gas/i386/vgather-check-warn.e	2012-08-03 16:49:48.000000000 +0200
@@ -0,0 +1,4 @@
+.*: Assembler messages:
+.*:6: Warning: .*
+.*:7: Warning: .*
+.*:8: Warning: .*
--- 2012-08-07/gas/testsuite/gas/i386/vgather-check.d	1970-01-01 01:00:00.000000000 +0100
+++ 2012-08-07/gas/testsuite/gas/i386/vgather-check.d	2012-08-03 17:28:17.000000000 +0200
@@ -0,0 +1,14 @@
+#as: -moperand-check=none
+#objdump: -dw
+#name: i386 vgather check (-moperand-check=none)
+
+.*:     file format .*
+
+Disassembly of section .text:
+
+0+ <vgather>:
+[ 	]*[a-f0-9]+:[ 	]+c4 e2 69 92 04 08[ 	]+vgatherdps %xmm2,\(%eax,%xmm1,1\),%xmm0
+[ 	]*[a-f0-9]+:[ 	]+c4 e2 69 92 14 48[ 	]+vgatherdps %xmm2,\(%eax,%xmm1,2\),%xmm2
+[ 	]*[a-f0-9]+:[ 	]+c4 e2 71 92 04 88[ 	]+vgatherdps %xmm1,\(%eax,%xmm1,4\),%xmm0
+[ 	]*[a-f0-9]+:[ 	]+c4 e2 69 92 0c c8[ 	]+vgatherdps %xmm2,\(%eax,%xmm1,8\),%xmm1
+#pass
--- 2012-08-07/gas/testsuite/gas/i386/vgather-check.s	1970-01-01 01:00:00.000000000 +0100
+++ 2012-08-07/gas/testsuite/gas/i386/vgather-check.s	2012-08-03 16:36:48.000000000 +0200
@@ -0,0 +1,8 @@
+# Check vgather instructions
+
+	.text
+vgather:
+	vgatherdps %xmm2,(%eax,%xmm1,1),%xmm0
+	vgatherdps %xmm2,(%eax,%xmm1,2),%xmm2
+	vgatherdps %xmm1,(%eax,%xmm1,4),%xmm0
+	vgatherdps %xmm2,(%eax,%xmm1,8),%xmm1
--- 2012-08-07/gas/testsuite/gas/i386/x86-64-vgather-check-error.l	1970-01-01 01:00:00.000000000 +0100
+++ 2012-08-07/gas/testsuite/gas/i386/x86-64-vgather-check-error.l	2012-08-03 16:55:49.000000000 +0200
@@ -0,0 +1,4 @@
+.*: Assembler messages:
+.*:6: Error: .*
+.*:8: Error: .*
+.*:10: Error: .*
--- 2012-08-07/gas/testsuite/gas/i386/x86-64-vgather-check-error.s	1970-01-01 01:00:00.000000000 +0100
+++ 2012-08-07/gas/testsuite/gas/i386/x86-64-vgather-check-error.s	2012-08-03 16:54:09.000000000 +0200
@@ -0,0 +1 @@
+.include "x86-64-vgather-check.s"
--- 2012-08-07/gas/testsuite/gas/i386/x86-64-vgather-check-none.d	1970-01-01 01:00:00.000000000 +0100
+++ 2012-08-07/gas/testsuite/gas/i386/x86-64-vgather-check-none.d	2012-08-03 17:27:38.000000000 +0200
@@ -0,0 +1,17 @@
+#as: -moperand-check=error -I${srcdir}/$subdir
+#objdump: -dw
+#name: x86-64 vgather check (.operand_check none)
+
+.*:     file format .*
+
+Disassembly of section .text:
+
+0+ <vgather>:
+[ 	]*[a-f0-9]+:[ 	]+c4 e2 69 92 04 08[ 	]+vgatherdps %xmm2,\(%rax,%xmm1,1\),%xmm0
+[ 	]*[a-f0-9]+:[ 	]+c4 e2 69 92 14 48[ 	]+vgatherdps %xmm2,\(%rax,%xmm1,2\),%xmm2
+[ 	]*[a-f0-9]+:[ 	]+c4 62 69 92 14 48[ 	]+vgatherdps %xmm2,\(%rax,%xmm1,2\),%xmm10
+[ 	]*[a-f0-9]+:[ 	]+c4 e2 71 92 04 88[ 	]+vgatherdps %xmm1,\(%rax,%xmm1,4\),%xmm0
+[ 	]*[a-f0-9]+:[ 	]+c4 e2 31 92 04 88[ 	]+vgatherdps %xmm9,\(%rax,%xmm1,4\),%xmm0
+[ 	]*[a-f0-9]+:[ 	]+c4 e2 69 92 0c c8[ 	]+vgatherdps %xmm2,\(%rax,%xmm1,8\),%xmm1
+[ 	]*[a-f0-9]+:[ 	]+c4 62 69 92 0c c8[ 	]+vgatherdps %xmm2,\(%rax,%xmm1,8\),%xmm9
+#pass
--- 2012-08-07/gas/testsuite/gas/i386/x86-64-vgather-check-none.s	1970-01-01 01:00:00.000000000 +0100
+++ 2012-08-07/gas/testsuite/gas/i386/x86-64-vgather-check-none.s	2012-08-03 16:54:26.000000000 +0200
@@ -0,0 +1,2 @@
+.operand_check none
+.include "x86-64-vgather-check.s"
--- 2012-08-07/gas/testsuite/gas/i386/x86-64-vgather-check-warn.d	1970-01-01 01:00:00.000000000 +0100
+++ 2012-08-07/gas/testsuite/gas/i386/x86-64-vgather-check-warn.d	2012-08-03 17:27:42.000000000 +0200
@@ -0,0 +1,18 @@
+#source: x86-64-vgather-check.s
+#stderr: x86-64-vgather-check-warn.e
+#objdump: -dw
+#name: x86-64 vgather check (warning)
+
+.*:     file format .*
+
+Disassembly of section .text:
+
+0+ <vgather>:
+[ 	]*[a-f0-9]+:[ 	]+c4 e2 69 92 04 08[ 	]+vgatherdps %xmm2,\(%rax,%xmm1,1\),%xmm0
+[ 	]*[a-f0-9]+:[ 	]+c4 e2 69 92 14 48[ 	]+vgatherdps %xmm2,\(%rax,%xmm1,2\),%xmm2
+[ 	]*[a-f0-9]+:[ 	]+c4 62 69 92 14 48[ 	]+vgatherdps %xmm2,\(%rax,%xmm1,2\),%xmm10
+[ 	]*[a-f0-9]+:[ 	]+c4 e2 71 92 04 88[ 	]+vgatherdps %xmm1,\(%rax,%xmm1,4\),%xmm0
+[ 	]*[a-f0-9]+:[ 	]+c4 e2 31 92 04 88[ 	]+vgatherdps %xmm9,\(%rax,%xmm1,4\),%xmm0
+[ 	]*[a-f0-9]+:[ 	]+c4 e2 69 92 0c c8[ 	]+vgatherdps %xmm2,\(%rax,%xmm1,8\),%xmm1
+[ 	]*[a-f0-9]+:[ 	]+c4 62 69 92 0c c8[ 	]+vgatherdps %xmm2,\(%rax,%xmm1,8\),%xmm9
+#pass
--- 2012-08-07/gas/testsuite/gas/i386/x86-64-vgather-check-warn.e	1970-01-01 01:00:00.000000000 +0100
+++ 2012-08-07/gas/testsuite/gas/i386/x86-64-vgather-check-warn.e	2012-08-03 16:56:00.000000000 +0200
@@ -0,0 +1,4 @@
+.*: Assembler messages:
+.*:6: Warning: .*
+.*:8: Warning: .*
+.*:10: Warning: .*
--- 2012-08-07/gas/testsuite/gas/i386/x86-64-vgather-check.d	1970-01-01 01:00:00.000000000 +0100
+++ 2012-08-07/gas/testsuite/gas/i386/x86-64-vgather-check.d	2012-08-03 17:28:12.000000000 +0200
@@ -0,0 +1,17 @@
+#as: -moperand-check=none
+#objdump: -dw
+#name: x86-64 vgather check (-moperand-check=none)
+
+.*:     file format .*
+
+Disassembly of section .text:
+
+0+ <vgather>:
+[ 	]*[a-f0-9]+:[ 	]+c4 e2 69 92 04 08[ 	]+vgatherdps %xmm2,\(%rax,%xmm1,1\),%xmm0
+[ 	]*[a-f0-9]+:[ 	]+c4 e2 69 92 14 48[ 	]+vgatherdps %xmm2,\(%rax,%xmm1,2\),%xmm2
+[ 	]*[a-f0-9]+:[ 	]+c4 62 69 92 14 48[ 	]+vgatherdps %xmm2,\(%rax,%xmm1,2\),%xmm10
+[ 	]*[a-f0-9]+:[ 	]+c4 e2 71 92 04 88[ 	]+vgatherdps %xmm1,\(%rax,%xmm1,4\),%xmm0
+[ 	]*[a-f0-9]+:[ 	]+c4 e2 31 92 04 88[ 	]+vgatherdps %xmm9,\(%rax,%xmm1,4\),%xmm0
+[ 	]*[a-f0-9]+:[ 	]+c4 e2 69 92 0c c8[ 	]+vgatherdps %xmm2,\(%rax,%xmm1,8\),%xmm1
+[ 	]*[a-f0-9]+:[ 	]+c4 62 69 92 0c c8[ 	]+vgatherdps %xmm2,\(%rax,%xmm1,8\),%xmm9
+#pass
--- 2012-08-07/gas/testsuite/gas/i386/x86-64-vgather-check.s	1970-01-01 01:00:00.000000000 +0100
+++ 2012-08-07/gas/testsuite/gas/i386/x86-64-vgather-check.s	2012-08-03 16:56:53.000000000 +0200
@@ -0,0 +1,11 @@
+# Check vgather instructions
+
+	.text
+vgather:
+	vgatherdps %xmm2,(%rax,%xmm1,1),%xmm0
+	vgatherdps %xmm2,(%rax,%xmm1,2),%xmm2
+	vgatherdps %xmm2,(%rax,%xmm1,2),%xmm10
+	vgatherdps %xmm1,(%rax,%xmm1,4),%xmm0
+	vgatherdps %xmm9,(%rax,%xmm1,4),%xmm0
+	vgatherdps %xmm2,(%rax,%xmm1,8),%xmm1
+	vgatherdps %xmm2,(%rax,%xmm1,8),%xmm9



[-- Attachment #2: binutils-mainline-x86-vgather-distinct-regs.patch --]
[-- Type: text/plain, Size: 19271 bytes --]

The VGATHER group of instructions requires that all three involved
xmm/ymm registers are distinct. This patch adds code to check for this,
and at once eliminates a superfluous check for not using PC-relative
addressing for these instructions (the fact that an index register is
required here already excludes valid PC-relative addresses). The
severity of the resulting diagnostics can be controlled via command
line option or directive.

Note that this patch depends on the introduction of register_number(),
which is being done by the patch at
http://www.sourceware.org/ml/binutils/2012-08/msg00119.html.

gas/
2012-08-07  Jan Beulich <jbeulich@suse.com>

	* config/tc-i386.c (set_check): Renamed from set_sse_check.
	Generalize to also handle operand checking option.
	(enum i386_error): New enumerator 'invalid_vector_register_set'.
	(match_template): Handle it.
	(enum check_kind): Give it a tag. Drop sse_ prefixes from
	enumerators.
	(operand_check): New.
	(md_pseudo_table): Add "operand_check".
	(check_VecOperands): Don't special case RIP addressing. Check
	that vSIB operands use distinct vector registers unless no
	checking was requested.
	(OPTION_MOPERAND_CHECK): New.
	(md_parse_option): Handle it.
	(OPTION_MAVXSCALAR, OPTION_X32): Adjust.
	(md_longopts): Add "moperand-check".
	(md_show_usage): Add help text for it.

gas/testsuite/
2012-08-07  Jan Beulich <jbeulich@suse.com>

	* gas/i386/vgather-check-error.{s,l}: New.
	* gas/i386/vgather-check-none.{s,d}: New.
	* gas/i386/vgather-check-warn.{d,e}: New.
	* gas/i386/vgather-check.{s,d}: New.
	* gas/i386/x86-64-vgather-check-error.{s,l}: New.
	* gas/i386/x86-64-vgather-check-none.{s,d}: New.
	* gas/i386/x86-64-vgather-check-warn.{d,e}: New.
	* gas/i386/x86-64-vgather-check.{s,d}: New.
	* gas/i386/i386.exp: Run new tests.

--- 2012-08-07/gas/config/tc-i386.c	2012-07-31 09:45:03.000000000 +0200
+++ 2012-08-07/gas/config/tc-i386.c	2012-08-07 11:53:37.000000000 +0200
@@ -144,7 +144,7 @@ static void set_16bit_gcc_code_flag (int
 static void set_intel_syntax (int);
 static void set_intel_mnemonic (int);
 static void set_allow_index_reg (int);
-static void set_sse_check (int);
+static void set_check (int);
 static void set_cpu_arch (int);
 #ifdef TE_PE
 static void pe_directive_secrel (int);
@@ -221,6 +221,7 @@ enum i386_error
     unsupported_syntax,
     unsupported,
     invalid_vsib_address,
+    invalid_vector_register_set,
     unsupported_vector_index_register
   };
 
@@ -449,13 +450,13 @@ static int allow_naked_reg = 0;
 /* 1 if pseudo index register, eiz/riz, is allowed .  */
 static int allow_index_reg = 0;
 
-static enum
+static enum check_kind
   {
-    sse_check_none = 0,
-    sse_check_warning,
-    sse_check_error
+    check_none = 0,
+    check_warning,
+    check_error
   }
-sse_check;
+sse_check, operand_check = check_warning;
 
 /* Register prefix used for error message.  */
 static const char *register_prefix = "%";
@@ -847,7 +848,8 @@ const pseudo_typeS md_pseudo_table[] =
   {"att_mnemonic", set_intel_mnemonic, 0},
   {"allow_index_reg", set_allow_index_reg, 1},
   {"disallow_index_reg", set_allow_index_reg, 0},
-  {"sse_check", set_sse_check, 0},
+  {"sse_check", set_check, 0},
+  {"operand_check", set_check, 1},
 #if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
   {"largecomm", handle_large_common, 0},
 #else
@@ -2111,8 +2113,22 @@ set_allow_index_reg (int flag)
 }
 
 static void
-set_sse_check (int dummy ATTRIBUTE_UNUSED)
+set_check (int what)
 {
+  enum check_kind *kind;
+  const char *str;
+
+  if (what)
+    {
+      kind = &operand_check;
+      str = "operand";
+    }
+  else
+    {
+      kind = &sse_check;
+      str = "sse";
+    }
+
   SKIP_WHITESPACE ();
 
   if (!is_end_of_line[(unsigned char) *input_line_pointer])
@@ -2121,17 +2137,17 @@ set_sse_check (int dummy ATTRIBUTE_UNUSE
       int e = get_symbol_end ();
 
       if (strcmp (string, "none") == 0)
-	sse_check = sse_check_none;
+	*kind = check_none;
       else if (strcmp (string, "warning") == 0)
-	sse_check = sse_check_warning;
+	*kind = check_warning;
       else if (strcmp (string, "error") == 0)
-	sse_check = sse_check_error;
+	*kind = check_error;
       else
-	as_bad (_("bad argument to sse_check directive."));
+	as_bad (_("bad argument to %s_check directive."), str);
       *input_line_pointer = e;
     }
   else
-    as_bad (_("missing argument for sse_check directive"));
+    as_bad (_("missing argument for %s_check directive"), str);
 
   demand_empty_rest_of_line ();
 }
@@ -3140,7 +3156,7 @@ md_assemble (char *line)
   if (!(t = match_template ()))
     return;
 
-  if (sse_check != sse_check_none
+  if (sse_check != check_none
       && !i.tm.opcode_modifier.noavx
       && (i.tm.cpu_flags.bitfield.cpusse
 	  || i.tm.cpu_flags.bitfield.cpusse2
@@ -3149,7 +3165,7 @@ md_assemble (char *line)
 	  || i.tm.cpu_flags.bitfield.cpusse4_1
 	  || i.tm.cpu_flags.bitfield.cpusse4_2))
     {
-      (sse_check == sse_check_warning
+      (sse_check == check_warning
        ? as_warn
        : as_bad) (_("SSE instruction `%s' is used"), i.tm.name);
     }
@@ -3969,18 +3985,38 @@ check_VecOperands (const insn_template *
       return 1;
     }
 
-  /* For VSIB byte, we need a vector register for index and no PC
-     relative addressing is allowed.  */
-  if (t->opcode_modifier.vecsib
-      && (!i.index_reg
+  /* For VSIB byte, we need a vector register for index, and all vector
+     registers must be distinct.  */
+  if (t->opcode_modifier.vecsib)
+    {
+      if (!i.index_reg
 	  || !((t->opcode_modifier.vecsib == VecSIB128
 		&& i.index_reg->reg_type.bitfield.regxmm)
 	       || (t->opcode_modifier.vecsib == VecSIB256
-		   && i.index_reg->reg_type.bitfield.regymm))
-	  || (i.base_reg && i.base_reg->reg_num == RegRip)))
-    {
-      i.error = invalid_vsib_address;
-      return 1;
+		   && i.index_reg->reg_type.bitfield.regymm)))
+      {
+	i.error = invalid_vsib_address;
+	return 1;
+      }
+
+      gas_assert (i.reg_operands == 2);
+      gas_assert (i.types[0].bitfield.regxmm
+		  || i.types[0].bitfield.regymm);
+      gas_assert (i.types[2].bitfield.regxmm
+		  || i.types[2].bitfield.regymm);
+
+      if (operand_check == check_none)
+	return 0;
+      if (register_number (i.op[0].regs) != register_number (i.index_reg)
+	  && register_number (i.op[2].regs) != register_number (i.index_reg)
+	  && register_number (i.op[0].regs) != register_number (i.op[2].regs))
+	return 0;
+      if (operand_check == check_error)
+	{
+	  i.error = invalid_vector_register_set;
+	  return 1;
+	}
+      as_warn (_("mask, index, and destination registers should be distinct"));
     }
 
   return 0;
@@ -4376,6 +4412,9 @@ check_reverse:
 	case invalid_vsib_address:
 	  err_msg = _("invalid VSIB address");
 	  break;
+	case invalid_vector_register_set:
+	  err_msg = _("mask, index, and destination registers must be distinct");
+	  break;
 	case unsupported_vector_index_register:
 	  err_msg = _("unsupported vector index register");
 	  break;
@@ -8408,8 +8447,9 @@ const char *md_shortopts = "qn";
 #define OPTION_MOLD_GCC (OPTION_MD_BASE + 9)
 #define OPTION_MSSE2AVX (OPTION_MD_BASE + 10)
 #define OPTION_MSSE_CHECK (OPTION_MD_BASE + 11)
-#define OPTION_MAVXSCALAR (OPTION_MD_BASE + 12)
-#define OPTION_X32 (OPTION_MD_BASE + 13)
+#define OPTION_MOPERAND_CHECK (OPTION_MD_BASE + 12)
+#define OPTION_MAVXSCALAR (OPTION_MD_BASE + 13)
+#define OPTION_X32 (OPTION_MD_BASE + 14)
 
 struct option md_longopts[] =
 {
@@ -8431,6 +8471,7 @@ struct option md_longopts[] =
   {"mold-gcc", no_argument, NULL, OPTION_MOLD_GCC},
   {"msse2avx", no_argument, NULL, OPTION_MSSE2AVX},
   {"msse-check", required_argument, NULL, OPTION_MSSE_CHECK},
+  {"moperand-check", required_argument, NULL, OPTION_MOPERAND_CHECK},
   {"mavxscalar", required_argument, NULL, OPTION_MAVXSCALAR},
   {NULL, no_argument, NULL, 0}
 };
@@ -8660,15 +8701,26 @@ md_parse_option (int c, char *arg)
 
     case OPTION_MSSE_CHECK:
       if (strcasecmp (arg, "error") == 0)
-	sse_check = sse_check_error;
+	sse_check = check_error;
       else if (strcasecmp (arg, "warning") == 0)
-	sse_check = sse_check_warning;
+	sse_check = check_warning;
       else if (strcasecmp (arg, "none") == 0)
-	sse_check = sse_check_none;
+	sse_check = check_none;
       else
 	as_fatal (_("invalid -msse-check= option: `%s'"), arg);
       break;
 
+    case OPTION_MOPERAND_CHECK:
+      if (strcasecmp (arg, "error") == 0)
+	operand_check = check_error;
+      else if (strcasecmp (arg, "warning") == 0)
+	operand_check = check_warning;
+      else if (strcasecmp (arg, "none") == 0)
+	operand_check = check_none;
+      else
+	as_fatal (_("invalid -moperand-check= option: `%s'"), arg);
+      break;
+
     case OPTION_MAVXSCALAR:
       if (strcasecmp (arg, "128") == 0)
 	avxscalar = vex128;
@@ -8807,6 +8859,9 @@ md_show_usage (FILE *stream)
   -msse-check=[none|error|warning]\n\
                           check SSE instructions\n"));
   fprintf (stream, _("\
+  -moperand-check=[none|error|warning]\n\
+                          check operand combinations for validity\n"));
+  fprintf (stream, _("\
   -mavxscalar=[128|256]   encode scalar AVX instructions with specific vector\n\
                            length\n"));
   fprintf (stream, _("\
--- 2012-08-07/gas/testsuite/gas/i386/i386.exp	2012-07-24 14:52:59.000000000 +0200
+++ 2012-08-07/gas/testsuite/gas/i386/i386.exp	2012-08-07 11:53:38.000000000 +0200
@@ -160,6 +160,10 @@ if [expr ([istarget "i*86-*-*"] ||  [ist
     run_dump_test "sse-check-none"
     run_dump_test "sse-check-warn"
     run_list_test "sse-check-error" "-msse-check=error -I${srcdir}/$subdir -al"
+    run_dump_test "vgather-check"
+    run_dump_test "vgather-check-none"
+    run_dump_test "vgather-check-warn"
+    run_list_test "vgather-check-error" "-moperand-check=error -I${srcdir}/$subdir"
     run_dump_test "sse-noavx"
     run_dump_test "movbe"
     run_dump_test "movbe-intel"
@@ -402,6 +406,10 @@ if [expr ([istarget "i*86-*-*"] || [ista
     run_dump_test "x86-64-sse-check-none"
     run_dump_test "x86-64-sse-check-warn"
     run_list_test "x86-64-sse-check-error" "-msse-check=error -I${srcdir}/$subdir -al"
+    run_dump_test "x86-64-vgather-check"
+    run_dump_test "x86-64-vgather-check-none"
+    run_dump_test "x86-64-vgather-check-warn"
+    run_list_test "x86-64-vgather-check-error" "-moperand-check=error -I${srcdir}/$subdir"
     run_dump_test "x86-64-sse-noavx"
     run_dump_test "x86-64-movbe"
     run_dump_test "x86-64-movbe-intel"
--- 2012-08-07/gas/testsuite/gas/i386/vgather-check-error.l	1970-01-01 01:00:00.000000000 +0100
+++ 2012-08-07/gas/testsuite/gas/i386/vgather-check-error.l	2012-08-03 16:45:09.000000000 +0200
@@ -0,0 +1,4 @@
+.*: Assembler messages:
+.*:6: Error: .*
+.*:7: Error: .*
+.*:8: Error: .*
--- 2012-08-07/gas/testsuite/gas/i386/vgather-check-error.s	1970-01-01 01:00:00.000000000 +0100
+++ 2012-08-07/gas/testsuite/gas/i386/vgather-check-error.s	2012-08-03 16:24:53.000000000 +0200
@@ -0,0 +1 @@
+.include "vgather-check.s"
--- 2012-08-07/gas/testsuite/gas/i386/vgather-check-none.d	1970-01-01 01:00:00.000000000 +0100
+++ 2012-08-07/gas/testsuite/gas/i386/vgather-check-none.d	2012-08-03 16:51:24.000000000 +0200
@@ -0,0 +1,14 @@
+#as: -moperand-check=error -I${srcdir}/$subdir
+#objdump: -dw
+#name: i386 vgather check (.operand_check none)
+
+.*:     file format .*
+
+Disassembly of section .text:
+
+0+ <vgather>:
+[ 	]*[a-f0-9]+:[ 	]+c4 e2 69 92 04 08[ 	]+vgatherdps %xmm2,\(%eax,%xmm1,1\),%xmm0
+[ 	]*[a-f0-9]+:[ 	]+c4 e2 69 92 14 48[ 	]+vgatherdps %xmm2,\(%eax,%xmm1,2\),%xmm2
+[ 	]*[a-f0-9]+:[ 	]+c4 e2 71 92 04 88[ 	]+vgatherdps %xmm1,\(%eax,%xmm1,4\),%xmm0
+[ 	]*[a-f0-9]+:[ 	]+c4 e2 69 92 0c c8[ 	]+vgatherdps %xmm2,\(%eax,%xmm1,8\),%xmm1
+#pass
--- 2012-08-07/gas/testsuite/gas/i386/vgather-check-none.s	1970-01-01 01:00:00.000000000 +0100
+++ 2012-08-07/gas/testsuite/gas/i386/vgather-check-none.s	2012-08-03 16:24:46.000000000 +0200
@@ -0,0 +1,2 @@
+.operand_check none
+.include "vgather-check.s"
--- 2012-08-07/gas/testsuite/gas/i386/vgather-check-warn.d	1970-01-01 01:00:00.000000000 +0100
+++ 2012-08-07/gas/testsuite/gas/i386/vgather-check-warn.d	2012-08-03 16:46:15.000000000 +0200
@@ -0,0 +1,15 @@
+#source: vgather-check.s
+#stderr: vgather-check-warn.e
+#objdump: -dw
+#name: i386 vgather check (warning)
+
+.*:     file format .*
+
+Disassembly of section .text:
+
+0+ <vgather>:
+[ 	]*[a-f0-9]+:[ 	]+c4 e2 69 92 04 08[ 	]+vgatherdps %xmm2,\(%eax,%xmm1,1\),%xmm0
+[ 	]*[a-f0-9]+:[ 	]+c4 e2 69 92 14 48[ 	]+vgatherdps %xmm2,\(%eax,%xmm1,2\),%xmm2
+[ 	]*[a-f0-9]+:[ 	]+c4 e2 71 92 04 88[ 	]+vgatherdps %xmm1,\(%eax,%xmm1,4\),%xmm0
+[ 	]*[a-f0-9]+:[ 	]+c4 e2 69 92 0c c8[ 	]+vgatherdps %xmm2,\(%eax,%xmm1,8\),%xmm1
+#pass
--- 2012-08-07/gas/testsuite/gas/i386/vgather-check-warn.e	1970-01-01 01:00:00.000000000 +0100
+++ 2012-08-07/gas/testsuite/gas/i386/vgather-check-warn.e	2012-08-03 16:49:48.000000000 +0200
@@ -0,0 +1,4 @@
+.*: Assembler messages:
+.*:6: Warning: .*
+.*:7: Warning: .*
+.*:8: Warning: .*
--- 2012-08-07/gas/testsuite/gas/i386/vgather-check.d	1970-01-01 01:00:00.000000000 +0100
+++ 2012-08-07/gas/testsuite/gas/i386/vgather-check.d	2012-08-03 17:28:17.000000000 +0200
@@ -0,0 +1,14 @@
+#as: -moperand-check=none
+#objdump: -dw
+#name: i386 vgather check (-moperand-check=none)
+
+.*:     file format .*
+
+Disassembly of section .text:
+
+0+ <vgather>:
+[ 	]*[a-f0-9]+:[ 	]+c4 e2 69 92 04 08[ 	]+vgatherdps %xmm2,\(%eax,%xmm1,1\),%xmm0
+[ 	]*[a-f0-9]+:[ 	]+c4 e2 69 92 14 48[ 	]+vgatherdps %xmm2,\(%eax,%xmm1,2\),%xmm2
+[ 	]*[a-f0-9]+:[ 	]+c4 e2 71 92 04 88[ 	]+vgatherdps %xmm1,\(%eax,%xmm1,4\),%xmm0
+[ 	]*[a-f0-9]+:[ 	]+c4 e2 69 92 0c c8[ 	]+vgatherdps %xmm2,\(%eax,%xmm1,8\),%xmm1
+#pass
--- 2012-08-07/gas/testsuite/gas/i386/vgather-check.s	1970-01-01 01:00:00.000000000 +0100
+++ 2012-08-07/gas/testsuite/gas/i386/vgather-check.s	2012-08-03 16:36:48.000000000 +0200
@@ -0,0 +1,8 @@
+# Check vgather instructions
+
+	.text
+vgather:
+	vgatherdps %xmm2,(%eax,%xmm1,1),%xmm0
+	vgatherdps %xmm2,(%eax,%xmm1,2),%xmm2
+	vgatherdps %xmm1,(%eax,%xmm1,4),%xmm0
+	vgatherdps %xmm2,(%eax,%xmm1,8),%xmm1
--- 2012-08-07/gas/testsuite/gas/i386/x86-64-vgather-check-error.l	1970-01-01 01:00:00.000000000 +0100
+++ 2012-08-07/gas/testsuite/gas/i386/x86-64-vgather-check-error.l	2012-08-03 16:55:49.000000000 +0200
@@ -0,0 +1,4 @@
+.*: Assembler messages:
+.*:6: Error: .*
+.*:8: Error: .*
+.*:10: Error: .*
--- 2012-08-07/gas/testsuite/gas/i386/x86-64-vgather-check-error.s	1970-01-01 01:00:00.000000000 +0100
+++ 2012-08-07/gas/testsuite/gas/i386/x86-64-vgather-check-error.s	2012-08-03 16:54:09.000000000 +0200
@@ -0,0 +1 @@
+.include "x86-64-vgather-check.s"
--- 2012-08-07/gas/testsuite/gas/i386/x86-64-vgather-check-none.d	1970-01-01 01:00:00.000000000 +0100
+++ 2012-08-07/gas/testsuite/gas/i386/x86-64-vgather-check-none.d	2012-08-03 17:27:38.000000000 +0200
@@ -0,0 +1,17 @@
+#as: -moperand-check=error -I${srcdir}/$subdir
+#objdump: -dw
+#name: x86-64 vgather check (.operand_check none)
+
+.*:     file format .*
+
+Disassembly of section .text:
+
+0+ <vgather>:
+[ 	]*[a-f0-9]+:[ 	]+c4 e2 69 92 04 08[ 	]+vgatherdps %xmm2,\(%rax,%xmm1,1\),%xmm0
+[ 	]*[a-f0-9]+:[ 	]+c4 e2 69 92 14 48[ 	]+vgatherdps %xmm2,\(%rax,%xmm1,2\),%xmm2
+[ 	]*[a-f0-9]+:[ 	]+c4 62 69 92 14 48[ 	]+vgatherdps %xmm2,\(%rax,%xmm1,2\),%xmm10
+[ 	]*[a-f0-9]+:[ 	]+c4 e2 71 92 04 88[ 	]+vgatherdps %xmm1,\(%rax,%xmm1,4\),%xmm0
+[ 	]*[a-f0-9]+:[ 	]+c4 e2 31 92 04 88[ 	]+vgatherdps %xmm9,\(%rax,%xmm1,4\),%xmm0
+[ 	]*[a-f0-9]+:[ 	]+c4 e2 69 92 0c c8[ 	]+vgatherdps %xmm2,\(%rax,%xmm1,8\),%xmm1
+[ 	]*[a-f0-9]+:[ 	]+c4 62 69 92 0c c8[ 	]+vgatherdps %xmm2,\(%rax,%xmm1,8\),%xmm9
+#pass
--- 2012-08-07/gas/testsuite/gas/i386/x86-64-vgather-check-none.s	1970-01-01 01:00:00.000000000 +0100
+++ 2012-08-07/gas/testsuite/gas/i386/x86-64-vgather-check-none.s	2012-08-03 16:54:26.000000000 +0200
@@ -0,0 +1,2 @@
+.operand_check none
+.include "x86-64-vgather-check.s"
--- 2012-08-07/gas/testsuite/gas/i386/x86-64-vgather-check-warn.d	1970-01-01 01:00:00.000000000 +0100
+++ 2012-08-07/gas/testsuite/gas/i386/x86-64-vgather-check-warn.d	2012-08-03 17:27:42.000000000 +0200
@@ -0,0 +1,18 @@
+#source: x86-64-vgather-check.s
+#stderr: x86-64-vgather-check-warn.e
+#objdump: -dw
+#name: x86-64 vgather check (warning)
+
+.*:     file format .*
+
+Disassembly of section .text:
+
+0+ <vgather>:
+[ 	]*[a-f0-9]+:[ 	]+c4 e2 69 92 04 08[ 	]+vgatherdps %xmm2,\(%rax,%xmm1,1\),%xmm0
+[ 	]*[a-f0-9]+:[ 	]+c4 e2 69 92 14 48[ 	]+vgatherdps %xmm2,\(%rax,%xmm1,2\),%xmm2
+[ 	]*[a-f0-9]+:[ 	]+c4 62 69 92 14 48[ 	]+vgatherdps %xmm2,\(%rax,%xmm1,2\),%xmm10
+[ 	]*[a-f0-9]+:[ 	]+c4 e2 71 92 04 88[ 	]+vgatherdps %xmm1,\(%rax,%xmm1,4\),%xmm0
+[ 	]*[a-f0-9]+:[ 	]+c4 e2 31 92 04 88[ 	]+vgatherdps %xmm9,\(%rax,%xmm1,4\),%xmm0
+[ 	]*[a-f0-9]+:[ 	]+c4 e2 69 92 0c c8[ 	]+vgatherdps %xmm2,\(%rax,%xmm1,8\),%xmm1
+[ 	]*[a-f0-9]+:[ 	]+c4 62 69 92 0c c8[ 	]+vgatherdps %xmm2,\(%rax,%xmm1,8\),%xmm9
+#pass
--- 2012-08-07/gas/testsuite/gas/i386/x86-64-vgather-check-warn.e	1970-01-01 01:00:00.000000000 +0100
+++ 2012-08-07/gas/testsuite/gas/i386/x86-64-vgather-check-warn.e	2012-08-03 16:56:00.000000000 +0200
@@ -0,0 +1,4 @@
+.*: Assembler messages:
+.*:6: Warning: .*
+.*:8: Warning: .*
+.*:10: Warning: .*
--- 2012-08-07/gas/testsuite/gas/i386/x86-64-vgather-check.d	1970-01-01 01:00:00.000000000 +0100
+++ 2012-08-07/gas/testsuite/gas/i386/x86-64-vgather-check.d	2012-08-03 17:28:12.000000000 +0200
@@ -0,0 +1,17 @@
+#as: -moperand-check=none
+#objdump: -dw
+#name: x86-64 vgather check (-moperand-check=none)
+
+.*:     file format .*
+
+Disassembly of section .text:
+
+0+ <vgather>:
+[ 	]*[a-f0-9]+:[ 	]+c4 e2 69 92 04 08[ 	]+vgatherdps %xmm2,\(%rax,%xmm1,1\),%xmm0
+[ 	]*[a-f0-9]+:[ 	]+c4 e2 69 92 14 48[ 	]+vgatherdps %xmm2,\(%rax,%xmm1,2\),%xmm2
+[ 	]*[a-f0-9]+:[ 	]+c4 62 69 92 14 48[ 	]+vgatherdps %xmm2,\(%rax,%xmm1,2\),%xmm10
+[ 	]*[a-f0-9]+:[ 	]+c4 e2 71 92 04 88[ 	]+vgatherdps %xmm1,\(%rax,%xmm1,4\),%xmm0
+[ 	]*[a-f0-9]+:[ 	]+c4 e2 31 92 04 88[ 	]+vgatherdps %xmm9,\(%rax,%xmm1,4\),%xmm0
+[ 	]*[a-f0-9]+:[ 	]+c4 e2 69 92 0c c8[ 	]+vgatherdps %xmm2,\(%rax,%xmm1,8\),%xmm1
+[ 	]*[a-f0-9]+:[ 	]+c4 62 69 92 0c c8[ 	]+vgatherdps %xmm2,\(%rax,%xmm1,8\),%xmm9
+#pass
--- 2012-08-07/gas/testsuite/gas/i386/x86-64-vgather-check.s	1970-01-01 01:00:00.000000000 +0100
+++ 2012-08-07/gas/testsuite/gas/i386/x86-64-vgather-check.s	2012-08-03 16:56:53.000000000 +0200
@@ -0,0 +1,11 @@
+# Check vgather instructions
+
+	.text
+vgather:
+	vgatherdps %xmm2,(%rax,%xmm1,1),%xmm0
+	vgatherdps %xmm2,(%rax,%xmm1,2),%xmm2
+	vgatherdps %xmm2,(%rax,%xmm1,2),%xmm10
+	vgatherdps %xmm1,(%rax,%xmm1,4),%xmm0
+	vgatherdps %xmm9,(%rax,%xmm1,4),%xmm0
+	vgatherdps %xmm2,(%rax,%xmm1,8),%xmm1
+	vgatherdps %xmm2,(%rax,%xmm1,8),%xmm9

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

* Re: [PATCH, v2] gas/x86: don't allow invalid operand combinations for VGATHER
  2012-08-07 10:32       ` [PATCH, v2] gas/x86: " Jan Beulich
@ 2012-08-07 13:25         ` H.J. Lu
  2012-08-07 13:44           ` Jan Beulich
  0 siblings, 1 reply; 9+ messages in thread
From: H.J. Lu @ 2012-08-07 13:25 UTC (permalink / raw)
  To: Jan Beulich; +Cc: binutils

On Tue, Aug 7, 2012 at 3:28 AM, Jan Beulich <JBeulich@suse.com> wrote:
>>>> On 31.07.12 at 17:43, "H.J. Lu" <hjl.tools@gmail.com> wrote:
>> On Tue, Jul 31, 2012 at 12:49 AM, Jan Beulich <JBeulich@suse.com> wrote:
>>>>>> On 30.07.12 at 18:10, "H.J. Lu" <hjl.tools@gmail.com> wrote:
>>>> The assembler should only check the operands which can't be
>>>> encoded.  It should shouldn't check if operands are functional
>>>> correct.  However, I don't mind to issue an error which is controlled
>>>> by a command line option.
>>>
>>> Hmm, not sure. Is there any precedent to such behavior? I as a
>>> programmer would appreciate if the assembler rejected anything
>>> that's invalid.
>>>
>>> In the case you stay on that position, would making the new
>>> diagnostic an unconditional warning be acceptable instead?
>>>
>>
>> Can you also add a command line option to turn it off and
>> turn warning into error?
>
> How about this then?
>
> Jan
>
> The VGATHER group of instructions requires that all three involved
> xmm/ymm registers are distinct. This patch adds code to check for this,
> and at once eliminates a superfluous check for not using PC-relative
> addressing for these instructions (the fact that an index register is
> required here already excludes valid PC-relative addresses). The
> severity of the resulting diagnostics can be controlled via command
> line option or directive.

Why

vgatherdps %xmm2,(%rax,%xmm1,2),%xmm2

can't be used?  XMM2 can be used for both mask and
destination.


H.J.

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

* Re: [PATCH, v2] gas/x86: don't allow invalid operand combinations for VGATHER
  2012-08-07 13:25         ` H.J. Lu
@ 2012-08-07 13:44           ` Jan Beulich
  2012-08-07 14:07             ` H.J. Lu
  0 siblings, 1 reply; 9+ messages in thread
From: Jan Beulich @ 2012-08-07 13:44 UTC (permalink / raw)
  To: H.J. Lu; +Cc: binutils

>>> On 07.08.12 at 15:21, "H.J. Lu" <hjl.tools@gmail.com> wrote:
> On Tue, Aug 7, 2012 at 3:28 AM, Jan Beulich <JBeulich@suse.com> wrote:
>>>>> On 31.07.12 at 17:43, "H.J. Lu" <hjl.tools@gmail.com> wrote:
>>> On Tue, Jul 31, 2012 at 12:49 AM, Jan Beulich <JBeulich@suse.com> wrote:
>>>>>>> On 30.07.12 at 18:10, "H.J. Lu" <hjl.tools@gmail.com> wrote:
>>>>> The assembler should only check the operands which can't be
>>>>> encoded.  It should shouldn't check if operands are functional
>>>>> correct.  However, I don't mind to issue an error which is controlled
>>>>> by a command line option.
>>>>
>>>> Hmm, not sure. Is there any precedent to such behavior? I as a
>>>> programmer would appreciate if the assembler rejected anything
>>>> that's invalid.
>>>>
>>>> In the case you stay on that position, would making the new
>>>> diagnostic an unconditional warning be acceptable instead?
>>>>
>>>
>>> Can you also add a command line option to turn it off and
>>> turn warning into error?
>>
>> How about this then?
>>
>> Jan
>>
>> The VGATHER group of instructions requires that all three involved
>> xmm/ymm registers are distinct. This patch adds code to check for this,
>> and at once eliminates a superfluous check for not using PC-relative
>> addressing for these instructions (the fact that an index register is
>> required here already excludes valid PC-relative addresses). The
>> severity of the resulting diagnostics can be controlled via command
>> line option or directive.
> 
> Why
> 
> vgatherdps %xmm2,(%rax,%xmm1,2),%xmm2
> 
> can't be used?  XMM2 can be used for both mask and
> destination.

Not that I'm aware of (quoting the documentation):

"If any pair of the index, mask, or destination registers are the
 same, this instruction results a #UD fault."

It's my understanding that this is because of the restartability of
the instruction (i.e. if the same register served as mask and
destination, the instruction might never complete if the loaded
vector element had its high bit set).

Jan

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

* Re: [PATCH, v2] gas/x86: don't allow invalid operand combinations for VGATHER
  2012-08-07 13:44           ` Jan Beulich
@ 2012-08-07 14:07             ` H.J. Lu
  0 siblings, 0 replies; 9+ messages in thread
From: H.J. Lu @ 2012-08-07 14:07 UTC (permalink / raw)
  To: Jan Beulich; +Cc: binutils

On Tue, Aug 7, 2012 at 6:34 AM, Jan Beulich <JBeulich@suse.com> wrote:
>>>> On 07.08.12 at 15:21, "H.J. Lu" <hjl.tools@gmail.com> wrote:
>> On Tue, Aug 7, 2012 at 3:28 AM, Jan Beulich <JBeulich@suse.com> wrote:
>>>>>> On 31.07.12 at 17:43, "H.J. Lu" <hjl.tools@gmail.com> wrote:
>>>> On Tue, Jul 31, 2012 at 12:49 AM, Jan Beulich <JBeulich@suse.com> wrote:
>>>>>>>> On 30.07.12 at 18:10, "H.J. Lu" <hjl.tools@gmail.com> wrote:
>>>>>> The assembler should only check the operands which can't be
>>>>>> encoded.  It should shouldn't check if operands are functional
>>>>>> correct.  However, I don't mind to issue an error which is controlled
>>>>>> by a command line option.
>>>>>
>>>>> Hmm, not sure. Is there any precedent to such behavior? I as a
>>>>> programmer would appreciate if the assembler rejected anything
>>>>> that's invalid.
>>>>>
>>>>> In the case you stay on that position, would making the new
>>>>> diagnostic an unconditional warning be acceptable instead?
>>>>>
>>>>
>>>> Can you also add a command line option to turn it off and
>>>> turn warning into error?
>>>
>>> How about this then?
>>>
>>> Jan
>>>
>>> The VGATHER group of instructions requires that all three involved
>>> xmm/ymm registers are distinct. This patch adds code to check for this,
>>> and at once eliminates a superfluous check for not using PC-relative
>>> addressing for these instructions (the fact that an index register is
>>> required here already excludes valid PC-relative addresses). The
>>> severity of the resulting diagnostics can be controlled via command
>>> line option or directive.
>>
>> Why
>>
>> vgatherdps %xmm2,(%rax,%xmm1,2),%xmm2
>>
>> can't be used?  XMM2 can be used for both mask and
>> destination.
>
> Not that I'm aware of (quoting the documentation):
>
> "If any pair of the index, mask, or destination registers are the
>  same, this instruction results a #UD fault."
>
> It's my understanding that this is because of the restartability of
> the instruction (i.e. if the same register served as mask and
> destination, the instruction might never complete if the loaded
> vector element had its high bit set).
>
> Jan
>

OK.

Thanks.


-- 
H.J.

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

end of thread, other threads:[~2012-08-07 14:03 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-07-24 14:19 [PATCH] x86: don't allow invalid operand combinations for VGATHER Jan Beulich
2012-07-30 16:10 ` H.J. Lu
2012-07-31  7:49   ` Jan Beulich
2012-07-31 15:44     ` H.J. Lu
2012-07-31 16:24       ` Jan Beulich
2012-08-07 10:32       ` [PATCH, v2] gas/x86: " Jan Beulich
2012-08-07 13:25         ` H.J. Lu
2012-08-07 13:44           ` Jan Beulich
2012-08-07 14:07             ` H.J. Lu

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).