aboutsummaryrefslogtreecommitdiff
path: root/gcc/config
diff options
context:
space:
mode:
authorJeff Law <law@gcc.gnu.org>1997-07-11 09:48:51 -0600
committerJeff Law <law@gcc.gnu.org>1997-07-11 09:48:51 -0600
commit1f2d8f510f4e516803427373e1625991756d4d91 (patch)
tree5e01199fcba309c34ef4cc3157abf0ce7fb2e7c8 /gcc/config
parent7a49a4fd7b45ce1c15859f6bd4ee46418310d8f1 (diff)
downloadgcc-1f2d8f510f4e516803427373e1625991756d4d91.zip
gcc-1f2d8f510f4e516803427373e1625991756d4d91.tar.gz
gcc-1f2d8f510f4e516803427373e1625991756d4d91.tar.bz2
mips.c (epilogue_reg_mentioned_p): Delete unused function.
* mips.c (epilogue_reg_mentioned_p): Delete unused function. (mips_epilogue_delay_slots): Likewise. (function_epilogue): Greatly simplify. (mips_expand_epilogue): If we have a null prologue/epilogue, then use a normal return insn. Emit blockage insns before stack pointer adjustments. (mips_can_use_return_insn): Renamed from simple_epilogue_p. All callers changed. Do not use return insns if $31 is live in the function or if generating profiling information. * mips.h (DELAY_SLOTS_FOR_EPILOGUE): Delete. (ELIGIBLE_FOR_EPILOGUE_DELAY): Likewise. * mips.md (return): Remove expander and change the pattern to look like a standard "return" insn. (return_internal): Show use of $31 explictly. (epilogue expander): Enable. From-SVN: r14412
Diffstat (limited to 'gcc/config')
-rw-r--r--gcc/config/mips/mips.c282
-rw-r--r--gcc/config/mips/mips.h16
-rw-r--r--gcc/config/mips/mips.md68
3 files changed, 44 insertions, 322 deletions
diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c
index 584de95..7ebb508 100644
--- a/gcc/config/mips/mips.c
+++ b/gcc/config/mips/mips.c
@@ -4730,71 +4730,6 @@ mips_output_float (stream, value)
}
-/* Return TRUE if any register used in the epilogue is used. This to insure
- any insn put into the epilogue delay slots is safe. */
-
-int
-epilogue_reg_mentioned_p (insn)
- rtx insn;
-{
- register char *fmt;
- register int i;
- register enum rtx_code code;
- register int regno;
-
- if (insn == (rtx)0)
- return 0;
-
- if (GET_CODE (insn) == LABEL_REF)
- return 0;
-
- code = GET_CODE (insn);
- switch (code)
- {
- case REG:
- regno = REGNO (insn);
- if (regno == STACK_POINTER_REGNUM)
- return 1;
-
- if (regno == FRAME_POINTER_REGNUM && frame_pointer_needed)
- return 1;
-
- if (!call_used_regs[regno])
- return 1;
-
- if (regno != MIPS_TEMP1_REGNUM && regno != MIPS_TEMP2_REGNUM)
- return 0;
-
- if (!current_frame_info.initialized)
- compute_frame_size (get_frame_size ());
-
- return (current_frame_info.total_size >= 32768);
-
- case SCRATCH:
- case CC0:
- case PC:
- case CONST_INT:
- case CONST_DOUBLE:
- return 0;
- }
-
- fmt = GET_RTX_FORMAT (code);
- for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
- {
- if (fmt[i] == 'E')
- {
- register int j;
- for (j = XVECLEN (insn, i) - 1; j >= 0; j--)
- if (epilogue_reg_mentioned_p (XVECEXP (insn, i, j)))
- return 1;
- }
- else if (fmt[i] == 'e' && epilogue_reg_mentioned_p (XEXP (insn, i)))
- return 1;
- }
-
- return 0;
-}
-
/* Return the bytes needed to compute the frame pointer from the current
stack pointer.
@@ -5525,170 +5460,6 @@ function_epilogue (file, size)
int size;
{
char *fnname;
- long tsize;
- char *sp_str = reg_names[STACK_POINTER_REGNUM];
- char *t1_str = reg_names[MIPS_TEMP1_REGNUM];
- rtx epilogue_delay = current_function_epilogue_delay_list;
- int noreorder = (epilogue_delay != 0);
- int noepilogue = FALSE;
- int load_nop = FALSE;
- int load_only_r31;
- rtx tmp_rtx = (rtx)0;
- rtx restore_rtx;
- int i;
-
- /* The epilogue does not depend on any registers, but the stack
- registers, so we assume that if we have 1 pending nop, it can be
- ignored, and 2 it must be filled (2 nops occur for integer
- multiply and divide). */
-
- if (dslots_number_nops > 0)
- {
- if (dslots_number_nops == 1)
- {
- dslots_number_nops = 0;
- dslots_load_filled++;
- }
- else
- {
- while (--dslots_number_nops > 0)
- fputs ("\t#nop\n", asm_out_file);
- }
- }
-
- if (set_noat != 0)
- {
- set_noat = 0;
- fputs ("\t.set\tat\n", file);
- error ("internal gcc error: .set noat left on in epilogue");
- }
-
- if (set_nomacro != 0)
- {
- set_nomacro = 0;
- fputs ("\t.set\tmacro\n", file);
- error ("internal gcc error: .set nomacro left on in epilogue");
- }
-
- if (set_noreorder != 0)
- {
- set_noreorder = 0;
- fputs ("\t.set\treorder\n", file);
- error ("internal gcc error: .set noreorder left on in epilogue");
- }
-
- if (set_volatile != 0)
- {
- set_volatile = 0;
- fprintf (file, "\t%s.set\tnovolatile\n", (TARGET_MIPS_AS) ? "" : "#");
- error ("internal gcc error: .set volatile left on in epilogue");
- }
-
- size = MIPS_STACK_ALIGN (size);
- tsize = (!current_frame_info.initialized)
- ? compute_frame_size (size)
- : current_frame_info.total_size;
-
- if (tsize == 0 && epilogue_delay == 0)
- {
- rtx insn = get_last_insn ();
-
- /* If the last insn was a BARRIER, we don't have to write any code
- because a jump (aka return) was put there. */
- if (GET_CODE (insn) == NOTE)
- insn = prev_nonnote_insn (insn);
- if (insn && GET_CODE (insn) == BARRIER)
- noepilogue = TRUE;
-
- noreorder = FALSE;
- }
-
- if (!noepilogue)
- {
- /* In the reload sequence, we don't need to fill the load delay
- slots for most of the loads, also see if we can fill the final
- delay slot if not otherwise filled by the reload sequence. */
-
- if (noreorder)
- fprintf (file, "\t.set\tnoreorder\n");
-
- if (tsize > 32767)
- {
- fprintf (file, "\tli\t%s,0x%.08lx\t# %ld\n", t1_str, (long)tsize, (long)tsize);
- tmp_rtx = gen_rtx (REG, Pmode, MIPS_TEMP1_REGNUM);
- }
-
- if (frame_pointer_needed)
- fprintf (file, "\tmove\t%s,%s\t\t\t# sp not trusted here\n",
- sp_str, reg_names[FRAME_POINTER_REGNUM]);
-
- save_restore_insns (FALSE, tmp_rtx, tsize, file);
-
- load_only_r31 = (((current_frame_info.mask
- & ~ (TARGET_ABICALLS && mips_abi == ABI_32
- ? PIC_OFFSET_TABLE_MASK : 0))
- == RA_MASK)
- && current_frame_info.fmask == 0);
-
- if (noreorder)
- {
- /* If the only register saved is the return address, we need a
- nop, unless we have an instruction to put into it. Otherwise
- we don't since reloading multiple registers doesn't reference
- the register being loaded. */
-
- if (load_only_r31)
- {
- if (epilogue_delay)
- final_scan_insn (XEXP (epilogue_delay, 0),
- file,
- 1, /* optimize */
- -2, /* prescan */
- 1); /* nopeepholes */
- else
- {
- fprintf (file, "\tnop\n");
- load_nop = TRUE;
- }
- }
-
- fprintf (file, "\tj\t%s\n", reg_names[GP_REG_FIRST + 31]);
-
- if (tsize > 32767)
- fprintf (file, "\t%s\t%s,%s,%s\n",
- TARGET_LONG64 ? "daddu" : "addu",
- sp_str, sp_str, t1_str);
-
- else if (tsize > 0)
- fprintf (file, "\t%s\t%s,%s,%d\n",
- TARGET_LONG64 ? "daddu" : "addu",
- sp_str, sp_str, tsize);
-
- else if (!load_only_r31 && epilogue_delay != 0)
- final_scan_insn (XEXP (epilogue_delay, 0),
- file,
- 1, /* optimize */
- -2, /* prescan */
- 1); /* nopeepholes */
-
- fprintf (file, "\t.set\treorder\n");
- }
-
- else
- {
- if (tsize > 32767)
- fprintf (file, "\t%s\t%s,%s,%s\n",
- TARGET_LONG64 ? "daddu" : "addu",
- sp_str, sp_str, t1_str);
-
- else if (tsize > 0)
- fprintf (file, "\t%s\t%s,%s,%d\n",
- TARGET_LONG64 ? "daddu" : "addu",
- sp_str, sp_str, tsize);
-
- fprintf (file, "\tj\t%s\n", reg_names[GP_REG_FIRST + 31]);
- }
- }
#ifndef FUNCTION_NAME_ALREADY_DECLARED
/* Get the function name the same way that toplev.c does before calling
@@ -5713,23 +5484,6 @@ function_epilogue (file, size)
dslots_load_total += num_regs;
- if (!noepilogue)
- dslots_jump_total++;
-
- if (noreorder)
- {
- dslots_load_filled += num_regs;
-
- /* If the only register saved is the return register, we
- can't fill this register's delay slot. */
-
- if (load_only_r31 && epilogue_delay == 0)
- dslots_load_filled--;
-
- if (tsize > 0 || (!load_only_r31 && epilogue_delay != 0))
- dslots_jump_filled++;
- }
-
fprintf (stderr,
"%-20s fp=%c leaf=%c alloca=%c setjmp=%c stack=%4ld arg=%3ld reg=%2d/%d delay=%3d/%3dL %3d/%3dJ refs=%3d/%3d/%3d",
name,
@@ -5791,6 +5545,12 @@ mips_expand_epilogue ()
rtx tsize_rtx = GEN_INT (tsize);
rtx tmp_rtx = (rtx)0;
+ if (mips_can_use_return_insn ())
+ {
+ emit_insn (gen_return ());
+ return;
+ }
+
if (tsize > 32767)
{
tmp_rtx = gen_rtx (REG, Pmode, MIPS_TEMP1_REGNUM);
@@ -5802,6 +5562,7 @@ mips_expand_epilogue ()
{
if (frame_pointer_needed)
{
+ emit_insn (gen_blockage ());
if (TARGET_LONG64)
emit_insn (gen_movdi (stack_pointer_rtx, frame_pointer_rtx));
else
@@ -5810,6 +5571,7 @@ mips_expand_epilogue ()
save_restore_insns (FALSE, tmp_rtx, tsize, (FILE *)0);
+ emit_insn (gen_blockage ());
if (TARGET_LONG64)
emit_insn (gen_adddi3 (stack_pointer_rtx, stack_pointer_rtx,
tsize_rtx));
@@ -5818,28 +5580,7 @@ mips_expand_epilogue ()
tsize_rtx));
}
- emit_jump_insn (gen_return_internal (gen_rtx (REG, Pmode, GP_REG_FIRST+31)));
-}
-
-
-/* Define the number of delay slots needed for the function epilogue.
-
- On the mips, we need a slot if either no stack has been allocated,
- or the only register saved is the return register. */
-
-int
-mips_epilogue_delay_slots ()
-{
- if (!current_frame_info.initialized)
- (void) compute_frame_size (get_frame_size ());
-
- if (current_frame_info.total_size == 0)
- return 1;
-
- if (current_frame_info.mask == RA_MASK && current_frame_info.fmask == 0)
- return 1;
-
- return 0;
+ emit_jump_insn (gen_return_internal ());
}
@@ -5848,11 +5589,14 @@ mips_epilogue_delay_slots ()
was created. */
int
-simple_epilogue_p ()
+mips_can_use_return_insn ()
{
if (!reload_completed)
return 0;
+ if (regs_ever_live[31] || profile_flag)
+ return 0;
+
if (current_frame_info.initialized)
return current_frame_info.total_size == 0;
diff --git a/gcc/config/mips/mips.h b/gcc/config/mips/mips.h
index 6aa3402..74068d4 100644
--- a/gcc/config/mips/mips.h
+++ b/gcc/config/mips/mips.h
@@ -2241,22 +2241,6 @@ typedef struct mips_args {
#define FUNCTION_EPILOGUE(FILE, SIZE) function_epilogue(FILE, SIZE)
-/* Define the number of delay slots needed for the function epilogue.
-
- On the mips, we need a slot if either no stack has been allocated,
- or the only register saved is the return register. */
-
-#define DELAY_SLOTS_FOR_EPILOGUE mips_epilogue_delay_slots ()
-
-/* Define whether INSN can be placed in delay slot N for the epilogue.
- No references to the stack must be made, since on the MIPS, the
- delay slot is done after the stack has been cleaned up. */
-
-#define ELIGIBLE_FOR_EPILOGUE_DELAY(INSN,N) \
- (get_attr_dslot (INSN) == DSLOT_NO \
- && get_attr_length (INSN) == 1 \
- && ! epilogue_reg_mentioned_p (PATTERN (INSN)))
-
/* Tell prologue and epilogue if register REGNO should be saved / restored. */
#define MUST_SAVE_REGISTER(regno) \
diff --git a/gcc/config/mips/mips.md b/gcc/config/mips/mips.md
index 36f9791..770a91c 100644
--- a/gcc/config/mips/mips.md
+++ b/gcc/config/mips/mips.md
@@ -6315,29 +6315,6 @@ move\\t%0,%z4\\n\\
(set_attr "mode" "none")
(set_attr "length" "1")])
-;; Function return, only allow after optimization, so that we can
-;; eliminate jumps to jumps if no stack space is used.
-
-;; (define_expand "return"
-;; [(set (pc) (reg:SI 31))]
-;; "simple_epilogue_p ()"
-;; "")
-
-(define_expand "return"
- [(parallel [(return)
- (use (reg:SI 31))])]
- "simple_epilogue_p ()"
- "")
-
-(define_insn "return_internal"
- [(parallel [(return)
- (use (match_operand:SI 0 "register_operand" "d"))])]
- ""
- "%*j\\t%0"
- [(set_attr "type" "jump")
- (set_attr "mode" "none")
- (set_attr "length" "1")])
-
;; Implement a switch statement when generating embedded PIC code.
;; Switches are implemented by `tablejump' when not using -membedded-pic.
@@ -6448,21 +6425,38 @@ move\\t%0,%z4\\n\\
(set_attr "mode" "none")
(set_attr "length" "0")])
-;; At present, don't expand the epilogue, reorg.c will clobber the
-;; return register in compiling gen_lowpart (emit-rtl.c).
-;;
-;; (define_expand "epilogue"
-;; [(const_int 2)]
-;; ""
-;; "
-;; {
-;; if (mips_isa >= 0) /* avoid unused code warnings */
-;; {
-;; mips_expand_epilogue ();
-;; DONE;
-;; }
-;; }")
+(define_expand "epilogue"
+ [(const_int 2)]
+ ""
+ "
+{
+ if (mips_isa >= 0) /* avoid unused code warnings */
+ {
+ mips_expand_epilogue ();
+ DONE;
+ }
+}")
+;; Trivial return. Make it look like a normal return insn as that
+;; allows jump optimizations to work better .
+(define_insn "return"
+ [(return)]
+ "mips_can_use_return_insn ()"
+ "%*j\\t$31"
+ [(set_attr "type" "jump")
+ (set_attr "mode" "none")
+ (set_attr "length" "1")])
+
+;; Normal return.
+(define_insn "return_internal"
+ [(use (reg:SI 31))
+ (return)]
+ ""
+ "%*j\\t$31"
+ [(set_attr "type" "jump")
+ (set_attr "mode" "none")
+ (set_attr "length" "1")])
+
;; When generating embedded PIC code we need to get the address of the
;; current function. This specialized instruction does just that.