Commit 3a5a4282 by Philip Blundell Committed by Nick Clifton

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
parent 9a29c058
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> Sun Jan 9 17:50:23 2000 Hans-Peter Nilsson <hp@axis.com>
* config/ns32k/ns32k.md (load or push effective address): Operand 1 * config/ns32k/ns32k.md (load or push effective address): Operand 1
......
/* Output routines for GCC for ARM. /* 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) Contributed by Pieter `Tiggr' Schoenmakers (rcpieter@win.tue.nl)
and Martin Simmons (@harleqn.co.uk). and Martin Simmons (@harleqn.co.uk).
More major hacks by Richard Earnshaw (rearnsha@arm.com). More major hacks by Richard Earnshaw (rearnsha@arm.com).
...@@ -5477,18 +5477,20 @@ output_return_instruction (operand, really_return, reverse) ...@@ -5477,18 +5477,20 @@ output_return_instruction (operand, really_return, reverse)
if (TARGET_ABORT_NORETURN && volatile_func) if (TARGET_ABORT_NORETURN && volatile_func)
{ {
rtx ops[2];
/* If this function was declared non-returning, and we have found a tail /* 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. */ call, then we have to trust that the called function won't return. */
if (! really_return) if (really_return)
return ""; {
rtx ops[2];
/* Otherwise, trap an attempted return by aborting. */
ops[0] = operand; /* Otherwise, trap an attempted return by aborting. */
ops[1] = gen_rtx_SYMBOL_REF (Pmode, NEED_PLT_RELOC ? "abort(PLT)" ops[0] = operand;
: "abort"); ops[1] = gen_rtx_SYMBOL_REF (Pmode, NEED_PLT_RELOC ? "abort(PLT)"
assemble_external_libcall (ops[1]); : "abort");
output_asm_insn (reverse ? "bl%D0\t%a1" : "bl%d0\t%a1", ops); assemble_external_libcall (ops[1]);
output_asm_insn (reverse ? "bl%D0\t%a1" : "bl%d0\t%a1", ops);
}
return ""; return "";
} }
...@@ -5509,7 +5511,19 @@ output_return_instruction (operand, really_return, reverse) ...@@ -5509,7 +5511,19 @@ output_return_instruction (operand, really_return, reverse)
if (frame_pointer_needed) if (frame_pointer_needed)
live_regs += 4; 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]) if (lr_save_eliminated || ! regs_ever_live[LR_REGNUM])
live_regs++; live_regs++;
......
...@@ -6534,25 +6534,39 @@ ...@@ -6534,25 +6534,39 @@
"" ""
"* "*
{ {
char pattern[100];
int i;
extern int lr_save_eliminated; extern int lr_save_eliminated;
int num_saves = XVECLEN (operands[2], 0);
if (lr_save_eliminated)
if (lr_save_eliminated)
{ {
if (XVECLEN (operands[2], 0) > 1) if (num_saves > 1)
abort (); abort ();
return \"\";
} }
strcpy (pattern, \"stmfd\\t%m0!, {%1\"); /* For the StrongARM at least it is faster to
for (i = 1; i < XVECLEN (operands[2], 0); i++) 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, \", %|\"); int i;
strcat (pattern, reg_names[REGNO (XEXP (XVECEXP (operands[2], 0, 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))]); 0))]);
}
strcat (pattern, \"}\");
output_asm_insn (pattern, operands);
} }
strcat (pattern, \"}\");
output_asm_insn (pattern, operands);
return \"\"; return \"\";
}" }"
[(set_attr "type" "store4")]) [(set_attr "type" "store4")])
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment