Add minimal support for __bf16 to -fdump-ada-spec
[official-gcc.git] / libgcc / soft-fp / fixtdbitint.c
blob66aca1cbdcce2e704f68445061bfd3259a85eacc
1 /* Software floating-point emulation.
2 Convert _Decimal128 to signed or unsigned _BitInt.
4 Copyright (C) 2023 Free Software Foundation, Inc.
6 This file is part of GCC.
8 GCC is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 3, or (at your option) any later
11 version.
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 for more details.
18 Under Section 7 of GPL version 3, you are granted additional
19 permissions described in the GCC Runtime Library Exception, version
20 3.1, as published by the Free Software Foundation.
22 You should have received a copy of the GNU General Public License and
23 a copy of the GCC Runtime Library Exception along with this program;
24 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
25 <http://www.gnu.org/licenses/>. */
27 #include "soft-fp.h"
28 #include "bitint.h"
30 #ifdef __BITINT_MAXWIDTH__
31 extern void __bid_fixtdbitint (UBILtype *, SItype, _Decimal128);
33 void
34 __bid_fixtdbitint (UBILtype *r, SItype rprec, _Decimal128 a)
36 FP_DECL_EX;
37 USItype arprec = rprec < 0 ? -rprec : rprec;
38 USItype rn = (arprec + BIL_TYPE_SIZE - 1) / BIL_TYPE_SIZE;
39 union { _Decimal128 d; UDItype u[2]; } u;
40 UDItype mantissahi, mantissalo, t;
41 SItype sgn;
42 SItype exponent;
43 USItype exp_bits, mant_bits;
44 UBILtype *pow10v, *resv;
45 USItype pow10_limbs, res_limbs, min_limbs, mant_limbs, low_zeros;
47 FP_INIT_EXCEPTIONS;
48 u.d = a;
49 mantissahi = u.u[__FLOAT_WORD_ORDER__ != __ORDER_BIG_ENDIAN__];
50 mantissalo = u.u[__FLOAT_WORD_ORDER__ == __ORDER_BIG_ENDIAN__];
51 t = mantissahi >> 47;
52 sgn = (DItype) mantissahi < 0;
53 if ((t & (3 << 14)) != (3 << 14))
55 mantissahi &= ((((UDItype) 1) << 49) - 1);
56 exponent = (t >> 2) & 0x3fff;
57 if (mantissahi > (UDItype) 0x1ed09bead87c0
58 || (mantissahi == (UDItype) 0x1ed09bead87c0
59 && mantissalo > (UDItype) 0x378d8e63ffffffff))
61 mantissahi = 0;
62 mantissalo = 0;
65 else if ((t & (3 << 12)) != (3 << 12))
67 mantissahi = 0;
68 mantissalo = 0;
69 exponent = t & 0x3fff;
71 else
73 FP_SET_EXCEPTION (FP_EX_INVALID
74 | FP_EX_INVALID_CVI
75 | ((FP_EX_INVALID_SNAN
76 && ((t & 0x800)) != 0)
77 ? FP_EX_INVALID_SNAN : 0));
78 ovf:
79 if (!sgn)
80 __builtin_memset (r, -1, rn * sizeof (UBILtype));
81 else
82 __builtin_memset (r, 0, rn * sizeof (UBILtype));
83 if (sgn ^ (rprec >= 0))
84 r[BITINT_END (0, rn - 1)]
85 |= (UBILtype) -1 << ((arprec - 1) % BIL_TYPE_SIZE);
86 else
87 r[BITINT_END (0, rn - 1)]
88 &= ~((UBILtype) -1 << ((arprec - 1) % BIL_TYPE_SIZE));
89 goto done;
91 exponent -= 6176;
93 if (mantissahi == 0 && mantissalo == 0)
95 /* Zero (with any exponent). */
96 zero:
97 __builtin_memset (r, 0, rn * sizeof (UBILtype));
98 goto done;
100 if (exponent <= -34)
102 FP_SET_EXCEPTION (FP_EX_INEXACT);
103 goto zero;
105 if (exponent < 0)
107 UBILtype limbs[4 * 128 / BIL_TYPE_SIZE];
108 #if BIL_TYPE_SIZE == 64
109 limbs[BITINT_END (0, 1)] = mantissahi;
110 limbs[BITINT_END (1, 0)] = mantissalo;
111 #elif BIL_TYPE_SIZE == 32
112 limbs[BITINT_END (0, 3)] = mantissahi >> 32;
113 limbs[BITINT_END (1, 2)] = mantissahi;
114 limbs[BITINT_END (2, 1)] = mantissalo >> 32;
115 limbs[BITINT_END (3, 0)] = mantissalo;
116 #elif
117 # error Unhandled BIL_TYPE_SIZE
118 #endif
119 __bid_pow10bitint (&limbs[128 / BIL_TYPE_SIZE], 128, -exponent);
120 __divmodbitint4 (&limbs[2 * 128 / BIL_TYPE_SIZE], 128,
121 &limbs[3 * 128 / BIL_TYPE_SIZE], 128,
122 &limbs[0], 128, &limbs[128 / BIL_TYPE_SIZE], 128);
123 UDItype rem;
124 #if BIL_TYPE_SIZE == 64
125 mantissahi = limbs[BITINT_END (4, 5)];
126 mantissalo = limbs[BITINT_END (5, 4)];
127 rem = limbs[6] | limbs[7];
128 #elif BIL_TYPE_SIZE == 32
129 mantissahi = (UDItype) limbs[BITINT_END (8, 11)] << 32;
130 mantissahi |= limbs[BITINT_END (9, 10)];
131 mantissalo = (UDItype) limbs[BITINT_END (10, 9)] << 32;
132 mantissalo |= limbs[BITINT_END (11, 8)];
133 rem = limbs[12] | limbs[13] | limbs[14] | limbs[15];
134 #endif
135 if (rem)
136 FP_SET_EXCEPTION (FP_EX_INEXACT);
137 if (mantissahi == 0 && mantissalo == 0)
138 goto zero;
139 exponent = 0;
142 if (rprec >= 0 && sgn)
144 ovf_ex:
145 FP_SET_EXCEPTION (FP_EX_INVALID | FP_EX_INVALID_CVI);
146 goto ovf;
149 /* Lower estimate for number of bits needed for pow10 (exponent). */
150 exp_bits = exponent / 3;
151 exp_bits = exp_bits * 10 - exp_bits / 29;
152 if (mantissahi)
153 mant_bits = sizeof (0ULL) * __CHAR_BIT__ - __builtin_clzll (mantissahi)
154 + 64;
155 else
156 mant_bits = sizeof (0ULL) * __CHAR_BIT__ - __builtin_clzll (mantissalo);
157 if (exp_bits + mant_bits > arprec + 1)
158 goto ovf_ex;
159 /* Upper estimate for number of bits needed for pow10 (exponent). */
160 exp_bits = (exponent + 2) / 3;
161 exp_bits = exp_bits * 10 - exp_bits / 30;
162 if (exp_bits == 0)
163 exp_bits = 1;
164 pow10_limbs = (exp_bits + BIL_TYPE_SIZE - 1) / BIL_TYPE_SIZE;
165 pow10v = __builtin_alloca (pow10_limbs * sizeof (UBILtype));
166 low_zeros = __bid_pow10bitint (pow10v, exp_bits, exponent);
168 res_limbs = ((exp_bits + mant_bits + BIL_TYPE_SIZE - 1)
169 / BIL_TYPE_SIZE) - low_zeros;
170 mant_limbs = (mant_bits + BIL_TYPE_SIZE - 1) / BIL_TYPE_SIZE;
171 resv = __builtin_alloca ((res_limbs + mant_limbs) * sizeof (UBILtype));
172 #if BIL_TYPE_SIZE >= 64
173 if (mant_limbs == 1)
174 resv[res_limbs] = mantissalo;
175 else
177 resv[res_limbs + BITINT_END (1, 0)] = mantissalo;
178 resv[res_limbs + BITINT_END (0, 1)] = mantissahi;
180 #else
181 resv[res_limbs + BITINT_END (mant_limbs - 1, 0)] = mantissalo;
182 if (mant_limbs >= 2)
184 resv[res_limbs + BITINT_END (mant_limbs - 2, 1)] = mantissalo >> 32;
185 if (mant_limbs >= 3)
187 resv[res_limbs + BITINT_END (mant_limbs - 3, 2)] = mantissahi;
188 if (mant_limbs == 4)
189 resv[res_limbs + BITINT_END (0, 3)] = mantissahi >> 32;
192 #endif
193 __mulbitint3 (resv, exp_bits + mant_bits - low_zeros * BIL_TYPE_SIZE,
194 resv + res_limbs, mant_bits,
195 pow10v + BITINT_END (0, low_zeros),
196 exp_bits - low_zeros * BIL_TYPE_SIZE);
197 if (res_limbs + low_zeros >= rn)
199 if (res_limbs + low_zeros > rn && resv[BITINT_END (0, res_limbs - 1)])
200 goto ovf_ex;
201 if ((arprec % BIL_TYPE_SIZE) != 0
202 && (resv[BITINT_END (rn - res_limbs, rn - 1) - low_zeros]
203 & ((UBILtype) -1 << (arprec % BIL_TYPE_SIZE))) != 0)
204 goto ovf_ex;
205 min_limbs = rn - low_zeros;
207 else
208 min_limbs = res_limbs;
209 if (low_zeros)
210 __builtin_memset (r + BITINT_END (rn - low_zeros, 0), '\0',
211 low_zeros * sizeof (UBILtype));
212 if (sgn)
213 bitint_negate (r + BITINT_END (rn - low_zeros - 1, low_zeros),
214 resv + BITINT_END (res_limbs - 1, 0), min_limbs);
215 else
216 __builtin_memcpy (r + BITINT_END (rn - low_zeros - min_limbs, low_zeros),
217 resv + BITINT_END (res_limbs - min_limbs, 0),
218 min_limbs * sizeof (UBILtype));
219 if (res_limbs + low_zeros < rn)
221 if (sgn)
222 __builtin_memset (r + BITINT_END (0, res_limbs + low_zeros), -1,
223 (rn - res_limbs - low_zeros) * sizeof (UBILtype));
224 else
225 __builtin_memset (r + BITINT_END (0, res_limbs + low_zeros), '\0',
226 (rn - res_limbs - low_zeros) * sizeof (UBILtype));
228 else if (sgn)
230 if ((r[BITINT_END (0, rn - 1)]
231 & ((UBILtype) 1 << ((arprec - 1) % BIL_TYPE_SIZE))) == 0)
232 goto ovf_ex;
234 else if (rprec < 0
235 && (r[BITINT_END (0, rn - 1)]
236 & ((UBILtype) 1 << ((arprec - 1) % BIL_TYPE_SIZE))) != 0)
237 goto ovf_ex;
239 done:
240 FP_HANDLE_EXCEPTIONS;
242 #endif