1 1.1 mrg /* Software floating-point emulation. 2 1.1 mrg Convert a _BitInt to _Decimal32. 3 1.1 mrg 4 1.1 mrg Copyright (C) 2023 Free Software Foundation, Inc. 5 1.1 mrg 6 1.1 mrg This file is part of GCC. 7 1.1 mrg 8 1.1 mrg GCC is free software; you can redistribute it and/or modify it under 9 1.1 mrg the terms of the GNU General Public License as published by the Free 10 1.1 mrg Software Foundation; either version 3, or (at your option) any later 11 1.1 mrg version. 12 1.1 mrg 13 1.1 mrg GCC is distributed in the hope that it will be useful, but WITHOUT ANY 14 1.1 mrg WARRANTY; without even the implied warranty of MERCHANTABILITY or 15 1.1 mrg FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 16 1.1 mrg for more details. 17 1.1 mrg 18 1.1 mrg Under Section 7 of GPL version 3, you are granted additional 19 1.1 mrg permissions described in the GCC Runtime Library Exception, version 20 1.1 mrg 3.1, as published by the Free Software Foundation. 21 1.1 mrg 22 1.1 mrg You should have received a copy of the GNU General Public License and 23 1.1 mrg a copy of the GCC Runtime Library Exception along with this program; 24 1.1 mrg see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 25 1.1 mrg <http://www.gnu.org/licenses/>. */ 26 1.1 mrg 27 1.1 mrg #include "soft-fp.h" 28 1.1 mrg #include "bitint.h" 29 1.1 mrg 30 1.1 mrg #ifdef __BITINT_MAXWIDTH__ 31 1.1 mrg extern _Decimal32 __bid_floatbitintsd (const UBILtype *, SItype); 32 1.1 mrg 33 1.1 mrg _Decimal32 34 1.1 mrg __bid_floatbitintsd (const UBILtype *i, SItype iprec) 35 1.1 mrg { 36 1.1 mrg iprec = bitint_reduce_prec (&i, iprec); 37 1.1 mrg USItype aiprec = iprec < 0 ? -iprec : iprec; 38 1.1 mrg USItype in = (aiprec + BIL_TYPE_SIZE - 1) / BIL_TYPE_SIZE; 39 1.1 mrg USItype idx = BITINT_END (0, in - 1); 40 1.1 mrg UBILtype msb = i[idx]; 41 1.1 mrg USItype mantissa; 42 1.1 mrg SItype exponent = 0; 43 1.1 mrg UBILtype inexact = 0; 44 1.1 mrg union { _Decimal32 d; USItype u; } u, ui; 45 1.1 mrg if (aiprec % BIL_TYPE_SIZE) 46 1.1 mrg { 47 1.1 mrg if (iprec > 0) 48 1.1 mrg msb &= ((UBILtype) 1 << (aiprec % BIL_TYPE_SIZE)) - 1; 49 1.1 mrg else 50 1.1 mrg msb |= (UBILtype) -1 << (aiprec % BIL_TYPE_SIZE); 51 1.1 mrg } 52 1.1 mrg if (iprec < 0) 53 1.1 mrg { 54 1.1 mrg SItype n = sizeof (0ULL) * __CHAR_BIT__ + 1 - __builtin_clzll (~msb); 55 1.1 mrg aiprec = (in - 1) * BIL_TYPE_SIZE + n; 56 1.1 mrg } 57 1.1 mrg else if (msb == 0) 58 1.1 mrg aiprec = 1; 59 1.1 mrg else 60 1.1 mrg { 61 1.1 mrg SItype n = sizeof (0ULL) * __CHAR_BIT__ - __builtin_clzll (msb); 62 1.1 mrg aiprec = (in - 1) * BIL_TYPE_SIZE + n; 63 1.1 mrg } 64 1.1 mrg /* Number of bits in (_BitInt(2048)) 9999999e+90DF. */ 65 1.1 mrg if (aiprec > 323 + (iprec < 0)) 66 1.1 mrg { 67 1.1 mrg ovf: 68 1.1 mrg if (iprec < 0) 69 1.1 mrg u.d = -9000000e+90DF; 70 1.1 mrg else 71 1.1 mrg u.d = 9000000e+90DF; 72 1.1 mrg __asm ("" : "+g" (u.d)); 73 1.1 mrg u.d += u.d; 74 1.1 mrg __asm ("" : "+g" (u.d)); 75 1.1 mrg goto done; 76 1.1 mrg } 77 1.1 mrg /* Bit precision of 9999999uwb. */ 78 1.1 mrg if (aiprec >= 24) 79 1.1 mrg { 80 1.1 mrg USItype pow10_limbs, q_limbs, q2_limbs, j; 81 1.1 mrg USItype exp_bits = 0, e; 82 1.1 mrg UDItype m; 83 1.1 mrg UBILtype *buf; 84 1.1 mrg /* First do a possibly large divide smaller enough such that 85 1.1 mrg we only need to check remainder for 0 or non-0 and then 86 1.1 mrg we'll do further division. */ 87 1.1 mrg if (aiprec >= 24 + 4 + 10) 88 1.1 mrg { 89 1.1 mrg exp_bits = (aiprec - 24 - 4) / 10; 90 1.1 mrg exponent = exp_bits * 3; 91 1.1 mrg /* Upper estimate for pow10 (exponent) bits. */ 92 1.1 mrg exp_bits = exp_bits * 10 - exp_bits / 30; 93 1.1 mrg } 94 1.1 mrg pow10_limbs = (exp_bits + BIL_TYPE_SIZE - 1) / BIL_TYPE_SIZE; 95 1.1 mrg /* 38 is the highest number of quotient bits needed on 96 1.1 mrg aiprec range of [38, 323]. E.g. if aiprec is 317, 97 1.1 mrg exponent will be 84 and exp_bits 280. 317 - 280 + 1 98 1.1 mrg is 38. */ 99 1.1 mrg q_limbs = (38 + BIL_TYPE_SIZE - 1) / BIL_TYPE_SIZE; 100 1.1 mrg q2_limbs = (32 + BIL_TYPE_SIZE - 1) / BIL_TYPE_SIZE; 101 1.1 mrg buf = __builtin_alloca ((q_limbs + pow10_limbs * 2 + q2_limbs + 2) 102 1.1 mrg * sizeof (UBILtype)); 103 1.1 mrg if (exponent) 104 1.1 mrg { 105 1.1 mrg __bid_pow10bitint (buf + q_limbs, exp_bits, exponent); 106 1.1 mrg __divmodbitint4 (buf, q_limbs * BIL_TYPE_SIZE, 107 1.1 mrg buf + q_limbs + pow10_limbs, 108 1.1 mrg pow10_limbs * BIL_TYPE_SIZE, 109 1.1 mrg i, iprec < 0 ? -aiprec : aiprec, 110 1.1 mrg buf + q_limbs, exp_bits); 111 1.1 mrg if (iprec < 0) 112 1.1 mrg bitint_negate (buf + BITINT_END (q_limbs - 1, 0), 113 1.1 mrg buf + BITINT_END (q_limbs - 1, 0), q_limbs); 114 1.1 mrg inexact = buf[q_limbs + pow10_limbs]; 115 1.1 mrg for (j = 1; j < pow10_limbs; ++j) 116 1.1 mrg inexact |= buf[q_limbs + pow10_limbs + j]; 117 1.1 mrg } 118 1.1 mrg else 119 1.1 mrg { 120 1.1 mrg __builtin_memcpy (buf + BITINT_END (q_limbs - in + 1, 0), i, 121 1.1 mrg (in - 1) * sizeof (UBILtype)); 122 1.1 mrg buf[BITINT_END (q_limbs - in, in - 1)] = msb; 123 1.1 mrg if (iprec < 0) 124 1.1 mrg bitint_negate (buf + BITINT_END (q_limbs - 1, 0), 125 1.1 mrg buf + BITINT_END (q_limbs - 1, 0), in); 126 1.1 mrg if (q_limbs > in) 127 1.1 mrg __builtin_memset (buf + BITINT_END (0, in), '\0', 128 1.1 mrg (q_limbs - in) * sizeof (UBILtype)); 129 1.1 mrg } 130 1.1 mrg e = 0; 131 1.1 mrg #if BIL_TYPE_SIZE == 64 132 1.1 mrg m = buf[0]; 133 1.1 mrg #elif BIL_TYPE_SIZE == 32 134 1.1 mrg m = ((UDItype) buf[BITINT_END (0, 1)] << 32) | buf[BITINT_END (1, 0)]; 135 1.1 mrg #else 136 1.1 mrg # error Unsupported BIL_TYPE_SIZE 137 1.1 mrg #endif 138 1.1 mrg if (m >= (UDItype) 10000000000) 139 1.1 mrg { 140 1.1 mrg if (m >= (UDItype) 100000000000) 141 1.1 mrg e = 5; 142 1.1 mrg else 143 1.1 mrg e = 4; 144 1.1 mrg } 145 1.1 mrg else if (m >= (UDItype) 100000000) 146 1.1 mrg { 147 1.1 mrg if (m >= (UDItype) 1000000000) 148 1.1 mrg e = 3; 149 1.1 mrg else 150 1.1 mrg e = 2; 151 1.1 mrg } 152 1.1 mrg else if (m >= (UDItype) 10000000) 153 1.1 mrg e = 1; 154 1.1 mrg exponent += e; 155 1.1 mrg if (exponent > 90) 156 1.1 mrg goto ovf; 157 1.1 mrg if (e) 158 1.1 mrg { 159 1.1 mrg UBILtype rem, half; 160 1.1 mrg __bid_pow10bitint (buf + q_limbs + pow10_limbs * 2, 161 1.1 mrg BIL_TYPE_SIZE, e); 162 1.1 mrg __divmodbitint4 (buf + q_limbs + pow10_limbs * 2 + 1, 163 1.1 mrg q2_limbs * BIL_TYPE_SIZE, 164 1.1 mrg buf + q_limbs + pow10_limbs * 2 + 1 + q2_limbs, 165 1.1 mrg BIL_TYPE_SIZE, 166 1.1 mrg buf, q_limbs * BIL_TYPE_SIZE, 167 1.1 mrg buf + q_limbs + pow10_limbs * 2, BIL_TYPE_SIZE); 168 1.1 mrg half = buf[q_limbs + pow10_limbs * 2] / 2; 169 1.1 mrg rem = buf[q_limbs + pow10_limbs * 2 + 1 + q2_limbs]; 170 1.1 mrg if (inexact) 171 1.1 mrg { 172 1.1 mrg /* If first division discovered some non-0 digits 173 1.1 mrg and this second division is by 10, e.g. 174 1.1 mrg for XXXXXX5499999999999 or XXXXXX5000000000001 175 1.1 mrg if first division is by 10^12 and second by 10^1, 176 1.1 mrg doing rem |= 1 wouldn't change the 5. Similarly 177 1.1 mrg for rem 4 doing rem |= 1 would change it to 5, 178 1.1 mrg but we don't want to change it in that case. */ 179 1.1 mrg if (e == 1) 180 1.1 mrg { 181 1.1 mrg if (rem == 5) 182 1.1 mrg rem = 6; 183 1.1 mrg else if (rem != 4) 184 1.1 mrg rem |= 1; 185 1.1 mrg } 186 1.1 mrg else 187 1.1 mrg rem |= 1; 188 1.1 mrg } 189 1.1 mrg /* Set inexact to 0, 1, 2, 3 depending on if remainder 190 1.1 mrg of the divisions is exact 0, smaller than 10^exponent / 2, 191 1.1 mrg exactly 10^exponent / 2 or greater than that. */ 192 1.1 mrg if (rem >= half) 193 1.1 mrg inexact = 2 + (rem > half); 194 1.1 mrg else 195 1.1 mrg inexact = (rem != 0); 196 1.1 mrg mantissa = buf[q_limbs + pow10_limbs * 2 + 1]; 197 1.1 mrg } 198 1.1 mrg else 199 1.1 mrg #if BIL_TYPE_SIZE == 64 200 1.1 mrg mantissa = buf[0]; 201 1.1 mrg #else 202 1.1 mrg mantissa = buf[BITINT_END (1, 0)]; 203 1.1 mrg #endif 204 1.1 mrg } 205 1.1 mrg else 206 1.1 mrg { 207 1.1 mrg mantissa = msb; 208 1.1 mrg if (iprec < 0) 209 1.1 mrg mantissa = -mantissa; 210 1.1 mrg } 211 1.1 mrg 212 1.1 mrg exponent += 101; 213 1.1 mrg if (mantissa >= (USItype) 0x800000) 214 1.1 mrg u.u = (((((iprec < 0) << 2) | (USItype) 3) << 29) 215 1.1 mrg | (((USItype) exponent) << 21) 216 1.1 mrg | (mantissa ^ (USItype) 0x800000)); 217 1.1 mrg else 218 1.1 mrg u.u = ((((USItype) (iprec < 0)) << 31) 219 1.1 mrg | (((USItype) exponent) << 23) 220 1.1 mrg | mantissa); 221 1.1 mrg if (inexact) 222 1.1 mrg { 223 1.1 mrg ui.u = ((((USItype) (iprec < 0)) << 31) 224 1.1 mrg | (((USItype) (exponent - 1)) << 23) 225 1.1 mrg | (inexact + 3)); 226 1.1 mrg __asm ("" : "+g" (u.d)); 227 1.1 mrg __asm ("" : "+g" (ui.d)); 228 1.1 mrg u.d += ui.d; 229 1.1 mrg __asm ("" : "+g" (u.d)); 230 1.1 mrg } 231 1.1 mrg 232 1.1 mrg done: 233 1.1 mrg return u.d; 234 1.1 mrg } 235 1.1 mrg #endif 236