Conversions between 128-bit integer and floating point values.

The files fixkfti-sw.c and fixunskfti-sw.c are renamed versions of
fixkfti.c and fixunskfti.c respectively to do the conversions in software.
The function names in the files were updated with the rename as well as
some white spaces fixes. The file float128-p10.c contains the functions
for using the ISA 3.1 hardware instructions to perform the conversions.

2021-06-08  Carl Love  <cel@us.ibm.com>

gcc/ChangeLog

	* config/rs6000/rs6000.c (__fixkfti, __fixunskfti, __floattikf,
	__floatuntikf): Names changed to __fixkfti_sw, __fixunskfti_sw,
	__floattikf_sw, __floatuntikf_sw respectively.
	* config/rs6000/rs6000.md (floatti<mode>2, floatunsti<mode>2,
	fix_trunc<mode>ti2, fixuns_trunc<mode>ti2): Add
	define_insn for mode IEEE 128.

gcc/testsuite/ChangeLog

	* gcc.target/powerpc/fp128_conversions.c: New file.
	* gcc.target/powerpc/int_128bit-runnable.c(vextsd2q,
	vcmpuq, vcmpsq, vcmpequq, vcmpequq., vcmpgtsq, vcmpgtsq.
	vcmpgtuq, vcmpgtuq.): Update scan-assembler-times.
	(ppc_native_128bit): Remove dg-require-effective-target.

libgcc/ChangeLog

	* config.host: Add if test and set for
	libgcc_cv_powerpc_3_1_float128_hw.
	* config/rs6000/fixkfti.c: Renamed to fixkfti-sw.c.
	Change calls of __fixkfti to __fixkfti_sw.
	* config/rs6000/fixunskfti.c: Renamed to fixunskfti-sw.c.
	Change calls of __fixunskfti to __fixunskfti_sw.
	* config/rs6000/float128-p10.c (__floattikf_hw,
	__floatuntikf_hw, __fixkfti_hw, __fixunskfti_hw): New file.
	* config/rs6000/float128-ifunc.c (SW_OR_HW_ISA3_1): New macro.
	(__floattikf_resolve, __floatuntikf_resolve, __fixkfti_resolve,
	__fixunskfti_resolve): Add resolve functions.
	(__floattikf, __floatuntikf, __fixkfti, __fixunskfti): New functions.
	* config/rs6000/float128-sed (floattitf, __floatuntitf,
	__fixtfti, __fixunstfti): Add editor commands to change names.
	* config/rs6000/float128-sed-hw (__floattitf,
	__floatuntitf, __fixtfti, __fixunstfti): Add editor commands to
	change names.
	* config/rs6000/floattikf.c: Renamed to floattikf-sw.c.
	* config/rs6000/floatuntikf.c: Renamed to floatuntikf-sw.c.
	* config/rs6000/quad-float128.h (__floattikf_sw,
	__floatuntikf_sw, __fixkfti_sw, __fixunskfti_sw, __floattikf_hw,
	__floatuntikf_hw, __fixkfti_hw, __fixunskfti_hw, __floattikf,
	__floatuntikf, __fixkfti, __fixunskfti): New extern declarations.
	* config/rs6000/t-float128 (floattikf, floatuntikf,
	fixkfti, fixunskfti): Remove file names from fp128_ppc_funcs.
	(floattikf-sw, floatuntikf-sw, fixkfti-sw, fixunskfti-sw): Add
	file names to fp128_ppc_funcs.
	* config/rs6000/t-float128-hw(fp128_3_1_hw_funcs,
	fp128_3_1_hw_src, fp128_3_1_hw_static_obj, fp128_3_1_hw_shared_obj,
	fp128_3_1_hw_obj): Add variables for ISA 3.1 support.
	* config/rs6000/t-float128-p10-hw: New file.
	* configure: Update script for isa 3.1 128-bit float support.
	* configure.ac: Add check for 128-bit float hardware support.
This commit is contained in:
Carl Love 2021-04-21 18:07:39 -04:00
parent f170186446
commit 9090f48071
19 changed files with 589 additions and 36 deletions

View File

@ -11014,10 +11014,10 @@ init_float128_ieee (machine_mode mode)
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");
}
}

View File

@ -6441,6 +6441,42 @@
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

View File

@ -0,0 +1,294 @@
/* { 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;
}

View File

@ -4,21 +4,16 @@
/* 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 } } */

View File

@ -1224,6 +1224,10 @@ powerpc*-*-linux*)
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
;;

View File

@ -5,7 +5,7 @@
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
@ -35,7 +35,7 @@
#include "quad-float128.h"
TItype
__fixkfti (TFtype a)
__fixkfti_sw (TFtype a)
{
FP_DECL_EX;
FP_DECL_Q (A);

View File

@ -5,7 +5,7 @@
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
@ -35,7 +35,7 @@
#include "quad-float128.h"
UTItype
__fixunskfti (TFtype a)
__fixunskfti_sw (TFtype a)
{
FP_DECL_EX;
FP_DECL_Q (A);

View File

@ -46,14 +46,9 @@
#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)
{
@ -102,6 +97,18 @@ __floatdikf_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)
{
@ -114,6 +121,19 @@ __floatundikf_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)
{
@ -303,6 +323,18 @@ TFtype __floatsikf (SItype_ppc)
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")));

View File

@ -0,0 +1,71 @@
/* 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;
}

View File

@ -8,6 +8,10 @@ s/__fixtfsi/__fixkfsi/g
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

View File

@ -8,6 +8,10 @@ s/__fixtfsi/__fixkfsi_sw/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

View File

@ -5,7 +5,7 @@
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
@ -35,7 +35,7 @@
#include "quad-float128.h"
TFtype
__floattikf (TItype i)
__floattikf_sw (TItype i)
{
FP_DECL_EX;
FP_DECL_Q (A);

View File

@ -5,7 +5,7 @@
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
@ -35,7 +35,7 @@
#include "quad-float128.h"
TFtype
__floatuntikf (UTItype i)
__floatuntikf_sw (UTItype i)
{
FP_DECL_EX;
FP_DECL_Q (A);

View File

@ -88,19 +88,18 @@ 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 __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);
@ -131,8 +130,12 @@ 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 __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);
@ -163,8 +166,12 @@ extern USItype_ppc __fixunskfsi (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);

View File

@ -31,7 +31,8 @@ ibm128_dec_funcs = _tf_to_sd _tf_to_dd _tf_to_td \
_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
@ -47,13 +48,16 @@ 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_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

View File

@ -13,6 +13,13 @@ fp128_hw_static_obj = $(addsuffix $(objext),$(fp128_hw_funcs))
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)
@ -30,9 +37,18 @@ FP128_CFLAGS_HW = -Wno-type-limits -mvsx -mfloat128 \
-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

View File

@ -0,0 +1,24 @@
# 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

37
libgcc/configure vendored
View File

@ -5263,6 +5263,43 @@ 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"
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.

View File

@ -458,6 +458,31 @@ powerpc*-*-linux*)
[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.