diff options
author | Richard Henderson <rth@redhat.com> | 2004-08-11 21:01:04 -0700 |
---|---|---|
committer | Richard Henderson <rth@gcc.gnu.org> | 2004-08-11 21:01:04 -0700 |
commit | 159319544b909404d2ba3997c58a0cbe6541030a (patch) | |
tree | fc30e6d27de3e811bf01d5d624f1b7c9f3a541d8 /gcc/fold-const.c | |
parent | 57d1dd8704212031da1e646aa672720262aa4352 (diff) | |
download | gcc-159319544b909404d2ba3997c58a0cbe6541030a.zip gcc-159319544b909404d2ba3997c58a0cbe6541030a.tar.gz gcc-159319544b909404d2ba3997c58a0cbe6541030a.tar.bz2 |
stor-layout.c (round_up, round_down): Move ...
* stor-layout.c (round_up, round_down): Move ...
* fold-const.c (round_up, round_down): ... here. Use
multiple_of_p to avoid any arithmetic at all.
From-SVN: r85848
Diffstat (limited to 'gcc/fold-const.c')
-rw-r--r-- | gcc/fold-const.c | 70 |
1 files changed, 70 insertions, 0 deletions
diff --git a/gcc/fold-const.c b/gcc/fold-const.c index 0b225c0..f7e90be 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -10678,4 +10678,74 @@ fold_ignored_result (tree t) } } +/* Return the value of VALUE, rounded up to a multiple of DIVISOR. + This can only be applied to objects of a sizetype. */ + +tree +round_up (tree value, int divisor) +{ + tree div, t; + + if (divisor == 0) + abort (); + if (divisor == 1) + return value; + + div = size_int_type (divisor, TREE_TYPE (value)); + + /* See if VALUE is already a multiple of DIVISOR. If so, we don't + have to do anything. */ + if (multiple_of_p (TREE_TYPE (value), value, div)) + return value; + + /* If divisor is a power of two, simplify this to bit manipulation. */ + if (divisor == (divisor & -divisor)) + { + t = size_int_type (divisor - 1, TREE_TYPE (value)); + value = size_binop (PLUS_EXPR, value, t); + t = size_int_type (-divisor, TREE_TYPE (value)); + value = size_binop (BIT_AND_EXPR, value, t); + } + else + { + value = size_binop (CEIL_DIV_EXPR, value, div); + value = size_binop (MULT_EXPR, value, div); + } + + return value; +} + +/* Likewise, but round down. */ + +tree +round_down (tree value, int divisor) +{ + tree div, t; + + if (divisor == 0) + abort (); + if (divisor == 1) + return value; + + div = size_int_type (divisor, TREE_TYPE (value)); + + /* See if VALUE is already a multiple of DIVISOR. If so, we don't + have to do anything. */ + if (multiple_of_p (TREE_TYPE (value), value, div)) + return value; + + /* If divisor is a power of two, simplify this to bit manipulation. */ + if (divisor == (divisor & -divisor)) + { + t = size_int_type (-divisor, TREE_TYPE (value)); + value = size_binop (BIT_AND_EXPR, value, t); + } + else + { + value = size_binop (FLOOR_DIV_EXPR, value, div); + value = size_binop (MULT_EXPR, value, div); + } + + return value; +} #include "gt-fold-const.h" |