* [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