patches/gcc/3.4.6/150-arm-ldm.patch
author "Benoît Thébaudeau" <benoit.thebaudeau@advansee.com>
Mon Apr 16 15:25:36 2012 +0200 (2012-04-16)
changeset 2941 13e40098fffc
parent 746 b150d6f590fc
permissions -rw-r--r--
cc/gcc: update Linaro GCC revisions to 2012.04

Update Linaro GCC with the latest available revisions.

The 4.7 revision is also released, but the infrastructure is not yet ready for
it in CT-NG.

Signed-off-by: "Benoît Thébaudeau" <benoit.thebaudeau@advansee.com>
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.  */