patches/gcc/3.4.4/601-gcc34-arm-ldm.patch
author "Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
Sat Jul 28 21:34:41 2007 +0000 (2007-07-28)
changeset 301 2be7232a73ac
permissions -rw-r--r--
Bump version to 0.2.2.
yann@1
     1
--- gcc-3.4.0/gcc/config/arm/arm.c.arm-ldm	2004-02-27 09:51:05.000000000 -0500
yann@1
     2
+++ gcc-3.4.0/gcc/config/arm/arm.c	2004-04-24 18:16:25.000000000 -0400
yann@1
     3
@@ -8520,6 +8520,26 @@
yann@1
     4
   return_used_this_function = 0;  
yann@1
     5
 }
yann@1
     6
 
yann@1
     7
+/* Return the number (counting from 0) of
yann@1
     8
+   the least significant set bit in MASK.  */
yann@1
     9
+
yann@1
    10
+#ifdef __GNUC__
yann@1
    11
+inline
yann@1
    12
+#endif
yann@1
    13
+static int
yann@1
    14
+number_of_first_bit_set (mask)
yann@1
    15
+     int mask;
yann@1
    16
+{
yann@1
    17
+  int bit;
yann@1
    18
+
yann@1
    19
+  for (bit = 0;
yann@1
    20
+       (mask & (1 << bit)) == 0;
yann@1
    21
+       ++bit)
yann@1
    22
+    continue;
yann@1
    23
+
yann@1
    24
+  return bit;
yann@1
    25
+}
yann@1
    26
+
yann@1
    27
 const char *
yann@1
    28
 arm_output_epilogue (rtx sibling)
yann@1
    29
 {
yann@1
    30
@@ -8753,27 +8773,47 @@
yann@1
    31
 	  saved_regs_mask |=   (1 << PC_REGNUM);
yann@1
    32
 	}
yann@1
    33
 
yann@1
    34
-      /* Load the registers off the stack.  If we only have one register
yann@1
    35
-	 to load use the LDR instruction - it is faster.  */
yann@1
    36
-      if (saved_regs_mask == (1 << LR_REGNUM))
yann@1
    37
-	{
yann@1
    38
-	  /* The exception handler ignores the LR, so we do
yann@1
    39
-	     not really need to load it off the stack.  */
yann@1
    40
-	  if (eh_ofs)
yann@1
    41
-	    asm_fprintf (f, "\tadd\t%r, %r, #4\n", SP_REGNUM, SP_REGNUM);
yann@1
    42
-	  else
yann@1
    43
-	    asm_fprintf (f, "\tldr\t%r, [%r], #4\n", LR_REGNUM, SP_REGNUM);
yann@1
    44
-	}
yann@1
    45
-      else if (saved_regs_mask)
yann@1
    46
+      if (saved_regs_mask)
yann@1
    47
 	{
yann@1
    48
-	  if (saved_regs_mask & (1 << SP_REGNUM))
yann@1
    49
-	    /* Note - write back to the stack register is not enabled
yann@1
    50
-	       (ie "ldmfd sp!...").  We know that the stack pointer is
yann@1
    51
-	       in the list of registers and if we add writeback the
yann@1
    52
-	       instruction becomes UNPREDICTABLE.  */
yann@1
    53
-	    print_multi_reg (f, "ldmfd\t%r", SP_REGNUM, saved_regs_mask);
yann@1
    54
+	  /* Load the registers off the stack.  If we only have one register
yann@1
    55
+	     to load use the LDR instruction - it is faster.  */
yann@1
    56
+	  if (bit_count (saved_regs_mask) == 1)
yann@1
    57
+	    {
yann@1
    58
+	      int reg = number_of_first_bit_set (saved_regs_mask);
yann@1
    59
+
yann@1
    60
+	      switch (reg)
yann@1
    61
+		{
yann@1
    62
+		case SP_REGNUM:
yann@1
    63
+		  /* Mustn't use base writeback when loading SP.  */
yann@1
    64
+		  asm_fprintf (f, "\tldr\t%r, [%r]\n", SP_REGNUM, SP_REGNUM);
yann@1
    65
+		  break;
yann@1
    66
+		  
yann@1
    67
+		case LR_REGNUM:
yann@1
    68
+		  if (eh_ofs)
yann@1
    69
+		    {
yann@1
    70
+		      /* The exception handler ignores the LR, so we do
yann@1
    71
+			 not really need to load it off the stack.  */
yann@1
    72
+		      asm_fprintf (f, "\tadd\t%r, %r, #4\n", SP_REGNUM, SP_REGNUM);
yann@1
    73
+		      break;
yann@1
    74
+		    }
yann@1
    75
+		  /* else fall through */
yann@1
    76
+		  
yann@1
    77
+		default:
yann@1
    78
+		  asm_fprintf (f, "\tldr\t%r, [%r], #4\n", reg, SP_REGNUM);
yann@1
    79
+		  break;
yann@1
    80
+		}
yann@1
    81
+	    }
yann@1
    82
 	  else
yann@1
    83
-	    print_multi_reg (f, "ldmfd\t%r!", SP_REGNUM, saved_regs_mask);
yann@1
    84
+	    {
yann@1
    85
+	      if (saved_regs_mask & (1 << SP_REGNUM))
yann@1
    86
+		/* Note - write back to the stack register is not enabled
yann@1
    87
+		   (ie "ldmfd sp!...").  We know that the stack pointer is
yann@1
    88
+		   in the list of registers and if we add writeback the
yann@1
    89
+		   instruction becomes UNPREDICTABLE.  */
yann@1
    90
+		print_multi_reg (f, "ldmfd\t%r", SP_REGNUM, saved_regs_mask);
yann@1
    91
+	      else
yann@1
    92
+		print_multi_reg (f, "ldmfd\t%r!", SP_REGNUM, saved_regs_mask);
yann@1
    93
+	    }
yann@1
    94
 	}
yann@1
    95
 
yann@1
    96
       if (current_function_pretend_args_size)
yann@1
    97
@@ -11401,22 +11441,6 @@
yann@1
    98
     }
yann@1
    99
 }
yann@1
   100
 
yann@1
   101
-/* Return the number (counting from 0) of
yann@1
   102
-   the least significant set bit in MASK.  */
yann@1
   103
-
yann@1
   104
-inline static int
yann@1
   105
-number_of_first_bit_set (int mask)
yann@1
   106
-{
yann@1
   107
-  int bit;
yann@1
   108
-
yann@1
   109
-  for (bit = 0;
yann@1
   110
-       (mask & (1 << bit)) == 0;
yann@1
   111
-       ++bit)
yann@1
   112
-    continue;
yann@1
   113
-
yann@1
   114
-  return bit;
yann@1
   115
-}
yann@1
   116
-
yann@1
   117
 /* Generate code to return from a thumb function.
yann@1
   118
    If 'reg_containing_return_addr' is -1, then the return address is
yann@1
   119
    actually on the stack, at the stack pointer.  */