diff options
author | rth <rth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2004-08-12 04:01:04 +0000 |
---|---|---|
committer | rth <rth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2004-08-12 04:01:04 +0000 |
commit | 59ff7b6e271e2d9b3cd5df791e039d9c12d178e0 (patch) | |
tree | fc30e6d27de3e811bf01d5d624f1b7c9f3a541d8 /gcc/fold-const.c | |
parent | d38cff3040db5b167aec03750793417522d85f6c (diff) | |
download | gcc-59ff7b6e271e2d9b3cd5df791e039d9c12d178e0.tar.gz |
* 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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@85848 138bc75d-0d04-0410-961f-82ee72b054a4
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 0b225c05e02..f7e90be6eaa 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" |