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]

[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


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