This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: Fix multi-reg regno_reg_rtx entry
Eric Botcazou <ebotcazou@adacore.com> writes:
> I'm not sure about the assertion though: if it happens to trigger, the
> fix will probably entail far-reaching changes in the back-end, so it's
> probably safer to delay it until the next stage #1.
Yeah, that's probably true. How does this version look?
Thanks,
Richard
gcc/
* function.h (regno_reg_rtx): Adjust comment.
* reginfo.c (init_reg_modes_target): Only use the previous mode
if it fits within one register. Remove MIPS comment.
Index: gcc/function.h
===================================================================
--- gcc/function.h 2012-01-30 19:23:22.000000000 +0000
+++ gcc/function.h 2012-01-30 19:23:51.000000000 +0000
@@ -87,10 +87,13 @@ struct GTY(()) emit_status {
};
-/* Indexed by pseudo register number, gives the rtx for that pseudo.
- Allocated in parallel with regno_pointer_align.
- FIXME: We could put it into emit_status struct, but gengtype is not able to deal
- with length attribute nested in top level structures. */
+/* Indexed by register number, gives an rtx for that register (and only
+ that register). For pseudo registers, it is the unique rtx for
+ that pseudo. For hard registers, it is an rtx of the mode specified
+ by reg_raw_mode.
+
+ FIXME: We could put it into emit_status struct, but gengtype is not
+ able to deal with length attribute nested in top level structures. */
extern GTY ((length ("crtl->emit.x_reg_rtx_no"))) rtx * regno_reg_rtx;
Index: gcc/reginfo.c
===================================================================
--- gcc/reginfo.c 2012-01-30 19:01:55.000000000 +0000
+++ gcc/reginfo.c 2012-01-30 19:25:01.000000000 +0000
@@ -615,13 +615,15 @@ init_reg_modes_target (void)
{
reg_raw_mode[i] = choose_hard_reg_mode (i, 1, false);
- /* If we couldn't find a valid mode, just use the previous mode.
- ??? One situation in which we need to do this is on the mips where
- HARD_REGNO_NREGS (fpreg, [SD]Fmode) returns 2. Ideally we'd like
- to use DF mode for the even registers and VOIDmode for the odd
- (for the cpu models where the odd ones are inaccessible). */
+ /* If we couldn't find a valid mode, just use the previous mode
+ if it is suitable, otherwise fall back on word_mode. */
if (reg_raw_mode[i] == VOIDmode)
- reg_raw_mode[i] = i == 0 ? word_mode : reg_raw_mode[i-1];
+ {
+ if (i > 0 && hard_regno_nregs[i][reg_raw_mode[i - 1]] == 1)
+ reg_raw_mode[i] = reg_raw_mode[i - 1];
+ else
+ reg_raw_mode[i] = word_mode;
+ }
}
}