From ed593f113065a503cf50f9ae324b0e36aaad3a37 Mon Sep 17 00:00:00 2001 From: nickc Date: Sun, 9 Jan 2000 19:42:57 +0000 Subject: [PATCH] Apply patch from Phillip Blundel to use single STR/LDR when only loading storing a single register in a function prologue/epilogue. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@31296 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 7 +++++++ gcc/config/arm/arm.c | 40 +++++++++++++++++++++++++++------------- gcc/config/arm/arm.md | 38 ++++++++++++++++++++++++++------------ 3 files changed, 60 insertions(+), 25 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 8d36715..12c43c7 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2000-01-09 Philip Blundell + + * 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 * config/ns32k/ns32k.md (load or push effective address): Operand 1 diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index 0b04a94..57cfff5 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -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++; diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md index 6d760d5..ed49d70 100644 --- a/gcc/config/arm/arm.md +++ b/gcc/config/arm/arm.md @@ -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")]) -- 2.7.4