diff options
author | bernds <bernds@138bc75d-0d04-0410-961f-82ee72b054a4> | 2011-06-21 14:16:39 +0000 |
---|---|---|
committer | bernds <bernds@138bc75d-0d04-0410-961f-82ee72b054a4> | 2011-06-21 14:16:39 +0000 |
commit | d8492bd3ebdf16222a744e495a4de4f2aa3bd58e (patch) | |
tree | ee32816cbc97cc6b5823412e083d7944b01b96a7 /gcc/simplify-rtx.c | |
parent | 0a5cd24b53f25f58c958cfae4e2aa478059f5fb8 (diff) | |
download | gcc-d8492bd3ebdf16222a744e495a4de4f2aa3bd58e.tar.gz |
libgcc/
* Makefile.in (lib2funcs): Add _clrsbsi2 and _clrsbdi2.
* libgcc-std.ver.in (GCC_4.7.0): New section.
gcc/
* doc/extend.texi (__builtin_clrsb, __builtin_clrsbl,
__builtin_clrsbll): Document.
* doc/rtl.texi (clrsb): New entry.
* optabs.c (widen_leading): Renamed from widen_clz. New argument
UNOPTAB. All callers changed. Use UNOPTAB instead of clz_optab.
(expand_unop): Handle clrsb_optab.
(init_optabs): Initialize it.
* optabs.h (enum optab_index): New entry OTI_clrsb.
(clrsb_optab): Define.
* genopinit.c (optabs): Add an entry for it.
* builtins.c (expand_builtin): Handle clrsb builtin functions.
* builtins.def (BUILT_IN_CLRSB, BUILT_IN_CLRSBIMAX, BUILT_IN_CLRSBL,
BUILT_IN_CLRSBLL): New.
* rtl.def (CLRSB): New code.
* dwarf2out.c (mem_loc_descriptor): Handle it.
* simplify-rtx.c (simplify_const_unary_operation): Likewise.
Use op_mode rather than mode when optimizing ffs, clz, ctz, parity
and popcount.
* libgcc2.c (__clrsbSI2, __clrsbDI2): New functions.
* libgcc2.h (__clrsbSI2, __clrsbDI2): Define and declare.
(__ctzDI2): Move declaration.
* config/bfin/bfin.md (clrsbsi2): New expander.
(signbitssi2): Use the CLRSB rtx.
(clrsbhi2): Renamed from signbitshi2. Use the CLRSB rtx.
* config/bfin/bfin.c (bdesc_1arg): Changed accordingly.
gcc/testsuite/
* gcc.c-torture/excute/builtin-bitops-1.c (MAKE_FUNS): Make
my_clrsb test functions.
(main): Test clrsb.
* gcc.dg/builtin-protos-1.c (test_s, test_u, test_sl, test_ul,
test_sll, test_ull): Add clrsb tests.
* gcc.dg/torture/builtin-attr-1.c: Add tests for clrsb, clrsbl,
clrsbll.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@175261 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/simplify-rtx.c')
-rw-r--r-- | gcc/simplify-rtx.c | 32 |
1 files changed, 22 insertions, 10 deletions
diff --git a/gcc/simplify-rtx.c b/gcc/simplify-rtx.c index 18f264b0ca9..3c4df973ff5 100644 --- a/gcc/simplify-rtx.c +++ b/gcc/simplify-rtx.c @@ -1211,6 +1211,7 @@ simplify_const_unary_operation (enum rtx_code code, enum machine_mode mode, rtx op, enum machine_mode op_mode) { unsigned int width = GET_MODE_BITSIZE (mode); + unsigned int op_width = GET_MODE_BITSIZE (op_mode); if (code == VEC_DUPLICATE) { @@ -1321,7 +1322,8 @@ simplify_const_unary_operation (enum rtx_code code, enum machine_mode mode, } if (CONST_INT_P (op) - && width <= HOST_BITS_PER_WIDE_INT && width > 0) + && width <= HOST_BITS_PER_WIDE_INT + && op_width <= HOST_BITS_PER_WIDE_INT && op_width > 0) { HOST_WIDE_INT arg0 = INTVAL (op); HOST_WIDE_INT val; @@ -1341,40 +1343,50 @@ simplify_const_unary_operation (enum rtx_code code, enum machine_mode mode, break; case FFS: - arg0 &= GET_MODE_MASK (mode); + arg0 &= GET_MODE_MASK (op_mode); val = ffs_hwi (arg0); break; case CLZ: - arg0 &= GET_MODE_MASK (mode); - if (arg0 == 0 && CLZ_DEFINED_VALUE_AT_ZERO (mode, val)) + arg0 &= GET_MODE_MASK (op_mode); + if (arg0 == 0 && CLZ_DEFINED_VALUE_AT_ZERO (op_mode, val)) ; else - val = GET_MODE_BITSIZE (mode) - floor_log2 (arg0) - 1; + val = GET_MODE_BITSIZE (op_mode) - floor_log2 (arg0) - 1; + break; + + case CLRSB: + arg0 &= GET_MODE_MASK (op_mode); + if (arg0 == 0) + val = GET_MODE_BITSIZE (op_mode) - 1; + else if (arg0 >= 0) + val = GET_MODE_BITSIZE (op_mode) - floor_log2 (arg0) - 2; + else if (arg0 < 0) + val = GET_MODE_BITSIZE (op_mode) - floor_log2 (~arg0) - 2; break; case CTZ: - arg0 &= GET_MODE_MASK (mode); + arg0 &= GET_MODE_MASK (op_mode); if (arg0 == 0) { /* Even if the value at zero is undefined, we have to come up with some replacement. Seems good enough. */ - if (! CTZ_DEFINED_VALUE_AT_ZERO (mode, val)) - val = GET_MODE_BITSIZE (mode); + if (! CTZ_DEFINED_VALUE_AT_ZERO (op_mode, val)) + val = GET_MODE_BITSIZE (op_mode); } else val = ctz_hwi (arg0); break; case POPCOUNT: - arg0 &= GET_MODE_MASK (mode); + arg0 &= GET_MODE_MASK (op_mode); val = 0; while (arg0) val++, arg0 &= arg0 - 1; break; case PARITY: - arg0 &= GET_MODE_MASK (mode); + arg0 &= GET_MODE_MASK (op_mode); val = 0; while (arg0) val++, arg0 &= arg0 - 1; |