This is the mail archive of the gcc-bugs@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]

[Bug middle-end/18887] [4.0 Regression] libgcc2.h Improperly determines required built-in function size requirements.


------- Additional Comments From bjoern dot m dot haase at web dot de  2005-01-18 21:40 -------
Indeed the problem seems to be related to a problem during the reload pass. I 
now think, that I have found a solution for the original problem that needs a 
tiny change in the back-end. 
 
DJ Delorie wrote me: 
 
>avr bug - GENERAL_REGS allows $r24 to contain a DImode, but you cannot 
>access the 5th byte of it via a subreg, because HARD_REGNO_MODE_OK 
>doesn't permit QImodes in $r29. ?This disqualifies GENERAL_REGS. 
 
Since anyway any useful function using long longs will require the frame 
pointer, there is (in my opinion) no use for DI objects in the upper register 
range. The following patch restricts DI objects to registers with smaller 
indices. When using this patch, I succeed in building the gcc-4.0.0 snapshot 
dating from the 12th of december 04 without problems. This snapshot previously 
did not compile with the symptoms mentioned above. 
 
For a later head revision, unfortunately something else and independent seems 
to be broken. I'll check today's head this evening and report on this, as soon 
as I have analyzed this more in detail. 
 
Patch that needs to be applied to /gcc/config/avr/avr.c 
Reported differences are differences against the 4.0.0-20041212 snapshot. 
 
--- avr.c.old	2005-01-18 22:24:44.942273520 +0100 
+++ avr.c.new	2005-01-18 22:19:19.000000000 +0100 
@@ -5116,40 +5116,47 @@ 
    register number REGNO.  On the enhanced core, anything larger than 
    1 byte must start in even numbered register for "movw" to work 
    (this way we don't have to check for odd registers everywhere).  */ 
  
 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; 
  
+  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); 
 } 
  
 /* Returns nonzero (bit number + 1) if X, or -X, is a constant power of 2.  */ 
  

-- 


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


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