armv6 mull register overlap warning

Paul Brook paul@codesourcery.com
Tue Nov 6 22:16:00 GMT 2007


Armv6 relaxes the restrictions on overlapping operands to multiply 
instructions. However gas still warns about the long multiply variants.

Patch below fixes this.

Tested on arm-none-eabi.
Applied to CVS head.

Paul

2007-11-06  Paul Brook  <paul@codesourcery.com>

	gas/
	* config/tc-arm.c (do_mull): Allow overlapping Rm for armv6.

	gas/testsuite/
	* gas/arm/mul-overlap.s: Add umull and smlal.
	* gas/arm/mul-overlap.l: Update expected results.

Index: gas/testsuite/gas/arm/mul-overlap.l
===================================================================
--- gas/testsuite/gas/arm/mul-overlap.l	(revision 186593)
+++ gas/testsuite/gas/arm/mul-overlap.l	(working copy)
@@ -1,3 +1,4 @@
 [^:]*: Assembler messages:
 [^:]*:5: Rd and Rm should be different in mul
 [^:]*:6: Rd and Rm should be different in mla
+[^:]*:8: rdhi, rdlo and rm must all be different
Index: gas/testsuite/gas/arm/mul-overlap.s
===================================================================
--- gas/testsuite/gas/arm/mul-overlap.s	(revision 186593)
+++ gas/testsuite/gas/arm/mul-overlap.s	(working copy)
@@ -5,4 +5,6 @@ foo:
 	mul	r0, r0, r0
 	mla	r0, r0, r1, r2
 	mls	r0, r0, r1, r2
+	umull	r0, r1, r0, r1
+	smlalbb	r0, r1, r0, r1
 	bx	lr
Index: gas/config/tc-arm.c
===================================================================
--- gas/config/tc-arm.c	(revision 186593)
+++ gas/config/tc-arm.c	(working copy)
@@ -7209,10 +7209,14 @@ do_mull (void)
   inst.instruction |= inst.operands[2].reg;
   inst.instruction |= inst.operands[3].reg << 8;
 
-  /* rdhi, rdlo and rm must all be different.  */
-  if (inst.operands[0].reg == inst.operands[1].reg
-      || inst.operands[0].reg == inst.operands[2].reg
+  /* rdhi and rdlo must be different.  */
+  if (inst.operands[0].reg == inst.operands[1].reg)
+    as_tsktsk (_("rdhi and rdlo must be different"));
+
+  /* rdhi, rdlo and rm must all be different before armv6.  */
+  if ((inst.operands[0].reg == inst.operands[2].reg
       || inst.operands[1].reg == inst.operands[2].reg)
+      && !ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v6))
     as_tsktsk (_("rdhi, rdlo and rm must all be different"));
 }
 



More information about the Binutils mailing list