This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[committed] Turn MIPS loadgp insns into SETs
- From: Richard Sandiford <rsandifo at nildram dot co dot uk>
- To: gcc-patches at gcc dot gnu dot org
- Date: Fri, 21 Dec 2007 10:01:30 +0000
- Subject: [committed] Turn MIPS loadgp insns into SETs
mips64-linux-gnu had a few test failures for -O3 -mabi={n32,64}.
They were caused by cases where we chose to use a call-clobbered
register as the global pointer (instead of the usual $28).
The instruction that sets the global pointer does not mention
it explicitly, so df thought that the GOT accesses were using
an uninitialised register. The register was never live between
instructions, so regrename.c decided that it could reuse it
between the intialisation and the last use.
Fixed by turning the loadgp instructions into SETs. For consistency,
I've added SImode and DImode versions of all loadgp insns, even though
we don't use loadgp_absolute or loadgp_rtp for DImode at present.
Tested on mips64-linux-gnu and applied.
Richard
gcc/
* config/mips/mips.c (mips_emit_loadgp): Replace gen_* calls with
separate gen_*_si and gen_*_di calls. Pass pic_offset_table_rtx
as the first argument.
* config/mips/mips.md (loadgp_newabi, loadgp_absolute)
(loadgp_rtp): Rename to...
(loadgp_newabi_<mode>, loadgp_absolute<mode>, loadgp_rtp<mode>):
...these. Add modes to all operands. Add the target register
as an operand. Combine loadgp_rtp<mode> with its splitter.
Index: gcc/config/mips/mips.c
===================================================================
--- gcc/config/mips/mips.c 2007-12-20 18:41:41.000000000 +0000
+++ gcc/config/mips/mips.c 2007-12-20 18:47:41.000000000 +0000
@@ -8281,8 +8281,9 @@ static GTY(()) rtx mips_gnu_local_gp;
static void
mips_emit_loadgp (void)
{
- rtx addr, offset, incoming_address, base, index;
+ rtx addr, offset, incoming_address, base, index, pic_reg;
+ pic_reg = pic_offset_table_rtx;
switch (mips_current_loadgp_style ())
{
case LOADGP_ABSOLUTE:
@@ -8291,14 +8292,18 @@ mips_emit_loadgp (void)
mips_gnu_local_gp = gen_rtx_SYMBOL_REF (Pmode, "__gnu_local_gp");
SYMBOL_REF_FLAGS (mips_gnu_local_gp) |= SYMBOL_FLAG_LOCAL;
}
- emit_insn (gen_loadgp_absolute (mips_gnu_local_gp));
+ emit_insn (Pmode == SImode
+ ? gen_loadgp_absolute_si (pic_reg, mips_gnu_local_gp)
+ : gen_loadgp_absolute_di (pic_reg, mips_gnu_local_gp));
break;
case LOADGP_NEWABI:
addr = XEXP (DECL_RTL (current_function_decl), 0);
offset = mips_unspec_address (addr, SYMBOL_GOTOFF_LOADGP);
incoming_address = gen_rtx_REG (Pmode, PIC_FUNCTION_ADDR_REGNUM);
- emit_insn (gen_loadgp_newabi (offset, incoming_address));
+ emit_insn (Pmode == SImode
+ ? gen_loadgp_newabi_si (pic_reg, offset, incoming_address)
+ : gen_loadgp_newabi_di (pic_reg, offset, incoming_address));
if (!TARGET_EXPLICIT_RELOCS)
emit_insn (gen_loadgp_blockage ());
break;
@@ -8306,7 +8311,9 @@ mips_emit_loadgp (void)
case LOADGP_RTP:
base = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (VXWORKS_GOTT_BASE));
index = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (VXWORKS_GOTT_INDEX));
- emit_insn (gen_loadgp_rtp (base, index));
+ emit_insn (Pmode == SImode
+ ? gen_loadgp_rtp_si (pic_reg, base, index)
+ : gen_loadgp_rtp_di (pic_reg, base, index));
if (!TARGET_EXPLICIT_RELOCS)
emit_insn (gen_loadgp_blockage ());
break;
Index: gcc/config/mips/mips.md
===================================================================
--- gcc/config/mips/mips.md 2007-12-20 18:27:44.000000000 +0000
+++ gcc/config/mips/mips.md 2007-12-20 18:55:13.000000000 +0000
@@ -4269,32 +4269,34 @@ (define_expand "load_const_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.
-(define_insn_and_split "loadgp_newabi"
- [(unspec_volatile [(match_operand 0 "" "")
- (match_operand 1 "register_operand" "")] UNSPEC_LOADGP)]
+(define_insn_and_split "loadgp_newabi_<mode>"
+ [(set (match_operand:P 0 "register_operand" "=d")
+ (unspec_volatile:P [(match_operand:P 1)
+ (match_operand:P 2 "register_operand" "d")]
+ UNSPEC_LOADGP))]
"mips_current_loadgp_style () == LOADGP_NEWABI"
"#"
""
- [(set (match_dup 2) (match_dup 3))
- (set (match_dup 2) (match_dup 4))
- (set (match_dup 2) (match_dup 5))]
-{
- operands[2] = pic_offset_table_rtx;
- operands[3] = gen_rtx_HIGH (Pmode, operands[0]);
- operands[4] = gen_rtx_PLUS (Pmode, operands[2], operands[1]);
- operands[5] = gen_rtx_LO_SUM (Pmode, operands[2], operands[0]);
+ [(set (match_dup 0) (match_dup 3))
+ (set (match_dup 0) (match_dup 4))
+ (set (match_dup 0) (match_dup 5))]
+{
+ operands[3] = gen_rtx_HIGH (Pmode, operands[1]);
+ operands[4] = gen_rtx_PLUS (Pmode, operands[0], operands[2]);
+ operands[5] = gen_rtx_LO_SUM (Pmode, operands[0], operands[1]);
}
[(set_attr "length" "12")])
;; Likewise, for -mno-shared code. Operand 0 is the __gnu_local_gp symbol.
-(define_insn_and_split "loadgp_absolute"
- [(unspec_volatile [(match_operand 0 "" "")] UNSPEC_LOADGP)]
+(define_insn_and_split "loadgp_absolute_<mode>"
+ [(set (match_operand:P 0 "register_operand" "=d")
+ (unspec_volatile:P [(match_operand:P 1)] UNSPEC_LOADGP))]
"mips_current_loadgp_style () == LOADGP_ABSOLUTE"
"#"
""
[(const_int 0)]
{
- mips_emit_move (pic_offset_table_rtx, operands[0]);
+ mips_emit_move (operands[0], operands[1]);
DONE;
}
[(set_attr "length" "8")])
@@ -4313,27 +4315,24 @@ (define_insn "loadgp_blockage"
;; Initialize $gp for RTP PIC. Operand 0 is the __GOTT_BASE__ symbol
;; and operand 1 is the __GOTT_INDEX__ symbol.
-(define_insn "loadgp_rtp"
- [(unspec_volatile [(match_operand 0 "symbol_ref_operand")
- (match_operand 1 "symbol_ref_operand")] UNSPEC_LOADGP)]
+(define_insn_and_split "loadgp_rtp_<mode>"
+ [(set (match_operand:P 0 "register_operand" "=d")
+ (unspec_volatile:P [(match_operand:P 1 "symbol_ref_operand")
+ (match_operand:P 2 "symbol_ref_operand")]
+ UNSPEC_LOADGP))]
"mips_current_loadgp_style () == LOADGP_RTP"
"#"
- [(set_attr "length" "12")])
-
-(define_split
- [(unspec_volatile [(match_operand:P 0 "symbol_ref_operand")
- (match_operand:P 1 "symbol_ref_operand")] UNSPEC_LOADGP)]
- "mips_current_loadgp_style () == LOADGP_RTP"
- [(set (match_dup 2) (high:P (match_dup 3)))
- (set (match_dup 2) (unspec:P [(match_dup 2)
+ ""
+ [(set (match_dup 0) (high:P (match_dup 3)))
+ (set (match_dup 0) (unspec:P [(match_dup 0)
(match_dup 3)] UNSPEC_LOAD_GOT))
- (set (match_dup 2) (unspec:P [(match_dup 2)
+ (set (match_dup 0) (unspec:P [(match_dup 0)
(match_dup 4)] UNSPEC_LOAD_GOT))]
{
- operands[2] = pic_offset_table_rtx;
- operands[3] = mips_unspec_address (operands[0], SYMBOL_ABSOLUTE);
- operands[4] = mips_unspec_address (operands[1], SYMBOL_HALF);
-})
+ operands[3] = mips_unspec_address (operands[1], SYMBOL_ABSOLUTE);
+ operands[4] = mips_unspec_address (operands[2], SYMBOL_HALF);
+}
+ [(set_attr "length" "12")])
;; Emit a .cprestore directive, which normally expands to a single store
;; instruction. Note that we continue to use .cprestore for explicit reloc