patches/gcc/3.4.6/150-arm-ldm.patch
author "Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
Tue Jan 12 19:24:03 2010 +0100 (2010-01-12)
changeset 1761 88020b2c3246
parent 746 b150d6f590fc
permissions -rw-r--r--
scripts/functions: change handling of nochdir

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