The VGATHER group of instructions requires that all three involved
authorJan Beulich <jbeulich@novell.com>
Tue, 7 Aug 2012 16:55:00 +0000 (16:55 +0000)
committerJan Beulich <jbeulich@novell.com>
Tue, 7 Aug 2012 16:55:00 +0000 (16:55 +0000)
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.

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.

20 files changed:
gas/ChangeLog
gas/config/tc-i386.c
gas/testsuite/ChangeLog
gas/testsuite/gas/i386/i386.exp
gas/testsuite/gas/i386/vgather-check-error.l [new file with mode: 0644]
gas/testsuite/gas/i386/vgather-check-error.s [new file with mode: 0644]
gas/testsuite/gas/i386/vgather-check-none.d [new file with mode: 0644]
gas/testsuite/gas/i386/vgather-check-none.s [new file with mode: 0644]
gas/testsuite/gas/i386/vgather-check-warn.d [new file with mode: 0644]
gas/testsuite/gas/i386/vgather-check-warn.e [new file with mode: 0644]
gas/testsuite/gas/i386/vgather-check.d [new file with mode: 0644]
gas/testsuite/gas/i386/vgather-check.s [new file with mode: 0644]
gas/testsuite/gas/i386/x86-64-vgather-check-error.l [new file with mode: 0644]
gas/testsuite/gas/i386/x86-64-vgather-check-error.s [new file with mode: 0644]
gas/testsuite/gas/i386/x86-64-vgather-check-none.d [new file with mode: 0644]
gas/testsuite/gas/i386/x86-64-vgather-check-none.s [new file with mode: 0644]
gas/testsuite/gas/i386/x86-64-vgather-check-warn.d [new file with mode: 0644]
gas/testsuite/gas/i386/x86-64-vgather-check-warn.e [new file with mode: 0644]
gas/testsuite/gas/i386/x86-64-vgather-check.d [new file with mode: 0644]
gas/testsuite/gas/i386/x86-64-vgather-check.s [new file with mode: 0644]

index b4c8ac0..2c6dfd2 100644 (file)
@@ -1,5 +1,24 @@
 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.
+
+2012-08-07  Jan Beulich <jbeulich@suse.com>
+
        * config/tc-i386.c (register_number): New function.
        (build_vex_prefix, process_immext, process_operands,
        build_modrm_byte, i386_index_check): Use it.
index 93500fe..7cc6fa7 100644 (file)
@@ -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_UNUSED)
       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 ();
 }
@@ -3136,7 +3152,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
@@ -3145,7 +3161,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);
     }
@@ -3965,18 +3981,38 @@ check_VecOperands (const insn_template *t)
       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;
@@ -4372,6 +4408,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;
@@ -8502,8 +8541,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[] =
 {
@@ -8525,6 +8565,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}
 };
@@ -8754,15 +8795,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;
@@ -8901,6 +8953,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, _("\
index e11121a..8225b23 100644 (file)
@@ -1,5 +1,17 @@
 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  Jan Beulich <jbeulich@suse.com>
+
        * gas/i386/x86-64-specific-reg.{s,l}: New.
        * gas/i386/i386.exp: Run new test.
 
index 85e6c4b..fb36423 100644 (file)
@@ -160,6 +160,10 @@ if [expr ([istarget "i*86-*-*"] ||  [istarget "x86_64-*-*"]) && [gas_32_check]]
     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"
@@ -403,6 +407,10 @@ if [expr ([istarget "i*86-*-*"] || [istarget "x86_64-*-*"]) && [gas_64_check]] t
     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"
diff --git a/gas/testsuite/gas/i386/vgather-check-error.l b/gas/testsuite/gas/i386/vgather-check-error.l
new file mode 100644 (file)
index 0000000..41273dc
--- /dev/null
@@ -0,0 +1,4 @@
+.*: Assembler messages:
+.*:6: Error: .*
+.*:7: Error: .*
+.*:8: Error: .*
diff --git a/gas/testsuite/gas/i386/vgather-check-error.s b/gas/testsuite/gas/i386/vgather-check-error.s
new file mode 100644 (file)
index 0000000..9db69c6
--- /dev/null
@@ -0,0 +1 @@
+.include "vgather-check.s"
diff --git a/gas/testsuite/gas/i386/vgather-check-none.d b/gas/testsuite/gas/i386/vgather-check-none.d
new file mode 100644 (file)
index 0000000..b51cc94
--- /dev/null
@@ -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
diff --git a/gas/testsuite/gas/i386/vgather-check-none.s b/gas/testsuite/gas/i386/vgather-check-none.s
new file mode 100644 (file)
index 0000000..cf31039
--- /dev/null
@@ -0,0 +1,2 @@
+.operand_check none
+.include "vgather-check.s"
diff --git a/gas/testsuite/gas/i386/vgather-check-warn.d b/gas/testsuite/gas/i386/vgather-check-warn.d
new file mode 100644 (file)
index 0000000..22be247
--- /dev/null
@@ -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
diff --git a/gas/testsuite/gas/i386/vgather-check-warn.e b/gas/testsuite/gas/i386/vgather-check-warn.e
new file mode 100644 (file)
index 0000000..095840b
--- /dev/null
@@ -0,0 +1,4 @@
+.*: Assembler messages:
+.*:6: Warning: .*
+.*:7: Warning: .*
+.*:8: Warning: .*
diff --git a/gas/testsuite/gas/i386/vgather-check.d b/gas/testsuite/gas/i386/vgather-check.d
new file mode 100644 (file)
index 0000000..25042f4
--- /dev/null
@@ -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
diff --git a/gas/testsuite/gas/i386/vgather-check.s b/gas/testsuite/gas/i386/vgather-check.s
new file mode 100644 (file)
index 0000000..c784029
--- /dev/null
@@ -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
diff --git a/gas/testsuite/gas/i386/x86-64-vgather-check-error.l b/gas/testsuite/gas/i386/x86-64-vgather-check-error.l
new file mode 100644 (file)
index 0000000..d5c7205
--- /dev/null
@@ -0,0 +1,4 @@
+.*: Assembler messages:
+.*:6: Error: .*
+.*:8: Error: .*
+.*:10: Error: .*
diff --git a/gas/testsuite/gas/i386/x86-64-vgather-check-error.s b/gas/testsuite/gas/i386/x86-64-vgather-check-error.s
new file mode 100644 (file)
index 0000000..f038be2
--- /dev/null
@@ -0,0 +1 @@
+.include "x86-64-vgather-check.s"
diff --git a/gas/testsuite/gas/i386/x86-64-vgather-check-none.d b/gas/testsuite/gas/i386/x86-64-vgather-check-none.d
new file mode 100644 (file)
index 0000000..e235e00
--- /dev/null
@@ -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
diff --git a/gas/testsuite/gas/i386/x86-64-vgather-check-none.s b/gas/testsuite/gas/i386/x86-64-vgather-check-none.s
new file mode 100644 (file)
index 0000000..42d0002
--- /dev/null
@@ -0,0 +1,2 @@
+.operand_check none
+.include "x86-64-vgather-check.s"
diff --git a/gas/testsuite/gas/i386/x86-64-vgather-check-warn.d b/gas/testsuite/gas/i386/x86-64-vgather-check-warn.d
new file mode 100644 (file)
index 0000000..33846d2
--- /dev/null
@@ -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
diff --git a/gas/testsuite/gas/i386/x86-64-vgather-check-warn.e b/gas/testsuite/gas/i386/x86-64-vgather-check-warn.e
new file mode 100644 (file)
index 0000000..24e6a57
--- /dev/null
@@ -0,0 +1,4 @@
+.*: Assembler messages:
+.*:6: Warning: .*
+.*:8: Warning: .*
+.*:10: Warning: .*
diff --git a/gas/testsuite/gas/i386/x86-64-vgather-check.d b/gas/testsuite/gas/i386/x86-64-vgather-check.d
new file mode 100644 (file)
index 0000000..bd8ce57
--- /dev/null
@@ -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
diff --git a/gas/testsuite/gas/i386/x86-64-vgather-check.s b/gas/testsuite/gas/i386/x86-64-vgather-check.s
new file mode 100644 (file)
index 0000000..43b058b
--- /dev/null
@@ -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