I fixed the #ifdef to use __NO_FPRS__ (thanks for the heads up on that). I also believe I fixed the various formatting issues. These two patches build on a big endian power7 host and little endian power8 host with no regressions in the testsuite (the gcc patch is included here, but it hasn't changed since the previous version of this patch). Are they ok to be checked in?
[gcc] 2016-01-11 Michael Meissner <meiss...@linux.vnet.ibm.com> * config/rs6000/rs6000-builtin.def (BU_FLOAT128_2): Add support for pack/unpack functions for __ibm128. (PACK_IF): Likewise. (UNPACK_IF): Likewise. * config/rs6000/rs6000.c (rs6000_builtin_mask_calculate): Add support for __ibm128 pack/unpack functions. (rs6000_invalid_builtin): Likewise. (rs6000_init_builtins): Likewise. (rs6000_opt_masks): Likewise. * config/rs6000/rs6000.h (MASK_FLOAT128): Add short name. (RS6000_BTM_FLOAT128): Add support for __ibm128 pack/unpack functions (RS6000_BTM_COMMON): Likewise. * config/rs6000/rs6000.md (f128_vsx): New mode attribute. (unpack<mode>): Use FMOVE128_FPR iterator instead of FMOVE128, to disallow __builtin_{pack,unpack}_longdouble if long double is IEEE 128-bit floating point. Add support for the double values to be in Altivec registers for TF/IF packing and unpacking, but restrict TD packing sub-fields to be FPR registers. Don't allow overlapped register support for packing. Allow pack inputs to be memory locations. Don't build generator functions for unpack<mode>_dm and unpack<mode>_nodm. (unpack<mode>_dm): Likewise. (unpack<mode>_nodm): Likewise. (pack<mode>): Likewise. * config/rs6000/rs6000-builtin.def (__builtin_pack_ibm128): Add built-in functions to pack/unpack explicit __ibm128 values. (__builtin_unpack_ibm128): Likewise. * doc/extend.texi (PowerPC Built-in Functions): Document __builtin_pack_ibm128 and __builtin_unpack_ibm128. [libgcc] 2016-01-11 Michael Meissner <meiss...@linux.vnet.ibm.com> Steven Munroe <munro...@linux.vnet.ibm.com> Tulio Magno Quites Machado Filho <tuli...@br.ibm.com> * config/rs6000/sfp-exceptions.c: New file to provide exception support for IEEE 128-bit floating point. * config/rs6000/float128-hw.c: New file for ISA 3.0 IEEE 128-bit floating point hardware support. * config/rs6000/floattikf.c: New files for IEEE 128-bit floating point conversions. * config/rs6000/fixunskfti.c: Likewise. * config/rs6000/fixkfti.c: Likewise. * config/rs6000/floatuntikf.c: Likewise. * config/rs6000/extendkftf2-sw.c: Likewise. * config/rs6000/trunctfkf2-sw.c: Likewise. * config/rs6000/float128-ifunc.c: New file to pick either IEEE 128-bit floating point software emulation or use ISA 3.0 hardware support if it is available. * config/rs6000/quad-float128.h: New file to support IEEE 128-bit floating point. * config/rs6000/t-float128: New Makefile fragments to enable building __float128 emulation support. * config/rs6000/t-float128-hw: Likewise. * config/rs6000/float128-sed: New file to convert TF names to KF names for PowerPC IEEE 128-bit floating point support. * config/rs6000/sfp-machine.h (_FP_W_TYPE_SIZE): Use 64-bit types when building on 64-bit systems, or when VSX is enabled. (_FP_W_TYPE): Likewise. (_FP_WS_TYPE): Likewise. (_FP_I_TYPE): Likewise. (TItype): Define on 64-bit systems. (UTItype): Likewise. (TI_BITS): Likewise. (_FP_MUL_MEAT_D): Add support for using 64-bit types. (_FP_MUL_MEAT_Q): Likewise. (_FP_DIV_MEAT_D): Likewise. (_FP_DIV_MEAT_Q): Likewise. (_FP_NANFRAC_D): Likewise. (_FP_NANFRAC_Q): Likewise. (ISA_BIT): Add exception support if we are being compiled on a machine with hardware floating point support to build the IEEE 128-bit emulation functions. (FP_EX_INVALID): Likewise. (FP_EX_OVERFLOW): Likewise. (FP_EX_UNDERFLOW): Likewise. (FP_EX_DIVZERO): Likewise. (FP_EX_INEXACT): Likewise. (FP_EX_ALL): Likewise. (__sfp_handle_exceptions): Likewise. (FP_HANDLE_EXCEPTIONS): Likewise. (FP_RND_NEAREST): Likewise. (FP_RND_ZERO): Likewise. (FP_RND_PINF): Likewise. (FP_RND_MINF): Likewise. (FP_RND_MASK): Likewise. (_FP_DECL_EX): Likewise. (FP_INIT_ROUNDMODE): Likewise. (FP_ROUNDMODE): Likewise. * configure.ac (powerpc*-*-linux*): Check whether the PowerPC compiler can do __float128. * configure: Regenerate. * libgcc/config.host (powerpc*-*-linux*): If compiler can compile VSX code, enable IEEE 128-bit floating point. -- Michael Meissner, IBM IBM, M/S 2506R, 550 King Street, Littleton, MA 01460-6245, USA email: meiss...@linux.vnet.ibm.com, phone: +1 (978) 899-4797
Index: gcc/config/rs6000/rs6000-builtin.def =================================================================== --- gcc/config/rs6000/rs6000-builtin.def (.../svn+ssh://meiss...@gcc.gnu.org/svn/gcc/trunk/gcc/config/rs6000) (revision 232093) +++ gcc/config/rs6000/rs6000-builtin.def (.../gcc/config/rs6000) (working copy) @@ -647,6 +647,15 @@ | RS6000_BTC_BINARY), \ CODE_FOR_ ## ICODE) /* ICODE */ +/* __float128 floating point builtins. */ +#define BU_FLOAT128_2(ENUM, NAME, ATTR, ICODE) \ + RS6000_BUILTIN_2 (MISC_BUILTIN_ ## ENUM, /* ENUM */ \ + "__builtin_" NAME, /* NAME */ \ + RS6000_BTM_FLOAT128, /* MASK */ \ + (RS6000_BTC_ ## ATTR /* ATTR */ \ + | RS6000_BTC_BINARY), \ + CODE_FOR_ ## ICODE) /* ICODE */ + #endif /* Insure 0 is not a legitimate index. */ @@ -1642,6 +1651,9 @@ BU_DFP_MISC_2 (UNPACK_TD, "unpack_dec128 BU_LDBL128_2 (PACK_TF, "pack_longdouble", CONST, packtf) BU_LDBL128_2 (UNPACK_TF, "unpack_longdouble", CONST, unpacktf) +BU_FLOAT128_2 (PACK_IF, "pack_ibm128", CONST, packif) +BU_FLOAT128_2 (UNPACK_IF, "unpack_ibm128", CONST, unpackif) + BU_P7_MISC_2 (PACK_V1TI, "pack_vector_int128", CONST, packv1ti) BU_P7_MISC_2 (UNPACK_V1TI, "unpack_vector_int128", CONST, unpackv1ti) Index: gcc/config/rs6000/rs6000.c =================================================================== --- gcc/config/rs6000/rs6000.c (.../svn+ssh://meiss...@gcc.gnu.org/svn/gcc/trunk/gcc/config/rs6000) (revision 232093) +++ gcc/config/rs6000/rs6000.c (.../gcc/config/rs6000) (working copy) @@ -3521,7 +3521,8 @@ rs6000_builtin_mask_calculate (void) | ((TARGET_HTM) ? RS6000_BTM_HTM : 0) | ((TARGET_DFP) ? RS6000_BTM_DFP : 0) | ((TARGET_HARD_FLOAT) ? RS6000_BTM_HARD_FLOAT : 0) - | ((TARGET_LONG_DOUBLE_128) ? RS6000_BTM_LDBL128 : 0)); + | ((TARGET_LONG_DOUBLE_128) ? RS6000_BTM_LDBL128 : 0) + | ((TARGET_FLOAT128) ? RS6000_BTM_FLOAT128 : 0)); } /* Implement TARGET_MD_ASM_ADJUST. All asm statements are considered @@ -14605,6 +14606,8 @@ rs6000_invalid_builtin (enum rs6000_buil " -mlong-double-128 options", name); else if ((fnmask & RS6000_BTM_HARD_FLOAT) != 0) error ("Builtin function %s requires the -mhard-float option", name); + else if ((fnmask & RS6000_BTM_FLOAT128) != 0) + error ("Builtin function %s requires the -mfloat128 options", name); else error ("Builtin function %s is not supported with the current options", name); @@ -14894,19 +14897,21 @@ rs6000_init_builtins (void) IFmode is the IBM extended 128-bit format that is a pair of doubles. TFmode will be either IEEE 128-bit floating point or the IBM double-double format that uses a pair of doubles, depending on the switches and - defaults. */ + defaults. Always create the types even if we don't register the keywords + to allow built-in functions using these types to be created. */ + + ibm128_float_type_node = make_node (REAL_TYPE); + TYPE_PRECISION (ibm128_float_type_node) = 128; + layout_type (ibm128_float_type_node); + SET_TYPE_MODE (ibm128_float_type_node, IFmode); + + ieee128_float_type_node = make_node (REAL_TYPE); + TYPE_PRECISION (ieee128_float_type_node) = 128; + layout_type (ieee128_float_type_node); + SET_TYPE_MODE (ieee128_float_type_node, KFmode); + if (TARGET_FLOAT128) { - ibm128_float_type_node = make_node (REAL_TYPE); - TYPE_PRECISION (ibm128_float_type_node) = 128; - layout_type (ibm128_float_type_node); - SET_TYPE_MODE (ibm128_float_type_node, IFmode); - - ieee128_float_type_node = make_node (REAL_TYPE); - TYPE_PRECISION (ieee128_float_type_node) = 128; - layout_type (ieee128_float_type_node); - SET_TYPE_MODE (ieee128_float_type_node, KFmode); - lang_hooks.types.register_builtin_type (ieee128_float_type_node, "__float128"); @@ -34223,6 +34228,7 @@ static struct rs6000_opt_mask const rs60 { "hard-dfp", RS6000_BTM_DFP, false, false }, { "hard-float", RS6000_BTM_HARD_FLOAT, false, false }, { "long-double-128", RS6000_BTM_LDBL128, false, false }, + { "float128", RS6000_BTM_FLOAT128, false, false }, }; /* Option variables that we want to support inside attribute((target)) and Index: gcc/config/rs6000/rs6000.h =================================================================== --- gcc/config/rs6000/rs6000.h (.../svn+ssh://meiss...@gcc.gnu.org/svn/gcc/trunk/gcc/config/rs6000) (revision 232093) +++ gcc/config/rs6000/rs6000.h (.../gcc/config/rs6000) (working copy) @@ -605,6 +605,7 @@ extern int rs6000_vector_align[]; #define MASK_DLMZB OPTION_MASK_DLMZB #define MASK_EABI OPTION_MASK_EABI #define MASK_FPRND OPTION_MASK_FPRND +#define MASK_FLOAT128 OPTION_MASK_FLOAT128 #define MASK_P8_FUSION OPTION_MASK_P8_FUSION #define MASK_HARD_FLOAT OPTION_MASK_HARD_FLOAT #define MASK_HTM OPTION_MASK_HTM @@ -2670,6 +2671,7 @@ extern int frame_pointer_needed; #define RS6000_BTM_DFP MASK_DFP /* Decimal floating point. */ #define RS6000_BTM_HARD_FLOAT MASK_SOFT_FLOAT /* Hardware floating point. */ #define RS6000_BTM_LDBL128 MASK_MULTIPLE /* 128-bit long double. */ +#define RS6000_BTM_FLOAT128 MASK_FLOAT128 /* IEEE 128-bit fp. */ #define RS6000_BTM_COMMON (RS6000_BTM_ALTIVEC \ | RS6000_BTM_VSX \ @@ -2684,7 +2686,8 @@ extern int frame_pointer_needed; | RS6000_BTM_CELL \ | RS6000_BTM_DFP \ | RS6000_BTM_HARD_FLOAT \ - | RS6000_BTM_LDBL128) + | RS6000_BTM_LDBL128 \ + | RS6000_BTM_FLOAT128) /* Define builtin enum index. */ Index: gcc/config/rs6000/rs6000.md =================================================================== --- gcc/config/rs6000/rs6000.md (.../svn+ssh://meiss...@gcc.gnu.org/svn/gcc/trunk/gcc/config/rs6000) (revision 232093) +++ gcc/config/rs6000/rs6000.md (.../gcc/config/rs6000) (working copy) @@ -469,6 +469,9 @@ (define_mode_attr f64_av [(DF "wv") (DD ; Definitions for 64-bit access to ISA 3.0 (power9) vector (define_mode_attr f64_p9 [(DF "wb") (DD "wn")]) +; Definitions for 128-bit IBM extended double word pack/unpack +(define_mode_attr f128_vsx [(TF "ws") (IF "ws") (TD "d")]) + ; These modes do not fit in integer registers in 32-bit mode. ; but on e500v2, the gpr are 64 bit registers (define_mode_iterator DIFD [DI (DF "!TARGET_E500_DOUBLE") DD]) @@ -13109,16 +13112,16 @@ (define_mode_attr FP128_64 [(TF "DF") (define_expand "unpack<mode>" [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "") (unspec:<FP128_64> - [(match_operand:FMOVE128 1 "register_operand" "") + [(match_operand:FMOVE128_FPR 1 "register_operand" "") (match_operand:QI 2 "const_0_to_1_operand" "")] UNSPEC_UNPACK_128BIT))] "FLOAT128_2REG_P (<MODE>mode)" "") -(define_insn_and_split "unpack<mode>_dm" - [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m,d,r,m") +(define_insn_and_split "*unpack<mode>_dm" + [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=<f128_vsx>,m,<f128_vsx>,r,m") (unspec:<FP128_64> - [(match_operand:FMOVE128 1 "register_operand" "d,d,r,d,r") + [(match_operand:FMOVE128_FPR 1 "register_operand" "d,d,r,d,r") (match_operand:QI 2 "const_0_to_1_operand" "i,i,i,i,i")] UNSPEC_UNPACK_128BIT))] "TARGET_POWERPC64 && TARGET_DIRECT_MOVE && FLOAT128_2REG_P (<MODE>mode)" @@ -13139,10 +13142,10 @@ (define_insn_and_split "unpack<mode>_dm" [(set_attr "type" "fp,fpstore,mffgpr,mftgpr,store") (set_attr "length" "4")]) -(define_insn_and_split "unpack<mode>_nodm" - [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m") +(define_insn_and_split "*unpack<mode>_nodm" + [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=<f128_vsx>,m") (unspec:<FP128_64> - [(match_operand:FMOVE128 1 "register_operand" "d,d") + [(match_operand:FMOVE128_FPR 1 "register_operand" "d,d") (match_operand:QI 2 "const_0_to_1_operand" "i,i")] UNSPEC_UNPACK_128BIT))] "(!TARGET_POWERPC64 || !TARGET_DIRECT_MOVE) && FLOAT128_2REG_P (<MODE>mode)" @@ -13164,30 +13167,31 @@ (define_insn_and_split "unpack<mode>_nod (set_attr "length" "4")]) (define_insn_and_split "pack<mode>" - [(set (match_operand:FMOVE128 0 "register_operand" "=d,&d") - (unspec:FMOVE128 - [(match_operand:<FP128_64> 1 "register_operand" "0,d") - (match_operand:<FP128_64> 2 "register_operand" "d,d")] + [(set (match_operand:FMOVE128_FPR 0 "register_operand" "=&d,&d,&d,&d") + (unspec:FMOVE128_FPR + [(match_operand:<FP128_64> 1 "input_operand" "<f128_vsx>,<f128_vsx>,m,m") + (match_operand:<FP128_64> 2 "input_operand" "<f128_vsx>,m,<f128_vsx>,m")] UNSPEC_PACK_128BIT))] "FLOAT128_2REG_P (<MODE>mode)" - "@ - fmr %L0,%2 - #" - "&& reload_completed && REGNO (operands[0]) != REGNO (operands[1])" + "#" + "&& reload_completed" [(set (match_dup 3) (match_dup 1)) (set (match_dup 4) (match_dup 2))] { - unsigned dest_hi = REGNO (operands[0]); + rtx op0 = operands[0]; + rtx op1 = operands[1]; + rtx op2 = operands[2]; + unsigned dest_hi = REGNO (op0); unsigned dest_lo = dest_hi + 1; - gcc_assert (!IN_RANGE (REGNO (operands[1]), dest_hi, dest_lo)); - gcc_assert (!IN_RANGE (REGNO (operands[2]), dest_hi, dest_lo)); + gcc_assert (!REG_P (op1) || !IN_RANGE (REGNO (op1), dest_hi, dest_lo)); + gcc_assert (!REG_P (op2) || !IN_RANGE (REGNO (op2), dest_hi, dest_lo)); operands[3] = gen_rtx_REG (<FP128_64>mode, dest_hi); operands[4] = gen_rtx_REG (<FP128_64>mode, dest_lo); } - [(set_attr "type" "fp,fp") - (set_attr "length" "4,8")]) + [(set_attr "type" "fp,fpload,fpload,fpload") + (set_attr "length" "8")]) (define_insn "unpack<mode>" [(set (match_operand:DI 0 "register_operand" "=d,d") Index: gcc/doc/extend.texi =================================================================== --- gcc/doc/extend.texi (.../svn+ssh://meiss...@gcc.gnu.org/svn/gcc/trunk/gcc/doc) (revision 232093) +++ gcc/doc/extend.texi (.../gcc/doc) (working copy) @@ -13512,6 +13512,8 @@ uint64_t __builtin_ppc_get_timebase (); unsigned long __builtin_ppc_mftb (); double __builtin_unpack_longdouble (long double, int); long double __builtin_pack_longdouble (double, double); +double __builtin_unpack_ibm128 (__ibm128, int); +__ibm128 __builtin_pack_ibm128 (double, double); @end smallexample The @code{vec_rsqrt}, @code{__builtin_rsqrt}, and
Index: libgcc/config/rs6000/sfp-exceptions.c =================================================================== --- libgcc/config/rs6000/sfp-exceptions.c (.../svn+ssh://meiss...@gcc.gnu.org/svn/gcc/trunk/libgcc) (revision 0) +++ libgcc/config/rs6000/sfp-exceptions.c (.../libgcc) (revision 232096) @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2016 Free Software Foundation, Inc. + * + * This file is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 3, or (at your option) any + * later version. + * + * This file 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 + * General Public License for more details. + * + * Under Section 7 of GPL version 3, you are granted additional + * permissions described in the GCC Runtime Library Exception, version + * 3.1, as published by the Free Software Foundation. + * + * You should have received a copy of the GNU General Public License and + * a copy of the GCC Runtime Library Exception along with this program; + * see the files COPYING3 and COPYING.RUNTIME respectively. If not, see + * <http://www.gnu.org/licenses/>. + */ + +#include "sfp-machine.h" + +/* Only provide exception support if we have hardware floating point and we can + execute the mtfsf instruction. This would only be true if we are using the + emulation routines for IEEE 128-bit floating point on pre-ISA 3.0 machines + without the IEEE 128-bit floating point support. */ + +#ifndef _SOFT_FLOAT + +void +__sfp_handle_exceptions (int _fex) +{ + const double fp_max = __DBL_MAX__; + const double fp_min = __DBL_MIN__; + const double fp_zero = (double) 0.0; + const double fp_one = 1.0; + double tmp; + + if (_fex & FP_EX_INVALID) + { + __asm__ __volatile__ ("fdiv %0, %1, %1" + : "=f" (tmp) + : "f" (fp_zero)); + } + if (_fex & FP_EX_DIVZERO) + { + __asm__ __volatile__ ("fdiv %0, %1, %2" + : "=f" (tmp) + : "f" (fp_one), "f" (fp_zero)); + } + if (_fex & FP_EX_OVERFLOW) + { + __asm__ __volatile__ ("fadd %0, %1, %1" + : "=f" (tmp) + : "f" (fp_max)); + } + if (_fex & FP_EX_UNDERFLOW) + { + __asm__ __volatile__ ("fmul %0, %1, %1" + : "=f" (tmp) + : "f" (fp_min)); + } + if (_fex & FP_EX_INEXACT) + { + __asm__ __volatile__ ("fsub %0, %1, %2" + : "=f" (tmp) + : "f" (fp_max), "f" (fp_one)); + } +} + +#endif /* !_SOFT_FLOAT */ Index: libgcc/config/rs6000/float128-hw.c =================================================================== --- libgcc/config/rs6000/float128-hw.c (.../svn+ssh://meiss...@gcc.gnu.org/svn/gcc/trunk/libgcc) (revision 0) +++ libgcc/config/rs6000/float128-hw.c (.../libgcc) (revision 232096) @@ -0,0 +1,207 @@ +/* Automatic switching between software and hardware IEEE 128-bit + floating-point emulation for PowerPC. + + Copyright (C) 2016 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Michael Meissner (meiss...@linux.vnet.ibm.com) + Code is based on the main soft-fp library written by: + Richard Henderson (r...@cygnus.com) and + Jakub Jelinek (j...@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> + +#ifndef __FLOAT128_HARDWARE__ +#error "This module must be compiled with IEEE 128-bit hardware support" +#endif + +TFtype +__addkf3_hw (TFtype a, TFtype b) +{ + return a + b; +} + +TFtype +__subkf3_hw (TFtype a, TFtype b) +{ + return a - b; +} + +TFtype +__mulkf3_hw (TFtype a, TFtype b) +{ + return a * b; +} + +TFtype +__divkf3_hw (TFtype a, TFtype b) +{ + return a / b; +} + +TFtype +__negkf2_hw (TFtype a) +{ + return -a; +} + +TFtype +__floatsikf_hw (SItype_ppc a) +{ + return (TFtype)a; +} + +TFtype +__floatunsikf_hw (USItype_ppc a) +{ + return (TFtype)a; +} + +TFtype +__floatdikf_hw (DItype_ppc a) +{ + return (TFtype)a; +} + +TFtype +__floatundikf_hw (UDItype_ppc a) +{ + return (TFtype)a; +} + +SItype_ppc +__fixkfsi_hw (TFtype a) +{ + return (SItype_ppc)a; +} + +USItype_ppc +__fixunskfsi_hw (TFtype a) +{ + return (USItype_ppc)a; +} + +DItype_ppc +__fixkfdi_hw (TFtype a) +{ + return (DItype_ppc)a; +} + +UDItype_ppc +__fixunskfdi_hw (TFtype a) +{ + return (UDItype_ppc)a; +} + +TFtype +__extendsfkf2_hw (float a) +{ + return (TFtype)a; +} + +TFtype +__extenddfkf2_hw (double a) +{ + return (TFtype)a; +} + +float +__trunckfsf2_hw (TFtype a) +{ + return (float)a; +} + +double +__trunckfdf2_hw (TFtype a) +{ + return (double)a; +} + +/* __eqkf2 returns 0 if equal, or 1 if not equal or NaN. */ +CMPtype +__eqkf2_hw (TFtype a, TFtype b) +{ + return (a != b); +} + +/* __gekf2 returns -1 if a < b, 0 if a == b, +1 if a > b, or -2 if NaN. */ +CMPtype +__gekf2_hw (TFtype a, TFtype b) +{ + if (a < b) + return -1; + + else if (__builtin_isunordered (a, b)) + return -2; + + else if (a == b) + return 0; + + return 1; +} + +/* __lekf2 returns -1 if a < b, 0 if a == b, +1 if a > b, or +2 if NaN. */ +CMPtype +__lekf2_hw (TFtype a, TFtype b) +{ + if (a < b) + return -1; + + else if (__builtin_isunordered (a, b)) + return 2; + + else if (a == b) + return 0; + + return 1; +} + +/* __unordkf2 returns 1 if Nan or 0 otherwise. */ +CMPtype +__unordkf2_hw (TFtype a, TFtype b) +{ + return (__builtin_isunordered (a, b)) ? 1 : 0; +} + +/* Convert __float128 to __ibm128. */ +__ibm128 +__extendkftf2_hw (TFtype value) +{ + __ibm128 ret; + + CVT_FLOAT128_TO_IBM128 (ret, value); + return ret; +} + +/* Convert __ibm128 to __float128. */ +TFtype +__trunctfkf2_hw (__ibm128 value) +{ + TFtype ret; + + CVT_IBM128_TO_FLOAT128 (ret, value); + return ret; +} Index: libgcc/config/rs6000/floattikf.c =================================================================== --- libgcc/config/rs6000/floattikf.c (.../svn+ssh://meiss...@gcc.gnu.org/svn/gcc/trunk/libgcc) (revision 0) +++ libgcc/config/rs6000/floattikf.c (.../libgcc) (revision 232096) @@ -0,0 +1,51 @@ +/* Software floating-point emulation, convert a 128bit signed integer to IEEE + quad. + + Copyright (C) 2016 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Steven Munroe (munro...@linux.vnet.ibm.com) + Code is based on the main soft-fp library written by: + Uros Bizjak (ubiz...@gmail.com). + + 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/>. */ + +#ifdef _ARCH_PPC64 +#include "soft-fp.h" +#include "quad-float128.h" + +TFtype +__floattikf (TItype i) +{ + FP_DECL_EX; + FP_DECL_Q (A); + TFtype a; + + FP_INIT_ROUNDMODE; + FP_FROM_INT_Q (A, i, TI_BITS, UTItype); + FP_PACK_RAW_Q (a, A); + FP_HANDLE_EXCEPTIONS; + + return a; +} +#endif Index: libgcc/config/rs6000/fixunskfti.c =================================================================== --- libgcc/config/rs6000/fixunskfti.c (.../svn+ssh://meiss...@gcc.gnu.org/svn/gcc/trunk/libgcc) (revision 0) +++ libgcc/config/rs6000/fixunskfti.c (.../libgcc) (revision 232096) @@ -0,0 +1,51 @@ +/* Software floating-point emulation, convert IEEE quad to 128bit unsigned + integer. + + Copyright (C) 2016 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Steven Munroe (munro...@linux.vnet.ibm.com) + Code is based on the main soft-fp library written by: + Uros Bizjak (ubiz...@gmail.com). + + 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/>. */ + +#ifdef _ARCH_PPC64 +#include "soft-fp.h" +#include "quad-float128.h" + +UTItype +__fixunskfti (TFtype a) +{ + FP_DECL_EX; + FP_DECL_Q (A); + UTItype r; + + FP_INIT_EXCEPTIONS; + FP_UNPACK_RAW_Q (A, a); + FP_TO_INT_Q (r, A, TI_BITS, 0); + FP_HANDLE_EXCEPTIONS; + + return r; +} +#endif Index: libgcc/config/rs6000/float128-ifunc.c =================================================================== --- libgcc/config/rs6000/float128-ifunc.c (.../svn+ssh://meiss...@gcc.gnu.org/svn/gcc/trunk/libgcc) (revision 0) +++ libgcc/config/rs6000/float128-ifunc.c (.../libgcc) (revision 232096) @@ -0,0 +1,358 @@ +/* Automatic switching between software and hardware IEEE 128-bit + floating-point emulation for PowerPC. + + Copyright (C) 2016 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Michael Meissner (meiss...@linux.vnet.ibm.com) + Code is based on the main soft-fp library written by: + Richard Henderson (r...@cygnus.com) and + Jakub Jelinek (j...@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> + +#ifdef FLOAT128_HW_INSNS +#include <sys/auxv.h> + +/* Use the namespace clean version of getauxval. However, not all versions of + sys/auxv.h declare it, so declare it here. This code is intended to be + temporary until a suitable version of __builtin_cpu_supports is added that + allows us to tell quickly if the machine supports IEEE 128-bit hardware. */ +extern unsigned long __getauxval (unsigned long); + +static int +have_ieee_hw_p (void) +{ + static int ieee_hw_p = -1; + + if (ieee_hw_p < 0) + { + char *p = (char *) __getauxval (AT_PLATFORM); + + ieee_hw_p = 0; + + /* Don't use atoi/strtol/strncmp/etc. These may require the normal + environment to be setup to set errno to 0, and the ifunc resolvers run + before the whole glibc environment is initialized. */ + if (p && p[0] == 'p' && p[1] == 'o' && p[2] == 'w' && p[3] == 'e' + && p[4] == 'r') + { + long n = 0; + char ch; + + p += 5; + while ((ch = *p++) >= '0' && (ch <= '9')) + n = (n * 10) + (ch - '0'); + + if (n >= 9) + ieee_hw_p = 1; + } + } + + return ieee_hw_p; +} + +#define SW_OR_HW(SW, HW) (have_ieee_hw_p () ? HW : SW) +#else +#define SW_OR_HW(SW, HW) (SW) +#endif /* ISA 3.0 hardware available. */ + +/* 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 __extendkftf2 (TFtype) + __attribute__ ((__ifunc__ ("__extendkftf2_resolve"))); + +TFtype __trunctfkf2 (__ibm128) + __attribute__ ((__ifunc__ ("__trunctfkf2_resolve"))); Index: libgcc/config/rs6000/fixkfti.c =================================================================== --- libgcc/config/rs6000/fixkfti.c (.../svn+ssh://meiss...@gcc.gnu.org/svn/gcc/trunk/libgcc) (revision 0) +++ libgcc/config/rs6000/fixkfti.c (.../libgcc) (revision 232096) @@ -0,0 +1,51 @@ +/* Software floating-point emulation, convert IEEE quad to 128bit signed + integer. + + Copyright (C) 2016 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Steven Munroe (munro...@linux.vnet.ibm.com) + Code is based on the main soft-fp library written by: + Uros Bizjak (ubiz...@gmail.com). + + 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/>. */ + +#ifdef _ARCH_PPC64 +#include "soft-fp.h" +#include "quad-float128.h" + +TItype +__fixkfti (TFtype a) +{ + FP_DECL_EX; + FP_DECL_Q (A); + UTItype r; + + FP_INIT_EXCEPTIONS; + FP_UNPACK_RAW_Q (A, a); + FP_TO_INT_Q (r, A, TI_BITS, 1); + FP_HANDLE_EXCEPTIONS; + + return r; +} +#endif Index: libgcc/config/rs6000/floatuntikf.c =================================================================== --- libgcc/config/rs6000/floatuntikf.c (.../svn+ssh://meiss...@gcc.gnu.org/svn/gcc/trunk/libgcc) (revision 0) +++ libgcc/config/rs6000/floatuntikf.c (.../libgcc) (revision 232096) @@ -0,0 +1,51 @@ +/* Software floating-point emulation, convert a 128bit unsigned integer to IEEE + quad. + + Copyright (C) 2016 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Steven Munroe (munro...@linux.vnet.ibm.com) + Code is based on the main soft-fp library written by: + Uros Bizjak (ubiz...@gmail.com). + + 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/>. */ + +#ifdef _ARCH_PPC64 +#include "soft-fp.h" +#include "quad-float128.h" + +TFtype +__floatuntikf (UTItype i) +{ + FP_DECL_EX; + FP_DECL_Q (A); + TFtype a; + + FP_INIT_ROUNDMODE; + FP_FROM_INT_Q (A, i, TI_BITS, UTItype); + FP_PACK_RAW_Q (a, A); + FP_HANDLE_EXCEPTIONS; + + return a; +} +#endif Index: libgcc/config/rs6000/quad-float128.h =================================================================== --- libgcc/config/rs6000/quad-float128.h (.../svn+ssh://meiss...@gcc.gnu.org/svn/gcc/trunk/libgcc) (revision 0) +++ libgcc/config/rs6000/quad-float128.h (.../libgcc) (revision 232096) @@ -0,0 +1,203 @@ +/* Software floating-point emulation. + Definitions for IEEE Quad Precision on the PowerPC. + Copyright (C) 2016 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Michael Meissner (meiss...@linux.vnet.ibm.com). + + 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/>. */ + +/* quad.h defines the TFtype type by: + typedef float TFtype __attribute__ ((mode (TF))); + + This define forces it to use KFmode (aka, ieee 128-bit floating point). */ +#define TF KF + +/* Force the use of the VSX instruction set. */ +#if defined(_ARCH_PPC) && (!defined(__VSX__) || !defined(__FLOAT128__)) +#pragma GCC target ("vsx,float128") +#endif + +#include <quad.h> + +/* Add prototypes of the library functions created. In case the appropriate + int/long types are not declared in scope by the time quad.h is included, + provide our own version. */ +typedef int SItype_ppc __attribute__ ((__mode__ (__SI__))); +typedef int DItype_ppc __attribute__ ((__mode__ (__DI__))); +typedef unsigned USItype_ppc __attribute__ ((__mode__ (__SI__))); +typedef unsigned UDItype_ppc __attribute__ ((__mode__ (__DI__))); + +#ifdef _ARCH_PPC64 +typedef int TItype_ppc __attribute__ ((__mode__ (__TI__))); +typedef unsigned UTItype_ppc __attribute__ ((__mode__ (__TI__))); +#endif + +/* Software emulation functions. */ +extern TFtype __addkf3_sw (TFtype, TFtype); +extern TFtype __subkf3_sw (TFtype, TFtype); +extern TFtype __mulkf3_sw (TFtype, TFtype); +extern TFtype __divkf3_sw (TFtype, TFtype); +extern TFtype __negkf2_sw (TFtype); +extern CMPtype __eqkf2_sw (TFtype, TFtype); +extern CMPtype __gekf2_sw (TFtype, TFtype); +extern CMPtype __lekf2_sw (TFtype, TFtype); +extern CMPtype __unordkf2_sw (TFtype, TFtype); +extern TFtype __extendsfkf2_sw (float); +extern TFtype __extenddfkf2_sw (double); +extern float __trunckfsf2_sw (TFtype); +extern double __trunckfdf2_sw (TFtype); +extern SItype_ppc __fixkfsi_sw (TFtype); +extern DItype_ppc __fixkfdi_sw (TFtype); +extern USItype_ppc __fixunskfsi_sw (TFtype); +extern UDItype_ppc __fixunskfdi_sw (TFtype); +extern TFtype __floatsikf_sw (SItype_ppc); +extern TFtype __floatdikf_sw (DItype_ppc); +extern TFtype __floatunsikf_sw (USItype_ppc); +extern TFtype __floatundikf_sw (UDItype_ppc); +extern __ibm128 __extendkftf2_sw (TFtype); +extern TFtype __trunctfkf2_sw (__ibm128); + +#ifdef _ARCH_PPC64 +/* 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. */ + +extern TItype_ppc __fixkfti (TFtype); +extern UTItype_ppc __fixunskfti (TFtype); +extern TFtype __floattikf (TItype_ppc); +extern TFtype __floatuntikf (UTItype_ppc); +#endif + +/* Functions using the ISA 3.0 hardware support. If the code is compiled with + -mcpu=power9, it will not use these functions, but if it was compiled with + -mcpu=power7 or -mcpu=power8 and run on a ISA 3.0 system, it will use the + hardware instruction. */ +extern TFtype __addkf3_hw (TFtype, TFtype); +extern TFtype __subkf3_hw (TFtype, TFtype); +extern TFtype __mulkf3_hw (TFtype, TFtype); +extern TFtype __divkf3_hw (TFtype, TFtype); +extern TFtype __negkf2_hw (TFtype); +extern CMPtype __eqkf2_hw (TFtype, TFtype); +extern CMPtype __gekf2_hw (TFtype, TFtype); +extern CMPtype __lekf2_hw (TFtype, TFtype); +extern CMPtype __unordkf2_hw (TFtype, TFtype); +extern TFtype __extendsfkf2_hw (float); +extern TFtype __extenddfkf2_hw (double); +extern float __trunckfsf2_hw (TFtype); +extern double __trunckfdf2_hw (TFtype); +extern SItype_ppc __fixkfsi_hw (TFtype); +extern DItype_ppc __fixkfdi_hw (TFtype); +extern USItype_ppc __fixunskfsi_hw (TFtype); +extern UDItype_ppc __fixunskfdi_hw (TFtype); +extern TFtype __floatsikf_hw (SItype_ppc); +extern TFtype __floatdikf_hw (DItype_ppc); +extern TFtype __floatunsikf_hw (USItype_ppc); +extern TFtype __floatundikf_hw (UDItype_ppc); +extern __ibm128 __extendkftf2_hw (TFtype); +extern TFtype __trunctfkf2_hw (__ibm128); + +/* Ifunc function declarations, to automatically switch between software + emulation and hardware support. */ +extern TFtype __addkf3 (TFtype, TFtype); +extern TFtype __subkf3 (TFtype, TFtype); +extern TFtype __mulkf3 (TFtype, TFtype); +extern TFtype __divkf3 (TFtype, TFtype); +extern TFtype __negkf2 (TFtype); +extern CMPtype __eqkf2 (TFtype, TFtype); +extern CMPtype __nekf2 (TFtype, TFtype); +extern CMPtype __gekf2 (TFtype, TFtype); +extern CMPtype __gtkf2 (TFtype, TFtype); +extern CMPtype __lekf2 (TFtype, TFtype); +extern CMPtype __ltkf2 (TFtype, TFtype); +extern CMPtype __unordkf2 (TFtype, TFtype); +extern TFtype __extendsfkf2 (float); +extern TFtype __extenddfkf2 (double); +extern float __trunckfsf2 (TFtype); +extern double __trunckfdf2 (TFtype); +extern SItype_ppc __fixkfsi (TFtype); +extern DItype_ppc __fixkfdi (TFtype); +extern USItype_ppc __fixunskfsi (TFtype); +extern UDItype_ppc __fixunskfdi (TFtype); +extern TFtype __floatsikf (SItype_ppc); +extern TFtype __floatdikf (DItype_ppc); +extern TFtype __floatunsikf (USItype_ppc); +extern TFtype __floatundikf (UDItype_ppc); +extern __ibm128 __extendkftf2 (TFtype); +extern TFtype __trunctfkf2 (__ibm128); + +#ifdef __LITTLE_ENDIAN__ +#define HIGH_WORD 1 +#define LOW_WORD 0 +#else +#define HIGH_WORD 0 +#define LOW_WORD 1 +#endif + +/* Implementation of conversions between __ibm128 and __float128, to allow the + same code to be used on systems with IEEE 128-bit emulation and with IEEE + 128-bit hardware support. */ + +#define CVT_FLOAT128_TO_IBM128(RESULT, VALUE) \ +{ \ + double __high, __low; \ + __float128 __value = (VALUE); \ + \ + __high = (double) __value; \ + if (__builtin_isnan (__high) || __builtin_isinf (__high)) \ + __low = 0.0; \ + \ + else \ + { \ + double __high_temp; \ + \ + __low = (double) (__value - (__float128)__high); \ + /* now renormalized move the high/low into canonical IBM long \ + double form. */ \ + __high_temp = __high + __low; \ + __low = (__high - __high_temp) + __low; \ + __high = __high_temp; \ + } \ + \ + RESULT = __builtin_pack_ibm128 (__high, __low); \ +} + +#define CVT_IBM128_TO_FLOAT128(RESULT, VALUE) \ +{ \ + __ibm128 __value = (VALUE); \ + double __high = __builtin_unpack_ibm128 (__value, HIGH_WORD); \ + double __low = __builtin_unpack_ibm128 (__value, LOW_WORD); \ + \ + /* Handle the special cases of NAN and inifinity. */ \ + if (__builtin_isnan (__high) || __builtin_isinf (__high)) \ + RESULT = (__float128) __high; \ + \ + /* If low is 0.0, there no need to do the add. In addition, \ + avoiding the add produces the correct sign if high is -0.0. */ \ + else if (__low == 0.0) \ + RESULT = (__float128) __high; \ + \ + else \ + RESULT = ((__float128)__high) + ((__float128)__low); \ +} Index: libgcc/config/rs6000/extendkftf2-sw.c =================================================================== --- libgcc/config/rs6000/extendkftf2-sw.c (.../svn+ssh://meiss...@gcc.gnu.org/svn/gcc/trunk/libgcc) (revision 0) +++ libgcc/config/rs6000/extendkftf2-sw.c (.../libgcc) (revision 232096) @@ -0,0 +1,49 @@ +/* Software IEEE 128-bit floating-point emulation for PowerPC. + + Copyright (C) 2016 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Michael Meissner (meiss...@linux.vnet.ibm.com) + Code is based on the main soft-fp library written by: + Richard Henderson (r...@cygnus.com) and + Jakub Jelinek (j...@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/>. */ + +/* Convert IEEE 128-bit floating point to IBM long double. */ + +#ifdef __FLOAT128_HARDWARE__ +#error "This module must not be compiled with IEEE 128-bit hardware support" +#endif + +#include "soft-fp.h" +#include "quad-float128.h" + +__ibm128 +__extendkftf2_sw (__float128 value) +{ + __ibm128 ret; + + CVT_FLOAT128_TO_IBM128 (ret, value); + return ret; +} Index: libgcc/config/rs6000/trunctfkf2-sw.c =================================================================== --- libgcc/config/rs6000/trunctfkf2-sw.c (.../svn+ssh://meiss...@gcc.gnu.org/svn/gcc/trunk/libgcc) (revision 0) +++ libgcc/config/rs6000/trunctfkf2-sw.c (.../libgcc) (revision 232096) @@ -0,0 +1,49 @@ +/* Software IEEE 128-bit floating-point emulation for PowerPC. + + Copyright (C) 2016 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Michael Meissner (meiss...@linux.vnet.ibm.com) + Code is based on the main soft-fp library written by: + Richard Henderson (r...@cygnus.com) and + Jakub Jelinek (j...@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/>. */ + +/* Convert IBM long double to IEEE 128-bit floating point. */ + +#ifdef __FLOAT128_HARDWARE__ +#error "This module must not be compiled with IEEE 128-bit hardware support" +#endif + +#include "soft-fp.h" +#include "quad-float128.h" + +__float128 +__trunctfkf2_sw (__ibm128 value) +{ + __float128 ret; + + CVT_IBM128_TO_FLOAT128 (ret, value); + return ret; +} Index: libgcc/config/rs6000/t-float128 =================================================================== --- libgcc/config/rs6000/t-float128 (.../svn+ssh://meiss...@gcc.gnu.org/svn/gcc/trunk/libgcc) (revision 0) +++ libgcc/config/rs6000/t-float128 (.../libgcc) (revision 232096) @@ -0,0 +1,95 @@ +# Support for adding __float128 to the powerpc. + +# The standard 128-bit floating point support functions are TFmode. Most +# PowerPC targets use a long double format that has a pair of doubles to give +# you more precision, but no extra expoenent range. This long double format is +# mostly compatible with the format used by the IBM XL compilers. Some of the +# names used by the IBM double-double format use TF in them, so we rename +# all of the functions provided for the new IEEE 128-bit support. +# +# We use the TF functions in soft-fp for 128-bit floating point support, using +# sed to transform the names in the files from TF names to KF names. + +# Emulator functions from the soft-fp directory +fp128_softfp_funcs = addkf3 subkf3 mulkf3 divkf3 negkf2 \ + unordkf2 eqkf2 gekf2 lekf2 \ + extendsfkf2 extenddfkf2 trunckfsf2 trunckfdf2 \ + fixkfsi fixkfdi fixunskfsi fixunskfdi \ + floatsikf floatdikf floatunsikf floatundikf + +fp128_softfp_src = $(addsuffix -sw.c,$(fp128_softfp_funcs)) +fp128_softfp_static_obj = $(addsuffix -sw$(objext),$(fp128_softfp_funcs)) +fp128_softfp_shared_obj = $(addsuffix -sw_s$(objext),$(fp128_softfp_funcs)) +fp128_softfp_obj = $(fp128_softfp_static_obj) $(fp128_softfp_shared_obj) + +# New functions for software emulation +fp128_ppc_funcs = floattikf floatuntikf fixkfti fixunskfti \ + extendkftf2-sw trunctfkf2-sw \ + sfp-exceptions float128-ifunc + +fp128_ppc_src = $(addprefix $(srcdir)/config/rs6000/,$(addsuffix \ + .c,$(fp128_ppc_funcs))) +fp128_ppc_static_obj = $(addsuffix $(objext),$(fp128_ppc_funcs)) +fp128_ppc_shared_obj = $(addsuffix _s$(objext),$(fp128_ppc_funcs)) +fp128_ppc_obj = $(fp128_ppc_static_obj) $(fp128_ppc_shared_obj) + +# All functions +fp128_funcs = $(fp128_softfp_funcs) $(fp128_ppc_funcs) \ + $(fp128_hw_funcs) + +fp128_src = $(fp128_softfp_src) $(fp128_ppc_src) \ + $(fp128_hw_src) + +fp128_obj = $(fp128_softfp_obj) $(fp128_ppc_obj) \ + $(fp128_hw_obj) + +fp128_sed = $(srcdir)/config/rs6000/float128-sed +fp128_dep = $(fp128_sed) $(srcdir)/config/rs6000/t-float128 + +fp128_includes = $(srcdir)/soft-fp/double.h \ + $(srcdir)/soft-fp/op-1.h \ + $(srcdir)/soft-fp/op-4.h \ + $(srcdir)/soft-fp/op-common.h \ + $(srcdir)/soft-fp/single.h \ + $(srcdir)/soft-fp/extended.h \ + $(srcdir)/soft-fp/op-2.h \ + $(srcdir)/soft-fp/op-8.h \ + $(srcdir)/soft-fp/quad.h \ + $(srcdir)/soft-fp/soft-fp.h + +# Build the emulator without ISA 3.0 hardware support. +FP128_CFLAGS_SW = -Wno-type-limits -mvsx -mfloat128 \ + -mno-float128-hardware \ + -I$(srcdir)/soft-fp \ + -I$(srcdir)/config/rs6000 \ + $(FLOAT128_HW_INSNS) + +$(fp128_softfp_obj) : INTERNAL_CFLAGS += $(FP128_CFLAGS_SW) +$(fp128_ppc_obj) : INTERNAL_CFLAGS += $(FP128_CFLAGS_SW) +$(fp128_obj) : $(fp128_includes) +$(fp128_obj) : $(srcdir)/config/rs6000/quad-float128.h + +$(fp128_softfp_src) : $(srcdir)/soft-fp/$(subst -sw,,$(subst kf,tf,$@)) $(fp128_dep) + @src="$(srcdir)/soft-fp/$(subst -sw,,$(subst kf,tf,$@))"; \ + echo "Create $@"; \ + (echo "/* file created from $$src */"; \ + echo; \ + sed -f $(fp128_sed) < $$src) > $@ + +.PHONY: test clean-float128 + +test: + @echo "fp128_src:"; \ + for x in $(fp128_src); do echo " $$x"; done; \ + echo; \ + echo "fp128_obj:"; \ + for x in $(fp128_obj); do echo " $$x"; done; + +clean-float128: + rm -rf $(fp128_softfp_src) + @$(MULTICLEAN) multi-clean DO=clean-float128 + +# For now, only put it in the static library +# LIB2ADD += $(fp128_src) + +LIB2ADD_ST += $(fp128_src) Index: libgcc/config/rs6000/float128-sed =================================================================== --- libgcc/config/rs6000/float128-sed (.../svn+ssh://meiss...@gcc.gnu.org/svn/gcc/trunk/libgcc) (revision 0) +++ libgcc/config/rs6000/float128-sed (.../libgcc) (revision 232096) @@ -0,0 +1,25 @@ +s/__addtf3/__addkf3_sw/g +s/__divtf3/__divkf3_sw/g +s/__eqtf2/__eqkf2_sw/g +s/__extenddftf2/__extenddfkf2_sw/g +s/__extendsftf2/__extendsfkf2_sw/g +s/__fixtfdi/__fixkfdi_sw/g +s/__fixtfsi/__fixkfsi_sw/g +s/__fixunstfdi/__fixunskfdi_sw/g +s/__fixunstfsi/__fixunskfsi_sw/g +s/__floatditf/__floatdikf_sw/g +s/__floatsitf/__floatsikf_sw/g +s/__floatunditf/__floatundikf_sw/g +s/__floatunsitf/__floatunsikf_sw/g +s/__getf2/__gekf2_sw/g +s/__gttf2/__gtkf2_sw/g +s/__letf2/__lekf2_sw/g +s/__lttf2/__ltkf2_sw/g +s/__multf3/__mulkf3_sw/g +s/__negtf2/__negkf2_sw/g +s/__netf2/__nekf2_sw/g +s/quad[.]h/quad-float128.h/g +s/__subtf3/__subkf3_sw/g +s/__trunctfdf2/__trunckfdf2_sw/g +s/__trunctfsf2/__trunckfsf2_sw/g +s/__unordtf2/__unordkf2_sw/g Index: libgcc/config/rs6000/t-float128-hw =================================================================== --- libgcc/config/rs6000/t-float128-hw (.../svn+ssh://meiss...@gcc.gnu.org/svn/gcc/trunk/libgcc) (revision 0) +++ libgcc/config/rs6000/t-float128-hw (.../libgcc) (revision 232096) @@ -0,0 +1,24 @@ +# Support for adding __float128 hardware support to the powerpc. +# Tell the float128 functions that the ISA 3.0 hardware support can +# be compiled it to be selected via IFUNC functions. + +FLOAT128_HW_INSNS = -DFLOAT128_HW_INSNS + +# New functions for hardware support +fp128_hw_funcs = float128-hw +fp128_hw_src = $(srcdir)/config/rs6000/float128-hw.c +fp128_hw_static_obj = float128-hw$(objext) +fp128_hw_shared_obj = float128-hw_s$(objext) +fp128_hw_obj = $(fp128_hw_static_obj) $(fp128_hw_shared_obj) + +# Build the hardware support functions with appropriate hardware support +FP128_CFLAGS_HW = -Wno-type-limits -mvsx -mfloat128 \ + -mpower8-vector -mpower9-vector \ + -mfloat128-hardware \ + -I$(srcdir)/soft-fp \ + -I$(srcdir)/config/rs6000 \ + $(FLOAT128_HW_INSNS) + +$(fp128_hw_obj) : INTERNAL_CFLAGS += $(FP128_CFLAGS_HW) +$(fp128_hw_obj) : $(srcdir)/config/rs6000/t-float128-hw + Index: libgcc/config/rs6000/sfp-machine.h =================================================================== --- libgcc/config/rs6000/sfp-machine.h (.../svn+ssh://meiss...@gcc.gnu.org/svn/gcc/trunk/libgcc) (revision 232093) +++ libgcc/config/rs6000/sfp-machine.h (.../libgcc) (working copy) @@ -1,7 +1,26 @@ +/* Decide whether to use 64 or 32-bit types to do the emulation. If we are + doing IEEE-128 with VSX, use 64-bit emulation even if we are compiling for a + 32-bit target. */ + +#if defined(_ARCH_PPC64) || defined(__VSX__) || defined(__FLOAT128__) +#define _FP_W_TYPE_SIZE 64 +#define _FP_W_TYPE unsigned long long +#define _FP_WS_TYPE signed long long +#define _FP_I_TYPE long long + +#ifdef _ARCH_PPC64 +typedef int TItype __attribute__ ((mode (TI))); +typedef unsigned int UTItype __attribute__ ((mode (TI))); + +#define TI_BITS (__CHAR_BIT__ * (int)sizeof(TItype)) +#endif + +#else /* 32-bits */ #define _FP_W_TYPE_SIZE 32 -#define _FP_W_TYPE unsigned long -#define _FP_WS_TYPE signed long -#define _FP_I_TYPE long +#define _FP_W_TYPE unsigned int +#define _FP_WS_TYPE signed int +#define _FP_I_TYPE int +#endif /* 32-bits */ /* The type of the result of a floating point comparison. This must match `__libgcc_cmp_return__' in GCC for the target. */ @@ -10,18 +29,39 @@ typedef int __gcc_CMPtype __attribute__ #define _FP_MUL_MEAT_S(R,X,Y) \ _FP_MUL_MEAT_1_wide(_FP_WFRACBITS_S,R,X,Y,umul_ppmm) + +#if (_FP_W_TYPE_SIZE==64) +#define _FP_MUL_MEAT_D(R,X,Y) \ + _FP_MUL_MEAT_1_wide(_FP_WFRACBITS_D,R,X,Y,umul_ppmm) +#define _FP_MUL_MEAT_Q(R,X,Y) \ + _FP_MUL_MEAT_2_wide(_FP_WFRACBITS_Q,R,X,Y,umul_ppmm) +#else #define _FP_MUL_MEAT_D(R,X,Y) \ _FP_MUL_MEAT_2_wide(_FP_WFRACBITS_D,R,X,Y,umul_ppmm) #define _FP_MUL_MEAT_Q(R,X,Y) \ _FP_MUL_MEAT_4_wide(_FP_WFRACBITS_Q,R,X,Y,umul_ppmm) +#endif #define _FP_DIV_MEAT_S(R,X,Y) _FP_DIV_MEAT_1_loop(S,R,X,Y) + +#if (_FP_W_TYPE_SIZE==64) +#define _FP_DIV_MEAT_D(R,X,Y) _FP_DIV_MEAT_1_udiv(D,R,X,Y) +#define _FP_DIV_MEAT_Q(R,X,Y) _FP_DIV_MEAT_2_udiv(Q,R,X,Y) +#else #define _FP_DIV_MEAT_D(R,X,Y) _FP_DIV_MEAT_2_udiv(D,R,X,Y) #define _FP_DIV_MEAT_Q(R,X,Y) _FP_DIV_MEAT_4_udiv(Q,R,X,Y) +#endif #define _FP_NANFRAC_S ((_FP_QNANBIT_S << 1) - 1) + +#if (_FP_W_TYPE_SIZE==64) +#define _FP_NANFRAC_D ((_FP_QNANBIT_D << 1) - 1) +#define _FP_NANFRAC_Q ((_FP_QNANBIT_Q << 1) - 1), -1 +#else #define _FP_NANFRAC_D ((_FP_QNANBIT_D << 1) - 1), -1 #define _FP_NANFRAC_Q ((_FP_QNANBIT_Q << 1) - 1), -1, -1, -1 +#endif + #define _FP_NANSIGN_S 0 #define _FP_NANSIGN_D 0 #define _FP_NANSIGN_Q 0 @@ -64,6 +104,53 @@ typedef int __gcc_CMPtype __attribute__ # endif #endif +/* Only provide exception support if we have hardware floating point and we can + execute the mtfsf instruction. This would only be true if we are using the + emulation routines for IEEE 128-bit floating point on pre-ISA 3.0 machines + without the IEEE 128-bit floating point support. */ + +#ifndef _SOFT_FLOAT +#define ISA_BIT(x) (1LL << (63 - x)) + +/* Use the same bits of the FPSCR. */ +# define FP_EX_INVALID ISA_BIT(34) +# define FP_EX_OVERFLOW ISA_BIT(35) +# define FP_EX_UNDERFLOW ISA_BIT(36) +# define FP_EX_DIVZERO ISA_BIT(37) +# define FP_EX_INEXACT ISA_BIT(38) +# define FP_EX_ALL (FP_EX_INVALID | FP_EX_OVERFLOW \ + | FP_EX_UNDERFLOW | FP_EX_DIVZERO \ + | FP_EX_INEXACT) + +void __sfp_handle_exceptions (int); + +# define FP_HANDLE_EXCEPTIONS \ + do { \ + if (__builtin_expect (_fex, 0)) \ + __sfp_handle_exceptions (_fex); \ + } while (0); +/* A set bit indicates an exception is masked and a clear bit indicates it is + trapping. */ +# define FP_TRAPPING_EXCEPTIONS (~_fpscr & (FP_EX_ALL >> 22)) + +# define FP_RND_NEAREST 0x0 +# define FP_RND_ZERO 0x1 +# define FP_RND_PINF 0x2 +# define FP_RND_MINF 0x3 +# define FP_RND_MASK 0x3 + +# define _FP_DECL_EX \ + unsigned long long _fpscr __attribute__ ((unused)) = FP_RND_NEAREST + +#define FP_INIT_ROUNDMODE \ + do { \ + __asm__ __volatile__ ("mtfsf 255, %0" \ + : \ + : "f" (_fpscr)); \ + } while (0) + +# define FP_ROUNDMODE (_fpscr & FP_RND_MASK) +#endif /* !_SOFT_FLOAT */ /* Define ALIASNAME as a strong alias for NAME. */ # define strong_alias(name, aliasname) _strong_alias(name, aliasname) Index: libgcc/configure.ac =================================================================== --- libgcc/configure.ac (.../svn+ssh://meiss...@gcc.gnu.org/svn/gcc/trunk/libgcc) (revision 232093) +++ libgcc/configure.ac (.../libgcc) (working copy) @@ -373,6 +373,31 @@ esac ;; esac +case ${host} in +powerpc*-*-linux*) + AC_CACHE_CHECK([whether the PowerPC compiler can do __float128], + [libgcc_cv_powerpc_float128], + [AC_COMPILE_IFELSE( + [#pragma GCC target ("vsx,float128") + __float128 add (__float128 *a) { return *a + *(a+1); }], + [libgcc_cv_powerpc_float128=yes], + [libgcc_cv_powerpc_float128=no])]) + + AC_CACHE_CHECK([whether the PowerPC compiler can do hardware __float128], + [libgcc_cv_powerpc_float128_hw], + [AC_COMPILE_IFELSE( + [#pragma GCC target ("cpu=power9,float128,float128-hardware") + #include <sys/auxv.h> + __float128 add (__float128 a, __float128 b) + { + __float128 ret; + __asm__ ("xsaddqp %0,%1,%2" : "=v" (ret) : "v" (a), "v" (b)); + return ret; + }], + [libgcc_cv_powerpc_float128_hw=yes], + [libgcc_cv_powerpc_float128_hw=no])]) +esac + # Collect host-machine-specific information. . ${srcdir}/config.host Index: libgcc/configure =================================================================== --- libgcc/configure (.../svn+ssh://meiss...@gcc.gnu.org/svn/gcc/trunk/libgcc) (revision 232093) +++ libgcc/configure (.../libgcc) (working copy) @@ -4766,6 +4766,55 @@ esac ;; esac +case ${host} in +powerpc*-*-linux*) + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the PowerPC compiler can do __float128" >&5 +$as_echo_n "checking whether the PowerPC compiler can do __float128... " >&6; } +if test "${libgcc_cv_powerpc_float128+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#pragma GCC target ("vsx,float128") + __float128 add (__float128 *a) { return *a + *(a+1); } +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + libgcc_cv_powerpc_float128=yes +else + libgcc_cv_powerpc_float128=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libgcc_cv_powerpc_float128" >&5 +$as_echo "$libgcc_cv_powerpc_float128" >&6; } + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the PowerPC compiler can do hardware __float128" >&5 +$as_echo_n "checking whether the PowerPC compiler can do hardware __float128... " >&6; } +if test "${libgcc_cv_powerpc_float128_hw+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#pragma GCC target ("cpu=power9,float128,float128-hardware") + #include <sys/auxv.h> + __float128 add (__float128 a, __float128 b) + { + __float128 ret; + __asm__ ("xsaddqp %0,%1,%2" : "=v" (ret) : "v" (a), "v" (b)); + return ret; + } +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + libgcc_cv_powerpc_float128_hw=yes +else + libgcc_cv_powerpc_float128_hw=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libgcc_cv_powerpc_float128_hw" >&5 +$as_echo "$libgcc_cv_powerpc_float128_hw" >&6; } +esac + # Collect host-machine-specific information. . ${srcdir}/config.host