This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH ARM] Add new immediates heuristic


This patch adds a new heuristic for synthesizing immediate values on ARM 
for cases that can be expressed as the difference of two valid immediates. 
 In some cases this can be significantly better than the old code.  For 
example, for the value

	0x77fbf

we previously needed 4 instructions to create this value without using a 
literal pool[1], but we can now create it as

	491520 - 65

Bootstrapped & tested on arm-netbsdelf and also by compiling test cases 
for every interesting difference of two ARM immediate values (this 
represents about 0.1% of all litteral values and for about 60% of these 
cases we previously generated a non-optimal solution).

2005-05-04  Richard Earnshaw  <richard.earnshaw@arm.com>

	* arm.c (arm_gen_constant): Add new heuristic for generating
	constant integers that can be expressed as the difference of two
	valid immediates.


R.

[1] In fact, it can be generated in three instructions, but the existing 
code failed to find that solution.
Index: config/arm/arm.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/arm/arm.c,v
retrieving revision 1.450
diff -p -p -r1.450 arm.c
*** config/arm/arm.c	29 Apr 2005 14:09:39 -0000	1.450
--- config/arm/arm.c	4 May 2005 22:48:03 -0000
*************** arm_gen_constant (enum rtx_code code, en
*** 1839,1844 ****
--- 1839,1879 ----
  	    }
  	}
  
+       /* See if we can calculate the value as the difference between two
+ 	 valid immediates.  */
+       if (clear_sign_bit_copies + clear_zero_bit_copies <= 16)
+ 	{
+ 	  int topshift = clear_sign_bit_copies & ~1;
+ 
+ 	  temp1 = ((remainder + (0x00800000 >> topshift))
+ 		   & (0xff000000 >> topshift));
+ 
+ 	  /* If temp1 is zero, then that means the 9 most significant
+ 	     bits of remainder were 1 and we've caused it to overflow.
+ 	     When topshift is 0 we don't need to do anything since we
+ 	     can borrow from 'bit 32'.  */
+ 	  if (temp1 == 0 && topshift != 0)
+ 	    temp1 = 0x80000000 >> (topshift - 1);
+ 
+ 	  temp2 = temp1 - remainder;
+ 	  
+ 	  if (const_ok_for_arm (temp2))
+ 	    {
+ 	      if (generate)
+ 		{
+ 		  rtx new_src = subtargets ? gen_reg_rtx (mode) : target;
+ 		  emit_constant_insn (cond,
+ 				      gen_rtx_SET (VOIDmode, new_src,
+ 						   GEN_INT (temp1)));
+ 		  emit_constant_insn (cond,
+ 				      gen_addsi3 (target, new_src,
+ 						  GEN_INT (-temp2)));
+ 		}
+ 
+ 	      return 2;
+ 	    }
+ 	}
+ 
        /* See if we can generate this by setting the bottom (or the top)
  	 16 bits, and then shifting these into the other half of the
  	 word.  We only look for the simplest cases, to do more would cost

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]