1 /* Round to int long double floating-point values.
2 IBM extended format long double version.
3 Copyright (C) 2004, 2006 Free Software Foundation, Inc.
4 This file is part of the GNU C Library.
6 The GNU C Library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Lesser General Public
8 License as published by the Free Software Foundation; either
9 version 2.1 of the License, or (at your option) any later version.
11 The GNU C Library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
16 You should have received a copy of the GNU Lesser General Public
17 License along with the GNU C Library; if not, write to the Free
18 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
21 /* This has been coded in assembler because GCC makes such a mess of it
22 when it's coded in C. */
25 #include <math_ldbl_opt.h>
29 .tc FD_43300000_0[TC],0x4330000000000000
35 fsub fp12,fp13,fp13 /* generate 0.0 */
37 fcmpu cr7,fp0,fp13 /* if (fabs(x) > TWO52) */
38 fcmpu cr6,fp1,fp12 /* if (x > 0.0) */
42 fadd fp1,fp1,fp13 /* x+= TWO52; */
43 fsub fp1,fp1,fp13 /* x-= TWO52; */
44 fabs fp1,fp1 /* if (x == 0.0) */
47 bnllr- cr6 /* if (x < 0.0) */
48 fsub fp1,fp1,fp13 /* x-= TWO52; */
49 fadd fp1,fp1,fp13 /* x+= TWO52; */
50 fnabs fp1,fp1 /* if (x == 0.0) */
53 /* The high double is > TWO52 so we need to round the low double and
54 perhaps the high double. In this case we have to round the low
55 double and handle any adjustment to the high double that may be
56 caused by rounding (up). This is complicated by the fact that the
57 high double may already be rounded and the low double may have the
58 opposite sign to compensate.This gets a bit tricky so we use the
61 tau = floor(x_high/TWO52);
66 y_low = x0 - y_high + r1;
69 fcmpu cr7,fp9,fp13 /* if (|x_low| > TWO52) */
70 fcmpu cr0,fp9,fp12 /* || (|x_low| == 0.0) */
71 fcmpu cr5,fp2,fp12 /* if (x_low > 0.0) */
72 bgelr- cr7 /* return x; */
74 fdiv fp8,fp1,fp13 /* x_high/TWO52 */
76 bng- cr6,.L6 /* if (x > 0.0) */
78 fcfid fp8,fp0 /* tau = floor(x_high/TWO52); */
79 fadd fp8,fp8,fp8 /* tau++; Make tau even */
80 bng cr5,.L4 /* if (x_low > 0.0) */
84 .L4: /* if (x_low < 0.0) */
85 fsub fp3,fp1,fp8 /* x0 = x_high - tau; */
86 fadd fp4,fp2,fp8 /* x1 = x_low + tau; */
88 fadd fp5,fp4,fp13 /* r1 = x1 + TWO52; */
89 fsub fp5,fp5,fp13 /* r1 = r1 - TWO52; */
91 .L6: /* if (x < 0.0) */
93 fcfid fp8,fp0 /* tau = floor(x_high/TWO52); */
94 fadd fp8,fp8,fp8 /* tau++; Make tau even */
95 bnl cr5,.L7 /* if (x_low < 0.0) */
99 .L7: /* if (x_low > 0.0) */
100 fsub fp3,fp1,fp8 /* x0 = x_high - tau; */
101 fadd fp4,fp2,fp8 /* x1 = x_low + tau; */
103 fsub fp5,fp13,fp4 /* r1 = TWO52 - x1; */
104 fsub fp0,fp5,fp13 /* r1 = - (r1 - TWO52); */
107 fadd fp1,fp3,fp5 /* y_high = x0 + r1; */
108 fsub fp2,fp3,fp1 /* y_low = x0 - y_high + r1; */
113 long_double_symbol (libm, __rintl, rintl)