summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4>2008-08-09 18:21:50 +0000
committerrsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4>2008-08-09 18:21:50 +0000
commit1d64dcb5e0dc944f12a9b2bf30fb50194e33d9ca (patch)
tree8a821f104451c851f75d2f4aa6adf5eb46eea58d
parent036b8c98825acb0340d0adaf8374f155afee9ffc (diff)
downloadgcc-1d64dcb5e0dc944f12a9b2bf30fb50194e33d9ca.tar.gz
gcc/
* config/mips/mips.c (mips_unspec_address_offset): Move earlier in file. (mips_unspec_address, mips_unspec_offset_high): Likewise. (mips_ok_for_lazy_binding_p, mips_load_call_address): Likewise. (mips16_cfun_returns_in_fpr_p): Likewise. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@138911 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/config/mips/mips.c202
2 files changed, 108 insertions, 101 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 8e3956187f2..513e54d05b5 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,12 @@
2008-08-09 Richard Sandiford <rdsandiford@googlemail.com>
+ * config/mips/mips.c (mips_unspec_address_offset): Move earlier in file.
+ (mips_unspec_address, mips_unspec_offset_high): Likewise.
+ (mips_ok_for_lazy_binding_p, mips_load_call_address): Likewise.
+ (mips16_cfun_returns_in_fpr_p): Likewise.
+
+2008-08-09 Richard Sandiford <rdsandiford@googlemail.com>
+
* config/mips/mips.h (MASK_RETURN_ADDR): Expand commentary.
* config/mips/linux-unwind.h (mips_fallback_frame_state): Add 2
rather than 4 to PC.
diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c
index 8429d153b46..d8336bbfa9e 100644
--- a/gcc/config/mips/mips.c
+++ b/gcc/config/mips/mips.c
@@ -2261,6 +2261,51 @@ mips_emit_call_insn (rtx pattern, bool lazy_p)
return insn;
}
+/* Wrap symbol or label BASE in an UNSPEC address of type SYMBOL_TYPE,
+ then add CONST_INT OFFSET to the result. */
+
+static rtx
+mips_unspec_address_offset (rtx base, rtx offset,
+ enum mips_symbol_type symbol_type)
+{
+ base = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, base),
+ UNSPEC_ADDRESS_FIRST + symbol_type);
+ if (offset != const0_rtx)
+ base = gen_rtx_PLUS (Pmode, base, offset);
+ return gen_rtx_CONST (Pmode, base);
+}
+
+/* Return an UNSPEC address with underlying address ADDRESS and symbol
+ type SYMBOL_TYPE. */
+
+rtx
+mips_unspec_address (rtx address, enum mips_symbol_type symbol_type)
+{
+ rtx base, offset;
+
+ split_const (address, &base, &offset);
+ return mips_unspec_address_offset (base, offset, symbol_type);
+}
+
+/* If mips_unspec_address (ADDR, SYMBOL_TYPE) is a 32-bit value, add the
+ high part to BASE and return the result. Just return BASE otherwise.
+ TEMP is as for mips_force_temporary.
+
+ The returned expression can be used as the first operand to a LO_SUM. */
+
+static rtx
+mips_unspec_offset_high (rtx temp, rtx base, rtx addr,
+ enum mips_symbol_type symbol_type)
+{
+ if (mips_split_p[symbol_type])
+ {
+ addr = gen_rtx_HIGH (Pmode, mips_unspec_address (addr, symbol_type));
+ addr = mips_force_temporary (temp, addr);
+ base = mips_force_temporary (temp, gen_rtx_PLUS (Pmode, addr, base));
+ }
+ return base;
+}
+
/* 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. */
@@ -2358,51 +2403,6 @@ mips_split_symbol (rtx temp, rtx addr, enum machine_mode mode, rtx *lo_sum_out)
return true;
}
-/* Wrap symbol or label BASE in an UNSPEC address of type SYMBOL_TYPE,
- then add CONST_INT OFFSET to the result. */
-
-static rtx
-mips_unspec_address_offset (rtx base, rtx offset,
- enum mips_symbol_type symbol_type)
-{
- base = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, base),
- UNSPEC_ADDRESS_FIRST + symbol_type);
- if (offset != const0_rtx)
- base = gen_rtx_PLUS (Pmode, base, offset);
- return gen_rtx_CONST (Pmode, base);
-}
-
-/* Return an UNSPEC address with underlying address ADDRESS and symbol
- type SYMBOL_TYPE. */
-
-rtx
-mips_unspec_address (rtx address, enum mips_symbol_type symbol_type)
-{
- rtx base, offset;
-
- split_const (address, &base, &offset);
- return mips_unspec_address_offset (base, offset, symbol_type);
-}
-
-/* If mips_unspec_address (ADDR, SYMBOL_TYPE) is a 32-bit value, add the
- high part to BASE and return the result. Just return BASE otherwise.
- TEMP is as for mips_force_temporary.
-
- The returned expression can be used as the first operand to a LO_SUM. */
-
-static rtx
-mips_unspec_offset_high (rtx temp, rtx base, rtx addr,
- enum mips_symbol_type symbol_type)
-{
- if (mips_split_p[symbol_type])
- {
- addr = gen_rtx_HIGH (Pmode, mips_unspec_address (addr, symbol_type));
- addr = mips_force_temporary (temp, addr);
- base = mips_force_temporary (temp, gen_rtx_PLUS (Pmode, addr, base));
- }
- return base;
-}
-
/* Return a legitimate address for REG + OFFSET. TEMP is as for
mips_force_temporary; it is only needed when OFFSET is not a
SMALL_OPERAND. */
@@ -5208,6 +5208,49 @@ mips_end_function_definition (const char *name)
}
}
+/* Return true if calls to X can use R_MIPS_CALL* relocations. */
+
+static bool
+mips_ok_for_lazy_binding_p (rtx x)
+{
+ return (TARGET_USE_GOT
+ && GET_CODE (x) == SYMBOL_REF
+ && !mips_symbol_binds_local_p (x));
+}
+
+/* Load function address ADDR into register DEST. SIBCALL_P is true
+ if the address is needed for a sibling call. Return true if we
+ used an explicit lazy-binding sequence. */
+
+static bool
+mips_load_call_address (rtx dest, rtx addr, bool sibcall_p)
+{
+ /* If we're generating PIC, and this call is to a global function,
+ try to allow its address to be resolved lazily. This isn't
+ possible for sibcalls when $gp is call-saved because the value
+ of $gp on entry to the stub would be our caller's gp, not ours. */
+ if (TARGET_EXPLICIT_RELOCS
+ && !(sibcall_p && TARGET_CALL_SAVED_GP)
+ && mips_ok_for_lazy_binding_p (addr))
+ {
+ rtx high, lo_sum_symbol;
+
+ high = mips_unspec_offset_high (dest, pic_offset_table_rtx,
+ addr, SYMBOL_GOTOFF_CALL);
+ lo_sum_symbol = mips_unspec_address (addr, SYMBOL_GOTOFF_CALL);
+ if (Pmode == SImode)
+ emit_insn (gen_load_callsi (dest, high, lo_sum_symbol));
+ else
+ emit_insn (gen_load_calldi (dest, high, lo_sum_symbol));
+ return true;
+ }
+ else
+ {
+ mips_emit_move (dest, addr);
+ return false;
+ }
+}
+
/* A chained list of functions for which mips16_build_call_stub has already
generated a stub. NAME is the name of the function and FP_RET_P is true
if the function returns a value in floating-point registers. */
@@ -5668,49 +5711,6 @@ mips16_build_call_stub (rtx retval, rtx fn, rtx args_size, int fp_code)
return insn;
}
-/* Return true if calls to X can use R_MIPS_CALL* relocations. */
-
-static bool
-mips_ok_for_lazy_binding_p (rtx x)
-{
- return (TARGET_USE_GOT
- && GET_CODE (x) == SYMBOL_REF
- && !mips_symbol_binds_local_p (x));
-}
-
-/* Load function address ADDR into register DEST. SIBCALL_P is true
- if the address is needed for a sibling call. Return true if we
- used an explicit lazy-binding sequence. */
-
-static bool
-mips_load_call_address (rtx dest, rtx addr, bool sibcall_p)
-{
- /* If we're generating PIC, and this call is to a global function,
- try to allow its address to be resolved lazily. This isn't
- possible for sibcalls when $gp is call-saved because the value
- of $gp on entry to the stub would be our caller's gp, not ours. */
- if (TARGET_EXPLICIT_RELOCS
- && !(sibcall_p && TARGET_CALL_SAVED_GP)
- && mips_ok_for_lazy_binding_p (addr))
- {
- rtx high, lo_sum_symbol;
-
- high = mips_unspec_offset_high (dest, pic_offset_table_rtx,
- addr, SYMBOL_GOTOFF_CALL);
- lo_sum_symbol = mips_unspec_address (addr, SYMBOL_GOTOFF_CALL);
- if (Pmode == SImode)
- emit_insn (gen_load_callsi (dest, high, lo_sum_symbol));
- else
- emit_insn (gen_load_calldi (dest, high, lo_sum_symbol));
- return true;
- }
- else
- {
- mips_emit_move (dest, addr);
- return false;
- }
-}
-
/* Expand a "call", "sibcall", "call_value" or "sibcall_value" instruction.
RESULT is where the result will go (null for "call"s and "sibcall"s),
ADDR is the address of the function, ARGS_SIZE is the size of the
@@ -7884,6 +7884,19 @@ mips_function_has_gp_insn (void)
return cfun->machine->has_gp_insn_p;
}
+/* Return true if the current function returns its value in a floating-point
+ register in MIPS16 mode. */
+
+static bool
+mips16_cfun_returns_in_fpr_p (void)
+{
+ tree return_type = DECL_RESULT (current_function_decl);
+ return (TARGET_MIPS16
+ && TARGET_HARD_FLOAT_ABI
+ && !aggregate_value_p (return_type, current_function_decl)
+ && mips_return_mode_in_fpr_p (DECL_MODE (return_type)));
+}
+
/* Return the register that should be used as the global pointer
within this function. Return 0 if the function doesn't need
a global pointer. */
@@ -7942,19 +7955,6 @@ mips_global_pointer (void)
return GLOBAL_POINTER_REGNUM;
}
-/* Return true if the current function returns its value in a floating-point
- register in MIPS16 mode. */
-
-static bool
-mips16_cfun_returns_in_fpr_p (void)
-{
- tree return_type = DECL_RESULT (current_function_decl);
- return (TARGET_MIPS16
- && TARGET_HARD_FLOAT_ABI
- && !aggregate_value_p (return_type, current_function_decl)
- && mips_return_mode_in_fpr_p (DECL_MODE (return_type)));
-}
-
/* Return true if the current function must save register REGNO. */
static bool