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]

ARM vector return ICE


In Thumb-1 mode we need a scratch low register to push/pop high registers.

thumb_find_work_register is used by other prologue code, so may return a 
register that overlaps the return value. The attached patch below makes sure a 
low register is pushed when the first choice prologue register overlaps the 
return value.

At this point the bug is mainly theoretical. Gcc generates poor really code 
for the cases that would be effected, so in practice ends up clobbering some 
low registers anyway. 

Tested on arm-none-eabi.
Applied to trunk

Paul

2007-07-12  Paul Brook  <paul@codesourcery.com>

	gcc/
	* config/arm/arm.c (thumb1_compute_save_reg_mask): Make sure scratch
	reg does not overlap return value.
Index: gcc/config/arm/arm.c
===================================================================
--- gcc/config/arm/arm.c	(revision 176121)
+++ gcc/config/arm/arm.c	(working copy)
@@ -10957,6 +10957,10 @@ thumb1_compute_save_reg_mask (void)
 	 have to push it.  Use LAST_LO_REGNUM as our fallback
 	 choice for the register to select.  */
       reg = thumb_find_work_register (1 << LAST_LO_REGNUM);
+      /* Make sure the register returned by thumb_find_work_register is
+	 not part of the return value.  */
+      if (reg * UNITS_PER_WORD <= arm_size_return_regs ())
+	reg = LAST_LO_REGNUM;
 
       if (! call_used_regs[reg])
 	mask |= 1 << reg;

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