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]

Re: [PATCH] PR middle-end/19378: Fix AVR build failures / possiblyless restrictive alternative.


On Wed, 19 Jan 2005, [iso-8859-1] Björn Haase wrote:
> 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.

I think your patch is only working around the fundamental problems in
avr.c's avr_hard_regno_mode_ok, which is slowly accumulating band-aids.
For example, if you work through the code you'll notice that allocating
an SImode register in r28 (when the frame pointer) is not required will
also ICE when attempting to refer to the QImode highpart in r29.

And as for determining when r28:r29 needs to be reserved for the frame
pointer, avr.c already has severe schizophrenia using the predicate
frame_pointer_required_p() in this function, but the global variable
frame_pointer_needed everywhere else in avr.c.

I believe my patch is still the better solution, the latest revision
of which I've attached below.


Index: config/avr/avr.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/avr/avr.c,v
retrieving revision 1.125
diff -c -3 -p -r1.125 avr.c
*** config/avr/avr.c	25 Dec 2004 22:20:04 -0000	1.125
--- config/avr/avr.c	15 Jan 2005 01:42:58 -0000
*************** jump_over_one_insn_p (rtx insn, rtx dest
*** 5121,5143 ****
  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 == QImode)
      return 1;
!   /*  if (regno < 24 && !AVR_ENHANCED)
!       return 1;*/
    return !(regno & 1);
  }

--- 5121,5142 ----
  int
  avr_hard_regno_mode_ok (int regno, enum machine_mode mode)
  {
!   /* The only thing that can go into registers r28:r29 is a Pmode.  */
!   if (regno == REG_Y && mode == Pmode)
!     return 1;

!   /* Otherwise disallow all regno/mode combinations that span r28:r29.  */
!   if (regno <= (REG_Y + 1) && (regno + GET_MODE_SIZE (mode)) >= (REG_Y + 1))
      return 0;

    if (mode == QImode)
      return 1;
!
!   /* Modes larger than QImode occupy consecutive registers.  */
!   if (regno + GET_MODE_SIZE (mode) > FIRST_PSEUDO_REGISTER)
!     return 0;
!
!   /* All modes larger than QImode should start in an even register.  */
    return !(regno & 1);
  }


Roger
--


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