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] PR middle-end/19378: Fix AVR build failures / possibly less restrictive alternative.


The bug that this patch is addressing is discussed more in detail in

?http://gcc.gnu.org/ml/gcc-patches/2005-01/msg00834.html

and the thread

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=18887
.
Brief summary: 

Current Head 4.0.0 cannot be built for the avr-target: It breaks due to some 
problem with reloading DI expressions. Problem appears to be a problem in the 
back-end code that has become evident only recently due to a change in 
reload.c .

Roger Sayle has suggested a very similar patch disallowing to span Reg28:29 
completely:

>The following patch resolves PR middle-end/19378 which is an ICE
>compiling libgcc for AVR, due to an abort in reload.c's find_valid_class.
>It turns out that the undelying problem is in avr.c's definition of
>avr_hard_regno_mode_ok.  This function currently allows a DImode psuedo
>to be allocated in the 8 QImode registers starting at r24.  Unfortunately,
>this same function doesn't allow the 6th register of that same DImode
>value to be accessed, as avr_hard_regno_mode_ok returns false for r29
>in QImode!
>
>The solution I've taken below is to completely rewrite this function
>such that the pair of registers r28 and r29 are effectively always
>reserved for holding Pmode values (i.e. the frame pointer).  We then
>reject any other regno/mode combination that overlaps with this pair.
>It may be possible to improve upon this logic allowing r28 and r29
>as general registers when the frame pointer is not required, but I
>didn't fancy risking this without more active avr maintainers.

Since in many occasions, especially for the more common case that the embedded 
application does not use any long longs, the frame pointer can be avoided 
completely. I would prefer a solution, that only affects the use of long 
longs since this way, the Y register possibly could be used also for 
containing SI or HI values.

The following alternative patch removes the problem for the current head 
revision by restricting the DI values to be allowed to be placed in all 
registers except for the pointer registers.

Yours,

Björn



Index: avr.c
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/config/avr/avr.c,v
retrieving revision 1.125
diff -U17 -r1.125 avr.c
--- avr.c	25 Dec 2004 22:20:04 -0000	1.125
+++ avr.c	18 Jan 2005 22:34:16 -0000
@@ -5120,34 +5120,45 @@
 
 int
 avr_hard_regno_mode_ok (int regno, enum machine_mode mode)
 {
   /* Bug workaround: recog.c (peep2_find_free_register) and probably
      a few other places assume that the frame pointer is a single hard
      register, so r29 may be allocated and overwrite the high byte of
      the frame pointer.  Do not allow any value to start in r29.  */
   if (regno == REG_Y + 1)
     return 0;
 
   /* Reload can use r28:r29 for reload register and for frame pointer
    in one insn. It's wrong. We must disable it.  */
   if (mode != Pmode && reload_in_progress && frame_pointer_required_p ()
       && regno <= REG_Y && (regno + GET_MODE_SIZE (mode)) >= (REG_Y + 1))
     return 0;
 
+  /* Reload has problems when trying to place DI in registers since    */
+  /* acessing r29 with mode QI is explicitly forbidden.                */
+  /* When allowing DI to start only below reg:20, we prevent also that */
+  /* the precious pointer registers are wasted for DI objects.         */
+  if (mode == DImode)
+   { if ((regno < 20) && (!(regno & 1)))
+      return 1;
+     else
+      return 0; 
+   }
+ 
   if (mode == QImode)
     return 1;
   /*  if (regno < 24 && !AVR_ENHANCED)
       return 1;*/
   return !(regno & 1);
 }
 
 /* Returns 1 if X is a valid address for an I/O register of size SIZE
    (1 or 2).  Used for lds/sts -> in/out optimization.  Add 0x20 to SIZE
    to check for the lower half of I/O space (for cbi/sbi/sbic/sbis).  */
 
 int
 avr_io_address_p (rtx x, int size)
 {
   return (optimize > 0 && GET_CODE (x) == CONST_INT
 	  && INTVAL (x) >= 0x20 && INTVAL (x) <= 0x60 - size);
 }


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