aboutsummaryrefslogtreecommitdiff
path: root/gcc/real.c
diff options
context:
space:
mode:
authorRoger Sayle <roger@eyesopen.com>2004-01-23 16:16:33 +0000
committerRoger Sayle <sayle@gcc.gnu.org>2004-01-23 16:16:33 +0000
commit25348c94e7a966a65fe94f62563ad1982f2f9923 (patch)
treea4e7871be466032d2019d3dd74d2f1702b848756 /gcc/real.c
parent69f2de23b2401a6602271262a103270a81d5f175 (diff)
downloadgcc-25348c94e7a966a65fe94f62563ad1982f2f9923.zip
gcc-25348c94e7a966a65fe94f62563ad1982f2f9923.tar.gz
gcc-25348c94e7a966a65fe94f62563ad1982f2f9923.tar.bz2
real.c (real_floor, real_ceil): Tweak to allow input and output arguments to overlap.
* real.c (real_floor, real_ceil): Tweak to allow input and output arguments to overlap. (real_round): New function to implement round(3m) semantics. * real.h (real_round): Prototype here. * builtins.c (fold_builtin_round): New function to constant fold round, roundf and roundl. (fold_builtin): Call fold_builtin_round for BUILT_IN_ROUND{,F,L}. * gcc.dg/builtins-29.c: New test case. From-SVN: r76428
Diffstat (limited to 'gcc/real.c')
-rw-r--r--gcc/real.c32
1 files changed, 25 insertions, 7 deletions
diff --git a/gcc/real.c b/gcc/real.c
index 5d9bc41..cd27d3e 100644
--- a/gcc/real.c
+++ b/gcc/real.c
@@ -4539,11 +4539,13 @@ void
real_floor (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);
+ REAL_VALUE_TYPE t;
+
+ do_fix_trunc (&t, x);
+ if (! real_identical (&t, x) && x->sign)
+ do_add (&t, &t, &dconstm1, 0);
if (mode != VOIDmode)
- real_convert (r, mode, r);
+ real_convert (r, mode, &t);
}
/* Round X to the smallest integer not less then argument, i.e. round
@@ -4553,9 +4555,25 @@ void
real_ceil (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);
+ REAL_VALUE_TYPE t;
+
+ do_fix_trunc (&t, x);
+ if (! real_identical (&t, x) && ! x->sign)
+ do_add (&t, &t, &dconst1, 0);
+ if (mode != VOIDmode)
+ real_convert (r, mode, &t);
+}
+
+/* Round X to the nearest integer, but round halfway cases away from
+ zero. */
+
+void
+real_round (REAL_VALUE_TYPE *r, enum machine_mode mode,
+ const REAL_VALUE_TYPE *x)
+{
+ do_add (r, x, &dconsthalf, x->sign);
+ do_fix_trunc (r, r);
if (mode != VOIDmode)
real_convert (r, mode, r);
}
+