This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug middle-end/18887] [4.0 Regression] libgcc2.h Improperly determines required built-in function size requirements.
- From: "bjoern dot m dot haase at web dot de" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: 18 Jan 2005 21:40:16 -0000
- Subject: [Bug middle-end/18887] [4.0 Regression] libgcc2.h Improperly determines required built-in function size requirements.
- References: <20041208130405.18887.schlie@comcast.net>
- Reply-to: gcc-bugzilla at gcc dot gnu dot org
------- 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