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