Apply patch from Phillip Blundel to use single STR/LDR when...
Apply patch from Phillip Blundel to use single STR/LDR when only loading storing a single register in a function prologue/epilogue. From-SVN: r31296
This commit is contained in:
parent
9a29c058e7
commit
3a5a428223
|
@ -1,3 +1,10 @@
|
|||
2000-01-09 Philip Blundell <philb@gnu.org>
|
||||
|
||||
* config/arm/arm.c (output_return_instruction): Use `ldr' rather
|
||||
than `ldm' with only one register.
|
||||
* config/arm/arm.md (push_multi): Use `str' rather than `stm' with
|
||||
only one register.
|
||||
|
||||
Sun Jan 9 17:50:23 2000 Hans-Peter Nilsson <hp@axis.com>
|
||||
|
||||
* config/ns32k/ns32k.md (load or push effective address): Operand 1
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* Output routines for GCC for ARM.
|
||||
Copyright (C) 1991, 93-98, 1999 Free Software Foundation, Inc.
|
||||
Copyright (C) 1991, 93-99, 2000 Free Software Foundation, Inc.
|
||||
Contributed by Pieter `Tiggr' Schoenmakers (rcpieter@win.tue.nl)
|
||||
and Martin Simmons (@harleqn.co.uk).
|
||||
More major hacks by Richard Earnshaw (rearnsha@arm.com).
|
||||
|
@ -5477,18 +5477,20 @@ output_return_instruction (operand, really_return, reverse)
|
|||
|
||||
if (TARGET_ABORT_NORETURN && volatile_func)
|
||||
{
|
||||
rtx ops[2];
|
||||
/* If this function was declared non-returning, and we have found a tail
|
||||
call, then we have to trust that the called function won't return. */
|
||||
if (! really_return)
|
||||
return "";
|
||||
|
||||
/* Otherwise, trap an attempted return by aborting. */
|
||||
ops[0] = operand;
|
||||
ops[1] = gen_rtx_SYMBOL_REF (Pmode, NEED_PLT_RELOC ? "abort(PLT)"
|
||||
: "abort");
|
||||
assemble_external_libcall (ops[1]);
|
||||
output_asm_insn (reverse ? "bl%D0\t%a1" : "bl%d0\t%a1", ops);
|
||||
call, then we have to trust that the called function won't return. */
|
||||
if (really_return)
|
||||
{
|
||||
rtx ops[2];
|
||||
|
||||
/* Otherwise, trap an attempted return by aborting. */
|
||||
ops[0] = operand;
|
||||
ops[1] = gen_rtx_SYMBOL_REF (Pmode, NEED_PLT_RELOC ? "abort(PLT)"
|
||||
: "abort");
|
||||
assemble_external_libcall (ops[1]);
|
||||
output_asm_insn (reverse ? "bl%D0\t%a1" : "bl%d0\t%a1", ops);
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
|
@ -5509,7 +5511,19 @@ output_return_instruction (operand, really_return, reverse)
|
|||
if (frame_pointer_needed)
|
||||
live_regs += 4;
|
||||
|
||||
if (live_regs)
|
||||
/* On some ARM architectures it is faster to use LDR rather than LDM to
|
||||
load a single register. On other architectures, the cost is the same. */
|
||||
if (live_regs == 1
|
||||
&& regs_ever_live[LR_REGNUM]
|
||||
&& ! lr_save_eliminated
|
||||
/* FIXME: We ought to handle the case TARGET_APCS_32 is true,
|
||||
really_return is true, and only the PC needs restoring. */
|
||||
&& ! really_return)
|
||||
{
|
||||
output_asm_insn (reverse ? "ldr%?%D0\t%|lr, [%|sp], #4"
|
||||
: "ldr%?%d0\t%|lr, [%|sp], #4", &operand);
|
||||
}
|
||||
else if (live_regs)
|
||||
{
|
||||
if (lr_save_eliminated || ! regs_ever_live[LR_REGNUM])
|
||||
live_regs++;
|
||||
|
|
|
@ -6534,25 +6534,39 @@
|
|||
""
|
||||
"*
|
||||
{
|
||||
char pattern[100];
|
||||
int i;
|
||||
extern int lr_save_eliminated;
|
||||
|
||||
if (lr_save_eliminated)
|
||||
int num_saves = XVECLEN (operands[2], 0);
|
||||
|
||||
if (lr_save_eliminated)
|
||||
{
|
||||
if (XVECLEN (operands[2], 0) > 1)
|
||||
if (num_saves > 1)
|
||||
abort ();
|
||||
return \"\";
|
||||
}
|
||||
strcpy (pattern, \"stmfd\\t%m0!, {%1\");
|
||||
for (i = 1; i < XVECLEN (operands[2], 0); i++)
|
||||
/* For the StrongARM at least it is faster to
|
||||
use STR to store only a single register. */
|
||||
else if (num_saves == 1)
|
||||
output_asm_insn (\"str\\t%1, [%m0, #-4]!\", operands);
|
||||
else
|
||||
{
|
||||
strcat (pattern, \", %|\");
|
||||
strcat (pattern, reg_names[REGNO (XEXP (XVECEXP (operands[2], 0, i),
|
||||
int i;
|
||||
char pattern[100];
|
||||
|
||||
if (lr_save_eliminated)
|
||||
abort ();
|
||||
|
||||
strcpy (pattern, \"stmfd\\t%m0!, {%1\");
|
||||
|
||||
for (i = 1; i < num_saves; i++)
|
||||
{
|
||||
strcat (pattern, \", %|\");
|
||||
strcat (pattern, reg_names[REGNO (XEXP (XVECEXP (operands[2], 0, i),
|
||||
0))]);
|
||||
}
|
||||
|
||||
strcat (pattern, \"}\");
|
||||
output_asm_insn (pattern, operands);
|
||||
}
|
||||
strcat (pattern, \"}\");
|
||||
output_asm_insn (pattern, operands);
|
||||
|
||||
return \"\";
|
||||
}"
|
||||
[(set_attr "type" "store4")])
|
||||
|
|
Loading…
Reference in New Issue