This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Thumb-2 assembler fixes, 1/5


This patch fixes a problem where the Thumb-2 assembler was failing to
use 16-bit encodings for mul instructions when possible.  Tested with
no regressions with cross to arm-none-eabi.  OK to commit?

gas:
2009-01-29  Paul Brook  <paul@codesourcery.com>
            Mark Mitchell  <mark@codesourcery.com>

	* config/tc-arm.c (do_t_mul): In Thumb-2 mode, use 16-bit encoding
	of MUL when possible.

gas/testsuite:
2009-01-29  Paul Brook  <paul@codesourcery.com>
            Mark Mitchell  <mark@codesourcery.com>

	* gas/arm/thumb2_mul.s: New file.
	* gas/arm/thumb2_mul.d: Likewise.
	* gas/arm/thumb2_mul-bad.s: Likewise.
	* gas/arm/thumb2_mul-bad.d: Likewise.
	* gas/arm/thumb2_mul-bad.l: Likewise.
	* gas/arm/t16-bad.s: Add tests for"mul" with high registers.
	* gas/arm/t16-bad.l: Update accordingly.

diff -rupN binutils.orig/gas/config/tc-arm.c binutils-1/gas/config/tc-arm.c
--- binutils.orig/gas/config/tc-arm.c	2009-01-26 14:36:42.000000000 +0000
+++ binutils-1/gas/config/tc-arm.c	2009-01-29 00:43:59.000000000 +0000
@@ -9879,24 +9879,35 @@ do_t_msr (void)
 static void
 do_t_mul (void)
 {
+  bfd_boolean narrow;
+
   if (!inst.operands[2].present)
     inst.operands[2].reg = inst.operands[0].reg;
 
-  /* There is no 32-bit MULS and no 16-bit MUL. */
-  if (unified_syntax && inst.instruction == T_MNEM_mul)
+  if (unified_syntax)
     {
-      inst.instruction = THUMB_OP32 (inst.instruction);
-      inst.instruction |= inst.operands[0].reg << 8;
-      inst.instruction |= inst.operands[1].reg << 16;
-      inst.instruction |= inst.operands[2].reg << 0;
+      if (inst.size_req == 4
+	  || (inst.operands[0].reg != inst.operands[1].reg
+	      && inst.operands[0].reg != inst.operands[2].reg)
+	  || inst.operands[1].reg > 7
+	  || inst.operands[2].reg > 7)
+	narrow = FALSE;
+      else if (inst.instruction == T_MNEM_muls)
+	narrow = (current_it_mask == 0);
+      else
+	narrow = (current_it_mask != 0);
     }
   else
     {
-      constraint (!unified_syntax
-		  && inst.instruction == T_MNEM_muls, BAD_THUMB32);
-      constraint (inst.operands[0].reg > 7 || inst.operands[1].reg > 7,
+      constraint (inst.instruction == T_MNEM_muls, BAD_THUMB32);
+      constraint (inst.operands[1].reg > 7 || inst.operands[2].reg > 7,
 		  BAD_HIREG);
+      narrow = TRUE;
+    }
 
+  if (narrow)
+    {
+      /* 16-bit MULS/Conditional MUL.  */
       inst.instruction = THUMB_OP16 (inst.instruction);
       inst.instruction |= inst.operands[0].reg;
 
@@ -9907,6 +9918,16 @@ do_t_mul (void)
       else
 	constraint (1, _("dest must overlap one source register"));
     }
+  else
+    {
+      constraint(inst.instruction != T_MNEM_mul,
+		 _("Thumb-2 MUL must not set flags"));
+      /* 32-bit MUL.  */
+      inst.instruction = THUMB_OP32 (inst.instruction);
+      inst.instruction |= inst.operands[0].reg << 8;
+      inst.instruction |= inst.operands[1].reg << 16;
+      inst.instruction |= inst.operands[2].reg << 0;
+    }
 }
 
 static void
diff -rupN binutils.orig/gas/testsuite/gas/arm/t16-bad.l binutils-1/gas/testsuite/gas/arm/t16-bad.l
--- binutils.orig/gas/testsuite/gas/arm/t16-bad.l	2008-03-05 01:31:26.000000000 +0000
+++ binutils-1/gas/testsuite/gas/arm/t16-bad.l	2009-01-29 00:43:59.000000000 +0000
@@ -185,3 +185,6 @@
 [^:]*:135: Error: Thumb does not support the 2-argument form of this instruction -- `cpsid ai,#5'
 [^:]*:138: Error: Thumb does not support conditional execution
 [^:]*:141: Error: cannot honor width suffix -- `add r0,r1'
+[^:]*:145: Error: lo register required -- `mul r0,r0,r8'
+[^:]*:146: Error: lo register required -- `mul r0,r8,r0'
+[^:]*:147: Error: dest must overlap one source register -- `mul r8,r0,r0'
diff -rupN binutils.orig/gas/testsuite/gas/arm/t16-bad.s binutils-1/gas/testsuite/gas/arm/t16-bad.s
--- binutils.orig/gas/testsuite/gas/arm/t16-bad.s	2008-03-05 01:31:26.000000000 +0000
+++ binutils-1/gas/testsuite/gas/arm/t16-bad.s	2009-01-29 00:43:59.000000000 +0000
@@ -140,3 +140,8 @@ l:
 	.syntax unified
 	add	r0, r1
 
+	@ Multiply
+	.syntax divided
+	mul	r0, r0, r8
+	mul	r0, r8, r0
+	mul	r8, r0, r0
diff -rupN binutils.orig/gas/testsuite/gas/arm/thumb2_mul-bad.d binutils-1/gas/testsuite/gas/arm/thumb2_mul-bad.d
--- binutils.orig/gas/testsuite/gas/arm/thumb2_mul-bad.d	1970-01-01 00:00:00.000000000 +0000
+++ binutils-1/gas/testsuite/gas/arm/thumb2_mul-bad.d	2009-01-29 00:43:59.000000000 +0000
@@ -0,0 +1,3 @@
+#name: Invalid Thumb-2 multiply instructions
+#as: -march=armv6kt2
+#error-output: thumb2_mul-bad.l
diff -rupN binutils.orig/gas/testsuite/gas/arm/thumb2_mul-bad.l binutils-1/gas/testsuite/gas/arm/thumb2_mul-bad.l
--- binutils.orig/gas/testsuite/gas/arm/thumb2_mul-bad.l	1970-01-01 00:00:00.000000000 +0000
+++ binutils-1/gas/testsuite/gas/arm/thumb2_mul-bad.l	2009-01-29 00:43:59.000000000 +0000
@@ -0,0 +1,8 @@
+[^:]*: Assembler messages:
+[^:]*:10: Error: cannot honor width suffix -- `muleq.n r0,r0,r8'
+[^:]*:12: Error: cannot honor width suffix -- `muleq.n r0,r1,r1'
+[^:]*:13: Error: cannot honor width suffix -- `muleq.n r0,r1,r2'
+[^:]*:15: Error: Thumb-2 MUL must not set flags -- `mulseq r0,r0,r1'
+[^:]*:17: Error: Thumb-2 MUL must not set flags -- `muls.w r0,r0,r1'
+[^:]*:19: Error: Thumb-2 MUL must not set flags -- `muls r0,r0,r8'
+[^:]*:20: Error: Thumb-2 MUL must not set flags -- `muls r0,r8,r0'
diff -rupN binutils.orig/gas/testsuite/gas/arm/thumb2_mul-bad.s binutils-1/gas/testsuite/gas/arm/thumb2_mul-bad.s
--- binutils.orig/gas/testsuite/gas/arm/thumb2_mul-bad.s	1970-01-01 00:00:00.000000000 +0000
+++ binutils-1/gas/testsuite/gas/arm/thumb2_mul-bad.s	2009-01-29 00:43:59.000000000 +0000
@@ -0,0 +1,20 @@
+	.syntax unified
+	.text
+	.align	2
+	.global	thumb2_mul
+	.thumb
+	.thumb_func
+thumb2_mul:
+	itttt eq
+	# Cannot use 16-bit encoding because of use of high register.
+	muleq.n r0, r0, r8
+	# Cannot use 16-bit encoding because source does not match destination.
+	muleq.n r0, r1, r1
+	muleq.n r0, r1, r2
+	# There is no conditional "muls".
+	mulseq r0, r0, r1
+	# There is no 32-bit "muls".
+	muls.w r0, r0, r1
+	# Cannot use high registers with "muls".
+	muls r0, r0, r8
+	muls r0, r8, r0
diff -rupN binutils.orig/gas/testsuite/gas/arm/thumb2_mul.d binutils-1/gas/testsuite/gas/arm/thumb2_mul.d
--- binutils.orig/gas/testsuite/gas/arm/thumb2_mul.d	1970-01-01 00:00:00.000000000 +0000
+++ binutils-1/gas/testsuite/gas/arm/thumb2_mul.d	2009-01-29 00:43:59.000000000 +0000
@@ -0,0 +1,19 @@
+# as: -march=armv6kt2
+# objdump: -dr --prefix-addresses --show-raw-insn
+
+.*: +file format .*arm.*
+
+Disassembly of section .text:
+0+000 <[^>]+> bf04      	itt	eq
+0+002 <[^>]+> 4348      	muleq	r0, r1
+0+004 <[^>]+> 4348      	muleq	r0, r1
+0+006 <[^>]+> bf02      	ittt	eq
+0+008 <[^>]+> fb00 f008 	muleq.w	r0, r0, r8
+0+00c <[^>]+> fb08 f000 	muleq.w	r0, r8, r0
+0+010 <[^>]+> fb00 f808 	muleq.w	r8, r0, r8
+0+014 <[^>]+> bf04      	itt	eq
+0+016 <[^>]+> fb01 f001 	muleq.w	r0, r1, r1
+0+01a <[^>]+> fb01 f002 	muleq.w	r0, r1, r2
+0+01e <[^>]+> bf04      	itt	eq
+0+020 <[^>]+> fb01 f000 	muleq.w	r0, r1, r0
+0+024 <[^>]+> fb00 f001 	muleq.w	r0, r0, r1
diff -rupN binutils.orig/gas/testsuite/gas/arm/thumb2_mul.s binutils-1/gas/testsuite/gas/arm/thumb2_mul.s
--- binutils.orig/gas/testsuite/gas/arm/thumb2_mul.s	1970-01-01 00:00:00.000000000 +0000
+++ binutils-1/gas/testsuite/gas/arm/thumb2_mul.s	2009-01-29 00:43:59.000000000 +0000
@@ -0,0 +1,29 @@
+	.syntax unified
+	.text
+	.align	2
+	.global	thumb2_mul
+	.thumb
+	.thumb_func
+thumb2_mul:
+	# These can use the 16-bit encoding.
+	itt eq
+	muleq r0, r1, r0
+	muleq r0, r0, r1
+	# These must use the 32-bit encoding because they involve
+	# high registers.
+	ittt eq
+	muleq r0, r0, r8
+	muleq r0, r8, r0
+	muleq r8, r0, r8
+	# These must use the 32-bit encoding because the source and
+	# destination do not match.
+	itt eq
+	muleq r0, r1, r1
+	muleq r0, r1, r2
+	# These must use the 32-bit encoding because of the explicit
+	# suffix.
+	itt eq
+	muleq.w r0, r1, r0
+	muleq.w r0, r0, r1
+	
+	

-- 
Joseph S. Myers
joseph@codesourcery.com


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]