if (TARGET_POWERPC64)
{
- set_conv_libfunc (sfix_optab, TImode, mode, "__fixkfti");
- set_conv_libfunc (ufix_optab, TImode, mode, "__fixunskfti");
- set_conv_libfunc (sfloat_optab, mode, TImode, "__floattikf");
- set_conv_libfunc (ufloat_optab, mode, TImode, "__floatuntikf");
+ set_conv_libfunc (sfix_optab, TImode, mode, "__fixkfti_sw");
+ set_conv_libfunc (ufix_optab, TImode, mode, "__fixunskfti_sw");
+ set_conv_libfunc (sfloat_optab, mode, TImode, "__floattikf_sw");
+ set_conv_libfunc (ufloat_optab, mode, TImode, "__floatuntikf_sw");
}
}
xscvsxddp %x0,%x1"
[(set_attr "type" "fp")])
+(define_insn "floatti<mode>2"
+ [(set (match_operand:IEEE128 0 "vsx_register_operand" "=v")
+ (float:IEEE128 (match_operand:TI 1 "vsx_register_operand" "v")))]
+ "TARGET_POWER10"
+{
+ return "xscvsqqp %0,%1";
+}
+ [(set_attr "type" "fp")])
+
+(define_insn "floatunsti<mode>2"
+ [(set (match_operand:IEEE128 0 "vsx_register_operand" "=v")
+ (unsigned_float:IEEE128 (match_operand:TI 1 "vsx_register_operand" "v")))]
+ "TARGET_POWER10"
+{
+ return "xscvuqqp %0,%1";
+}
+ [(set_attr "type" "fp")])
+
+(define_insn "fix_trunc<mode>ti2"
+ [(set (match_operand:TI 0 "vsx_register_operand" "=v")
+ (fix:TI (match_operand:IEEE128 1 "vsx_register_operand" "v")))]
+ "TARGET_POWER10"
+{
+ return "xscvqpsqz %0,%1";
+}
+ [(set_attr "type" "fp")])
+
+(define_insn "fixuns_trunc<mode>ti2"
+ [(set (match_operand:TI 0 "vsx_register_operand" "=v")
+ (unsigned_fix:TI (match_operand:IEEE128 1 "vsx_register_operand" "v")))]
+ "TARGET_POWER10"
+{
+ return "xscvqpuqz %0,%1";
+}
+ [(set_attr "type" "fp")])
+
; Allow the combiner to merge source memory operands to the conversion so that
; the optimizer/register allocator doesn't try to load the value too early in a
; GPR and then use store/load to move it to a FPR and suffer from a store-load
--- /dev/null
+/* { dg-do run } */
+/* { dg-require-effective-target power10_hw } */
+/* { dg-options "-mdejagnu-cpu=power10 -save-temps" } */
+
+/* Check that the expected 128-bit instructions are generated if the processor
+ supports the 128-bit integer instructions. */
+/* { dg-final { scan-assembler-times {\mxscvsqqp\M} 1 } } */
+/* { dg-final { scan-assembler-times {\mxscvuqqp\M} 1 } } */
+/* { dg-final { scan-assembler-times {\mxscvqpsqz\M} 1 } } */
+/* { dg-final { scan-assembler-times {\mxscvqpuqz\M} 1 } } */
+
+#include <stdio.h>
+#include <math.h>
+#include <fenv.h>
+#include <stdlib.h>
+#include <wchar.h>
+
+#define DEBUG 0
+
+void
+abort (void);
+
+float
+conv_i_2_fp( long long int a)
+{
+ return (float) a;
+}
+
+double
+conv_i_2_fpd( long long int a)
+{
+ return (double) a;
+}
+
+double
+conv_ui_2_fpd( unsigned long long int a)
+{
+ return (double) a;
+}
+
+__float128
+conv_i128_2_fp128 (__int128_t a)
+{
+ // default, gen inst KF mode
+ // -mabi=ibmlongdouble, gen inst floattiieee KF mode
+ // -mabi=ieeelongdouble gen inst floattiieee TF mode
+ return (__float128) a;
+}
+
+__float128
+conv_ui128_2_fp128 (__uint128_t a)
+{
+ // default, gen inst KF mode
+ // -mabi=ibmlongdouble, gen inst floattiieee KF mode
+ // -mabi=ieeelongdouble gen inst floattiieee TF mode
+ return (__float128) a;
+}
+
+__int128_t
+conv_fp128_2_i128 (__float128 a)
+{
+ // default, gen inst KF mode
+ // -mabi=ibmlongdouble, gen inst floattiieee KF mode
+ // -mabi=ieeelongdouble gen inst floattiieee TF mode
+ return (__int128_t) a;
+}
+
+__uint128_t
+conv_fp128_2_ui128 (__float128 a)
+{
+ // default, gen inst KF mode
+ // -mabi=ibmlongdouble, gen inst floattiieee KF mode
+ // -mabi=ieeelongdouble gen inst floattiieee TF mode
+ return (__uint128_t) a;
+}
+
+long double
+conv_i128_2_ld (__int128_t a)
+{
+ // default, gen call __floattitf
+ // -mabi=ibmlongdouble, gen call __floattitf
+ // -mabi=ieeelongdouble gen inst floattiieee TF mode
+ return (long double) a;
+}
+
+__ibm128
+conv_i128_2_ibm128 (__int128_t a)
+{
+ // default, gen call __floattitf
+ // -mabi=ibmlongdouble, gen call __floattitf
+ // -mabi=ieeelongdouble, message uses IBM long double, no binary output
+ return (__ibm128) a;
+}
+
+int
+main()
+{
+ float a, expected_result_float;
+ double b, expected_result_double;
+ long long int c, expected_result_llint;
+ unsigned long long int u;
+ __int128_t d;
+ __uint128_t u128;
+ unsigned long long expected_result_uint128[2] ;
+ __float128 e;
+ long double ld; // another 128-bit float version
+
+ union conv_t {
+ float a;
+ double b;
+ long long int c;
+ long long int128[2] ;
+ unsigned long long uint128[2] ;
+ unsigned long long int u;
+ __int128_t d;
+ __uint128_t u128;
+ __float128 e;
+ long double ld; // another 128-bit float version
+ } conv, conv_result;
+
+ c = 20;
+ expected_result_llint = 20.00000;
+ a = conv_i_2_fp (c);
+
+ if (a != expected_result_llint) {
+#if DEBUG
+ printf("ERROR: conv_i_2_fp(%lld) = %10.5f\n", c, a);
+ printf("\n does not match expected_result = %10.5f\n\n",
+ expected_result_llint);
+#else
+ abort();
+#endif
+ }
+
+ c = 20;
+ expected_result_double = 20.00000;
+ b = conv_i_2_fpd (c);
+
+ if (b != expected_result_double) {
+#if DEBUG
+ printf("ERROR: conv_i_2_fpd(%lld) = %10.5f\n", d, b);
+ printf("\n does not match expected_result = %10.5f\n\n",
+ expected_result_double);
+ #else
+ abort();
+#endif
+ }
+
+ u = 20;
+ expected_result_double = 20.00000;
+ b = conv_ui_2_fpd (u);
+
+ if (b != expected_result_double) {
+#if DEBUG
+ printf("ERROR: conv_ui_2_fpd(%llu) = %10.5f\n", u, b);
+ printf("\n does not match expected_result = %10.5f\n\n",
+ expected_result_double);
+ #else
+ abort();
+#endif
+ }
+
+ d = -3210;
+ d = (d * 10000000000) + 9876543210;
+ conv_result.e = conv_i128_2_fp128 (d);
+ expected_result_uint128[1] = 0xc02bd2f9068d1160;
+ expected_result_uint128[0] = 0x0;
+
+ if ((conv_result.uint128[1] != expected_result_uint128[1])
+ && (conv_result.uint128[0] != expected_result_uint128[0])) {
+#if DEBUG
+ printf("ERROR: conv_i128_2_fp128(-32109876543210) = (result in hex) 0x%llx %llx\n",
+ conv.uint128[1], conv.uint128[0]);
+ printf("\n does not match expected_result = (result in hex) 0x%llx %llx\n\n",
+ expected_result_uint128[1], expected_result_uint128[0]);
+ #else
+ abort();
+#endif
+ }
+
+ d = 123;
+ d = (d * 10000000000) + 1234567890;
+ conv_result.ld = conv_i128_2_fp128 (d);
+ expected_result_uint128[1] = 0x0;
+ expected_result_uint128[0] = 0x4271eab4c8ed2000;
+
+ if ((conv_result.uint128[1] != expected_result_uint128[1])
+ && (conv_result.uint128[0] != expected_result_uint128[0])) {
+#if DEBUG
+ printf("ERROR: conv_i128_2_fp128(1231234567890) = (result in hex) 0x%llx %llx\n",
+ conv.uint128[1], conv.uint128[0]);
+ printf("\n does not match expected_result = (result in hex) 0x%llx %llx\n\n",
+ expected_result_uint128[1], expected_result_uint128[0]);
+ #else
+ abort();
+#endif
+ }
+
+ u128 = 8760;
+ u128 = (u128 * 10000000000) + 1234567890;
+ conv_result.e = conv_ui128_2_fp128 (u128);
+ expected_result_uint128[1] = 0x402d3eb101df8b48;
+ expected_result_uint128[0] = 0x0;
+
+ if ((conv_result.uint128[1] != expected_result_uint128[1])
+ && (conv_result.uint128[0] != expected_result_uint128[0])) {
+#if DEBUG
+ printf("ERROR: conv_ui128_2_fp128(87601234567890) = (result in hex) 0x%llx %llx\n",
+ conv.uint128[1], conv.uint128[0]);
+ printf("\n does not match expected_result = (result in hex) 0x%llx %llx\n\n",
+ expected_result_uint128[1], expected_result_uint128[0]);
+ #else
+ abort();
+#endif
+ }
+
+ u128 = 3210;
+ u128 = (u128 * 10000000000) + 9876543210;
+ expected_result_uint128[1] = 0x402bd3429c8feea0;
+ expected_result_uint128[0] = 0x0;
+ conv_result.e = conv_ui128_2_fp128 (u128);
+
+ if ((conv_result.uint128[1] != expected_result_uint128[1])
+ && (conv_result.uint128[0] != expected_result_uint128[0])) {
+#if DEBUG
+ printf("ERROR: conv_ui128_2_fp128(32109876543210) = (result in hex) 0x%llx %llx\n",
+ conv.uint128[1], conv.uint128[0]);
+ printf("\n does not match expected_result = (result in hex) 0x%llx %llx\n\n",
+ expected_result_uint128[1], expected_result_uint128[0]);
+ #else
+ abort();
+#endif
+ }
+
+ conv.e = 12345.6789;
+ expected_result_uint128[1] = 0x1407374883526960;
+ expected_result_uint128[0] = 0x3039;
+
+ conv_result.d = conv_fp128_2_i128 (conv.e);
+
+ if ((conv_result.uint128[1] != expected_result_uint128[1])
+ && (conv_result.uint128[0] != expected_result_uint128[0])) {
+#if DEBUG
+ printf("ERROR: conv_fp128_2_i128(0x%llx %llx) = ",
+ conv.uint128[1], conv.uint128[0]);
+ printf("0x%llx %llx\n", conv_result.uint128[1], conv_result.uint128[0]);
+
+ printf("\n does not match expected_result = (result in hex) 0x%llx %llx\n\n",
+ expected_result_uint128[1], expected_result_uint128[0]);
+ #else
+ abort();
+#endif
+ }
+
+ conv.e = -6789.12345;
+ expected_result_uint128[1] = 0x0;
+ expected_result_uint128[0] = 0xffffffffffffe57b;
+ conv_result.d = conv_fp128_2_i128 (conv.e);
+
+ if ((conv_result.uint128[1] != expected_result_uint128[1])
+ && (conv_result.uint128[0] != expected_result_uint128[0])) {
+#if DEBUG
+ printf("ERROR: conv_fp128_2_i128(0x%llx %llx) = ",
+ conv.uint128[1], conv.uint128[0]);
+ printf("0x%llx %llx\n", conv_result.uint128[1], conv_result.uint128[0]);
+
+ printf("\n does not match expected_result = (result in hex) 0x%llx %llx\n\n",
+ expected_result_uint128[1], expected_result_uint128[0]);
+ #else
+ abort();
+#endif
+ }
+
+ conv.e = 6789.12345;
+ expected_result_uint128[1] = 0x0;
+ expected_result_uint128[0] = 0x1a85;
+ conv_result.d = conv_fp128_2_ui128 (conv.e);
+
+ if ((conv_result.uint128[1] != expected_result_uint128[1])
+ && (conv_result.uint128[0] != expected_result_uint128[0])) {
+#if DEBUG
+ printf("ERROR: conv_fp128_2_ui128(0x%llx %llx) = ",
+ conv.uint128[1], conv.uint128[0]);
+ printf("0x%llx %llx\n", conv_result.uint128[1], conv_result.uint128[0]);
+
+ printf("\n does not match expected_result = (result in hex) 0x%llx %llx\n\n",
+ expected_result_uint128[1], expected_result_uint128[0]);
+ #else
+ abort();
+#endif
+ }
+
+ return 0;
+}
/* Check that the expected 128-bit instructions are generated if the processor
supports the 128-bit integer instructions. */
+/* { dg-final { scan-assembler-times {\mvextsd2q\M} 4 } } */
/* { dg-final { scan-assembler-times {\mvslq\M} 2 } } */
/* { dg-final { scan-assembler-times {\mvsrq\M} 2 } } */
/* { dg-final { scan-assembler-times {\mvsraq\M} 2 } } */
/* { dg-final { scan-assembler-times {\mvrlq\M} 2 } } */
/* { dg-final { scan-assembler-times {\mvrlqnm\M} 2 } } */
/* { dg-final { scan-assembler-times {\mvrlqmi\M} 2 } } */
-/* { dg-final { scan-assembler-times {\mvcmpuq\M} 0 } } */
-/* { dg-final { scan-assembler-times {\mvcmpsq\M} 0 } } */
-/* { dg-final { scan-assembler-times {\mvcmpequq\M} 0 } } */
-/* { dg-final { scan-assembler-times {\mvcmpequq.\M} 16 } } */
-/* { dg-final { scan-assembler-times {\mvcmpgtsq\M} 0 } } */
-/* { dg-final { scan-assembler-times {\mvcmpgtsq.\M} 16 } } */
-/* { dg-final { scan-assembler-times {\mvcmpgtuq\M} 0 } } */
-/* { dg-final { scan-assembler-times {\mvcmpgtuq.\M} 16 } } */
-/* { dg-final { scan-assembler-times {\mvmuleud\M} 1 } } */
+/* { dg-final { scan-assembler-times {\mvcmpequq\M} 16 } } */
+/* { dg-final { scan-assembler-times {\mvcmpgtsq\M} 16 } } */
+/* { dg-final { scan-assembler-times {\mvcmpgtuq\M} 16 } } */
/* { dg-final { scan-assembler-times {\mvmuloud\M} 1 } } */
/* { dg-final { scan-assembler-times {\mvmulesd\M} 1 } } */
/* { dg-final { scan-assembler-times {\mvmulosd\M} 1 } } */
tmake_file="${tmake_file} rs6000/t-float128-hw"
fi
+ if test $libgcc_cv_powerpc_3_1_float128_hw = yes; then
+ tmake_file="${tmake_file} rs6000/t-float128-p10-hw"
+ fi
+
extra_parts="$extra_parts ecrti.o ecrtn.o ncrti.o ncrtn.o"
md_unwind_header=rs6000/linux-unwind.h
;;
This file is part of the GNU C Library.
Contributed by Steven Munroe (munroesj@linux.vnet.ibm.com)
Code is based on the main soft-fp library written by:
- Uros Bizjak (ubizjak@gmail.com).
+ Uros Bizjak (ubizjak@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
#include "quad-float128.h"
TItype
-__fixkfti (TFtype a)
+__fixkfti_sw (TFtype a)
{
FP_DECL_EX;
FP_DECL_Q (A);
This file is part of the GNU C Library.
Contributed by Steven Munroe (munroesj@linux.vnet.ibm.com)
Code is based on the main soft-fp library written by:
- Uros Bizjak (ubizjak@gmail.com).
+ Uros Bizjak (ubizjak@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
#include "quad-float128.h"
UTItype
-__fixunskfti (TFtype a)
+__fixunskfti_sw (TFtype a)
{
FP_DECL_EX;
FP_DECL_Q (A);
#endif
#define SW_OR_HW(SW, HW) (__builtin_cpu_supports ("ieee128") ? HW : SW)
+#define SW_OR_HW_ISA3_1(SW, HW) (__builtin_cpu_supports ("arch_3_1") ? 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 __typeof__ (__addkf3_sw) *
__addkf3_resolve (void)
{
return SW_OR_HW (__floatdikf_sw, __floatdikf_hw);
}
+static __typeof__ (__floattikf_sw) *
+__floattikf_resolve (void)
+{
+ return SW_OR_HW_ISA3_1 (__floattikf_sw, __floattikf_hw);
+}
+
+static __typeof__ (__floatuntikf_sw) *
+__floatuntikf_resolve (void)
+{
+ return SW_OR_HW_ISA3_1 (__floatuntikf_sw, __floatuntikf_hw);
+}
+
static __typeof__ (__floatunsikf_sw) *
__floatunsikf_resolve (void)
{
return SW_OR_HW (__floatundikf_sw, __floatundikf_hw);
}
+
+static __typeof__ (__fixkfti_sw) *
+__fixkfti_resolve (void)
+{
+ return SW_OR_HW_ISA3_1 (__fixkfti_sw, __fixkfti_hw);
+}
+
+static __typeof__ (__fixunskfti_sw) *
+__fixunskfti_resolve (void)
+{
+ return SW_OR_HW_ISA3_1 (__fixunskfti_sw, __fixunskfti_hw);
+}
+
static __typeof__ (__fixkfsi_sw) *
__fixkfsi_resolve (void)
{
TFtype __floatdikf (DItype_ppc)
__attribute__ ((__ifunc__ ("__floatdikf_resolve")));
+TFtype __floattikf (TItype_ppc)
+ __attribute__ ((__ifunc__ ("__floattikf_resolve")));
+
+TFtype __floatuntikf (UTItype_ppc)
+ __attribute__ ((__ifunc__ ("__floatuntikf_resolve")));
+
+TItype_ppc __fixkfti (TFtype)
+ __attribute__ ((__ifunc__ ("__fixkfti_resolve")));
+
+UTItype_ppc __fixunskfti (TFtype)
+ __attribute__ ((__ifunc__ ("__fixunskfti_resolve")));
+
TFtype __floatunsikf (USItype_ppc)
__attribute__ ((__ifunc__ ("__floatunsikf_resolve")));
--- /dev/null
+/* Automatic switching between software and hardware IEEE 128-bit
+ ISA 3.1 floating-point emulation for PowerPC.
+
+ Copyright (C) 2016-2020 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Carl Love (cel@us.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/>. */
+
+/* Note, the hardware conversion instructions for 128-bit integers are
+ supported for ISA 3.1 and later. Only compile this file with -mcpu=power10
+ or newer support. */
+
+#include <soft-fp.h>
+#include <quad-float128.h>
+
+#ifndef __FLOAT128_HARDWARE__
+#error "This module must be compiled with IEEE 128-bit hardware support"
+#endif
+
+#ifndef _ARCH_PWR10
+#error "This module must be compiled for Power 10 support"
+#endif
+
+TFtype
+__floattikf_hw (TItype_ppc a)
+{
+ return (TFtype) a;
+}
+
+TFtype
+__floatuntikf_hw (UTItype_ppc a)
+{
+ return (TFtype) a;
+}
+
+TItype_ppc
+__fixkfti_hw (TFtype a)
+{
+ return (TItype_ppc) a;
+}
+
+UTItype_ppc
+__fixunskfti_hw (TFtype a)
+{
+ return (UTItype_ppc) a;
+}
s/__fixunstfdi/__fixunskfdi/g
s/__fixunstfsi/__fixunskfsi/g
s/__floatditf/__floatdikf/g
+s/__floattitf/__floattikf/g
+s/__floatuntitf/__floatuntikf/g
+s/__fixtfti/__fixkfti/g
+s/__fixunstfti/__fixunskfti/g
s/__floatsitf/__floatsikf/g
s/__floatunditf/__floatundikf/g
s/__floatunsitf/__floatunsikf/g
s/__fixunstfdi/__fixunskfdi_sw/g
s/__fixunstfsi/__fixunskfsi_sw/g
s/__floatditf/__floatdikf_sw/g
+s/__floattitf/__floattikf_sw/g
+s/__floatuntitf/__floatuntikf_sw/g
+s/__fixtfti/__fixkfti_sw/g
+s/__fixunstfti/__fixunskfti_sw/g
s/__floatsitf/__floatsikf_sw/g
s/__floatunditf/__floatundikf_sw/g
s/__floatunsitf/__floatunsikf_sw/g
This file is part of the GNU C Library.
Contributed by Steven Munroe (munroesj@linux.vnet.ibm.com)
Code is based on the main soft-fp library written by:
- Uros Bizjak (ubizjak@gmail.com).
+ Uros Bizjak (ubizjak@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
#include "quad-float128.h"
TFtype
-__floattikf (TItype i)
+__floattikf_sw (TItype i)
{
FP_DECL_EX;
FP_DECL_Q (A);
This file is part of the GNU C Library.
Contributed by Steven Munroe (munroesj@linux.vnet.ibm.com)
Code is based on the main soft-fp library written by:
- Uros Bizjak (ubizjak@gmail.com).
+ Uros Bizjak (ubizjak@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
#include "quad-float128.h"
TFtype
-__floatuntikf (UTItype i)
+__floatuntikf_sw (UTItype i)
{
FP_DECL_EX;
FP_DECL_Q (A);
extern UDItype_ppc __fixunskfdi_sw (TFtype);
extern TFtype __floatsikf_sw (SItype_ppc);
extern TFtype __floatdikf_sw (DItype_ppc);
+extern TFtype __floattikf_sw (TItype_ppc);
extern TFtype __floatunsikf_sw (USItype_ppc);
extern TFtype __floatundikf_sw (UDItype_ppc);
+extern TFtype __floatuntikf_sw (UTItype_ppc);
+extern TItype_ppc __fixkfti_sw (TFtype);
+extern UTItype_ppc __fixunskfti_sw (TFtype);
extern IBM128_TYPE __extendkftf2_sw (TFtype);
extern TFtype __trunctfkf2_sw (IBM128_TYPE);
extern TCtype __mulkc3_sw (TFtype, TFtype, TFtype, TFtype);
extern TCtype __divkc3_sw (TFtype, TFtype, TFtype, TFtype);
#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 UDItype_ppc __fixunskfdi_hw (TFtype);
extern TFtype __floatsikf_hw (SItype_ppc);
extern TFtype __floatdikf_hw (DItype_ppc);
+extern TFtype __floattikf_hw (TItype_ppc);
extern TFtype __floatunsikf_hw (USItype_ppc);
extern TFtype __floatundikf_hw (UDItype_ppc);
+extern TFtype __floatuntikf_hw (UTItype_ppc);
+extern TItype_ppc __fixkfti_hw (TFtype);
+extern UTItype_ppc __fixunskfti_hw (TFtype);
extern IBM128_TYPE __extendkftf2_hw (TFtype);
extern TFtype __trunctfkf2_hw (IBM128_TYPE);
extern TCtype __mulkc3_hw (TFtype, TFtype, TFtype, TFtype);
extern UDItype_ppc __fixunskfdi (TFtype);
extern TFtype __floatsikf (SItype_ppc);
extern TFtype __floatdikf (DItype_ppc);
+extern TFtype __floattikf (TItype_ppc);
extern TFtype __floatunsikf (USItype_ppc);
extern TFtype __floatundikf (UDItype_ppc);
+extern TFtype __floatuntikf (UTItype_ppc);
+extern TItype_ppc __fixkfti (TFtype);
+extern UTItype_ppc __fixunskfti (TFtype);
extern IBM128_TYPE __extendkftf2 (TFtype);
extern TFtype __trunctfkf2 (IBM128_TYPE);
_sd_to_tf _dd_to_tf _td_to_tf
# New functions for software emulation
-fp128_ppc_funcs = floattikf floatuntikf fixkfti fixunskfti \
+fp128_ppc_funcs = floattikf-sw floatuntikf-sw \
+ fixkfti-sw fixunskfti-sw \
extendkftf2-sw trunctfkf2-sw \
sfp-exceptions _mulkc3 _divkc3 _powikf2
# All functions
fp128_funcs = $(fp128_softfp_funcs) $(fp128_ppc_funcs) \
- $(fp128_hw_funcs) $(fp128_ifunc_funcs)
+ $(fp128_hw_funcs) $(fp128_ifunc_funcs) \
+ $(fp128_3_1_hw_funcs)
fp128_src = $(fp128_softfp_src) $(fp128_ppc_src) \
- $(fp128_hw_src) $(fp128_ifunc_src)
+ $(fp128_hw_src) $(fp128_ifunc_src) \
+ $(fp128_3_1_hw_src)
fp128_obj = $(fp128_softfp_obj) $(fp128_ppc_obj) \
- $(fp128_hw_obj) $(fp128_ifunc_obj)
+ $(fp128_hw_obj) $(fp128_ifunc_obj) \
+ $(fp128_3_1_hw_obj)
fp128_sed = $(srcdir)/config/rs6000/float128-sed$(fp128_sed_hw)
fp128_dep = $(fp128_sed) $(srcdir)/config/rs6000/t-float128
fp128_hw_shared_obj = $(addsuffix _s$(objext),$(fp128_hw_funcs))
fp128_hw_obj = $(fp128_hw_static_obj) $(fp128_hw_shared_obj)
+# New functions for ISA 3.1 hardware support
+fp128_3_1_hw_funcs = float128-p10
+fp128_3_1_hw_src = $(srcdir)/config/rs6000/float128-p10.c
+fp128_3_1_hw_static_obj = $(addsuffix $(objext),$(fp128_3_1_hw_funcs))
+fp128_3_1_hw_shared_obj = $(addsuffix _s$(objext),$(fp128_3_1_hw_funcs))
+fp128_3_1_hw_obj = $(fp128_3_1_hw_static_obj) $(fp128_3_1_hw_shared_obj)
+
fp128_ifunc_funcs = float128-ifunc
fp128_ifunc_src = $(srcdir)/config/rs6000/float128-ifunc.c
fp128_ifunc_static_obj = float128-ifunc$(objext)
-I$(srcdir)/config/rs6000 \
$(FLOAT128_HW_INSNS)
+FP128_3_1_CFLAGS_HW = -Wno-type-limits -mvsx -mcpu=power10 \
+ -mfloat128-hardware -mno-gnu-attribute \
+ -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
+$(fp128_3_1_hw_obj) : INTERNAL_CFLAGS += $(FP128_3_1_CFLAGS_HW)
+$(fp128_3_1_hw_obj) : $(srcdir)/config/rs6000/t-float128-p10-hw
+
$(fp128_ifunc_obj) : INTERNAL_CFLAGS += $(FP128_CFLAGS_SW)
$(fp128_ifunc_obj) : $(srcdir)/config/rs6000/t-float128-hw
--- /dev/null
+# Support for adding __float128 hardware support to the powerpc.
+# Tell the float128 functions that the ISA 3.1 hardware support can
+# be compiled it to be selected via IFUNC functions.
+
+FLOAT128_HW_INSNS = -DFLOAT128_HW_INSNS
+
+# New functions for hardware support
+
+fp128_3_1_hw_funcs = float128-p10
+fp128_3_1_hw_src = $(srcdir)/config/rs6000/float128-p10.c
+fp128_3_1_hw_static_obj = $(addsuffix $(objext),$(fp128_3_1_hw_funcs))
+fp128_3_1_hw_shared_obj = $(addsuffix _s$(objext),$(fp128_3_1_hw_funcs))
+fp128_3_1_hw_obj = $(fp128_3_1_hw_static_obj) $(fp128_3_1_hw_shared_obj)
+
+# Build the hardware support functions with appropriate hardware support
+FP128_3_1_CFLAGS_HW = -Wno-type-limits -mvsx -mfloat128 \
+ -mpower10 \
+ -mfloat128-hardware -mno-gnu-attribute \
+ -I$(srcdir)/soft-fp \
+ -I$(srcdir)/config/rs6000 \
+ $(FLOAT128_HW_INSNS)
+
+$(fp128_3_1_hw_obj) : INTERNAL_CFLAGS += $(FP128_3_1_CFLAGS_HW)
+$(fp128_3_1_hw_obj) : $(srcdir)/config/rs6000/t-float128-p10-hw
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libgcc_cv_powerpc_float128_hw" >&5
$as_echo "$libgcc_cv_powerpc_float128_hw" >&6; }
CFLAGS="$saved_CFLAGS"
+
+ saved_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS -mpower10 -mfloat128-hardware"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for PowerPC ISA 3.1 to build hardware __float128 libraries" >&5
+$as_echo_n "checking for PowerPC ISA 3.1 to build hardware __float128 libraries... " >&6; }
+if ${libgcc_cv_powerpc_float128_hw+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <sys/auxv.h>
+ #ifndef AT_PLATFORM
+ #error "AT_PLATFORM is not defined"
+ #endif
+ #ifndef __BUILTIN_CPU_SUPPORTS__
+ #error "__builtin_cpu_supports is not available"
+ #endif
+ vector unsigned char add (vector unsigned char a, vector unsigned char b)
+ {
+ vector unsigned char ret;
+ __asm__ ("xscvsqqp %0,%1,%2" : "=v" (ret) : "v" (a), "v" (b));
+ return ret;
+ }
+ void *add_resolver (void) { return (void *) add; }
+ __float128 add_ifunc (__float128, __float128)
+ __attribute__ ((__ifunc__ ("add_resolver")));
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ libgcc_cv_powerpc_3_1_float128_hw=yes
+else
+ libgcc_cv_powerpc_3_1_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; }
+ CFLAGS="$saved_CFLAGS"
esac
# Collect host-machine-specific information.
[libgcc_cv_powerpc_float128_hw=yes],
[libgcc_cv_powerpc_float128_hw=no])])
CFLAGS="$saved_CFLAGS"
+
+ saved_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS -mpower10 -mfloat128-hardware"
+ AC_CACHE_CHECK([for PowerPC ISA 3.1 to build hardware __float128 libraries],
+ [libgcc_cv_powerpc_float128_hw],
+ [AC_COMPILE_IFELSE(
+ [AC_LANG_SOURCE([#include <sys/auxv.h>
+ #ifndef AT_PLATFORM
+ #error "AT_PLATFORM is not defined"
+ #endif
+ #ifndef __BUILTIN_CPU_SUPPORTS__
+ #error "__builtin_cpu_supports is not available"
+ #endif
+ vector unsigned char add (vector unsigned char a, vector unsigned char b)
+ {
+ vector unsigned char ret;
+ __asm__ ("xscvsqqp %0,%1,%2" : "=v" (ret) : "v" (a), "v" (b));
+ return ret;
+ }
+ void *add_resolver (void) { return (void *) add; }
+ __float128 add_ifunc (__float128, __float128)
+ __attribute__ ((__ifunc__ ("add_resolver")));])],
+ [libgcc_cv_powerpc_3_1_float128_hw=yes],
+ [libgcc_cv_powerpc_3_1_float128_hw=no])])
+ CFLAGS="$saved_CFLAGS"
esac
# Collect host-machine-specific information.