This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC 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]

[Patch PR43399] Fix bootstrap on arm-linux-gnueabi with VTA changes.


Hi,

The attached patch fixes the ICE with bootstrap on the arm-linux-gnueabi
target and does this by using a PRE_MODIFY instead of a PRE_DEC in the
prologue for the push_multi pattern. 

As mentioned in the audit trail, we could fix this by exposing the
entire push multiple sequence to the middle end but given some of the
restrictions with the various store multiple instructions. We need
slightly invasive changes in the backend which might not be
suitable for stage4. 

I've tested this by completing a bootstrap with arm-linux-gnueabi for C
and C++ and a full testrun is on at the minute.

Ok to commit for trunk and backport to the 4.4 branch if this is a
regression there as well ? 

cheers
Ramana

2010-03-18  Ramana Radhakrishnan  <ramana.radhakrishnan@arm.com>

        PR target/43399
        * config/arm/arm.c (emit_multi_reg_push): Update comments.
        Use PRE_MODIFY instead of PRE_DEC.
        (emit_sfm): Use PRE_MODIFY instead of PRE_DEC.
        (vfp_emit_fstmd): Likewise.

Index: arm.c
===================================================================
--- arm.c	(revision 157543)
+++ arm.c	(working copy)
@@ -11656,8 +11656,10 @@ vfp_emit_fstmd (int base_reg, int count)
   XVECEXP (par, 0, 0)
     = gen_rtx_SET (VOIDmode,
 		   gen_frame_mem (BLKmode,
-				  gen_rtx_PRE_DEC (BLKmode,
-						   stack_pointer_rtx)),
+				  gen_rtx_PRE_MODIFY (Pmode,
+						      stack_pointer_rtx,
+						      plus_constant (stack_pointer_rtx, 
+								     - (count * 8)))),
 		   gen_rtx_UNSPEC (BLKmode,
 				   gen_rtvec (1, reg),
 				   UNSPEC_PUSH_MULT));
@@ -13910,11 +13912,12 @@ emit_multi_reg_push (unsigned long mask)
 
   /* For the body of the insn we are going to generate an UNSPEC in
      parallel with several USEs.  This allows the insn to be recognized
-     by the push_multi pattern in the arm.md file.  The insn looks
-     something like this:
+     by the push_multi pattern in the arm.md file.
+
+     The body of the insn looks something like this:
 
        (parallel [
-           (set (mem:BLK (pre_dec:BLK (reg:SI sp)))
+           (set (mem:BLK (pre_modify:SI (reg:SI sp)))
 	        (unspec:BLK [(reg:SI r4)] UNSPEC_PUSH_MULT))
            (use (reg:SI 11 fp))
            (use (reg:SI 12 ip))
@@ -13922,6 +13925,7 @@ emit_multi_reg_push (unsigned long mask)
            (use (reg:SI 15 pc))
         ])
 
+
      For the frame note however, we try to be more explicit and actually
      show each register being stored into the stack frame, plus a (single)
      decrement of the stack pointer.  We do it this way in order to be
@@ -13937,9 +13941,27 @@ emit_multi_reg_push (unsigned long mask)
            (set (mem:SI (plus:SI (reg:SI sp) (const_int 12))) (reg:SI lr))
         ])
 
-      This sequence is used both by the code to support stack unwinding for
-      exceptions handlers and the code to generate dwarf2 frame debugging.  */
+	1.  For the APCS i.e. arm-elf / arm-linux the registers saved using this scheme
+	are fp, ip,  lr, pc.
 
+	2. For the AAPCS i.e. arm-eabi and arm-linux-gnueabi targets
+	or what is known as AAPCS we generate a variation where the 
+	note expression and the insn are controlled by the number of 
+	registers being stored and could be any number of registers.
+	
+	This sequence is used both by the code to support stack unwinding for
+	exception handlers and the code to generate dwarf2 frame debugging.
+	
+	FIXME:: In an ideal world the PRE_MODIFY would not exist and
+	instead we'd have a parallel expression detailing all
+	the stores to the various memory addresses so that debug
+	information is more up-to-date. Remember however while writing
+	this to take care of the constraints with the push instruction.
+
+	Note also that this has to be taken care of for the VFP registers.
+
+	For more see PR43399.  */
+  
   par = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (num_regs));
   dwarf = gen_rtx_SEQUENCE (VOIDmode, rtvec_alloc (num_dwarf_regs + 1));
   dwarf_par_index = 1;
@@ -13953,8 +13975,10 @@ emit_multi_reg_push (unsigned long mask)
 	  XVECEXP (par, 0, 0)
 	    = gen_rtx_SET (VOIDmode,
 			   gen_frame_mem (BLKmode,
-					  gen_rtx_PRE_DEC (BLKmode,
-							   stack_pointer_rtx)),
+					  gen_rtx_PRE_MODIFY (Pmode,
+							      stack_pointer_rtx,
+							      plus_constant (stack_pointer_rtx, 
+									     -4 * num_regs))),
 			   gen_rtx_UNSPEC (BLKmode,
 					   gen_rtvec (1, reg),
 					   UNSPEC_PUSH_MULT));
@@ -14040,8 +14064,10 @@ emit_sfm (int base_reg, int count)
   XVECEXP (par, 0, 0)
     = gen_rtx_SET (VOIDmode,
 		   gen_frame_mem (BLKmode,
-				  gen_rtx_PRE_DEC (BLKmode,
-						   stack_pointer_rtx)),
+				  gen_rtx_PRE_MODIFY (Pmode,
+						      stack_pointer_rtx,
+						      plus_constant (stack_pointer_rtx,
+								     -12 * count))),
 		   gen_rtx_UNSPEC (BLKmode,
 				   gen_rtvec (1, reg),
 				   UNSPEC_PUSH_MULT));

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