1 /* Software floating-point emulation. 2 Definitions for IEEE Quad Precision on the PowerPC. 3 Copyright (C) 2016-2018 Free Software Foundation, Inc. 4 This file is part of the GNU C Library. 5 Contributed by Michael Meissner (meissner@linux.vnet.ibm.com). 6 7 The GNU C Library is free software; you can redistribute it and/or 8 modify it under the terms of the GNU Lesser General Public 9 License as published by the Free Software Foundation; either 10 version 2.1 of the License, or (at your option) any later version. 11 12 In addition to the permissions in the GNU Lesser General Public 13 License, the Free Software Foundation gives you unlimited 14 permission to link the compiled version of this file into 15 combinations with other programs, and to distribute those 16 combinations without any restriction coming from the use of this 17 file. (The Lesser General Public License restrictions do apply in 18 other respects; for example, they cover modification of the file, 19 and distribution when not linked into a combine executable.) 20 21 The GNU C Library is distributed in the hope that it will be useful, 22 but WITHOUT ANY WARRANTY; without even the implied warranty of 23 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 24 Lesser General Public License for more details. 25 26 You should have received a copy of the GNU Lesser General Public 27 License along with the GNU C Library; if not, see 28 <http://www.gnu.org/licenses/>. */ 29 30 /* quad.h defines the TFtype type by: 31 typedef float TFtype __attribute__ ((mode (TF))); 32 33 This define forces it to use KFmode (aka, ieee 128-bit floating point). 34 However, when the compiler's default is changed so that long double is IEEE 35 128-bit floating point, we need to go back to using TFmode and TCmode. */ 36 #ifndef __LONG_DOUBLE_IEEE128__ 37 #define TF KF 38 39 /* We also need TCtype to represent complex ieee 128-bit float for 40 __mulkc3 and __divkc3. */ 41 typedef __complex float TCtype __attribute__ ((mode (KC))); 42 43 #else 44 typedef __complex float TCtype __attribute__ ((mode (TC))); 45 #endif 46 47 /* Force the use of the VSX instruction set. */ 48 #if defined(_ARCH_PPC) && (!defined(__VSX__) || !defined(__FLOAT128__)) 49 #pragma GCC target ("vsx,float128") 50 #endif 51 52 #include <quad.h> 53 54 #define IBM128_TYPE __ibm128 55 56 /* Add prototypes of the library functions created. In case the appropriate 57 int/long types are not declared in scope by the time quad.h is included, 58 provide our own version. */ 59 typedef int SItype_ppc __attribute__ ((__mode__ (__SI__))); 60 typedef int DItype_ppc __attribute__ ((__mode__ (__DI__))); 61 typedef unsigned USItype_ppc __attribute__ ((__mode__ (__SI__))); 62 typedef unsigned UDItype_ppc __attribute__ ((__mode__ (__DI__))); 63 64 #ifdef _ARCH_PPC64 65 typedef int TItype_ppc __attribute__ ((__mode__ (__TI__))); 66 typedef unsigned UTItype_ppc __attribute__ ((__mode__ (__TI__))); 67 #endif 68 69 /* Software emulation functions. */ 70 extern TFtype __addkf3_sw (TFtype, TFtype); 71 extern TFtype __subkf3_sw (TFtype, TFtype); 72 extern TFtype __mulkf3_sw (TFtype, TFtype); 73 extern TFtype __divkf3_sw (TFtype, TFtype); 74 extern TFtype __negkf2_sw (TFtype); 75 extern TFtype __powikf2_sw (TFtype, SItype_ppc); 76 extern CMPtype __eqkf2_sw (TFtype, TFtype); 77 extern CMPtype __gekf2_sw (TFtype, TFtype); 78 extern CMPtype __lekf2_sw (TFtype, TFtype); 79 extern CMPtype __unordkf2_sw (TFtype, TFtype); 80 extern TFtype __extendsfkf2_sw (float); 81 extern TFtype __extenddfkf2_sw (double); 82 extern float __trunckfsf2_sw (TFtype); 83 extern double __trunckfdf2_sw (TFtype); 84 extern SItype_ppc __fixkfsi_sw (TFtype); 85 extern DItype_ppc __fixkfdi_sw (TFtype); 86 extern USItype_ppc __fixunskfsi_sw (TFtype); 87 extern UDItype_ppc __fixunskfdi_sw (TFtype); 88 extern TFtype __floatsikf_sw (SItype_ppc); 89 extern TFtype __floatdikf_sw (DItype_ppc); 90 extern TFtype __floatunsikf_sw (USItype_ppc); 91 extern TFtype __floatundikf_sw (UDItype_ppc); 92 extern IBM128_TYPE __extendkftf2_sw (TFtype); 93 extern TFtype __trunctfkf2_sw (IBM128_TYPE); 94 extern TCtype __mulkc3_sw (TFtype, TFtype, TFtype, TFtype); 95 extern TCtype __divkc3_sw (TFtype, TFtype, TFtype, TFtype); 96 97 #ifdef _ARCH_PPC64 98 /* We do not provide ifunc resolvers for __fixkfti, __fixunskfti, __floattikf, 99 and __floatuntikf. There is no ISA 3.0 instruction that converts between 100 128-bit integer types and 128-bit IEEE floating point, or vice versa. So 101 use the emulator functions for these conversions. */ 102 103 extern TItype_ppc __fixkfti (TFtype); 104 extern UTItype_ppc __fixunskfti (TFtype); 105 extern TFtype __floattikf (TItype_ppc); 106 extern TFtype __floatuntikf (UTItype_ppc); 107 #endif 108 109 /* Functions using the ISA 3.0 hardware support. If the code is compiled with 110 -mcpu=power9, it will not use these functions, but if it was compiled with 111 -mcpu=power7 or -mcpu=power8 and run on a ISA 3.0 system, it will use the 112 hardware instruction. */ 113 extern TFtype __addkf3_hw (TFtype, TFtype); 114 extern TFtype __subkf3_hw (TFtype, TFtype); 115 extern TFtype __mulkf3_hw (TFtype, TFtype); 116 extern TFtype __divkf3_hw (TFtype, TFtype); 117 extern TFtype __negkf2_hw (TFtype); 118 extern TFtype __powikf2_hw (TFtype, SItype_ppc); 119 extern CMPtype __eqkf2_hw (TFtype, TFtype); 120 extern CMPtype __gekf2_hw (TFtype, TFtype); 121 extern CMPtype __lekf2_hw (TFtype, TFtype); 122 extern CMPtype __unordkf2_hw (TFtype, TFtype); 123 extern TFtype __extendsfkf2_hw (float); 124 extern TFtype __extenddfkf2_hw (double); 125 extern float __trunckfsf2_hw (TFtype); 126 extern double __trunckfdf2_hw (TFtype); 127 extern SItype_ppc __fixkfsi_hw (TFtype); 128 extern DItype_ppc __fixkfdi_hw (TFtype); 129 extern USItype_ppc __fixunskfsi_hw (TFtype); 130 extern UDItype_ppc __fixunskfdi_hw (TFtype); 131 extern TFtype __floatsikf_hw (SItype_ppc); 132 extern TFtype __floatdikf_hw (DItype_ppc); 133 extern TFtype __floatunsikf_hw (USItype_ppc); 134 extern TFtype __floatundikf_hw (UDItype_ppc); 135 extern IBM128_TYPE __extendkftf2_hw (TFtype); 136 extern TFtype __trunctfkf2_hw (IBM128_TYPE); 137 extern TCtype __mulkc3_hw (TFtype, TFtype, TFtype, TFtype); 138 extern TCtype __divkc3_hw (TFtype, TFtype, TFtype, TFtype); 139 140 /* Ifunc function declarations, to automatically switch between software 141 emulation and hardware support. */ 142 extern TFtype __addkf3 (TFtype, TFtype); 143 extern TFtype __subkf3 (TFtype, TFtype); 144 extern TFtype __mulkf3 (TFtype, TFtype); 145 extern TFtype __divkf3 (TFtype, TFtype); 146 extern TFtype __negkf2 (TFtype); 147 extern TFtype __powikf2 (TFtype, SItype_ppc); 148 extern CMPtype __eqkf2 (TFtype, TFtype); 149 extern CMPtype __nekf2 (TFtype, TFtype); 150 extern CMPtype __gekf2 (TFtype, TFtype); 151 extern CMPtype __gtkf2 (TFtype, TFtype); 152 extern CMPtype __lekf2 (TFtype, TFtype); 153 extern CMPtype __ltkf2 (TFtype, TFtype); 154 extern CMPtype __unordkf2 (TFtype, TFtype); 155 extern TFtype __extendsfkf2 (float); 156 extern TFtype __extenddfkf2 (double); 157 extern float __trunckfsf2 (TFtype); 158 extern double __trunckfdf2 (TFtype); 159 extern SItype_ppc __fixkfsi (TFtype); 160 extern DItype_ppc __fixkfdi (TFtype); 161 extern USItype_ppc __fixunskfsi (TFtype); 162 extern UDItype_ppc __fixunskfdi (TFtype); 163 extern TFtype __floatsikf (SItype_ppc); 164 extern TFtype __floatdikf (DItype_ppc); 165 extern TFtype __floatunsikf (USItype_ppc); 166 extern TFtype __floatundikf (UDItype_ppc); 167 extern IBM128_TYPE __extendkftf2 (TFtype); 168 extern TFtype __trunctfkf2 (IBM128_TYPE); 169 170 /* Complex __float128 built on __float128 interfaces. */ 171 extern TCtype __mulkc3 (TFtype, TFtype, TFtype, TFtype); 172 extern TCtype __divkc3 (TFtype, TFtype, TFtype, TFtype); 173 174 /* Implementation of conversions between __ibm128 and __float128, to allow the 175 same code to be used on systems with IEEE 128-bit emulation and with IEEE 176 128-bit hardware support. */ 177 178 union ibm128_union { 179 IBM128_TYPE ibm128; 180 double dbl[2]; 181 }; 182 183 #define CVT_FLOAT128_TO_IBM128(RESULT, VALUE) \ 184 { \ 185 double __high, __low; \ 186 TFtype __value = (VALUE); \ 187 union ibm128_union u; \ 188 \ 189 __high = (double) __value; \ 190 if (__builtin_isnan (__high) || __builtin_isinf (__high)) \ 191 __low = 0.0; \ 192 \ 193 else \ 194 { \ 195 double __high_temp; \ 196 \ 197 __low = (double) (__value - (TFtype) __high); \ 198 /* Renormalize low/high and move them into canonical IBM long \ 199 double form. */ \ 200 __high_temp = __high + __low; \ 201 __low = (__high - __high_temp) + __low; \ 202 __high = __high_temp; \ 203 } \ 204 \ 205 u.dbl[0] = __high; \ 206 u.dbl[1] = __low; \ 207 RESULT = u.ibm128; \ 208 } 209 210 #define CVT_IBM128_TO_FLOAT128(RESULT, VALUE) \ 211 { \ 212 union ibm128_union u; \ 213 double __high, __low; \ 214 \ 215 u.ibm128 = (VALUE); \ 216 __high = u.dbl[0]; \ 217 __low = u.dbl[1]; \ 218 \ 219 /* Handle the special cases of NAN and infinity. */ \ 220 if (__builtin_isnan (__high) || __builtin_isinf (__high)) \ 221 RESULT = (TFtype) __high; \ 222 \ 223 /* If low is 0.0, there no need to do the add. In addition, \ 224 avoiding the add produces the correct sign if high is -0.0. */ \ 225 else if (__low == 0.0) \ 226 RESULT = (TFtype) __high; \ 227 \ 228 else \ 229 RESULT = ((TFtype) __high) + ((TFtype) __low); \ 230 } 231