diff options
Diffstat (limited to 'libgcc/config/rs6000/float128-ifunc.c')
-rw-r--r-- | libgcc/config/rs6000/float128-ifunc.c | 322 |
1 files changed, 322 insertions, 0 deletions
diff --git a/libgcc/config/rs6000/float128-ifunc.c b/libgcc/config/rs6000/float128-ifunc.c new file mode 100644 index 0000000000..882c56ef21 --- /dev/null +++ b/libgcc/config/rs6000/float128-ifunc.c @@ -0,0 +1,322 @@ +/* Automatic switching between software and hardware IEEE 128-bit + floating-point emulation for PowerPC. + + Copyright (C) 2016-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Michael Meissner (meissner@linux.vnet.ibm.com) + Code is based on the main soft-fp library written by: + Richard Henderson (rth@cygnus.com) and + Jakub Jelinek (jj@ultra.linux.cz). + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + In addition to the permissions in the GNU Lesser General Public + License, the Free Software Foundation gives you unlimited + permission to link the compiled version of this file into + combinations with other programs, and to distribute those + combinations without any restriction coming from the use of this + file. (The Lesser General Public License restrictions do apply in + other respects; for example, they cover modification of the file, + and distribution when not linked into a combine executable.) + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <soft-fp.h> +#include <quad-float128.h> +#include <string.h> +#include <stdlib.h> +#include <ctype.h> + +#ifndef FLOAT128_HW_INSNS +#error "float128-ifunc.c needs access to ISA 3.0 instructions and ifunc" +#endif + +#ifdef __FLOAT128_HARDWARE__ +#error "This module must not be compiled with IEEE 128-bit hardware support" +#endif + +#define SW_OR_HW(SW, HW) (__builtin_cpu_supports ("ieee128") ? HW : SW) + +/* Resolvers. */ + +/* We do not provide ifunc resolvers for __fixkfti, __fixunskfti, __floattikf, + and __floatuntikf. There is no ISA 3.0 instruction that converts between + 128-bit integer types and 128-bit IEEE floating point, or vice versa. So + use the emulator functions for these conversions. */ + +static void *__addkf3_resolve (void); +static void *__subkf3_resolve (void); +static void *__mulkf3_resolve (void); +static void *__divkf3_resolve (void); +static void *__negkf2_resolve (void); +static void *__eqkf2_resolve (void); +static void *__nekf2_resolve (void); +static void *__gekf2_resolve (void); +static void *__gtkf2_resolve (void); +static void *__lekf2_resolve (void); +static void *__ltkf2_resolve (void); +static void *__unordkf2_resolve (void); +static void *__extendsfkf2_resolve (void); +static void *__extenddfkf2_resolve (void); +static void *__trunckfsf2_resolve (void); +static void *__trunckfdf2_resolve (void); +static void *__fixkfsi_resolve (void); +static void *__fixkfdi_resolve (void); +static void *__fixunskfsi_resolve (void); +static void *__fixunskfdi_resolve (void); +static void *__floatsikf_resolve (void); +static void *__floatdikf_resolve (void); +static void *__floatunsikf_resolve (void); +static void *__floatundikf_resolve (void); +static void *__extendkftf2_resolve (void); +static void *__trunctfkf2_resolve (void); + +static void * +__addkf3_resolve (void) +{ + return (void *) SW_OR_HW (__addkf3_sw, __addkf3_hw); +} + +static void * +__subkf3_resolve (void) +{ + return (void *) SW_OR_HW (__subkf3_sw, __subkf3_hw); +} + +static void * +__mulkf3_resolve (void) +{ + return (void *) SW_OR_HW (__mulkf3_sw, __mulkf3_hw); +} + +static void * +__divkf3_resolve (void) +{ + return (void *) SW_OR_HW (__divkf3_sw, __divkf3_hw); +} + +static void * +__negkf2_resolve (void) +{ + return (void *) SW_OR_HW (__negkf2_sw, __negkf2_hw); +} + +static void * +__floatsikf_resolve (void) +{ + return (void *) SW_OR_HW (__floatsikf_sw, __floatsikf_hw); +} + +static void * +__floatdikf_resolve (void) +{ + return (void *) SW_OR_HW (__floatdikf_sw, __floatdikf_hw); +} + +static void * +__floatunsikf_resolve (void) +{ + return (void *) SW_OR_HW (__floatunsikf_sw, __floatunsikf_hw); +} + +static void * +__floatundikf_resolve (void) +{ + return (void *) SW_OR_HW (__floatundikf_sw, __floatundikf_hw); +} + +static void * +__fixkfsi_resolve (void) +{ + return (void *) SW_OR_HW (__fixkfsi_sw, __fixkfsi_hw); +} + +static void * +__fixkfdi_resolve (void) +{ + return (void *) SW_OR_HW (__fixkfdi_sw, __fixkfdi_hw); +} + +static void * +__fixunskfsi_resolve (void) +{ + return (void *) SW_OR_HW (__fixunskfsi_sw, __fixunskfsi_hw); +} + +static void * +__fixunskfdi_resolve (void) +{ + return (void *) SW_OR_HW (__fixunskfdi_sw, __fixunskfdi_hw); +} + +static void * +__extendsfkf2_resolve (void) +{ + return (void *) SW_OR_HW (__extendsfkf2_sw, __extendsfkf2_hw); +} + +static void * +__extenddfkf2_resolve (void) +{ + return (void *) SW_OR_HW (__extenddfkf2_sw, __extenddfkf2_hw); +} + +static void * +__trunckfsf2_resolve (void) +{ + return (void *) SW_OR_HW (__trunckfsf2_sw, __trunckfsf2_hw); +} + +static void * +__trunckfdf2_resolve (void) +{ + return (void *) SW_OR_HW (__trunckfdf2_sw, __trunckfdf2_hw); +} + +static void * +__extendkftf2_resolve (void) +{ + return (void *) SW_OR_HW (__extendkftf2_sw, __extendkftf2_hw); +} + +static void * +__trunctfkf2_resolve (void) +{ + return (void *) SW_OR_HW (__trunctfkf2_sw, __trunctfkf2_hw); +} + +static void * +__eqkf2_resolve (void) +{ + return (void *) SW_OR_HW (__eqkf2_sw, __eqkf2_hw); +} + +static void * +__gekf2_resolve (void) +{ + return (void *) SW_OR_HW (__gekf2_sw, __gekf2_hw); +} + +static void * +__lekf2_resolve (void) +{ + return (void *) SW_OR_HW (__lekf2_sw, __lekf2_hw); +} + +static void * +__unordkf2_resolve (void) +{ + return (void *) SW_OR_HW (__unordkf2_sw, __unordkf2_hw); +} + +/* Resolve __nekf2, __gtkf2, __ltkf2 like __eqkf2, __gekf2, and __lekf2, since + the functions return the same values. */ + +static void * +__nekf2_resolve (void) +{ + return (void *) SW_OR_HW (__eqkf2_sw, __eqkf2_hw); +} + +static void * +__gtkf2_resolve (void) +{ + return (void *) SW_OR_HW (__gekf2_sw, __gekf2_hw); +} + +static void * +__ltkf2_resolve (void) +{ + return (void *) SW_OR_HW (__lekf2_sw, __lekf2_hw); +} + + + +/* Ifunc definitions. */ +TFtype __addkf3 (TFtype, TFtype) + __attribute__ ((__ifunc__ ("__addkf3_resolve"))); + +TFtype __subkf3 (TFtype, TFtype) + __attribute__ ((__ifunc__ ("__subkf3_resolve"))); + +TFtype __mulkf3 (TFtype, TFtype) + __attribute__ ((__ifunc__ ("__mulkf3_resolve"))); + +TFtype __divkf3 (TFtype, TFtype) + __attribute__ ((__ifunc__ ("__divkf3_resolve"))); + +TFtype __negkf2 (TFtype) + __attribute__ ((__ifunc__ ("__negkf2_resolve"))); + +CMPtype __eqkf2 (TFtype, TFtype) + __attribute__ ((__ifunc__ ("__eqkf2_resolve"))); + +CMPtype __nekf2 (TFtype, TFtype) + __attribute__ ((__ifunc__ ("__nekf2_resolve"))); + +CMPtype __gekf2 (TFtype, TFtype) + __attribute__ ((__ifunc__ ("__gekf2_resolve"))); + +CMPtype __gtkf2 (TFtype, TFtype) + __attribute__ ((__ifunc__ ("__gtkf2_resolve"))); + +CMPtype __lekf2 (TFtype, TFtype) + __attribute__ ((__ifunc__ ("__lekf2_resolve"))); + +CMPtype __ltkf2 (TFtype, TFtype) + __attribute__ ((__ifunc__ ("__ltkf2_resolve"))); + +CMPtype __unordkf2 (TFtype, TFtype) + __attribute__ ((__ifunc__ ("__unordkf2_resolve"))); + +TFtype __extendsfkf2 (float) + __attribute__ ((__ifunc__ ("__extendsfkf2_resolve"))); + +TFtype __extenddfkf2 (double) + __attribute__ ((__ifunc__ ("__extenddfkf2_resolve"))); + +float __trunckfsf2 (TFtype) + __attribute__ ((__ifunc__ ("__trunckfsf2_resolve"))); + +double __trunckfdf2 (TFtype) + __attribute__ ((__ifunc__ ("__trunckfdf2_resolve"))); + +SItype_ppc __fixkfsi (TFtype) + __attribute__ ((__ifunc__ ("__fixkfsi_resolve"))); + +DItype_ppc __fixkfdi (TFtype) + __attribute__ ((__ifunc__ ("__fixkfdi_resolve"))); + +USItype_ppc __fixunskfsi (TFtype) + __attribute__ ((__ifunc__ ("__fixunskfsi_resolve"))); + +UDItype_ppc __fixunskfdi (TFtype) + __attribute__ ((__ifunc__ ("__fixunskfdi_resolve"))); + +TFtype __floatsikf (SItype_ppc) + __attribute__ ((__ifunc__ ("__floatsikf_resolve"))); + +TFtype __floatdikf (DItype_ppc) + __attribute__ ((__ifunc__ ("__floatdikf_resolve"))); + +TFtype __floatunsikf (USItype_ppc) + __attribute__ ((__ifunc__ ("__floatunsikf_resolve"))); + +TFtype __floatundikf (UDItype_ppc) + __attribute__ ((__ifunc__ ("__floatundikf_resolve"))); + +IBM128_TYPE __extendkftf2 (TFtype) + __attribute__ ((__ifunc__ ("__extendkftf2_resolve"))); + +TFtype __trunctfkf2 (IBM128_TYPE) + __attribute__ ((__ifunc__ ("__trunctfkf2_resolve"))); |