1 1.1.1.9 mrg /* Copyright (C) 1989-2024 Free Software Foundation, Inc. 2 1.1 mrg 3 1.1 mrg This file is part of GCC. 4 1.1 mrg 5 1.1 mrg GCC is free software; you can redistribute it and/or modify it under 6 1.1 mrg the terms of the GNU General Public License as published by the Free 7 1.1 mrg Software Foundation; either version 3, or (at your option) any later 8 1.1 mrg version. 9 1.1 mrg 10 1.1 mrg GCC is distributed in the hope that it will be useful, but WITHOUT ANY 11 1.1 mrg WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 1.1 mrg FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 1.1 mrg for more details. 14 1.1 mrg 15 1.1 mrg Under Section 7 of GPL version 3, you are granted additional 16 1.1 mrg permissions described in the GCC Runtime Library Exception, version 17 1.1 mrg 3.1, as published by the Free Software Foundation. 18 1.1 mrg 19 1.1 mrg You should have received a copy of the GNU General Public License and 20 1.1 mrg a copy of the GCC Runtime Library Exception along with this program; 21 1.1 mrg see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 22 1.1 mrg <http://www.gnu.org/licenses/>. */ 23 1.1 mrg 24 1.1 mrg /* This is a temporary specialization of code from libgcc/libgcc2.c. */ 25 1.1 mrg 26 1.1.1.5 mrg #include "soft-fp.h" 27 1.1.1.5 mrg #include "quad-float128.h" 28 1.1 mrg 29 1.1.1.9 mrg /* Use the correct built-in function based on whether TFmode is _Float128 or 30 1.1.1.9 mrg long double. See quad-float128.h for more details. */ 31 1.1.1.9 mrg #ifndef __LONG_DOUBLE_IEEE128__ 32 1.1.1.5 mrg #define COPYSIGN(x,y) __builtin_copysignf128 (x, y) 33 1.1.1.5 mrg #define INFINITY __builtin_inff128 () 34 1.1.1.5 mrg #define FABS __builtin_fabsf128 35 1.1.1.9 mrg 36 1.1.1.9 mrg #else 37 1.1.1.9 mrg #define COPYSIGN(x,y) __builtin_copysignl (x, y) 38 1.1.1.9 mrg #define INFINITY __builtin_infl () 39 1.1.1.9 mrg #define FABS __builtin_fabsl 40 1.1.1.9 mrg #endif 41 1.1.1.9 mrg 42 1.1 mrg #define isnan __builtin_isnan 43 1.1 mrg #define isinf __builtin_isinf 44 1.1 mrg #define isfinite __builtin_isfinite 45 1.1 mrg 46 1.1.1.5 mrg #if defined(FLOAT128_HW_INSNS) && !defined(__divkc3) 47 1.1.1.5 mrg #define __divkc3 __divkc3_sw 48 1.1.1.5 mrg #endif 49 1.1.1.5 mrg 50 1.1.1.8 mrg #ifndef __LONG_DOUBLE_IEEE128__ 51 1.1.1.8 mrg #define RBIG (__LIBGCC_KF_MAX__ / 2) 52 1.1.1.8 mrg #define RMIN (__LIBGCC_KF_MIN__) 53 1.1.1.8 mrg #define RMIN2 (__LIBGCC_KF_EPSILON__) 54 1.1.1.8 mrg #define RMINSCAL (1 / __LIBGCC_KF_EPSILON__) 55 1.1.1.8 mrg #define RMAX2 (RBIG * RMIN2) 56 1.1.1.8 mrg #else 57 1.1.1.8 mrg #define RBIG (__LIBGCC_TF_MAX__ / 2) 58 1.1.1.8 mrg #define RMIN (__LIBGCC_TF_MIN__) 59 1.1.1.8 mrg #define RMIN2 (__LIBGCC_TF_EPSILON__) 60 1.1.1.8 mrg #define RMINSCAL (1 / __LIBGCC_TF_EPSILON__) 61 1.1.1.8 mrg #define RMAX2 (RBIG * RMIN2) 62 1.1.1.8 mrg #endif 63 1.1.1.8 mrg 64 1.1.1.5 mrg TCtype 65 1.1.1.5 mrg __divkc3 (TFtype a, TFtype b, TFtype c, TFtype d) 66 1.1 mrg { 67 1.1.1.5 mrg TFtype denom, ratio, x, y; 68 1.1.1.5 mrg TCtype res; 69 1.1 mrg 70 1.1.1.8 mrg /* long double has significant potential underflow/overflow errors that 71 1.1.1.8 mrg can be greatly reduced with a limited number of tests and adjustments. 72 1.1.1.8 mrg */ 73 1.1.1.8 mrg 74 1.1.1.8 mrg /* Scale by max(c,d) to reduce chances of denominator overflowing. */ 75 1.1 mrg if (FABS (c) < FABS (d)) 76 1.1 mrg { 77 1.1.1.8 mrg /* Prevent underflow when denominator is near max representable. */ 78 1.1.1.8 mrg if (FABS (d) >= RBIG) 79 1.1.1.8 mrg { 80 1.1.1.8 mrg a = a / 2; 81 1.1.1.8 mrg b = b / 2; 82 1.1.1.8 mrg c = c / 2; 83 1.1.1.8 mrg d = d / 2; 84 1.1.1.8 mrg } 85 1.1.1.8 mrg /* Avoid overflow/underflow issues when c and d are small. 86 1.1.1.8 mrg Scaling up helps avoid some underflows. 87 1.1.1.8 mrg No new overflow possible since c&d < RMIN2. */ 88 1.1.1.8 mrg if (FABS (d) < RMIN2) 89 1.1.1.8 mrg { 90 1.1.1.8 mrg a = a * RMINSCAL; 91 1.1.1.8 mrg b = b * RMINSCAL; 92 1.1.1.8 mrg c = c * RMINSCAL; 93 1.1.1.8 mrg d = d * RMINSCAL; 94 1.1.1.8 mrg } 95 1.1.1.8 mrg else 96 1.1.1.8 mrg { 97 1.1.1.8 mrg if (((FABS (a) < RMIN) && (FABS (b) < RMAX2) && (FABS (d) < RMAX2)) 98 1.1.1.8 mrg || ((FABS (b) < RMIN) && (FABS (a) < RMAX2) 99 1.1.1.8 mrg && (FABS (d) < RMAX2))) 100 1.1.1.8 mrg { 101 1.1.1.8 mrg a = a * RMINSCAL; 102 1.1.1.8 mrg b = b * RMINSCAL; 103 1.1.1.8 mrg c = c * RMINSCAL; 104 1.1.1.8 mrg d = d * RMINSCAL; 105 1.1.1.8 mrg } 106 1.1.1.8 mrg } 107 1.1 mrg ratio = c / d; 108 1.1 mrg denom = (c * ratio) + d; 109 1.1.1.8 mrg /* Choose alternate order of computation if ratio is subnormal. */ 110 1.1.1.8 mrg if (FABS (ratio) > RMIN) 111 1.1.1.8 mrg { 112 1.1.1.8 mrg x = ((a * ratio) + b) / denom; 113 1.1.1.8 mrg y = ((b * ratio) - a) / denom; 114 1.1.1.8 mrg } 115 1.1.1.8 mrg else 116 1.1.1.8 mrg { 117 1.1.1.8 mrg x = ((c * (a / d)) + b) / denom; 118 1.1.1.8 mrg y = ((c * (b / d)) - a) / denom; 119 1.1.1.8 mrg } 120 1.1 mrg } 121 1.1 mrg else 122 1.1 mrg { 123 1.1.1.8 mrg /* Prevent underflow when denominator is near max representable. */ 124 1.1.1.8 mrg if (FABS (c) >= RBIG) 125 1.1.1.8 mrg { 126 1.1.1.8 mrg a = a / 2; 127 1.1.1.8 mrg b = b / 2; 128 1.1.1.8 mrg c = c / 2; 129 1.1.1.8 mrg d = d / 2; 130 1.1.1.8 mrg } 131 1.1.1.8 mrg /* Avoid overflow/underflow issues when both c and d are small. 132 1.1.1.8 mrg Scaling up helps avoid some underflows. 133 1.1.1.8 mrg No new overflow possible since both c&d are less than RMIN2. */ 134 1.1.1.8 mrg if (FABS (c) < RMIN2) 135 1.1.1.8 mrg { 136 1.1.1.8 mrg a = a * RMINSCAL; 137 1.1.1.8 mrg b = b * RMINSCAL; 138 1.1.1.8 mrg c = c * RMINSCAL; 139 1.1.1.8 mrg d = d * RMINSCAL; 140 1.1.1.8 mrg } 141 1.1.1.8 mrg else 142 1.1.1.8 mrg { 143 1.1.1.8 mrg if (((FABS (a) < RMIN) && (FABS (b) < RMAX2) && (FABS (c) < RMAX2)) 144 1.1.1.8 mrg || ((FABS (b) < RMIN) && (FABS (a) < RMAX2) 145 1.1.1.8 mrg && (FABS (c) < RMAX2))) 146 1.1.1.8 mrg { 147 1.1.1.8 mrg a = a * RMINSCAL; 148 1.1.1.8 mrg b = b * RMINSCAL; 149 1.1.1.8 mrg c = c * RMINSCAL; 150 1.1.1.8 mrg d = d * RMINSCAL; 151 1.1.1.8 mrg } 152 1.1.1.8 mrg } 153 1.1 mrg ratio = d / c; 154 1.1 mrg denom = (d * ratio) + c; 155 1.1.1.8 mrg /* Choose alternate order of computation if ratio is subnormal. */ 156 1.1.1.8 mrg if (FABS (ratio) > RMIN) 157 1.1.1.8 mrg { 158 1.1.1.8 mrg x = ((b * ratio) + a) / denom; 159 1.1.1.8 mrg y = (b - (a * ratio)) / denom; 160 1.1.1.8 mrg } 161 1.1.1.8 mrg else 162 1.1.1.8 mrg { 163 1.1.1.8 mrg x = (a + (d * (b / c))) / denom; 164 1.1.1.8 mrg y = (b - (d * (a / c))) / denom; 165 1.1.1.8 mrg } 166 1.1 mrg } 167 1.1 mrg 168 1.1 mrg /* Recover infinities and zeros that computed as NaN+iNaN; the only cases 169 1.1 mrg are nonzero/zero, infinite/finite, and finite/infinite. */ 170 1.1 mrg if (isnan (x) && isnan (y)) 171 1.1 mrg { 172 1.1 mrg if (c == 0.0 && d == 0.0 && (!isnan (a) || !isnan (b))) 173 1.1 mrg { 174 1.1 mrg x = COPYSIGN (INFINITY, c) * a; 175 1.1 mrg y = COPYSIGN (INFINITY, c) * b; 176 1.1 mrg } 177 1.1 mrg else if ((isinf (a) || isinf (b)) && isfinite (c) && isfinite (d)) 178 1.1 mrg { 179 1.1 mrg a = COPYSIGN (isinf (a) ? 1 : 0, a); 180 1.1 mrg b = COPYSIGN (isinf (b) ? 1 : 0, b); 181 1.1 mrg x = INFINITY * (a * c + b * d); 182 1.1 mrg y = INFINITY * (b * c - a * d); 183 1.1 mrg } 184 1.1 mrg else if ((isinf (c) || isinf (d)) && isfinite (a) && isfinite (b)) 185 1.1 mrg { 186 1.1 mrg c = COPYSIGN (isinf (c) ? 1 : 0, c); 187 1.1 mrg d = COPYSIGN (isinf (d) ? 1 : 0, d); 188 1.1 mrg x = 0.0 * (a * c + b * d); 189 1.1 mrg y = 0.0 * (b * c - a * d); 190 1.1 mrg } 191 1.1 mrg } 192 1.1 mrg 193 1.1 mrg __real__ res = x; 194 1.1 mrg __imag__ res = y; 195 1.1 mrg return res; 196 1.1 mrg } 197