diff options
author | Anatoly Sokolov <aesok@post.ru> | 2010-06-18 19:58:48 +0400 |
---|---|---|
committer | Anatoly Sokolov <aesok@gcc.gnu.org> | 2010-06-18 19:58:48 +0400 |
commit | fd7de64cee04fd08c9a849a20e9cf0fd8d6906e1 (patch) | |
tree | 43dbfc5a3de6b7b8c559675266ac518bbcabd39a /gcc/simplify-rtx.c | |
parent | bc87224e9341b186905d8ac849aeb59463ae4f6b (diff) | |
download | gcc-fd7de64cee04fd08c9a849a20e9cf0fd8d6906e1.zip gcc-fd7de64cee04fd08c9a849a20e9cf0fd8d6906e1.tar.gz gcc-fd7de64cee04fd08c9a849a20e9cf0fd8d6906e1.tar.bz2 |
double-int.h (double_int_to_shwi, [...]): Implement as static inline.
* double-int.h (double_int_to_shwi, double_int_to_uhwi,
double_int_fits_in_uhwi_p): Implement as static inline.
(double_int_xor): New inline function.
(double_int_lrotate, double_int_rrotate, double_int_max,
double_int_umax, double_int_smax, double_int_min, double_int_umin,
double_int_smin): Declare.
(lrotate_double, rrotate_double): Remove declaration.
* double-int.c (double_int_fits_in_uhwi_p, double_int_to_shwi,
double_int_to_uhwi, lrotate_double, rrotate_double): Remove function.
(double_int_lrotate, double_int_rrotate, double_int_max,
double_int_umax, double_int_smax, double_int_min, double_int_umin,
double_int_smin): New function.
* fold-const.c (int_const_binop): Clean up, use double_int_*
functions.
* simplify-rtx.c (simplify_const_binary_operation): Clean up, use
double_int_* and immed_double_int_const functions.
From-SVN: r161002
Diffstat (limited to 'gcc/simplify-rtx.c')
-rw-r--r-- | gcc/simplify-rtx.c | 129 |
1 files changed, 56 insertions, 73 deletions
diff --git a/gcc/simplify-rtx.c b/gcc/simplify-rtx.c index b38ab2e..be63198 100644 --- a/gcc/simplify-rtx.c +++ b/gcc/simplify-rtx.c @@ -3268,141 +3268,124 @@ simplify_const_binary_operation (enum rtx_code code, enum machine_mode mode, /* We can fold some multi-word operations. */ if (GET_MODE_CLASS (mode) == MODE_INT - && width == HOST_BITS_PER_WIDE_INT * 2 - && (GET_CODE (op0) == CONST_DOUBLE || CONST_INT_P (op0)) - && (GET_CODE (op1) == CONST_DOUBLE || CONST_INT_P (op1))) + && width == HOST_BITS_PER_DOUBLE_INT + && (CONST_DOUBLE_P (op0) || CONST_INT_P (op0)) + && (CONST_DOUBLE_P (op1) || CONST_INT_P (op1))) { - unsigned HOST_WIDE_INT l1, l2, lv, lt; - HOST_WIDE_INT h1, h2, hv, ht; + double_int o0, o1, res, tmp; - if (GET_CODE (op0) == CONST_DOUBLE) - l1 = CONST_DOUBLE_LOW (op0), h1 = CONST_DOUBLE_HIGH (op0); - else - l1 = INTVAL (op0), h1 = HWI_SIGN_EXTEND (l1); - - if (GET_CODE (op1) == CONST_DOUBLE) - l2 = CONST_DOUBLE_LOW (op1), h2 = CONST_DOUBLE_HIGH (op1); - else - l2 = INTVAL (op1), h2 = HWI_SIGN_EXTEND (l2); + o0 = rtx_to_double_int (op0); + o1 = rtx_to_double_int (op1); switch (code) { case MINUS: /* A - B == A + (-B). */ - neg_double (l2, h2, &lv, &hv); - l2 = lv, h2 = hv; + o1 = double_int_neg (o1); /* Fall through.... */ case PLUS: - add_double (l1, h1, l2, h2, &lv, &hv); + res = double_int_add (o0, o1); break; case MULT: - mul_double (l1, h1, l2, h2, &lv, &hv); + res = double_int_mul (o0, o1); break; case DIV: - if (div_and_round_double (TRUNC_DIV_EXPR, 0, l1, h1, l2, h2, - &lv, &hv, <, &ht)) + if (div_and_round_double (TRUNC_DIV_EXPR, 0, + o0.low, o0.high, o1.low, o1.high, + &res.low, &res.high, + &tmp.low, &tmp.high)) return 0; break; case MOD: - if (div_and_round_double (TRUNC_DIV_EXPR, 0, l1, h1, l2, h2, - <, &ht, &lv, &hv)) + if (div_and_round_double (TRUNC_DIV_EXPR, 0, + o0.low, o0.high, o1.low, o1.high, + &tmp.low, &tmp.high, + &res.low, &res.high)) return 0; break; case UDIV: - if (div_and_round_double (TRUNC_DIV_EXPR, 1, l1, h1, l2, h2, - &lv, &hv, <, &ht)) + if (div_and_round_double (TRUNC_DIV_EXPR, 1, + o0.low, o0.high, o1.low, o1.high, + &res.low, &res.high, + &tmp.low, &tmp.high)) return 0; break; case UMOD: - if (div_and_round_double (TRUNC_DIV_EXPR, 1, l1, h1, l2, h2, - <, &ht, &lv, &hv)) + if (div_and_round_double (TRUNC_DIV_EXPR, 1, + o0.low, o0.high, o1.low, o1.high, + &tmp.low, &tmp.high, + &res.low, &res.high)) return 0; break; case AND: - lv = l1 & l2, hv = h1 & h2; + res = double_int_and (o0, o1); break; case IOR: - lv = l1 | l2, hv = h1 | h2; + res = double_int_ior (o0, o1); break; case XOR: - lv = l1 ^ l2, hv = h1 ^ h2; + res = double_int_xor (o0, o1); break; case SMIN: - if (h1 < h2 - || (h1 == h2 - && ((unsigned HOST_WIDE_INT) l1 - < (unsigned HOST_WIDE_INT) l2))) - lv = l1, hv = h1; - else - lv = l2, hv = h2; + res = double_int_smin (o0, o1); break; case SMAX: - if (h1 > h2 - || (h1 == h2 - && ((unsigned HOST_WIDE_INT) l1 - > (unsigned HOST_WIDE_INT) l2))) - lv = l1, hv = h1; - else - lv = l2, hv = h2; + res = double_int_smax (o0, o1); break; case UMIN: - if ((unsigned HOST_WIDE_INT) h1 < (unsigned HOST_WIDE_INT) h2 - || (h1 == h2 - && ((unsigned HOST_WIDE_INT) l1 - < (unsigned HOST_WIDE_INT) l2))) - lv = l1, hv = h1; - else - lv = l2, hv = h2; + res = double_int_umin (o0, o1); break; case UMAX: - if ((unsigned HOST_WIDE_INT) h1 > (unsigned HOST_WIDE_INT) h2 - || (h1 == h2 - && ((unsigned HOST_WIDE_INT) l1 - > (unsigned HOST_WIDE_INT) l2))) - lv = l1, hv = h1; - else - lv = l2, hv = h2; + res = double_int_umax (o0, o1); break; case LSHIFTRT: case ASHIFTRT: case ASHIFT: case ROTATE: case ROTATERT: - if (SHIFT_COUNT_TRUNCATED) - l2 &= (GET_MODE_BITSIZE (mode) - 1), h2 = 0; - - if (h2 != 0 || l2 >= GET_MODE_BITSIZE (mode)) - return 0; - - if (code == LSHIFTRT || code == ASHIFTRT) - rshift_double (l1, h1, l2, GET_MODE_BITSIZE (mode), &lv, &hv, - code == ASHIFTRT); - else if (code == ASHIFT) - lshift_double (l1, h1, l2, GET_MODE_BITSIZE (mode), &lv, &hv, 1); - else if (code == ROTATE) - lrotate_double (l1, h1, l2, GET_MODE_BITSIZE (mode), &lv, &hv); - else /* code == ROTATERT */ - rrotate_double (l1, h1, l2, GET_MODE_BITSIZE (mode), &lv, &hv); + { + unsigned HOST_WIDE_INT cnt; + + if (SHIFT_COUNT_TRUNCATED) + o1 = double_int_zext (o1, GET_MODE_BITSIZE (mode)); + + if (!double_int_fits_in_uhwi_p (o1) + || double_int_to_uhwi (o1) >= GET_MODE_BITSIZE (mode)) + return 0; + + cnt = double_int_to_uhwi (o1); + + if (code == LSHIFTRT || code == ASHIFTRT) + res = double_int_rshift (o0, cnt, GET_MODE_BITSIZE (mode), + code == ASHIFTRT); + else if (code == ASHIFT) + res = double_int_lshift (o0, cnt, GET_MODE_BITSIZE (mode), + true); + else if (code == ROTATE) + res = double_int_lrotate (o0, cnt, GET_MODE_BITSIZE (mode)); + else /* code == ROTATERT */ + res = double_int_rrotate (o0, cnt, GET_MODE_BITSIZE (mode)); + } break; default: return 0; } - return immed_double_const (lv, hv, mode); + return immed_double_int_const (res, mode); } if (CONST_INT_P (op0) && CONST_INT_P (op1) |