120 lines
		
	
	
		
			3.3 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
			
		
		
	
	
			120 lines
		
	
	
		
			3.3 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
| --- gcc-3.4.0/gcc/config/arm/arm.c.arm-ldm	2004-02-27 09:51:05.000000000 -0500
 | |
| +++ gcc-3.4.0/gcc/config/arm/arm.c	2004-04-24 18:16:25.000000000 -0400
 | |
| @@ -8520,6 +8520,26 @@
 | |
|    return_used_this_function = 0;  
 | |
|  }
 | |
|  
 | |
| +/* Return the number (counting from 0) of
 | |
| +   the least significant set bit in MASK.  */
 | |
| +
 | |
| +#ifdef __GNUC__
 | |
| +inline
 | |
| +#endif
 | |
| +static int
 | |
| +number_of_first_bit_set (mask)
 | |
| +     int mask;
 | |
| +{
 | |
| +  int bit;
 | |
| +
 | |
| +  for (bit = 0;
 | |
| +       (mask & (1 << bit)) == 0;
 | |
| +       ++bit)
 | |
| +    continue;
 | |
| +
 | |
| +  return bit;
 | |
| +}
 | |
| +
 | |
|  const char *
 | |
|  arm_output_epilogue (rtx sibling)
 | |
|  {
 | |
| @@ -8753,27 +8773,47 @@
 | |
|  	  saved_regs_mask |=   (1 << PC_REGNUM);
 | |
|  	}
 | |
|  
 | |
| -      /* Load the registers off the stack.  If we only have one register
 | |
| -	 to load use the LDR instruction - it is faster.  */
 | |
| -      if (saved_regs_mask == (1 << LR_REGNUM))
 | |
| -	{
 | |
| -	  /* The exception handler ignores the LR, so we do
 | |
| -	     not really need to load it off the stack.  */
 | |
| -	  if (eh_ofs)
 | |
| -	    asm_fprintf (f, "\tadd\t%r, %r, #4\n", SP_REGNUM, SP_REGNUM);
 | |
| -	  else
 | |
| -	    asm_fprintf (f, "\tldr\t%r, [%r], #4\n", LR_REGNUM, SP_REGNUM);
 | |
| -	}
 | |
| -      else if (saved_regs_mask)
 | |
| +      if (saved_regs_mask)
 | |
|  	{
 | |
| -	  if (saved_regs_mask & (1 << SP_REGNUM))
 | |
| -	    /* Note - write back to the stack register is not enabled
 | |
| -	       (ie "ldmfd sp!...").  We know that the stack pointer is
 | |
| -	       in the list of registers and if we add writeback the
 | |
| -	       instruction becomes UNPREDICTABLE.  */
 | |
| -	    print_multi_reg (f, "ldmfd\t%r", SP_REGNUM, saved_regs_mask);
 | |
| +	  /* Load the registers off the stack.  If we only have one register
 | |
| +	     to load use the LDR instruction - it is faster.  */
 | |
| +	  if (bit_count (saved_regs_mask) == 1)
 | |
| +	    {
 | |
| +	      int reg = number_of_first_bit_set (saved_regs_mask);
 | |
| +
 | |
| +	      switch (reg)
 | |
| +		{
 | |
| +		case SP_REGNUM:
 | |
| +		  /* Mustn't use base writeback when loading SP.  */
 | |
| +		  asm_fprintf (f, "\tldr\t%r, [%r]\n", SP_REGNUM, SP_REGNUM);
 | |
| +		  break;
 | |
| +		  
 | |
| +		case LR_REGNUM:
 | |
| +		  if (eh_ofs)
 | |
| +		    {
 | |
| +		      /* The exception handler ignores the LR, so we do
 | |
| +			 not really need to load it off the stack.  */
 | |
| +		      asm_fprintf (f, "\tadd\t%r, %r, #4\n", SP_REGNUM, SP_REGNUM);
 | |
| +		      break;
 | |
| +		    }
 | |
| +		  /* else fall through */
 | |
| +		  
 | |
| +		default:
 | |
| +		  asm_fprintf (f, "\tldr\t%r, [%r], #4\n", reg, SP_REGNUM);
 | |
| +		  break;
 | |
| +		}
 | |
| +	    }
 | |
|  	  else
 | |
| -	    print_multi_reg (f, "ldmfd\t%r!", SP_REGNUM, saved_regs_mask);
 | |
| +	    {
 | |
| +	      if (saved_regs_mask & (1 << SP_REGNUM))
 | |
| +		/* Note - write back to the stack register is not enabled
 | |
| +		   (ie "ldmfd sp!...").  We know that the stack pointer is
 | |
| +		   in the list of registers and if we add writeback the
 | |
| +		   instruction becomes UNPREDICTABLE.  */
 | |
| +		print_multi_reg (f, "ldmfd\t%r", SP_REGNUM, saved_regs_mask);
 | |
| +	      else
 | |
| +		print_multi_reg (f, "ldmfd\t%r!", SP_REGNUM, saved_regs_mask);
 | |
| +	    }
 | |
|  	}
 | |
|  
 | |
|        if (current_function_pretend_args_size)
 | |
| @@ -11401,22 +11441,6 @@
 | |
|      }
 | |
|  }
 | |
|  
 | |
| -/* Return the number (counting from 0) of
 | |
| -   the least significant set bit in MASK.  */
 | |
| -
 | |
| -inline static int
 | |
| -number_of_first_bit_set (int mask)
 | |
| -{
 | |
| -  int bit;
 | |
| -
 | |
| -  for (bit = 0;
 | |
| -       (mask & (1 << bit)) == 0;
 | |
| -       ++bit)
 | |
| -    continue;
 | |
| -
 | |
| -  return bit;
 | |
| -}
 | |
| -
 | |
|  /* Generate code to return from a thumb function.
 | |
|     If 'reg_containing_return_addr' is -1, then the return address is
 | |
|     actually on the stack, at the stack pointer.  */
 |