aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/arm/arm.c
diff options
context:
space:
mode:
authorBernd Schmidt <bernd.schmidt@codesourcery.com>2010-03-19 18:41:22 +0000
committerBernd Schmidt <bernds@gcc.gnu.org>2010-03-19 18:41:22 +0000
commitc99102b8b4cc0ec725c741b13c6f406bbd924c73 (patch)
tree2bcf096e2c7a2d0589b6d0f349bfdd7ccaef90f5 /gcc/config/arm/arm.c
parent002b2dee5d23dff9cc0a7f3196838534bc084da4 (diff)
downloadgcc-c99102b8b4cc0ec725c741b13c6f406bbd924c73.zip
gcc-c99102b8b4cc0ec725c741b13c6f406bbd924c73.tar.gz
gcc-c99102b8b4cc0ec725c741b13c6f406bbd924c73.tar.bz2
re PR target/40697 (inefficient code to extract least bits from an integer value)
gcc/ PR target/40697 * optabs.c (avoid_expensive_constant): Use rtx_cost to find out the cost of loading the constant rather than assuming COSTS_N_INSNS (1). * config/arm/arm.c (thumb1_rtx_costs) <case CONST_INT>: If the outer code is AND, do the same tests as the andsi3 expander and return COSTS_N_INSNS (1) if and is cheap. testsuite/ PR target/40697 * gcc.target/arm/thumb-andsi.c: New test. From-SVN: r157582
Diffstat (limited to 'gcc/config/arm/arm.c')
-rw-r--r--gcc/config/arm/arm.c9
1 files changed, 9 insertions, 0 deletions
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index 870e56e..cc023c1 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -6228,6 +6228,15 @@ thumb1_rtx_costs (rtx x, enum rtx_code code, enum rtx_code outer)
else if ((outer == IOR || outer == XOR || outer == AND)
&& INTVAL (x) < 256 && INTVAL (x) >= -256)
return COSTS_N_INSNS (1);
+ else if (outer == AND)
+ {
+ int i;
+ /* This duplicates the tests in the andsi3 expander. */
+ for (i = 9; i <= 31; i++)
+ if ((((HOST_WIDE_INT) 1) << i) - 1 == INTVAL (x)
+ || (((HOST_WIDE_INT) 1) << i) - 1 == ~INTVAL (x))
+ return COSTS_N_INSNS (2);
+ }
else if (outer == ASHIFT || outer == ASHIFTRT
|| outer == LSHIFTRT)
return 0;