This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[4.2, committed] Fix PR34900: mips64vrel-elf build failure
- From: Richard Sandiford <rsandifo at nildram dot co dot uk>
- To: gcc-patches at gcc dot gnu dot org
- Date: Sat, 02 Feb 2008 09:44:00 +0000
- Subject: [4.2, committed] Fix PR34900: mips64vrel-elf build failure
Richard Sandiford <rsandifo@nildram.co.uk> writes:
> PR34900 is a 4.2 build failure for mips64vrel-elf. It is really the
> same as PR 31388, which was fixed on mainline with:
>
> 2007-04-01 Richard Sandiford <richard@codesourcery.com>
>
> PR target/31388
> * config/mips/mips.md (load_const_gp): New insn.
> * config/mips/mips.c (mips_split_symbol): Avoid using or creating
> the MIPS16 GP pseudo register if no_new_pseudos.
> (mips16_gp_pseudo_reg): Use gen_load_const_gp.
>
> However, while backporting that patch, I noticed that it had a rather
> obvious flaw: the new const had no mode. I fixed that in the backport,
> and although I don't know that the original patch causes any specific
> failure, I thought it was safer to fix the 4.3 sources in the same way.
> Not doing so might introduce a 4.2.4->4.3 regression.
>
> Tested on mipsisa64-elfoabi and applied. I'll apply the 4.2 patch
> after 4.2.3 is released.
Now applied to 4.2 as follows after regression-testing on
mips64-linux-gnu.
Richard
gcc/
PR target/31388
* config/mips/mips.md (load_const_gp_<mode>): New insns.
* config/mips/mips.c (gen_load_const_gp): New function.
(mips_split_symbol): Avoid using or creating the MIPS16 GP
pseudo register if no_new_pseudos.
(mips16_gp_pseudo_reg): Use gen_load_const_gp.
Index: gcc/config/mips/mips.md
===================================================================
--- gcc/config/mips/mips.md 2008-01-31 16:39:48.000000000 +0000
+++ gcc/config/mips/mips.md 2008-01-31 19:24:49.000000000 +0000
@@ -4001,6 +4001,11 @@ (define_insn "store_df_high"
[(set_attr "type" "xfer,fpstore")
(set_attr "mode" "SF")])
+;; Move a constant that satisfies CONST_GP_P into operand 0.
+(define_expand "load_const_gp_<mode>"
+ [(set (match_operand:P 0 "register_operand" "=d")
+ (const:P (unspec:P [(const_int 0)] UNSPEC_GP)))])
+
;; Insn to initialize $gp for n32/n64 abicalls. Operand 0 is the offset
;; of _gp from the start of this function. Operand 1 is the incoming
;; function address.
Index: gcc/config/mips/mips.c
===================================================================
--- gcc/config/mips/mips.c 2008-01-31 16:39:48.000000000 +0000
+++ gcc/config/mips/mips.c 2008-01-31 19:24:49.000000000 +0000
@@ -1935,6 +1935,19 @@ mips_force_temporary (rtx dest, rtx valu
}
+/* Return an instruction that copies $gp into register REG. We want
+ GCC to treat the register's value as constant, so that its value
+ can be rematerialized on demand. */
+
+static rtx
+gen_load_const_gp (rtx reg)
+{
+ return (Pmode == SImode
+ ? gen_load_const_gp_si (reg)
+ : gen_load_const_gp_di (reg));
+}
+
+
/* Return a LO_SUM expression for ADDR. TEMP is as for mips_force_temporary
and is used to load the high part into a register. */
@@ -1943,10 +1956,15 @@ mips_split_symbol (rtx temp, rtx addr)
{
rtx high;
- if (TARGET_MIPS16)
- high = mips16_gp_pseudo_reg ();
- else
+ if (!TARGET_MIPS16)
high = mips_force_temporary (temp, gen_rtx_HIGH (Pmode, copy_rtx (addr)));
+ else if (no_new_pseudos)
+ {
+ emit_insn (gen_load_const_gp (copy_rtx (temp)));
+ high = temp;
+ }
+ else
+ high = mips16_gp_pseudo_reg ();
return gen_rtx_LO_SUM (Pmode, high, addr);
}
@@ -7882,19 +7900,11 @@ mips16_gp_pseudo_reg (void)
{
if (cfun->machine->mips16_gp_pseudo_rtx == NULL_RTX)
{
- rtx unspec;
rtx insn, scan;
cfun->machine->mips16_gp_pseudo_rtx = gen_reg_rtx (Pmode);
- /* We want to initialize this to a value which gcc will believe
- is constant. */
- start_sequence ();
- unspec = gen_rtx_UNSPEC (VOIDmode, gen_rtvec (1, const0_rtx), UNSPEC_GP);
- emit_move_insn (cfun->machine->mips16_gp_pseudo_rtx,
- gen_rtx_CONST (Pmode, unspec));
- insn = get_insns ();
- end_sequence ();
+ insn = gen_load_const_gp (cfun->machine->mips16_gp_pseudo_rtx);
push_topmost_sequence ();
/* We need to emit the initialization after the FUNCTION_BEG