patches/gcc/3.4.4/601-gcc34-arm-ldm.patch
changeset 1 eeea35fbf182
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/patches/gcc/3.4.4/601-gcc34-arm-ldm.patch	Sat Feb 24 11:00:05 2007 +0000
     1.3 @@ -0,0 +1,119 @@
     1.4 +--- gcc-3.4.0/gcc/config/arm/arm.c.arm-ldm	2004-02-27 09:51:05.000000000 -0500
     1.5 ++++ gcc-3.4.0/gcc/config/arm/arm.c	2004-04-24 18:16:25.000000000 -0400
     1.6 +@@ -8520,6 +8520,26 @@
     1.7 +   return_used_this_function = 0;  
     1.8 + }
     1.9 + 
    1.10 ++/* Return the number (counting from 0) of
    1.11 ++   the least significant set bit in MASK.  */
    1.12 ++
    1.13 ++#ifdef __GNUC__
    1.14 ++inline
    1.15 ++#endif
    1.16 ++static int
    1.17 ++number_of_first_bit_set (mask)
    1.18 ++     int mask;
    1.19 ++{
    1.20 ++  int bit;
    1.21 ++
    1.22 ++  for (bit = 0;
    1.23 ++       (mask & (1 << bit)) == 0;
    1.24 ++       ++bit)
    1.25 ++    continue;
    1.26 ++
    1.27 ++  return bit;
    1.28 ++}
    1.29 ++
    1.30 + const char *
    1.31 + arm_output_epilogue (rtx sibling)
    1.32 + {
    1.33 +@@ -8753,27 +8773,47 @@
    1.34 + 	  saved_regs_mask |=   (1 << PC_REGNUM);
    1.35 + 	}
    1.36 + 
    1.37 +-      /* Load the registers off the stack.  If we only have one register
    1.38 +-	 to load use the LDR instruction - it is faster.  */
    1.39 +-      if (saved_regs_mask == (1 << LR_REGNUM))
    1.40 +-	{
    1.41 +-	  /* The exception handler ignores the LR, so we do
    1.42 +-	     not really need to load it off the stack.  */
    1.43 +-	  if (eh_ofs)
    1.44 +-	    asm_fprintf (f, "\tadd\t%r, %r, #4\n", SP_REGNUM, SP_REGNUM);
    1.45 +-	  else
    1.46 +-	    asm_fprintf (f, "\tldr\t%r, [%r], #4\n", LR_REGNUM, SP_REGNUM);
    1.47 +-	}
    1.48 +-      else if (saved_regs_mask)
    1.49 ++      if (saved_regs_mask)
    1.50 + 	{
    1.51 +-	  if (saved_regs_mask & (1 << SP_REGNUM))
    1.52 +-	    /* Note - write back to the stack register is not enabled
    1.53 +-	       (ie "ldmfd sp!...").  We know that the stack pointer is
    1.54 +-	       in the list of registers and if we add writeback the
    1.55 +-	       instruction becomes UNPREDICTABLE.  */
    1.56 +-	    print_multi_reg (f, "ldmfd\t%r", SP_REGNUM, saved_regs_mask);
    1.57 ++	  /* Load the registers off the stack.  If we only have one register
    1.58 ++	     to load use the LDR instruction - it is faster.  */
    1.59 ++	  if (bit_count (saved_regs_mask) == 1)
    1.60 ++	    {
    1.61 ++	      int reg = number_of_first_bit_set (saved_regs_mask);
    1.62 ++
    1.63 ++	      switch (reg)
    1.64 ++		{
    1.65 ++		case SP_REGNUM:
    1.66 ++		  /* Mustn't use base writeback when loading SP.  */
    1.67 ++		  asm_fprintf (f, "\tldr\t%r, [%r]\n", SP_REGNUM, SP_REGNUM);
    1.68 ++		  break;
    1.69 ++		  
    1.70 ++		case LR_REGNUM:
    1.71 ++		  if (eh_ofs)
    1.72 ++		    {
    1.73 ++		      /* The exception handler ignores the LR, so we do
    1.74 ++			 not really need to load it off the stack.  */
    1.75 ++		      asm_fprintf (f, "\tadd\t%r, %r, #4\n", SP_REGNUM, SP_REGNUM);
    1.76 ++		      break;
    1.77 ++		    }
    1.78 ++		  /* else fall through */
    1.79 ++		  
    1.80 ++		default:
    1.81 ++		  asm_fprintf (f, "\tldr\t%r, [%r], #4\n", reg, SP_REGNUM);
    1.82 ++		  break;
    1.83 ++		}
    1.84 ++	    }
    1.85 + 	  else
    1.86 +-	    print_multi_reg (f, "ldmfd\t%r!", SP_REGNUM, saved_regs_mask);
    1.87 ++	    {
    1.88 ++	      if (saved_regs_mask & (1 << SP_REGNUM))
    1.89 ++		/* Note - write back to the stack register is not enabled
    1.90 ++		   (ie "ldmfd sp!...").  We know that the stack pointer is
    1.91 ++		   in the list of registers and if we add writeback the
    1.92 ++		   instruction becomes UNPREDICTABLE.  */
    1.93 ++		print_multi_reg (f, "ldmfd\t%r", SP_REGNUM, saved_regs_mask);
    1.94 ++	      else
    1.95 ++		print_multi_reg (f, "ldmfd\t%r!", SP_REGNUM, saved_regs_mask);
    1.96 ++	    }
    1.97 + 	}
    1.98 + 
    1.99 +       if (current_function_pretend_args_size)
   1.100 +@@ -11401,22 +11441,6 @@
   1.101 +     }
   1.102 + }
   1.103 + 
   1.104 +-/* Return the number (counting from 0) of
   1.105 +-   the least significant set bit in MASK.  */
   1.106 +-
   1.107 +-inline static int
   1.108 +-number_of_first_bit_set (int mask)
   1.109 +-{
   1.110 +-  int bit;
   1.111 +-
   1.112 +-  for (bit = 0;
   1.113 +-       (mask & (1 << bit)) == 0;
   1.114 +-       ++bit)
   1.115 +-    continue;
   1.116 +-
   1.117 +-  return bit;
   1.118 +-}
   1.119 +-
   1.120 + /* Generate code to return from a thumb function.
   1.121 +    If 'reg_containing_return_addr' is -1, then the return address is
   1.122 +    actually on the stack, at the stack pointer.  */