aboutsummaryrefslogtreecommitdiff
path: root/gcc/real.c
diff options
context:
space:
mode:
authorRoger Sayle <roger@eyesopen.com>2003-07-03 21:38:55 +0000
committerRoger Sayle <roger@eyesopen.com>2003-07-03 21:38:55 +0000
commit420809dd52d2c1d3fb6815b2ca125022d2d1a99a (patch)
tree6f8671ee7d010f3f877a3ed92690c0d270f47544 /gcc/real.c
parent032f09b3924c8582ef1a15f6a7e64498e7e43fcb (diff)
* real.c (real_trunc, real_floor, real_ceil): New functions
to implement trunc, floor and ceil respectively. * real.h (real_trunc, real_floor, real_ceil): Prototype here. * builtins.c (integer_valued_real_p): New function to test if a floating point expression has an integer valued result. (fold_trunc_transparent_mathfn): Optimize foo(foo(x)) as foo(x) where foo is an integer rounding function. Similarly, optimize foo(bar(x)) as bar(x), and foo((double)(int)x) as (double)(int)x when both foo and bar are integer rounding functions and we don't need to honor errno. (fold_builtin_trunc, fold_builtin_floor, fold_builtin_ceil): New functions to fold trunc, floor and ceil. (fold_builtin): Use fold_builtin_trunc to fold BUILT_IN_TRUNC*, fold_builtin_floor to fold BUILT_IN_FLOOR* and fold_builtin_ceil to fold BUILT_IN_CEIL*. * fold-const.c (tree_expr_nonnegative_p): Handle FLOAT_EXPR and the remaining integer rounding functions. * gcc.dg/builtins-25.c: New testcase. * gcc.dg/builtins-26.c: New testcase. git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@68903 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/real.c')
-rw-r--r--gcc/real.c46
1 files changed, 46 insertions, 0 deletions
diff --git a/gcc/real.c b/gcc/real.c
index b491d885a9f..6bc4d52fabc 100644
--- a/gcc/real.c
+++ b/gcc/real.c
@@ -4748,3 +4748,49 @@ real_powi (r, mode, x, n)
return inexact;
}
+/* Round X to the nearest integer not larger in absolute value, i.e.
+ towards zero, placing the result in R in mode MODE. */
+
+void
+real_trunc (r, mode, x)
+ REAL_VALUE_TYPE *r;
+ enum machine_mode mode;
+ const REAL_VALUE_TYPE *x;
+{
+ do_fix_trunc (r, x);
+ if (mode != VOIDmode)
+ real_convert (r, mode, r);
+}
+
+/* Round X to the largest integer not greater in value, i.e. round
+ down, placing the result in R in mode MODE. */
+
+void
+real_floor (r, mode, x)
+ REAL_VALUE_TYPE *r;
+ enum machine_mode mode;
+ const REAL_VALUE_TYPE *x;
+{
+ do_fix_trunc (r, x);
+ if (! real_identical (r, x) && r->sign)
+ do_add (r, r, &dconstm1, 0);
+ if (mode != VOIDmode)
+ real_convert (r, mode, r);
+}
+
+/* Round X to the smallest integer not less then argument, i.e. round
+ up, placing the result in R in mode MODE. */
+
+void
+real_ceil (r, mode, x)
+ REAL_VALUE_TYPE *r;
+ enum machine_mode mode;
+ const REAL_VALUE_TYPE *x;
+{
+ do_fix_trunc (r, x);
+ if (! real_identical (r, x) && ! r->sign)
+ do_add (r, r, &dconst1, 0);
+ if (mode != VOIDmode)
+ real_convert (r, mode, r);
+}
+