aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog11
-rw-r--r--gcc/config/mips/mips.c15
-rw-r--r--gcc/config/mips/mips.md57
3 files changed, 50 insertions, 33 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 9674a7c..6cec0bb 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,14 @@
+2007-12-21 Richard Sandiford <rsandifo@nildram.co.uk>
+
+ * 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.
+
2007-12-20 Bob Wilson <bob.wilson@acm.org>
* config/xtensa/xtensa.md (fix_return_addr): Remove.
diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c
index e7c9909..b81029e 100644
--- a/gcc/config/mips/mips.c
+++ b/gcc/config/mips/mips.c
@@ -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;
diff --git a/gcc/config/mips/mips.md b/gcc/config/mips/mips.md
index b4177ff..b32ed33 100644
--- a/gcc/config/mips/mips.md
+++ b/gcc/config/mips/mips.md
@@ -4269,32 +4269,34 @@
;; 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))]
+ [(set (match_dup 0) (match_dup 3))
+ (set (match_dup 0) (match_dup 4))
+ (set (match_dup 0) (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]);
+ 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 @@
;; 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