1 /* Automatic switching between software and hardware IEEE 128-bit 2 floating-point emulation for PowerPC. 3 4 Copyright (C) 2016-2017 Free Software Foundation, Inc. 5 This file is part of the GNU C Library. 6 Contributed by Michael Meissner (meissner@linux.vnet.ibm.com) 7 Code is based on the main soft-fp library written by: 8 Richard Henderson (rth@cygnus.com) and 9 Jakub Jelinek (jj@ultra.linux.cz). 10 11 The GNU C Library is free software; you can redistribute it and/or 12 modify it under the terms of the GNU Lesser General Public 13 License as published by the Free Software Foundation; either 14 version 2.1 of the License, or (at your option) any later version. 15 16 In addition to the permissions in the GNU Lesser General Public 17 License, the Free Software Foundation gives you unlimited 18 permission to link the compiled version of this file into 19 combinations with other programs, and to distribute those 20 combinations without any restriction coming from the use of this 21 file. (The Lesser General Public License restrictions do apply in 22 other respects; for example, they cover modification of the file, 23 and distribution when not linked into a combine executable.) 24 25 The GNU C Library is distributed in the hope that it will be useful, 26 but WITHOUT ANY WARRANTY; without even the implied warranty of 27 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 28 Lesser General Public License for more details. 29 30 You should have received a copy of the GNU Lesser General Public 31 License along with the GNU C Library; if not, see 32 <http://www.gnu.org/licenses/>. */ 33 34 #include <soft-fp.h> 35 #include <quad-float128.h> 36 #include <string.h> 37 #include <stdlib.h> 38 #include <ctype.h> 39 40 #ifndef FLOAT128_HW_INSNS 41 #error "float128-ifunc.c needs access to ISA 3.0 instructions and ifunc" 42 #endif 43 44 #ifdef __FLOAT128_HARDWARE__ 45 #error "This module must not be compiled with IEEE 128-bit hardware support" 46 #endif 47 48 #define SW_OR_HW(SW, HW) (__builtin_cpu_supports ("ieee128") ? HW : SW) 49 50 /* Resolvers. */ 51 52 /* We do not provide ifunc resolvers for __fixkfti, __fixunskfti, __floattikf, 53 and __floatuntikf. There is no ISA 3.0 instruction that converts between 54 128-bit integer types and 128-bit IEEE floating point, or vice versa. So 55 use the emulator functions for these conversions. */ 56 57 static void *__addkf3_resolve (void); 58 static void *__subkf3_resolve (void); 59 static void *__mulkf3_resolve (void); 60 static void *__divkf3_resolve (void); 61 static void *__negkf2_resolve (void); 62 static void *__eqkf2_resolve (void); 63 static void *__nekf2_resolve (void); 64 static void *__gekf2_resolve (void); 65 static void *__gtkf2_resolve (void); 66 static void *__lekf2_resolve (void); 67 static void *__ltkf2_resolve (void); 68 static void *__unordkf2_resolve (void); 69 static void *__extendsfkf2_resolve (void); 70 static void *__extenddfkf2_resolve (void); 71 static void *__trunckfsf2_resolve (void); 72 static void *__trunckfdf2_resolve (void); 73 static void *__fixkfsi_resolve (void); 74 static void *__fixkfdi_resolve (void); 75 static void *__fixunskfsi_resolve (void); 76 static void *__fixunskfdi_resolve (void); 77 static void *__floatsikf_resolve (void); 78 static void *__floatdikf_resolve (void); 79 static void *__floatunsikf_resolve (void); 80 static void *__floatundikf_resolve (void); 81 static void *__extendkftf2_resolve (void); 82 static void *__trunctfkf2_resolve (void); 83 84 static void * 85 __addkf3_resolve (void) 86 { 87 return (void *) SW_OR_HW (__addkf3_sw, __addkf3_hw); 88 } 89 90 static void * 91 __subkf3_resolve (void) 92 { 93 return (void *) SW_OR_HW (__subkf3_sw, __subkf3_hw); 94 } 95 96 static void * 97 __mulkf3_resolve (void) 98 { 99 return (void *) SW_OR_HW (__mulkf3_sw, __mulkf3_hw); 100 } 101 102 static void * 103 __divkf3_resolve (void) 104 { 105 return (void *) SW_OR_HW (__divkf3_sw, __divkf3_hw); 106 } 107 108 static void * 109 __negkf2_resolve (void) 110 { 111 return (void *) SW_OR_HW (__negkf2_sw, __negkf2_hw); 112 } 113 114 static void * 115 __floatsikf_resolve (void) 116 { 117 return (void *) SW_OR_HW (__floatsikf_sw, __floatsikf_hw); 118 } 119 120 static void * 121 __floatdikf_resolve (void) 122 { 123 return (void *) SW_OR_HW (__floatdikf_sw, __floatdikf_hw); 124 } 125 126 static void * 127 __floatunsikf_resolve (void) 128 { 129 return (void *) SW_OR_HW (__floatunsikf_sw, __floatunsikf_hw); 130 } 131 132 static void * 133 __floatundikf_resolve (void) 134 { 135 return (void *) SW_OR_HW (__floatundikf_sw, __floatundikf_hw); 136 } 137 138 static void * 139 __fixkfsi_resolve (void) 140 { 141 return (void *) SW_OR_HW (__fixkfsi_sw, __fixkfsi_hw); 142 } 143 144 static void * 145 __fixkfdi_resolve (void) 146 { 147 return (void *) SW_OR_HW (__fixkfdi_sw, __fixkfdi_hw); 148 } 149 150 static void * 151 __fixunskfsi_resolve (void) 152 { 153 return (void *) SW_OR_HW (__fixunskfsi_sw, __fixunskfsi_hw); 154 } 155 156 static void * 157 __fixunskfdi_resolve (void) 158 { 159 return (void *) SW_OR_HW (__fixunskfdi_sw, __fixunskfdi_hw); 160 } 161 162 static void * 163 __extendsfkf2_resolve (void) 164 { 165 return (void *) SW_OR_HW (__extendsfkf2_sw, __extendsfkf2_hw); 166 } 167 168 static void * 169 __extenddfkf2_resolve (void) 170 { 171 return (void *) SW_OR_HW (__extenddfkf2_sw, __extenddfkf2_hw); 172 } 173 174 static void * 175 __trunckfsf2_resolve (void) 176 { 177 return (void *) SW_OR_HW (__trunckfsf2_sw, __trunckfsf2_hw); 178 } 179 180 static void * 181 __trunckfdf2_resolve (void) 182 { 183 return (void *) SW_OR_HW (__trunckfdf2_sw, __trunckfdf2_hw); 184 } 185 186 static void * 187 __extendkftf2_resolve (void) 188 { 189 return (void *) SW_OR_HW (__extendkftf2_sw, __extendkftf2_hw); 190 } 191 192 static void * 193 __trunctfkf2_resolve (void) 194 { 195 return (void *) SW_OR_HW (__trunctfkf2_sw, __trunctfkf2_hw); 196 } 197 198 static void * 199 __eqkf2_resolve (void) 200 { 201 return (void *) SW_OR_HW (__eqkf2_sw, __eqkf2_hw); 202 } 203 204 static void * 205 __gekf2_resolve (void) 206 { 207 return (void *) SW_OR_HW (__gekf2_sw, __gekf2_hw); 208 } 209 210 static void * 211 __lekf2_resolve (void) 212 { 213 return (void *) SW_OR_HW (__lekf2_sw, __lekf2_hw); 214 } 215 216 static void * 217 __unordkf2_resolve (void) 218 { 219 return (void *) SW_OR_HW (__unordkf2_sw, __unordkf2_hw); 220 } 221 222 /* Resolve __nekf2, __gtkf2, __ltkf2 like __eqkf2, __gekf2, and __lekf2, since 223 the functions return the same values. */ 224 225 static void * 226 __nekf2_resolve (void) 227 { 228 return (void *) SW_OR_HW (__eqkf2_sw, __eqkf2_hw); 229 } 230 231 static void * 232 __gtkf2_resolve (void) 233 { 234 return (void *) SW_OR_HW (__gekf2_sw, __gekf2_hw); 235 } 236 237 static void * 238 __ltkf2_resolve (void) 239 { 240 return (void *) SW_OR_HW (__lekf2_sw, __lekf2_hw); 241 } 242 243 244 245 /* Ifunc definitions. */ 246 TFtype __addkf3 (TFtype, TFtype) 247 __attribute__ ((__ifunc__ ("__addkf3_resolve"))); 248 249 TFtype __subkf3 (TFtype, TFtype) 250 __attribute__ ((__ifunc__ ("__subkf3_resolve"))); 251 252 TFtype __mulkf3 (TFtype, TFtype) 253 __attribute__ ((__ifunc__ ("__mulkf3_resolve"))); 254 255 TFtype __divkf3 (TFtype, TFtype) 256 __attribute__ ((__ifunc__ ("__divkf3_resolve"))); 257 258 TFtype __negkf2 (TFtype) 259 __attribute__ ((__ifunc__ ("__negkf2_resolve"))); 260 261 CMPtype __eqkf2 (TFtype, TFtype) 262 __attribute__ ((__ifunc__ ("__eqkf2_resolve"))); 263 264 CMPtype __nekf2 (TFtype, TFtype) 265 __attribute__ ((__ifunc__ ("__nekf2_resolve"))); 266 267 CMPtype __gekf2 (TFtype, TFtype) 268 __attribute__ ((__ifunc__ ("__gekf2_resolve"))); 269 270 CMPtype __gtkf2 (TFtype, TFtype) 271 __attribute__ ((__ifunc__ ("__gtkf2_resolve"))); 272 273 CMPtype __lekf2 (TFtype, TFtype) 274 __attribute__ ((__ifunc__ ("__lekf2_resolve"))); 275 276 CMPtype __ltkf2 (TFtype, TFtype) 277 __attribute__ ((__ifunc__ ("__ltkf2_resolve"))); 278 279 CMPtype __unordkf2 (TFtype, TFtype) 280 __attribute__ ((__ifunc__ ("__unordkf2_resolve"))); 281 282 TFtype __extendsfkf2 (float) 283 __attribute__ ((__ifunc__ ("__extendsfkf2_resolve"))); 284 285 TFtype __extenddfkf2 (double) 286 __attribute__ ((__ifunc__ ("__extenddfkf2_resolve"))); 287 288 float __trunckfsf2 (TFtype) 289 __attribute__ ((__ifunc__ ("__trunckfsf2_resolve"))); 290 291 double __trunckfdf2 (TFtype) 292 __attribute__ ((__ifunc__ ("__trunckfdf2_resolve"))); 293 294 SItype_ppc __fixkfsi (TFtype) 295 __attribute__ ((__ifunc__ ("__fixkfsi_resolve"))); 296 297 DItype_ppc __fixkfdi (TFtype) 298 __attribute__ ((__ifunc__ ("__fixkfdi_resolve"))); 299 300 USItype_ppc __fixunskfsi (TFtype) 301 __attribute__ ((__ifunc__ ("__fixunskfsi_resolve"))); 302 303 UDItype_ppc __fixunskfdi (TFtype) 304 __attribute__ ((__ifunc__ ("__fixunskfdi_resolve"))); 305 306 TFtype __floatsikf (SItype_ppc) 307 __attribute__ ((__ifunc__ ("__floatsikf_resolve"))); 308 309 TFtype __floatdikf (DItype_ppc) 310 __attribute__ ((__ifunc__ ("__floatdikf_resolve"))); 311 312 TFtype __floatunsikf (USItype_ppc) 313 __attribute__ ((__ifunc__ ("__floatunsikf_resolve"))); 314 315 TFtype __floatundikf (UDItype_ppc) 316 __attribute__ ((__ifunc__ ("__floatundikf_resolve"))); 317 318 IBM128_TYPE __extendkftf2 (TFtype) 319 __attribute__ ((__ifunc__ ("__extendkftf2_resolve"))); 320 321 TFtype __trunctfkf2 (IBM128_TYPE) 322 __attribute__ ((__ifunc__ ("__trunctfkf2_resolve"))); 323