1 1.1 mrg /* Software floating-point emulation. 2 1.1 mrg Convert _Decimal32 to signed or unsigned _BitInt. 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 void __bid_fixsdbitint (UBILtype *, SItype, _Decimal32); 32 1.1 mrg 33 1.1 mrg void 34 1.1 mrg __bid_fixsdbitint (UBILtype *r, SItype rprec, _Decimal32 a) 35 1.1 mrg { 36 1.1 mrg FP_DECL_EX; 37 1.1 mrg USItype arprec = rprec < 0 ? -rprec : rprec; 38 1.1 mrg USItype rn = (arprec + BIL_TYPE_SIZE - 1) / BIL_TYPE_SIZE; 39 1.1 mrg union { _Decimal32 d; USItype u; } u; 40 1.1 mrg USItype mantissa, t; 41 1.1 mrg SItype sgn; 42 1.1 mrg SItype exponent; 43 1.1 mrg USItype exp_bits, mant_bits; 44 1.1 mrg UBILtype *pow10v, *resv; 45 1.1 mrg USItype pow10_limbs, res_limbs, min_limbs, mant_limbs, low_zeros; 46 1.1 mrg 47 1.1 mrg FP_INIT_EXCEPTIONS; 48 1.1 mrg u.d = a; 49 1.1 mrg t = u.u >> 21; 50 1.1 mrg sgn = (SItype) u.u < 0; 51 1.1 mrg if ((t & (3 << 8)) != (3 << 8)) 52 1.1 mrg { 53 1.1 mrg mantissa = u.u & ((((USItype) 1) << 23) - 1); 54 1.1 mrg exponent = (t >> 2) & 0xff; 55 1.1 mrg } 56 1.1 mrg else if ((t & (3 << 6)) != (3 << 6)) 57 1.1 mrg { 58 1.1 mrg mantissa = u.u & ((((USItype) 1) << 21) - 1); 59 1.1 mrg mantissa |= ((USItype) 1) << 23; 60 1.1 mrg exponent = t & 0xff; 61 1.1 mrg if (mantissa > (USItype) 9999999) 62 1.1 mrg mantissa = 0; 63 1.1 mrg } 64 1.1 mrg else 65 1.1 mrg { 66 1.1 mrg FP_SET_EXCEPTION (FP_EX_INVALID 67 1.1 mrg | FP_EX_INVALID_CVI 68 1.1 mrg | ((FP_EX_INVALID_SNAN 69 1.1 mrg && ((t & 0x20)) != 0) 70 1.1 mrg ? FP_EX_INVALID_SNAN : 0)); 71 1.1 mrg ovf: 72 1.1 mrg if (!sgn) 73 1.1 mrg __builtin_memset (r, -1, rn * sizeof (UBILtype)); 74 1.1 mrg else 75 1.1 mrg __builtin_memset (r, 0, rn * sizeof (UBILtype)); 76 1.1 mrg if (sgn ^ (rprec >= 0)) 77 1.1 mrg r[BITINT_END (0, rn - 1)] 78 1.1 mrg |= (UBILtype) -1 << ((arprec - 1) % BIL_TYPE_SIZE); 79 1.1 mrg else 80 1.1 mrg r[BITINT_END (0, rn - 1)] 81 1.1 mrg &= ~((UBILtype) -1 << ((arprec - 1) % BIL_TYPE_SIZE)); 82 1.1 mrg goto done; 83 1.1 mrg } 84 1.1 mrg exponent -= 101; 85 1.1 mrg 86 1.1 mrg if (mantissa == 0) 87 1.1 mrg { 88 1.1 mrg /* Zero (with any exponent). */ 89 1.1 mrg zero: 90 1.1 mrg __builtin_memset (r, 0, rn * sizeof (UBILtype)); 91 1.1 mrg goto done; 92 1.1 mrg } 93 1.1 mrg if (exponent <= -7) 94 1.1 mrg { 95 1.1 mrg FP_SET_EXCEPTION (FP_EX_INEXACT); 96 1.1 mrg goto zero; 97 1.1 mrg } 98 1.1 mrg else if (exponent < 0) 99 1.1 mrg { 100 1.1 mrg UBILtype limbs[64 / BIL_TYPE_SIZE]; 101 1.1 mrg USItype rem; 102 1.1 mrg UDItype d; 103 1.1 mrg __bid_pow10bitint (limbs, 64, -exponent); 104 1.1 mrg #if BIL_TYPE_SIZE == 64 105 1.1 mrg d = limbs[0]; 106 1.1 mrg #elif BIL_TYPE_SIZE == 32 107 1.1 mrg d = (UDItype) limbs[BITINT_END (0, 1)] << 32 | limbs[BITINT_END (1, 0)]; 108 1.1 mrg #else 109 1.1 mrg # error Unsupported BIL_TYPE_SIZE 110 1.1 mrg #endif 111 1.1 mrg rem = mantissa % (USItype) d; 112 1.1 mrg mantissa /= (USItype) d; 113 1.1 mrg if (rem) 114 1.1 mrg FP_SET_EXCEPTION (FP_EX_INEXACT); 115 1.1 mrg if (mantissa == 0) 116 1.1 mrg goto zero; 117 1.1 mrg exponent = 0; 118 1.1 mrg } 119 1.1 mrg 120 1.1 mrg if (rprec >= 0 && sgn) 121 1.1 mrg { 122 1.1 mrg ovf_ex: 123 1.1 mrg FP_SET_EXCEPTION (FP_EX_INVALID | FP_EX_INVALID_CVI); 124 1.1 mrg goto ovf; 125 1.1 mrg } 126 1.1 mrg 127 1.1 mrg /* Lower estimate for number of bits needed for pow10 (exponent). */ 128 1.1 mrg exp_bits = exponent / 3; 129 1.1 mrg exp_bits = exp_bits * 10 - exp_bits / 29; 130 1.1 mrg mant_bits = sizeof (0ULL) * __CHAR_BIT__ - __builtin_clzll (mantissa); 131 1.1 mrg if (exp_bits + mant_bits > arprec + 1) 132 1.1 mrg goto ovf_ex; 133 1.1 mrg /* Upper estimate for number of bits needed for pow10 (exponent). */ 134 1.1 mrg exp_bits = (exponent + 2) / 3; 135 1.1 mrg exp_bits = exp_bits * 10 - exp_bits / 30; 136 1.1 mrg if (exp_bits == 0) 137 1.1 mrg exp_bits = 1; 138 1.1 mrg pow10_limbs = (exp_bits + BIL_TYPE_SIZE - 1) / BIL_TYPE_SIZE; 139 1.1 mrg pow10v = __builtin_alloca (pow10_limbs * sizeof (UBILtype)); 140 1.1 mrg low_zeros = __bid_pow10bitint (pow10v, exp_bits, exponent); 141 1.1 mrg 142 1.1 mrg res_limbs = ((exp_bits + mant_bits + BIL_TYPE_SIZE - 1) 143 1.1 mrg / BIL_TYPE_SIZE) - low_zeros; 144 1.1 mrg mant_limbs = 1; 145 1.1 mrg resv = __builtin_alloca ((res_limbs + mant_limbs) * sizeof (UBILtype)); 146 1.1 mrg resv[res_limbs] = mantissa; 147 1.1 mrg __mulbitint3 (resv, exp_bits + mant_bits - low_zeros * BIL_TYPE_SIZE, 148 1.1 mrg resv + res_limbs, mant_bits, 149 1.1 mrg pow10v + BITINT_END (0, low_zeros), 150 1.1 mrg exp_bits - low_zeros * BIL_TYPE_SIZE); 151 1.1 mrg if (res_limbs + low_zeros >= rn) 152 1.1 mrg { 153 1.1 mrg if (res_limbs + low_zeros > rn && resv[BITINT_END (0, res_limbs - 1)]) 154 1.1 mrg goto ovf_ex; 155 1.1 mrg if ((arprec % BIL_TYPE_SIZE) != 0 156 1.1 mrg && (resv[BITINT_END (rn - res_limbs, rn - 1) - low_zeros] 157 1.1 mrg & ((UBILtype) -1 << (arprec % BIL_TYPE_SIZE))) != 0) 158 1.1 mrg goto ovf_ex; 159 1.1 mrg min_limbs = rn - low_zeros; 160 1.1 mrg } 161 1.1 mrg else 162 1.1 mrg min_limbs = res_limbs; 163 1.1 mrg if (low_zeros) 164 1.1 mrg __builtin_memset (r + BITINT_END (rn - low_zeros, 0), '\0', 165 1.1 mrg low_zeros * sizeof (UBILtype)); 166 1.1 mrg if (sgn) 167 1.1 mrg bitint_negate (r + BITINT_END (rn - low_zeros - 1, low_zeros), 168 1.1 mrg resv + BITINT_END (res_limbs - 1, 0), min_limbs); 169 1.1 mrg else 170 1.1 mrg __builtin_memcpy (r + BITINT_END (rn - low_zeros - min_limbs, low_zeros), 171 1.1 mrg resv + BITINT_END (res_limbs - min_limbs, 0), 172 1.1 mrg min_limbs * sizeof (UBILtype)); 173 1.1 mrg if (res_limbs + low_zeros < rn) 174 1.1 mrg { 175 1.1 mrg if (sgn) 176 1.1 mrg __builtin_memset (r + BITINT_END (0, res_limbs + low_zeros), -1, 177 1.1 mrg (rn - res_limbs - low_zeros) * sizeof (UBILtype)); 178 1.1 mrg else 179 1.1 mrg __builtin_memset (r + BITINT_END (0, res_limbs + low_zeros), '\0', 180 1.1 mrg (rn - res_limbs - low_zeros) * sizeof (UBILtype)); 181 1.1 mrg } 182 1.1 mrg else if (sgn) 183 1.1 mrg { 184 1.1 mrg if ((r[BITINT_END (0, rn - 1)] 185 1.1 mrg & ((UBILtype) 1 << ((arprec - 1) % BIL_TYPE_SIZE))) == 0) 186 1.1 mrg goto ovf_ex; 187 1.1 mrg } 188 1.1 mrg else if (rprec < 0 189 1.1 mrg && (r[BITINT_END (0, rn - 1)] 190 1.1 mrg & ((UBILtype) 1 << ((arprec - 1) % BIL_TYPE_SIZE))) != 0) 191 1.1 mrg goto ovf_ex; 192 1.1 mrg 193 1.1 mrg done: 194 1.1 mrg FP_HANDLE_EXCEPTIONS; 195 1.1 mrg } 196 1.1 mrg #endif 197