x86: correct operand size match checks for BMI/BMI2 insns

Message ID 5A9FFA0302000078001AF6C8@prv-mh.provo.novell.com
State New
Headers show
Series
  • x86: correct operand size match checks for BMI/BMI2 insns
Related show

Commit Message

Jan Beulich March 7, 2018, 1:41 p.m.
Some BMI/BMI2 insns allow their middle operands to be a memory one. In
such a case, matching register types between operands 0 and 1 as well as
1 and 2 won't help - operands 0 and 2 also need to be checked.

gas/
2018-03-07  Jan Beulich  <jbeulich@suse.com>

	* config/tc-i386.c (match_template): Also match register
	operands 0 and 2 for 3-operand forms.
	* testsuite/gas/i386/unspec64.l, testsuite/gas/i386/unspec64.s:
	New.
	* testsuite/gas/i386/i386.exp: Run new test.

Comments

H.J. Lu March 7, 2018, 1:44 p.m. | #1
On Wed, Mar 7, 2018 at 5:41 AM, Jan Beulich <JBeulich@suse.com> wrote:
> Some BMI/BMI2 insns allow their middle operands to be a memory one. In

> such a case, matching register types between operands 0 and 1 as well as

> 1 and 2 won't help - operands 0 and 2 also need to be checked.

>

> gas/

> 2018-03-07  Jan Beulich  <jbeulich@suse.com>

>

>         * config/tc-i386.c (match_template): Also match register

>         operands 0 and 2 for 3-operand forms.

>         * testsuite/gas/i386/unspec64.l, testsuite/gas/i386/unspec64.s:

>         New.

>         * testsuite/gas/i386/i386.exp: Run new test.


OK.

Thanks.

-- 
H.J.

Patch

--- a/gas/config/tc-i386.c
+++ b/gas/config/tc-i386.c
@@ -5499,15 +5499,17 @@  check_reverse:
 		  /* Fall through.  */
 		case 3:
 		  /* Here we make use of the fact that there are no
-		     reverse match 3 operand instructions, and all 3
-		     operand instructions only need to be checked for
-		     register consistency between operands 2 and 3.  */
+		     reverse match 3 operand instructions.  */
 		  if (!operand_type_match (overlap2, i.types[2])
 		      || (check_register
-			  && !operand_type_register_match (i.types[1],
-							   operand_types[1],
-							   i.types[2],
-							   operand_types[2])))
+			  && (!operand_type_register_match (i.types[0],
+							    operand_types[0],
+							    i.types[2],
+							    operand_types[2])
+			      || !operand_type_register_match (i.types[1],
+							       operand_types[1],
+							       i.types[2],
+							       operand_types[2]))))
 		    continue;
 		  break;
 		}
--- a/gas/testsuite/gas/i386/i386.exp
+++ b/gas/testsuite/gas/i386/i386.exp
@@ -661,6 +661,7 @@  if [expr ([istarget "i*86-*-*"] || [ista
     run_list_test "x86-64-specific-reg"
     run_list_test "suffix-bad"
     run_list_test "x86-64-suffix-bad"
+    run_list_test "unspec64" ""
     run_dump_test "x86-64-fxsave"
     run_dump_test "x86-64-fxsave-intel"
     run_dump_test "x86-64-arch-1"
--- /dev/null
+++ b/gas/testsuite/gas/i386/unspec64.l
@@ -0,0 +1,21 @@ 
+.*: Assembler messages:
+.*:3: Error: .*bextr.*
+.*:4: Error: .*bextr.*
+.*:5: Error: .*bzhi.*
+.*:6: Error: .*bzhi.*
+.*:7: Error: .*sarx.*
+.*:8: Error: .*sarx.*
+.*:9: Error: .*shlx.*
+.*:10: Error: .*shlx.*
+.*:11: Error: .*shrx.*
+.*:12: Error: .*shrx.*
+.*:16: Error: .*bextr.*
+.*:17: Error: .*bextr.*
+.*:18: Error: .*bzhi.*
+.*:19: Error: .*bzhi.*
+.*:20: Error: .*sarx.*
+.*:21: Error: .*sarx.*
+.*:22: Error: .*shlx.*
+.*:23: Error: .*shlx.*
+.*:24: Error: .*shrx.*
+.*:25: Error: .*shrx.*
--- /dev/null
+++ b/gas/testsuite/gas/i386/unspec64.s
@@ -0,0 +1,25 @@ 
+	.text
+unspec:
+	bextr	%eax, (%rax), %rax
+	bextr	%rax, (%rax), %eax
+	bzhi	%eax, (%rax), %rax
+	bzhi	%rax, (%rax), %eax
+	sarx	%eax, (%rax), %rax
+	sarx	%rax, (%rax), %eax
+	shlx	%eax, (%rax), %rax
+	shlx	%rax, (%rax), %eax
+	shrx	%eax, (%rax), %rax
+	shrx	%rax, (%rax), %eax
+
+	.intel_syntax noprefix
+
+	bextr	eax, [rax], rax
+	bextr	rax, [rax], eax
+	bzhi	eax, [rax], rax
+	bzhi	rax, [rax], eax
+	sarx	eax, [rax], rax
+	sarx	rax, [rax], eax
+	shlx	eax, [rax], rax
+	shlx	rax, [rax], eax
+	shrx	eax, [rax], rax
+	shrx	rax, [rax], eax