Bug 12698

Summary: fails to build with march=all on arm
Product: binutils Reporter: Arnaud Patard <arnaud.patard>
Component: gasAssignee: unassigned
Status: RESOLVED FIXED    
Severity: normal CC: nickc, zhenqiang.chen
Priority: P2    
Version: unspecified   
Target Milestone: ---   
Host: Target:
Build: Last reconfirmed:
Attachments: failed case

Description Arnaud Patard 2011-04-24 22:20:50 UTC
As noticed by debian bug 623964, when building an arm kernel with a snasphot made on 04/19, compiling head.S is failing with :

Error: selected processor does not support requested special purpose register -- `mrs r2,cpsr'

It's valid for current head.

To reproduce, create a head.S containing:

                mrs     r2, cpsr
                msr     cpsr_c, r2

And then build with ./gas/as-new -march=all -c head.S -o head.o

I believe it's due to this commit :
http://sourceware.org/git/?p=binutils.git;a=commitdiff;h=335cd49156302284cea0438fd068f0a7cc11355a

I've written this workaround:

--- binutils.orig/gas/config/tc-arm.c
+++ binutils/gas/config/tc-arm.c
@@ -5356,6 +5356,11 @@ parse_psr (char **str, bfd_boolean lhs)
   bfd_boolean is_apsr = FALSE;
   bfd_boolean m_profile = ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_m);
 
+  /* march=all, will match the m_profile case too, so things like 'mrs r2,cpsr'
+   * will now fail. Workaround by saying it's not a m profile */
+  if (selected_cpu.core == arm_arch_any.core)
+         m_profile = FALSE;
+
   /* CPSR's and SPSR's can now be lowercase.  This is just a convenience
      feature for ease of use and backwards compatibility.  */
   p = *str;

It doesn't seem to create any regression but I'm not sure how good is this patch. At least, I hope it'll help fixing the bug.
Comment 1 Sourceware Commits 2011-06-03 14:42:51 UTC
CVSROOT:	/cvs/src
Module name:	src
Changes by:	nickc@sourceware.org	2011-06-03 14:42:48

Modified files:
	gas            : ChangeLog 
	gas/config     : tc-arm.c 

Log message:
	PR gas/12698
	* config/tc-arm.c (parse_psr): Set m_profile to false when
	assembling for any architecture.

Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/src/gas/ChangeLog.diff?cvsroot=src&r1=1.4499&r2=1.4500
http://sourceware.org/cgi-bin/cvsweb.cgi/src/gas/config/tc-arm.c.diff?cvsroot=src&r1=1.490&r2=1.491
Comment 2 Nick Clifton 2011-06-03 14:45:07 UTC
Hi Arnaud,

  Thanks for reporting this problem and providing a patch.  Your solution works, so I have checked it in, with a slightly tweaked comment.

Cheers
  Nick
Comment 3 zhenqiang.chen 2012-06-05 07:06:31 UTC
Created attachment 6435 [details]
failed case

Assembler fail.
Comment 4 zhenqiang.chen 2012-06-05 07:11:05 UTC
The attached case is from kernel. We still get fail:

head2.s: Assembler messages:
head2.s:60: Error: selected processor does not support requested special purpose register -- `mrs r2,cpsr'
head2.s:67: Error: selected processor does not support requested special purpose register -- `mrs r2,cpsr'
head2.s:69: Error: selected processor does not support requested special purpose register -- `msr cpsr_c,r2'

The fault occurs in 2.22 and current trunk.

To reproduce it:
arm-linux-gnueabi-as --gdwarf2 -EL -march=armv7-a -mfloat-abi=soft -mfpu=vfpv3-d16 -meabi=5 -mimplicit-it=always -mno-warn-deprecated -mthumb -march=all -o head.o head2.s
Comment 5 zhenqiang.chen 2012-06-05 07:15:20 UTC
Here is a reference patch based on your previous one.
Both function do_t_mrs and do_t_msr need update. 

diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c
index 6ff64a6..7f69ffa 100644
--- a/gas/config/tc-arm.c
+++ b/gas/config/tc-arm.c
@@ -11201,8 +11201,14 @@ do_t_mrs (void)
       int flags = inst.operands[1].imm & (PSR_c|PSR_x|PSR_s|PSR_f|SPSR_BIT);
 
       if (ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_m))
-	constraint (flags != 0, _("selected processor does not support "
-        	    "requested special purpose register"));
+	{
+	  /* PR gas/12698:  The constraint is only applied for m_profile.
+	     If the user has specified -march=all, we want to ignore it as
+	     we are building for any CPU type, including non-m variants.  */
+	  bfd_boolean m_profile = selected_cpu.core != arm_arch_any.core;
+	  constraint ((flags != 0) && m_profile, _("selected processor does "
+        	      "not support requested special purpose register"));
+	}
       else
 	/* mrs only accepts APSR/CPSR/SPSR/CPSR_all/SPSR_all (for non-M profile
 	   devices).  */
@@ -11235,11 +11241,14 @@ do_t_msr (void)
   if (ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_m))
     {
       int bits = inst.operands[0].imm & (PSR_c|PSR_x|PSR_s|PSR_f|SPSR_BIT);
-
-      constraint ((ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v6_dsp)
+      /* PR gas/12698:  The constraint is only applied for m_profile.
+         If the user has specified -march=all, we want to ignore it as
+         we are building for any CPU type, including non-m variants.  */
+      bfd_boolean m_profile = selected_cpu.core != arm_arch_any.core;
+      constraint (((ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v6_dsp)
 		   && (bits & ~(PSR_s | PSR_f)) != 0)
 		  || (!ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v6_dsp)
-		      && bits != PSR_f),
+		      && bits != PSR_f)) && m_profile,
 		  _("selected processor does not support requested special "
 		    "purpose register"));
     }
Comment 6 Sourceware Commits 2012-06-13 14:19:10 UTC
CVSROOT:	/cvs/src
Module name:	src
Changes by:	nickc@sourceware.org	2012-06-13 14:19:00

Modified files:
	gas            : ChangeLog 
	gas/config     : tc-arm.c 

Log message:
	PR gas/12698
	* config/tc-arm.c (do_t_mrs): Do not require an m-profile
	architecure when assembling for all archiectures.
	(do_t_msr): Likewise.

Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/src/gas/ChangeLog.diff?cvsroot=src&r1=1.4752&r2=1.4753
http://sourceware.org/cgi-bin/cvsweb.cgi/src/gas/config/tc-arm.c.diff?cvsroot=src&r1=1.519&r2=1.520
Comment 7 Nick Clifton 2012-06-13 14:24:59 UTC
Hi Chen,

  Thanks for the patch - I have applied it to the mainline sources.

Cheers
  Nick