]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Apply patch from Phillip Blundel to use single STR/LDR when only loading
authornickc <nickc@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 9 Jan 2000 19:42:57 +0000 (19:42 +0000)
committernickc <nickc@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 9 Jan 2000 19:42:57 +0000 (19:42 +0000)
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
gcc/config/arm/arm.c
gcc/config/arm/arm.md

index 8d367154075505850bca238c89fb2789ef33344f..12c43c7c28933f6e4fbdb1ac7d90cae6b4c63773 100644 (file)
@@ -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
index 0b04a94ef32e8f93cc63a3e00c2613f36bf712f3..57cfff57d687ee1a28f91169fbda25c7c14a30f0 100644 (file)
@@ -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++;
index 6d760d53926ce66e4b49153c88c47533e401fd5c..ed49d701c18a10419ded8020c9e9af1672e967c4 100644 (file)
   ""
   "*
 {
-  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")])