diff options
author | Roger Sayle <roger@eyesopen.com> | 2007-02-08 17:10:56 +0000 |
---|---|---|
committer | Roger Sayle <sayle@gcc.gnu.org> | 2007-02-08 17:10:56 +0000 |
commit | 9f05adb09fd35252136f4d28182e5d60cc03fb36 (patch) | |
tree | 048a2641bea241f51fef4600e4852357f5c9e51e /gcc/simplify-rtx.c | |
parent | d37d06fef83c5f8355fa327d5fa0ff25cd31bb77 (diff) | |
download | gcc-9f05adb09fd35252136f4d28182e5d60cc03fb36.zip gcc-9f05adb09fd35252136f4d28182e5d60cc03fb36.tar.gz gcc-9f05adb09fd35252136f4d28182e5d60cc03fb36.tar.bz2 |
simplify-rtx.c (simplify_unary_operation_1): We can strip zero_extend, bswap and rotates from POCOUNT's argument.
* simplify-rtx.c (simplify_unary_operation_1) <POPCOUNT>: We can
strip zero_extend, bswap and rotates from POCOUNT's argument.
<PARITY>: Likewise, we can strip not, bswap, sign_extend,
zero_extend and rotates from PARITY's argument.
<BSWAP>: A byte-swap followed by a byte-swap is an identity.
(simplify_const_unary_operation) <BSWAP>: Evaluate the byte-swap
of an integer constant at compile-time.
* gcc.target/i386/builtin-bswap-2.c: New test case.
From-SVN: r121716
Diffstat (limited to 'gcc/simplify-rtx.c')
-rw-r--r-- | gcc/simplify-rtx.c | 89 |
1 files changed, 84 insertions, 5 deletions
diff --git a/gcc/simplify-rtx.c b/gcc/simplify-rtx.c index f04f052..8d8bbe5 100644 --- a/gcc/simplify-rtx.c +++ b/gcc/simplify-rtx.c @@ -790,11 +790,54 @@ simplify_unary_operation_1 (enum rtx_code code, enum machine_mode mode, rtx op) break; case POPCOUNT: + switch (GET_CODE (op)) + { + case BSWAP: + case ZERO_EXTEND: + /* (popcount (zero_extend <X>)) = (popcount <X>) */ + return simplify_gen_unary (POPCOUNT, mode, XEXP (op, 0), + GET_MODE (XEXP (op, 0))); + + case ROTATE: + case ROTATERT: + /* Rotations don't affect popcount. */ + if (!side_effects_p (XEXP (op, 1))) + return simplify_gen_unary (POPCOUNT, mode, XEXP (op, 0), + GET_MODE (XEXP (op, 0))); + break; + + default: + break; + } + break; + case PARITY: - /* (pop* (zero_extend <X>)) = (pop* <X>) */ - if (GET_CODE (op) == ZERO_EXTEND) - return simplify_gen_unary (code, mode, XEXP (op, 0), - GET_MODE (XEXP (op, 0))); + switch (GET_CODE (op)) + { + case NOT: + case BSWAP: + case ZERO_EXTEND: + case SIGN_EXTEND: + return simplify_gen_unary (PARITY, mode, XEXP (op, 0), + GET_MODE (XEXP (op, 0))); + + case ROTATE: + case ROTATERT: + /* Rotations don't affect parity. */ + if (!side_effects_p (XEXP (op, 1))) + return simplify_gen_unary (PARITY, mode, XEXP (op, 0), + GET_MODE (XEXP (op, 0))); + break; + + default: + break; + } + break; + + case BSWAP: + /* (bswap (bswap x)) -> x. */ + if (GET_CODE (op) == BSWAP) + return XEXP (op, 0); break; case FLOAT: @@ -1047,7 +1090,19 @@ simplify_const_unary_operation (enum rtx_code code, enum machine_mode mode, break; case BSWAP: - return 0; + { + unsigned int s; + + val = 0; + for (s = 0; s < width; s += 8) + { + unsigned int d = width - s - 8; + unsigned HOST_WIDE_INT byte; + byte = (arg0 >> s) & 0xff; + val |= byte << d; + } + } + break; case TRUNCATE: val = arg0; @@ -1195,6 +1250,30 @@ simplify_const_unary_operation (enum rtx_code code, enum machine_mode mode, lv &= 1; break; + case BSWAP: + { + unsigned int s; + + hv = 0; + lv = 0; + for (s = 0; s < width; s += 8) + { + unsigned int d = width - s - 8; + unsigned HOST_WIDE_INT byte; + + if (s < HOST_BITS_PER_WIDE_INT) + byte = (l1 >> s) & 0xff; + else + byte = (h1 >> (s - HOST_BITS_PER_WIDE_INT)) & 0xff; + + if (d < HOST_BITS_PER_WIDE_INT) + lv |= byte << d; + else + hv |= byte << (d - HOST_BITS_PER_WIDE_INT); + } + } + break; + case TRUNCATE: /* This is just a change-of-mode, so do nothing. */ lv = l1, hv = h1; |