1/* Automatic switching between software and hardware IEEE 128-bit 2 floating-point emulation for PowerPC. 3 4 Copyright (C) 2016-2022 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#ifdef FLOAT128_HW_INSNS_ISA3_1 50#define SW_OR_HW_ISA3_1(SW, HW) (__builtin_cpu_supports ("arch_3_1") ? HW : SW) 51#endif 52 53/* Resolvers. */ 54static __typeof__ (__addkf3_sw) * 55__addkf3_resolve (void) 56{ 57 return SW_OR_HW (__addkf3_sw, __addkf3_hw); 58} 59 60static __typeof__ (__subkf3_sw) * 61__subkf3_resolve (void) 62{ 63 return SW_OR_HW (__subkf3_sw, __subkf3_hw); 64} 65 66static __typeof__ (__mulkf3_sw) * 67__mulkf3_resolve (void) 68{ 69 return SW_OR_HW (__mulkf3_sw, __mulkf3_hw); 70} 71 72static __typeof__ (__divkf3_sw) * 73__divkf3_resolve (void) 74{ 75 return SW_OR_HW (__divkf3_sw, __divkf3_hw); 76} 77 78static __typeof__ (__negkf2_sw) * 79__negkf2_resolve (void) 80{ 81 return SW_OR_HW (__negkf2_sw, __negkf2_hw); 82} 83 84static __typeof__ (__powikf2_sw) * 85__powikf2_resolve (void) 86{ 87 return SW_OR_HW (__powikf2_sw, __powikf2_hw); 88} 89 90static __typeof__ (__floatsikf_sw) * 91__floatsikf_resolve (void) 92{ 93 return SW_OR_HW (__floatsikf_sw, __floatsikf_hw); 94} 95 96static __typeof__ (__floatdikf_sw) * 97__floatdikf_resolve (void) 98{ 99 return SW_OR_HW (__floatdikf_sw, __floatdikf_hw); 100} 101 102#ifdef FLOAT128_HW_INSNS_ISA3_1 103static __typeof__ (__floattikf_sw) * 104__floattikf_resolve (void) 105{ 106 return SW_OR_HW_ISA3_1 (__floattikf_sw, __floattikf_hw); 107} 108 109static __typeof__ (__floatuntikf_sw) * 110__floatuntikf_resolve (void) 111{ 112 return SW_OR_HW_ISA3_1 (__floatuntikf_sw, __floatuntikf_hw); 113} 114#endif 115 116static __typeof__ (__floatunsikf_sw) * 117__floatunsikf_resolve (void) 118{ 119 return SW_OR_HW (__floatunsikf_sw, __floatunsikf_hw); 120} 121 122static __typeof__ (__floatundikf_sw) * 123__floatundikf_resolve (void) 124{ 125 return SW_OR_HW (__floatundikf_sw, __floatundikf_hw); 126} 127 128#ifdef FLOAT128_HW_INSNS_ISA3_1 129static __typeof__ (__fixkfti_sw) * 130__fixkfti_resolve (void) 131{ 132 return SW_OR_HW_ISA3_1 (__fixkfti_sw, __fixkfti_hw); 133} 134 135static __typeof__ (__fixunskfti_sw) * 136__fixunskfti_resolve (void) 137{ 138 return SW_OR_HW_ISA3_1 (__fixunskfti_sw, __fixunskfti_hw); 139} 140#endif 141 142static __typeof__ (__fixkfsi_sw) * 143__fixkfsi_resolve (void) 144{ 145 return SW_OR_HW (__fixkfsi_sw, __fixkfsi_hw); 146} 147 148static __typeof__ (__fixkfdi_sw) * 149__fixkfdi_resolve (void) 150{ 151 return SW_OR_HW (__fixkfdi_sw, __fixkfdi_hw); 152} 153 154static __typeof__ (__fixunskfsi_sw) * 155__fixunskfsi_resolve (void) 156{ 157 return SW_OR_HW (__fixunskfsi_sw, __fixunskfsi_hw); 158} 159 160static __typeof__ (__fixunskfdi_sw) * 161__fixunskfdi_resolve (void) 162{ 163 return SW_OR_HW (__fixunskfdi_sw, __fixunskfdi_hw); 164} 165 166static __typeof__ (__extendsfkf2_sw) * 167__extendsfkf2_resolve (void) 168{ 169 return SW_OR_HW (__extendsfkf2_sw, __extendsfkf2_hw); 170} 171 172static __typeof__ (__extenddfkf2_sw) * 173__extenddfkf2_resolve (void) 174{ 175 return SW_OR_HW (__extenddfkf2_sw, __extenddfkf2_hw); 176} 177 178static __typeof__ (__trunckfsf2_sw) * 179__trunckfsf2_resolve (void) 180{ 181 return SW_OR_HW (__trunckfsf2_sw, __trunckfsf2_hw); 182} 183 184static __typeof__ (__trunckfdf2_sw) * 185__trunckfdf2_resolve (void) 186{ 187 return (void *) SW_OR_HW (__trunckfdf2_sw, __trunckfdf2_hw); 188} 189 190static __typeof__ (__extendkftf2_sw) * 191__extendkftf2_resolve (void) 192{ 193 return SW_OR_HW (__extendkftf2_sw, __extendkftf2_hw); 194} 195 196static __typeof__ (__trunctfkf2_sw) * 197__trunctfkf2_resolve (void) 198{ 199 return SW_OR_HW (__trunctfkf2_sw, __trunctfkf2_hw); 200} 201 202static __typeof__ (__mulkc3_sw) * 203__mulkc3_resolve (void) 204{ 205 return SW_OR_HW (__mulkc3_sw, __mulkc3_hw); 206} 207 208static __typeof__ (__divkc3_sw) * 209__divkc3_resolve (void) 210{ 211 return SW_OR_HW (__divkc3_sw, __divkc3_hw); 212} 213 214static __typeof__ (__eqkf2_sw) * 215__eqkf2_resolve (void) 216{ 217 return SW_OR_HW (__eqkf2_sw, __eqkf2_hw); 218} 219 220static __typeof__ (__gekf2_sw) * 221__gekf2_resolve (void) 222{ 223 return SW_OR_HW (__gekf2_sw, __gekf2_hw); 224} 225 226static __typeof__ (__lekf2_sw) * 227__lekf2_resolve (void) 228{ 229 return SW_OR_HW (__lekf2_sw, __lekf2_hw); 230} 231 232static __typeof__ (__unordkf2_sw) * 233__unordkf2_resolve (void) 234{ 235 return SW_OR_HW (__unordkf2_sw, __unordkf2_hw); 236} 237 238/* Resolve __nekf2, __gtkf2, __ltkf2 like __eqkf2, __gekf2, and __lekf2, since 239 the functions return the same values. */ 240 241static __typeof__ (__eqkf2_sw) * 242__nekf2_resolve (void) 243{ 244 return SW_OR_HW (__eqkf2_sw, __eqkf2_hw); 245} 246 247static __typeof__ (__eqkf2_sw) * 248__gtkf2_resolve (void) 249{ 250 return SW_OR_HW (__gekf2_sw, __gekf2_hw); 251} 252 253static __typeof__ (__eqkf2_sw) * 254__ltkf2_resolve (void) 255{ 256 return SW_OR_HW (__lekf2_sw, __lekf2_hw); 257} 258 259 260 261/* Ifunc definitions. */ 262TFtype __addkf3 (TFtype, TFtype) 263 __attribute__ ((__ifunc__ ("__addkf3_resolve"))); 264 265TFtype __subkf3 (TFtype, TFtype) 266 __attribute__ ((__ifunc__ ("__subkf3_resolve"))); 267 268TFtype __mulkf3 (TFtype, TFtype) 269 __attribute__ ((__ifunc__ ("__mulkf3_resolve"))); 270 271TFtype __divkf3 (TFtype, TFtype) 272 __attribute__ ((__ifunc__ ("__divkf3_resolve"))); 273 274TFtype __negkf2 (TFtype) 275 __attribute__ ((__ifunc__ ("__negkf2_resolve"))); 276 277TFtype __powikf2 (TFtype, SItype_ppc) 278 __attribute__ ((__ifunc__ ("__powikf2_resolve"))); 279 280CMPtype __eqkf2 (TFtype, TFtype) 281 __attribute__ ((__ifunc__ ("__eqkf2_resolve"))); 282 283CMPtype __nekf2 (TFtype, TFtype) 284 __attribute__ ((__ifunc__ ("__nekf2_resolve"))); 285 286CMPtype __gekf2 (TFtype, TFtype) 287 __attribute__ ((__ifunc__ ("__gekf2_resolve"))); 288 289CMPtype __gtkf2 (TFtype, TFtype) 290 __attribute__ ((__ifunc__ ("__gtkf2_resolve"))); 291 292CMPtype __lekf2 (TFtype, TFtype) 293 __attribute__ ((__ifunc__ ("__lekf2_resolve"))); 294 295CMPtype __ltkf2 (TFtype, TFtype) 296 __attribute__ ((__ifunc__ ("__ltkf2_resolve"))); 297 298CMPtype __unordkf2 (TFtype, TFtype) 299 __attribute__ ((__ifunc__ ("__unordkf2_resolve"))); 300 301TFtype __extendsfkf2 (float) 302 __attribute__ ((__ifunc__ ("__extendsfkf2_resolve"))); 303 304TFtype __extenddfkf2 (double) 305 __attribute__ ((__ifunc__ ("__extenddfkf2_resolve"))); 306 307float __trunckfsf2 (TFtype) 308 __attribute__ ((__ifunc__ ("__trunckfsf2_resolve"))); 309 310double __trunckfdf2 (TFtype) 311 __attribute__ ((__ifunc__ ("__trunckfdf2_resolve"))); 312 313SItype_ppc __fixkfsi (TFtype) 314 __attribute__ ((__ifunc__ ("__fixkfsi_resolve"))); 315 316DItype_ppc __fixkfdi (TFtype) 317 __attribute__ ((__ifunc__ ("__fixkfdi_resolve"))); 318 319USItype_ppc __fixunskfsi (TFtype) 320 __attribute__ ((__ifunc__ ("__fixunskfsi_resolve"))); 321 322UDItype_ppc __fixunskfdi (TFtype) 323 __attribute__ ((__ifunc__ ("__fixunskfdi_resolve"))); 324 325TFtype __floatsikf (SItype_ppc) 326 __attribute__ ((__ifunc__ ("__floatsikf_resolve"))); 327 328TFtype __floatdikf (DItype_ppc) 329 __attribute__ ((__ifunc__ ("__floatdikf_resolve"))); 330 331#ifdef FLOAT128_HW_INSNS_ISA3_1 332TFtype __floattikf (TItype_ppc) 333 __attribute__ ((__ifunc__ ("__floattikf_resolve"))); 334 335TFtype __floatuntikf (UTItype_ppc) 336 __attribute__ ((__ifunc__ ("__floatuntikf_resolve"))); 337 338TItype_ppc __fixkfti (TFtype) 339 __attribute__ ((__ifunc__ ("__fixkfti_resolve"))); 340 341UTItype_ppc __fixunskfti (TFtype) 342 __attribute__ ((__ifunc__ ("__fixunskfti_resolve"))); 343#endif 344 345TFtype __floatunsikf (USItype_ppc) 346 __attribute__ ((__ifunc__ ("__floatunsikf_resolve"))); 347 348TFtype __floatundikf (UDItype_ppc) 349 __attribute__ ((__ifunc__ ("__floatundikf_resolve"))); 350 351IBM128_TYPE __extendkftf2 (TFtype) 352 __attribute__ ((__ifunc__ ("__extendkftf2_resolve"))); 353 354TFtype __trunctfkf2 (IBM128_TYPE) 355 __attribute__ ((__ifunc__ ("__trunctfkf2_resolve"))); 356 357TCtype __mulkc3 (TFtype, TFtype, TFtype, TFtype) 358 __attribute__ ((__ifunc__ ("__mulkc3_resolve"))); 359 360TCtype __divkc3 (TFtype, TFtype, TFtype, TFtype) 361 __attribute__ ((__ifunc__ ("__divkc3_resolve"))); 362