This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[Patch] PR21990
- From: BjÃrn Haase <bjoern dot m dot haase at web dot de>
- To: gcc-patches at gcc dot gnu dot org
- Date: Sun, 4 Sep 2005 13:02:24 +0200
- Subject: [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;