PR middle-end/19378
authorsayle <sayle@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 23 Jan 2005 04:51:28 +0000 (04:51 +0000)
committersayle <sayle@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 23 Jan 2005 04:51:28 +0000 (04:51 +0000)
* config/avr/avr.c (avr_hard_regno_mode_ok): Rewrite.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@94102 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/config/avr/avr.c

index 10018db..07c5b17 100644 (file)
@@ -1,3 +1,8 @@
+2005-01-22  Roger Sayle  <roger@eyesopen.com>
+
+       PR middle-end/19378
+       * config/avr/avr.c (avr_hard_regno_mode_ok): Rewrite.
+
 2005-01-22  Richard Henderson  <rth@redhat.com>
 
        PR target/19506
index 061a81e..0f6b2de 100644 (file)
@@ -5121,23 +5121,22 @@ jump_over_one_insn_p (rtx insn, rtx dest)
 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;
+  /* The only thing that can go into registers r28:r29 is a Pmode.  */
+  if (regno == REG_Y && mode == Pmode)
+    return 1;
 
-  /* 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))
+  /* 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;
-  /*  if (regno < 24 && !AVR_ENHANCED)
-      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);
 }