annotate libquadmath/math/lroundq.c @ 145:1830386684a0

gcc-9.2.0
author anatofuz
date Thu, 13 Feb 2020 11:34:05 +0900
parents 04ced10e8804
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 111
diff changeset
1 /* Round long double value to long int.
1830386684a0 gcc-9.2.0
anatofuz
parents: 111
diff changeset
2 Copyright (C) 1997-2018 Free Software Foundation, Inc.
68
561a7518be6b update gcc-4.6
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3 This file is part of the GNU C Library.
561a7518be6b update gcc-4.6
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
4 Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997 and
111
kono
parents: 68
diff changeset
5 Jakub Jelinek <jj@ultra.linux.cz>, 1999.
68
561a7518be6b update gcc-4.6
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
6
561a7518be6b update gcc-4.6
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
7 The GNU C Library is free software; you can redistribute it and/or
561a7518be6b update gcc-4.6
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
8 modify it under the terms of the GNU Lesser General Public
561a7518be6b update gcc-4.6
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
9 License as published by the Free Software Foundation; either
561a7518be6b update gcc-4.6
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
10 version 2.1 of the License, or (at your option) any later version.
561a7518be6b update gcc-4.6
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
11
561a7518be6b update gcc-4.6
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
12 The GNU C Library is distributed in the hope that it will be useful,
561a7518be6b update gcc-4.6
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
561a7518be6b update gcc-4.6
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
561a7518be6b update gcc-4.6
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
15 Lesser General Public License for more details.
561a7518be6b update gcc-4.6
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
16
561a7518be6b update gcc-4.6
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
17 You should have received a copy of the GNU Lesser General Public
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 111
diff changeset
18 License along with the GNU C Library; if not, see
1830386684a0 gcc-9.2.0
anatofuz
parents: 111
diff changeset
19 <http://www.gnu.org/licenses/>. */
68
561a7518be6b update gcc-4.6
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
20
561a7518be6b update gcc-4.6
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
21 #include "quadmath-imp.h"
561a7518be6b update gcc-4.6
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
22
561a7518be6b update gcc-4.6
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
23 long int
561a7518be6b update gcc-4.6
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
24 lroundq (__float128 x)
561a7518be6b update gcc-4.6
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
25 {
561a7518be6b update gcc-4.6
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
26 int64_t j0;
561a7518be6b update gcc-4.6
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
27 uint64_t i1, i0;
561a7518be6b update gcc-4.6
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
28 long int result;
561a7518be6b update gcc-4.6
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
29 int sign;
561a7518be6b update gcc-4.6
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
30
561a7518be6b update gcc-4.6
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
31 GET_FLT128_WORDS64 (i0, i1, x);
561a7518be6b update gcc-4.6
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
32 j0 = ((i0 >> 48) & 0x7fff) - 0x3fff;
561a7518be6b update gcc-4.6
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
33 sign = (i0 & 0x8000000000000000ULL) != 0 ? -1 : 1;
561a7518be6b update gcc-4.6
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
34 i0 &= 0x0000ffffffffffffLL;
561a7518be6b update gcc-4.6
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
35 i0 |= 0x0001000000000000LL;
561a7518be6b update gcc-4.6
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
36
111
kono
parents: 68
diff changeset
37 if (j0 < (int32_t) (8 * sizeof (long int)) - 1)
68
561a7518be6b update gcc-4.6
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
38 {
111
kono
parents: 68
diff changeset
39 if (j0 < 48)
68
561a7518be6b update gcc-4.6
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
40 {
111
kono
parents: 68
diff changeset
41 if (j0 < 0)
kono
parents: 68
diff changeset
42 return j0 < -1 ? 0 : sign;
kono
parents: 68
diff changeset
43 else
kono
parents: 68
diff changeset
44 {
kono
parents: 68
diff changeset
45 i0 += 0x0000800000000000LL >> j0;
kono
parents: 68
diff changeset
46 result = i0 >> (48 - j0);
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 111
diff changeset
47 #ifdef FE_INVALID
111
kono
parents: 68
diff changeset
48 if (sizeof (long int) == 4
kono
parents: 68
diff changeset
49 && sign == 1
kono
parents: 68
diff changeset
50 && result == LONG_MIN)
kono
parents: 68
diff changeset
51 /* Rounding brought the value out of range. */
kono
parents: 68
diff changeset
52 feraiseexcept (FE_INVALID);
kono
parents: 68
diff changeset
53 #endif
kono
parents: 68
diff changeset
54 }
68
561a7518be6b update gcc-4.6
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
55 }
111
kono
parents: 68
diff changeset
56 else if (j0 >= 112)
68
561a7518be6b update gcc-4.6
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
57 result = ((long int) i0 << (j0 - 48)) | (i1 << (j0 - 112));
561a7518be6b update gcc-4.6
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
58 else
561a7518be6b update gcc-4.6
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
59 {
561a7518be6b update gcc-4.6
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
60 uint64_t j = i1 + (0x8000000000000000ULL >> (j0 - 48));
561a7518be6b update gcc-4.6
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
61 if (j < i1)
561a7518be6b update gcc-4.6
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
62 ++i0;
561a7518be6b update gcc-4.6
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
63
561a7518be6b update gcc-4.6
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
64 if (j0 == 48)
561a7518be6b update gcc-4.6
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
65 result = (long int) i0;
561a7518be6b update gcc-4.6
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
66 else
111
kono
parents: 68
diff changeset
67 {
kono
parents: 68
diff changeset
68 result = ((long int) i0 << (j0 - 48)) | (j >> (112 - j0));
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 111
diff changeset
69 #ifdef FE_INVALID
111
kono
parents: 68
diff changeset
70 if (sizeof (long int) == 8
kono
parents: 68
diff changeset
71 && sign == 1
kono
parents: 68
diff changeset
72 && result == LONG_MIN)
kono
parents: 68
diff changeset
73 /* Rounding brought the value out of range. */
kono
parents: 68
diff changeset
74 feraiseexcept (FE_INVALID);
kono
parents: 68
diff changeset
75 #endif
kono
parents: 68
diff changeset
76 }
68
561a7518be6b update gcc-4.6
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
77 }
561a7518be6b update gcc-4.6
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
78 }
561a7518be6b update gcc-4.6
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
79 else
561a7518be6b update gcc-4.6
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
80 {
111
kono
parents: 68
diff changeset
81 /* The number is too large. Unless it rounds to LONG_MIN,
kono
parents: 68
diff changeset
82 FE_INVALID must be raised and the return value is
kono
parents: 68
diff changeset
83 unspecified. */
kono
parents: 68
diff changeset
84 #ifdef FE_INVALID
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 111
diff changeset
85 if (FIX_FLT128_LONG_CONVERT_OVERFLOW
1830386684a0 gcc-9.2.0
anatofuz
parents: 111
diff changeset
86 && !(sign == -1 && x > (__float128) LONG_MIN - 0.5Q))
1830386684a0 gcc-9.2.0
anatofuz
parents: 111
diff changeset
87 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 111
diff changeset
88 feraiseexcept (FE_INVALID);
1830386684a0 gcc-9.2.0
anatofuz
parents: 111
diff changeset
89 return sign == 1 ? LONG_MAX : LONG_MIN;
1830386684a0 gcc-9.2.0
anatofuz
parents: 111
diff changeset
90 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 111
diff changeset
91 else if (!FIX_FLT128_LONG_CONVERT_OVERFLOW
1830386684a0 gcc-9.2.0
anatofuz
parents: 111
diff changeset
92 && x <= (__float128) LONG_MIN - 0.5Q)
111
kono
parents: 68
diff changeset
93 {
kono
parents: 68
diff changeset
94 /* If truncation produces LONG_MIN, the cast will not raise
kono
parents: 68
diff changeset
95 the exception, but may raise "inexact". */
kono
parents: 68
diff changeset
96 feraiseexcept (FE_INVALID);
kono
parents: 68
diff changeset
97 return LONG_MIN;
kono
parents: 68
diff changeset
98 }
kono
parents: 68
diff changeset
99 #endif
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 111
diff changeset
100 /* The number is too large. It is left implementation defined
1830386684a0 gcc-9.2.0
anatofuz
parents: 111
diff changeset
101 what happens. */
68
561a7518be6b update gcc-4.6
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
102 return (long int) x;
561a7518be6b update gcc-4.6
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
103 }
561a7518be6b update gcc-4.6
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
104
561a7518be6b update gcc-4.6
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
105 return sign * result;
561a7518be6b update gcc-4.6
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
106 }