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] PR21990


Hi,

IMO PR21990 has been introduced by the patch:

+2005-01-22  Roger Sayle  <roger@eyesopen.com>
+
+	PR middle-end/19378
+	* config/avr/avr.c (avr_hard_regno_mode_ok): Rewrite.
+

My analysis shows that the problematic change is

-  /* 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;

Denis Chertykov's older version using "frame_pointer_required_p ()" has now
vanished. A problem during register allocation has been removed by Roger
Sayle's patch. However, the old frame pointer bug has been re-introduced.

My suggestion is to use an implementation again using the information wether
the frame pointer is required or not and disallow use of REG_Y and REG_Y + 1
accordingly.
The patch has passed regression tests on head without any changes for the
c-testsuite run (both, compilation and simulator excecution for the
atmega128).

I also verified on an old snapshot that had exposed PR21990 that this patch
resolves PR21990.

Open coding style question is, if it's better to use
 "frame_pointer_required_p ()" or rather "frame_pointer_needed". Since all
 over avr.c
"frame_pointer_needed" is used, I have chosen the latter one in my patch.

OK for mainline and 4.0.2?

Yours,

Bjoern


2005-09-04  Bjoern Haase  <bjoern.m.haase@web.de>

	PR middle-end/21990
	* config/avr/avr.c (avr_hard_regno_mode_ok):
	Disallow use of REG_Y by register allocation when (frame_pointer_needed).

-------------------------------------------------------
Index: avr.c
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/config/avr/avr.c,v
retrieving revision 1.141
diff -U8 -r1.141 avr.c
--- avr.c	27 Jul 2005 22:29:46 -0000	1.141
+++ avr.c	4 Sep 2005 10:17:47 -0000
@@ -5695,23 +5695,29 @@
 /* Returns 1 if a value of mode MODE can be stored starting with hard
    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)
 {
-  /* The only thing that can go into registers r28:r29 is a Pmode.  */
-  if (regno == REG_Y && mode == Pmode)
-    return 1;
+  if (frame_pointer_needed)
+    {
+      /* disallow all regno/mode combinations that span r28 and r29.  */
+      if (regno <= REG_Y && (regno + GET_MODE_SIZE (mode)) > REG_Y)
+        return 0;
+      if (regno <= (REG_Y + 1) && (regno + GET_MODE_SIZE (mode)) > (REG_Y + 1))
+        return 0;
+    }
 
-  /* 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;
+  /* Only allow 2 byte values in the pointer registers.  */
+  if (GET_MODE_SIZE (mode) > 2)
+    if (regno >= REG_Y)
+      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;
 

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