diff options
author | rearnsha <rearnsha@138bc75d-0d04-0410-961f-82ee72b054a4> | 2005-05-09 21:55:08 +0000 |
---|---|---|
committer | rearnsha <rearnsha@138bc75d-0d04-0410-961f-82ee72b054a4> | 2005-05-09 21:55:08 +0000 |
commit | b616908520cb4834992d8d375de58c6ad32d21ba (patch) | |
tree | 7297e5bc9c199d8424196e39c140d44184b116ee /gcc | |
parent | 5381eb98a264ed2e15673ceba37806390ce85a8f (diff) | |
download | gcc-b616908520cb4834992d8d375de58c6ad32d21ba.tar.gz |
* arm.c (arm_gen_constant): Add new heuristic for generating
constant integers that can be expressed as the difference of two
valid immediates.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@99472 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/config/arm/arm.c | 31 |
2 files changed, 24 insertions, 13 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index ae7d68e4672..e6fd1afebdc 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2005-05-09 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. + 2005-05-09 Roger Sayle <roger@eyesopen.com> * c-tree.h (parser_build_unary_op): New prototype. diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index 1743980b1cf..aaa9daaeaec 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -1531,8 +1531,8 @@ use_return_insn (int iscond, rtx sibling) int const_ok_for_arm (HOST_WIDE_INT i) { - unsigned HOST_WIDE_INT mask = ~(unsigned HOST_WIDE_INT)0xFF; - + int lowbit; + /* For machines with >32 bit HOST_WIDE_INT, the bits above bit 31 must be all zero, or all one. */ if ((i & ~(unsigned HOST_WIDE_INT) 0xffffffff) != 0 @@ -1541,19 +1541,24 @@ const_ok_for_arm (HOST_WIDE_INT i) & ~(unsigned HOST_WIDE_INT) 0xffffffff))) return FALSE; - /* Fast return for 0 and powers of 2 */ - if ((i & (i - 1)) == 0) + i &= (unsigned HOST_WIDE_INT) 0xffffffff; + + /* Fast return for 0 and small values. We must do this for zero, since + the code below can't handle that one case. */ + if ((i & ~(unsigned HOST_WIDE_INT) 0xff) == 0) return TRUE; - do - { - if ((i & mask & (unsigned HOST_WIDE_INT) 0xffffffff) == 0) - return TRUE; - mask = - (mask << 2) | ((mask & (unsigned HOST_WIDE_INT) 0xffffffff) - >> (32 - 2)) | ~(unsigned HOST_WIDE_INT) 0xffffffff; - } - while (mask != ~(unsigned HOST_WIDE_INT) 0xFF); + /* Get the number of trailing zeros, rounded down to the nearest even + number. */ + lowbit = (ffs ((int) i) - 1) & ~1; + + if ((i & ~(((unsigned HOST_WIDE_INT) 0xff) << lowbit)) == 0) + return TRUE; + else if (lowbit <= 4 + && ((i & ~0xc000003f) == 0 + || (i & ~0xf000000f) == 0 + || (i & ~0xfc000003) == 0)) + return TRUE; return FALSE; } |