https://gcc.gnu.org/g:f394c45d502ec6e2f910156eb01cab574792b1ff
commit f394c45d502ec6e2f910156eb01cab574792b1ff Author: Michael Meissner <[email protected]> Date: Thu Oct 1 17:41:00 2026 -0400 Generate 16-bit floating extend functions Add support for automatically converting the soft-ftp extend functions for 16-bit. Also rework the pevious conversion support. 2026-10-01 Michael Meissner <[email protected]> libgcc/ * config/rs6000/convert-16bit-fp-extend: New perl script. * config/rs6000/convert-16bit-fp-fix: Rewrite to use -t conversion instead of -b/-h. * config/rs6000/convert-16bit-fp-float: Likewise. * config/rs6000/t-float16: Update. * config/rs6000/extendbf-sfdf2.c: Delete. * config/rs6000/extendhf-sfdf2.c: Likewise. Diff: --- libgcc/config/rs6000/convert-16bit-fp-extend | 220 ++++++++++++++++++++++++++ libgcc/config/rs6000/convert-16bit-fp-fix | 102 ++++++++---- libgcc/config/rs6000/convert-16bit-fp-float | 107 +++++++++---- libgcc/config/rs6000/extendbf-sfdf2.c | 90 ----------- libgcc/config/rs6000/extendhf-sfdf2.c | 90 ----------- libgcc/config/rs6000/t-float16 | 226 ++++++++++++--------------- 6 files changed, 477 insertions(+), 358 deletions(-) diff --git a/libgcc/config/rs6000/convert-16bit-fp-extend b/libgcc/config/rs6000/convert-16bit-fp-extend new file mode 100755 index 000000000000..157fe3f48a68 --- /dev/null +++ b/libgcc/config/rs6000/convert-16bit-fp-extend @@ -0,0 +1,220 @@ +#! /usr/bin/perl -w +# Convert a libgcc/soft-fp fix<fp><int> fuunction for the PowerPC + +# Copyright (C) 2020-2026 Free Software Foundation, Inc. +# +# This file is part of GCC. +# +# GCC 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. +# +# GCC 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. +# +# You should have received a copy of the GNU General Public License +# along with GCC; see the file COPYING3. If not see +# <http://www.gnu.org/licenses/>. +# +# The PowerPC 16-bit floating point support is considering requiring +# 16-bit floating point arguments to the 32/64-bit scalar format in +# registers and similarly returning the 16-bit floating point return to +# a 32/64-bit scalar value. However, this presents a problem in that +# if a machine doesn't have instructions to do a conversion in +# hardware, you can't call the soft-fp conversion function using the +# native calling sequence. +# +# This perl script converts a extend<fp1><fp2>.c to do the conversion +# to BFtype (Google brain 16-bit float) or HFtype (IEEE 754 _Float16). +# It produces 2 functions, one that has the normal name and takes the +# normal arguments, and the other that adds a _gpr suffix and changes +# the 16-bit floating point to unsigned short. +# +# A typical extend* conversion file looks like: +# +# <copyright message> +# +# #define FP_NO_EXACT_UNDERFLOW +# #include "soft-fp.h" +# #include "single.h" +# #include "double.h" +# +# DFtype +# __extendsfdf2 (SFtype a) +# { +# FP_DECL_EX; +# FP_DECL_S (A); +# FP_DECL_D (R); +# DFtype r; +# +# FP_INIT_EXCEPTIONS; +# FP_UNPACK_RAW_S (A, a); +# #if _FP_W_TYPE_SIZE < _FP_FRACBITS_D +# FP_EXTEND (D, S, 2, 1, R, A); +# #else +# FP_EXTEND (D, S, 1, 1, R, A); +# #endif +# FP_PACK_RAW_D (r, R); +# FP_HANDLE_EXCEPTIONS; +# +# return r; +# } + +use warnings; +use strict; +use Getopt::Std; + +use vars qw($opt_t); + +$opt_t = undef; + +&getopts ("t:") || die "Useage $0 [-t type] <input >output\n"; + +die "$0: No -t option.\n" if (! defined ($opt_t)); + +my ($input_lc, $output_lc); + +if ($opt_t =~ /extend([bh])f([sd])f2/) { + ($input_lc, $output_lc) = ($1, $2); + +} else { + die "$0: Invalid -t ${opt_t}\n"; +} + +my $input_uc = uc ($input_lc); +my $input_uc_F = "${input_uc}F"; +my $input_lc_f = "${input_lc}f"; +my $input_type = "${input_uc}Ftype"; + +my $output_uc = uc ($output_lc); +my $output_uc_F = "${output_uc}F"; +my $output_lc_f = "${output_lc}f"; +my $output_type = "${output_uc}Ftype"; + +my %include_file = ("bf" => "#include \"brain.h\"", + "hf" => "#include \"half.h\"", + "sf" => "#include \"single.h\"", + "df" => "#include \"double.h\""); + +# Scan the input and put out the copyright message + +my $line; +my $input = $ARGV[0]; + +while ($line = <>) { + chomp $line; + + last if ($line =~ /^[#](include|define)/); + print $line, "\n"; +} + +if ($input) { + print "/* Automatically converted from $input. */\n"; + print "\n"; +} + +# Change the include file from the floating point type to either half.h +# or brain.h. + +die "$0: No include files\n" if (! defined ($line)); + +my $include_found = 0; + +do { + if ($line =~ /^#include ["](brain|half|single|double|quad)[.]h["]$/) { + if (!$include_found) { + print $include_file{$input_lc_f}, "\n"; + print $include_file{$output_lc_f}, "\n"; + $include_found = 1; + } + + } else { + print $line, "\n"; + } + + $line = <>; + +} while (defined ($line) && $line =~ /^(\s*$|[#](include|define))/); + +# Scoop up the rest of the file, convert the input and function to +# operate on HFtype or BFtype. + +die "$0: No main source\n" if (! defined ($line)); + +my @func = (); +my $FP = "BDHSTQ"; + +do { + chomp $line; + + # Return type + if ($line =~ /^[${FP}]Ftype$/) { + $line = $output_type; + + # Function line + } elsif ($line =~ /^__extend/) { + $line = "__extend${input_lc_f}${output_lc_f}2 (${input_type} a)"; + + # Declaration line of the input type + } elsif ($line =~ /^(\s*FP_DECL_)[${FP}] [(]A[)];/) { + $line = "${1}${input_uc} (A);"; + + # Declaration line of the output type + } elsif ($line =~ /^(\s*FP_DECL_)[${FP}] [(]R[)];/) { + $line = "${1}${output_uc} (R);"; + + # Declaration of the actual result + } elsif ($line =~ /^(\s*)[${FP}]Ftype r;/) { + $line = "${1}${output_type} r;"; + + } else { + # Unpack input type + $line =~ s/FP_UNPACK_RAW_[${FP}]/FP_UNPACK_RAW_${input_uc}/; + + # Pack output type + $line =~ s/FP_PACK_RAW_[${FP}]/FP_PACK_RAW_${output_uc}/; + + # Extend line + $line =~ s/FP_EXTEND [(][${FP}], [${FP}],/FP_EXTEND (${output_uc}, ${input_uc},/; + } + + push (@func, $line); + $line = <>; + +} while (defined ($line)); + +# Print out the normal conversion function + +print "/* ${input_type} passed in FPR registers. */\n"; + +foreach $line (@func) { + print $line, "\n"; +} + +# Print out the conversion function that uses GPRs + +print "\n"; +print "/* ${input_type} passed in GPR registers. */\n"; + +foreach $line (@func) { + if ($line =~ /^__extend/) { + $line = "__extend${input_lc_f}${output_lc_f}2_gpr (unsigned short us)"; + } + + print $line, "\n"; + + + if ($line =~ /^(\s*)[${FP}]Ftype r;/) { + print "${1}union ushort_${input_lc_f} u;\n"; + print "${1}${input_type} a;\n"; + print "\n"; + print "${1}u.us = us;\n"; + print "${1}a = u.${input_lc_f};\n"; + } +} + +# Done +exit 0; diff --git a/libgcc/config/rs6000/convert-16bit-fp-fix b/libgcc/config/rs6000/convert-16bit-fp-fix index 5417c3694b1f..5878b0d3c50b 100755 --- a/libgcc/config/rs6000/convert-16bit-fp-fix +++ b/libgcc/config/rs6000/convert-16bit-fp-fix @@ -59,15 +59,48 @@ use warnings; use strict; use Getopt::Std; -use vars qw($opt_b $opt_h); +use vars qw($opt_t); -$opt_b = 0; -$opt_h = 0; +$opt_t = undef; -&getopts ("bh") || die "Useage $0 [-b] [-h] <input >output\n"; +&getopts ("t:") || die "Useage $0 [-t type] <input >output\n"; -die "$0: Either -b or -h must be passed\n" if (!$opt_b && !$opt_h); -die "$0: Both -b and -h must not be passed\n" if ($opt_b && $opt_h); +die "$0: No -t option.\n" if (! defined ($opt_t)); + +my ($input_lc, + $output_lc, + $uns_lc, + $uns_uc_U, + $uns_sign); + +if ($opt_t =~ /fix(|uns)([bh])f([sdt])i/) { + if (defined ($1) && $1 ne "") { + ($uns_lc, $uns_uc_U, $uns_sign) = ("uns", "U", 0); + + } else { + ($uns_lc, $uns_uc_U, $uns_sign) = ("", "", 1); + } + + ($input_lc, $output_lc) = ($2, $3); + +} else { + die "$0: Invalid -t ${opt_t}\n"; +} + +my $input_uc = uc ($input_lc); +my $input_uc_F = "${input_uc}F"; +my $input_lc_f = "${input_lc}f"; +my $input_type = "${input_uc}Ftype"; + +my $output_uc = uc ($output_lc); +my $output_uc_I = "${output_uc}I"; +my $output_lc_i = "${output_lc}i"; +my $output_type = "${uns_uc_U}${output_uc}Itype"; + +my %include_file = ("bf" => "#include \"brain.h\"", + "hf" => "#include \"half.h\"", + "sf" => "#include \"single.h\"", + "df" => "#include \"double.h\""); # Scan the input and put out the copyright message @@ -77,7 +110,7 @@ my $input = $ARGV[0]; while ($line = <>) { chomp $line; - last if ($line =~ /^[#]include/); + last if ($line =~ /^[#](include|define)/); print $line, "\n"; } @@ -91,14 +124,17 @@ if ($input) { die "$0: No include files\n" if (! defined ($line)); -my $inc = ($opt_h ? "half" : "brain"); - do { - $line =~ s/(single|double|extended|half|quad)/$inc/; - print $line, "\n"; + if ($line =~ /^[#]include [\"](single|double|extended|half|quad|brain)[.]h[\"]$/) { + print $include_file{$input_lc_f}, "\n"; + + } else { + print $line, "\n"; + } + $line = <>; -} while (defined ($line) && $line =~ /^[#]include/); +} while (defined ($line) && $line =~ /^[#](include|define)/); # Scoop up the rest of the file, convert the input and function to # operate on HFtype or BFtype. @@ -106,19 +142,30 @@ do { die "$0: No main source\n" if (! defined ($line)); my @func = (); -my $u_letter = ($opt_h ? "H" : "B"); -my $l_letter = ($opt_h ? "h" : "b"); +my $FP = "BDHST"; +my $INT = "QHSDT"; do { chomp $line; # Function line if ($line =~ /^__fix/) { - $line =~ s/[BDHST]F/${u_letter}F/; - $line =~ s/[bdhst]f/${l_letter}f/; + $line = "__fix${uns_lc}${input_lc_f}${output_lc_i} (${input_type} a)"; + + # Return type for function + } elsif ($line =~ /^(U)?[${INT}]Itype$/) { + $line = $output_type; + + # Return value + } elsif ($line =~ /^(\s*)(U)?[${INT}]Itype r;/) { + $line = "${1}${output_type} r;"; + + # Conversion to int + } elsif ($line =~ /^(\s*)FP_TO_INT_[${FP}] [(]r, A, [${INT}]I_BITS, [01][)];/) { + $line = "${1}FP_TO_INT_${input_uc} (r, A, ${output_uc_I}_BITS, ${uns_sign});"; } else { - $line =~ s/_(DECL|RAW|INT)_[BHDST]/_${1}_${u_letter}/; + $line =~ s/_(DECL|RAW|INT)_[${FP}]/_${1}_${input_uc}/; } push (@func, $line); @@ -128,7 +175,8 @@ do { # Print out the normal conversion function -print "/* ${u_letter}Ftype passed in FPR registers. */\n"; +print "\n"; +print "/* ${input_type} passed in FPR registers. */\n"; foreach $line (@func) { print $line, "\n"; @@ -137,25 +185,25 @@ foreach $line (@func) { # Print out the special GPR function. print "\n"; -print "/* ${u_letter}Ftype passed in GPR registers. */\n"; +print "/* ${input_type} passed in GPR registers. */\n"; foreach $line (@func) { # Function header if ($line =~ /^__(fix|fixuns)([bh]f)([sdt]i)/) { $line = "__${1}${2}${3}_gpr (unsigned short us)"; + } + + print $line, "\n"; # Add conversion from unsigned short - } elsif ($line =~ /FP_INIT_EXCEPTIONS/) { - print " ${u_letter}Ftype a;\n"; - print " union ushort_${l_letter}f u;\n"; - print "\n"; - print " u.us = us;\n"; - print " a = u.${l_letter}f;\n"; + if ($line =~ /^(\s*)U?[${INT}]Itype r;/) { + print "${1}${input_type} a;\n"; + print "${1}union ushort_${input_lc_f} u;\n"; print "\n"; + print "${1}u.us = us;\n"; + print "${1}a = u.${input_lc_f};\n"; } - - print $line, "\n"; } # Done diff --git a/libgcc/config/rs6000/convert-16bit-fp-float b/libgcc/config/rs6000/convert-16bit-fp-float index 0c4381cec55c..232c498bb22a 100755 --- a/libgcc/config/rs6000/convert-16bit-fp-float +++ b/libgcc/config/rs6000/convert-16bit-fp-float @@ -57,15 +57,47 @@ use warnings; use strict; use Getopt::Std; -use vars qw($opt_b $opt_h); +use vars qw($opt_t); -$opt_b = 0; -$opt_h = 0; +$opt_t = undef; -&getopts ("bh") || die "Useage $0 [-b] [-h] <input >output\n"; +&getopts ("t:") || die "Useage $0 [-t type] <input >output\n"; -die "$0: Either -b or -h must be passed\n" if (!$opt_b && !$opt_h); -die "$0: Both -b and -h must not be passed\n" if ($opt_b && $opt_h); +die "$0: No -t option.\n" if (! defined ($opt_t)); + +my ($input_lc, + $output_lc, + $uns_lc, + $uns_uc_U); + +if ($opt_t =~ /float(|un)([sdt])i([bh])f/) { + if (defined ($1) && $1 ne "") { + ($uns_lc, $uns_uc_U) = ("un", "U"); + + } else { + ($uns_lc, $uns_uc_U) = ("", ""); + } + + ($input_lc, $output_lc) = ($2, $3); + +} else { + die "$0: Invalid -t ${opt_t}\n"; +} + +my $input_uc = uc ($input_lc); +my $input_uc_I = "${input_uc}I"; +my $input_lc_i = "${input_lc}i"; +my $input_type = "${uns_uc_U}${input_uc}Itype"; + +my $output_uc = uc ($output_lc); +my $output_uc_F = "${output_uc}F"; +my $output_lc_f = "${output_lc}f"; +my $output_type = "${output_uc}Ftype"; + +my %include_file = ("bf" => "#include \"brain.h\"", + "hf" => "#include \"half.h\"", + "sf" => "#include \"single.h\"", + "df" => "#include \"double.h\""); # Scan the input and put out the copyright message @@ -75,7 +107,7 @@ my $input = $ARGV[0]; while ($line = <>) { chomp $line; - last if ($line =~ /^[#]include/); + last if ($line =~ /^[#](include|define)/); print $line, "\n"; } @@ -89,14 +121,17 @@ if ($input) { die "$0: No include files\n" if (! defined ($line)); -my $inc = ($opt_h ? "half" : "brain"); - do { - $line =~ s/(single|double|extended|half|quad)/$inc/; - print $line, "\n"; + if ($line =~ /^[#]include [\"](single|double|extended|half|quad|brain)[.]h[\"]$/) { + print $include_file{$output_lc_f}, "\n"; + + } else { + print $line, "\n"; + } + $line = <>; -} while (defined ($line) && $line =~ /^[#]include/); +} while (defined ($line) && $line =~ /^[#](include|define)/); # Scoop up the rest of the file, convert the function to # return a HFtype or BFtype type. @@ -104,22 +139,34 @@ do { die "$0: No main source\n" if (! defined ($line)); my @func = (); -my $u_letter = ($opt_h ? "H" : "B"); -my $l_letter = ($opt_h ? "h" : "b"); +my $FP = "BDHST"; +my $fp = lc ($FP); +my $INT = "QHSDT"; +my $int = lc ($INT); do { chomp $line; # Function return - if ($line =~ /^[BDHST]Ftype$/) { - $line = "${u_letter}Ftype"; + if ($line =~ /^[${FP}]Ftype$/) { + $line = $output_type; # Function line } elsif ($line =~ /^__float/) { - $line =~ s/[bdhst]f/${l_letter}f/; + $line = "__float${uns_lc}${input_lc_i}${output_lc_f} (${input_type} i)"; + + # Return variable declaration + } elsif ($line =~ /^(\s*)[${FP}]Ftype a;/) { + $line = "${1}${output_type} a;"; + + # Int input + } elsif ($line =~ /FROM_INT_[${INT}]/) { + $line =~ s/FROM_INT_[${INT}]/FROM_INT_${output_uc}/; + $line =~ s/[${INT}]I_BITS/${input_uc_I}_BITS/; + $line =~ s/(U)?[${INT}]Itype/${input_type}/; } - $line =~ s/_(DECL|RAW|INT)_[BHDST]/_${1}_${u_letter}/; + $line =~ s/_(DECL|RAW)_[${FP}]/_${1}_${output_uc}/; push (@func, $line); $line = <>; @@ -128,7 +175,8 @@ do { # Print out the normal conversion function -print "/* ${u_letter}Ftype returned in FPR registers. */\n"; +print "\n"; +print "/* ${output_type} returned in FPR registers. */\n"; foreach $line (@func) { print $line, "\n"; @@ -137,30 +185,31 @@ foreach $line (@func) { # Print out the special GPR function. print "\n"; -print "/* ${u_letter}Ftype returned in GPR registers. */\n"; +print "/* ${output_type} returned in GPR registers. */\n"; foreach $line (@func) { # Function return - if ($line eq "${u_letter}Ftype") { + if ($line eq $output_type) { $line = "unsigned short"; # Function header } elsif ($line =~ /^__(float|floatun)([sdt]i)([bh]f) (.*)$/) { $line = "__${1}${2}${3}_gpr ${4}"; - # Add declartion of union - } elsif ($line =~ /FP_INIT_ROUNDMODE/) { - print " union ushort_or_${l_letter}f u;\n"; - print "\n"; - # Return value - } elsif ($line =~ /return a;/) { - print " u.${l_letter}f = a;\n"; - $line = " return u.us;"; + } elsif ($line =~ /^(\s*)return a;/) { + print "${1}u.${output_lc_f} = a;\n"; + $line = "${1}return u.us;"; } print $line, "\n"; + + # Add declartion of union + if ($line =~ /^(\s*)[${FP}]Ftype a;/) { + print " union ushort_${output_lc_f} u;\n"; + } + } # Done diff --git a/libgcc/config/rs6000/extendbf-sfdf2.c b/libgcc/config/rs6000/extendbf-sfdf2.c deleted file mode 100644 index b46805e998cf..000000000000 --- a/libgcc/config/rs6000/extendbf-sfdf2.c +++ /dev/null @@ -1,90 +0,0 @@ -/* Software floating-point emulation. - Return an bfloat16 converted to IEEE single - Copyright (C) 2022 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - 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/>. - - This is a clone of soft-fp/extendbfsf2.c for the PowerPC. - - We provide an alternative version of the conversion that takes the value in - a GPR passed as an unsigned short. This is to allow the calling sequence - where arguments are converted to the 32/64-bit scalar format. If we don't - have the hardware support, we can't use the standard __extend function. */ - -#define FP_NO_EXACT_UNDERFLOW -#include "soft-fp.h" -#include "brain.h" -#include "single.h" -#include "double.h" - -/* BFtype passed in FPR register. */ -SFtype -__extendbfsf2 (BFtype a) -{ - FP_DECL_EX; - FP_DECL_B (A); - FP_DECL_S (R); - SFtype r; - - FP_INIT_EXCEPTIONS; - FP_UNPACK_RAW_B (A, a); - FP_EXTEND (S, B, 1, 1, R, A); - FP_PACK_RAW_S (r, R); - FP_HANDLE_EXCEPTIONS; - - return r; -} - -/* BFtype passed in GPR register. */ -SFtype -__extendbfsf2_gpr (unsigned short us) -{ - union ushort_bf u; - BFtype a; - - u.us = us; - a = u.bf; - - FP_DECL_EX; - FP_DECL_B (A); - FP_DECL_S (R); - SFtype r; - - FP_INIT_EXCEPTIONS; - FP_UNPACK_RAW_B (A, a); - FP_EXTEND (S, B, 1, 1, R, A); - FP_PACK_RAW_S (r, R); - FP_HANDLE_EXCEPTIONS; - - return r; -} - -/* On the PowerPC DFtype scalars use the same encoding as SFtype, so we can use - the same function for both. */ -__asm__ ("\t.globl __extendbfdf2\n" - "__extendbfdf2 = __extendbfsf2\n" - "\n" - "\t.globl __extendbfdf2_gpr\n" - "__extendbfdf2_gpr = __extendbfsf2_gpr"); diff --git a/libgcc/config/rs6000/extendhf-sfdf2.c b/libgcc/config/rs6000/extendhf-sfdf2.c deleted file mode 100644 index 58fe008dbcae..000000000000 --- a/libgcc/config/rs6000/extendhf-sfdf2.c +++ /dev/null @@ -1,90 +0,0 @@ -/* Software floating-point emulation. - Return an IEEE half converted to IEEE single - Copyright (C) 2021-2022 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - 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/>. - - This is a clone of soft-fp/extendhfsf2.c for the PowerPC. - - We provide an alternative version of the conversion that takes the value in - a GPR passed as an unsigned short. This is to allow the calling sequence - where arguments are converted to the 32/64-bit scalar format. If we don't - have the hardware support, we can't use the standard __extend function. */ - -#define FP_NO_EXACT_UNDERFLOW -#include "soft-fp.h" -#include "half.h" -#include "single.h" -#include "double.h" - -/* HFtype passed in FPR register. */ -SFtype -__extendhfsf2 (HFtype a) -{ - FP_DECL_EX; - FP_DECL_H (A); - FP_DECL_S (R); - SFtype r; - - FP_INIT_EXCEPTIONS; - FP_UNPACK_RAW_H (A, a); - FP_EXTEND (S, H, 1, 1, R, A); - FP_PACK_RAW_S (r, R); - FP_HANDLE_EXCEPTIONS; - - return r; -} - -/* HFtype passed in GPR register. */ -SFtype -__extendhfsf2_gpr (unsigned short us) -{ - union ushort_hf u; - HFtype a; - - u.us = us; - a = u.hf; - - FP_DECL_EX; - FP_DECL_H (A); - FP_DECL_S (R); - SFtype r; - - FP_INIT_EXCEPTIONS; - FP_UNPACK_RAW_H (A, a); - FP_EXTEND (S, H, 1, 1, R, A); - FP_PACK_RAW_S (r, R); - FP_HANDLE_EXCEPTIONS; - - return r; -} - -/* On the PowerPC DFtype scalars use the same encoding as SFtype, so use the - same function for both. */ -__asm__ ("\t.globl __extendhfdf2\n" - "__extendhfdf2 = __extendhfsf2\n" - "\n" - "\t.globl __extendhfdf2_gpr\n" - "__extendhfdf2_gpr = __extendhfsf2_gpr"); diff --git a/libgcc/config/rs6000/t-float16 b/libgcc/config/rs6000/t-float16 index ac4b52fe08aa..af6254a70249 100644 --- a/libgcc/config/rs6000/t-float16 +++ b/libgcc/config/rs6000/t-float16 @@ -1,7 +1,7 @@ PERL := perl # _Float16 library support, source files in soft-ftp -fp16_funcs = extendhf-sfdf2 truncsfdf-hf2 \ +fp16_funcs = truncsfdf-hf2 \ ppc-eqhf2 ppc-floatbitinthf ppc-fixhfbitint fp16_src = $(addprefix $(srcdir)/config/rs6000/,$(addsuffix .c,$(fp16_funcs))) @@ -14,7 +14,7 @@ FP16_CFLAGS = -mfloat16 -Wno-psabi \ $(fp16_obj) : INTERNAL_CFLAGS += $(FP16_CFLAGS) # __bf16 library support, source files in config/rs6000 -bfp16_funcs = extendbf-sfdf2 truncsfdf-bf2 \ +bfp16_funcs = truncsfdf-bf2 \ ppc-eqbf2 ppc-floatbitintbf ppc-fixbfbitint bfp16_src = $(addprefix $(srcdir)/config/rs6000/,$(addsuffix .c,$(bfp16_funcs))) @@ -34,131 +34,114 @@ $(both_fp16_obj) : INTERNAL_CFLAGS += $(FP16_CFLAGS) # pass/return 16-bit floating point in gprs. float16_prefix = ppc- -float16_fix_orig = $(srcdir)/soft-fp/fixsfdi.c -float16_fixuns_orig = $(srcdir)/soft-fp/fixsfdi.c -float16_float_orig = $(srcdir)/soft-fp/floatdisf.c -float16_floatun_orig = $(srcdir)/soft-fp/floatundisf.c +float16_dep = $(srcdir)/config/rs6000/t-float16 + +# We don't have a full set of BFmode conversions in soft-fp, so modify the HFmode +# conversions to do what we want +float16_fix_ti_orig = $(srcdir)/soft-fp/fixhfti.c +float16_fix_di_orig = $(srcdir)/soft-fp/fixhfdi.c +float16_fix_si_orig = $(srcdir)/soft-fp/fixhfsi.c +float16_fixuns_ti_orig = $(srcdir)/soft-fp/fixunshfti.c +float16_fixuns_di_orig = $(srcdir)/soft-fp/fixhunsfdi.c +float16_fixuns_si_orig = $(srcdir)/soft-fp/fixunshfsi.c +float16_extend_orig = $(srcdir)/soft-fp/extendhfsf2.c float16_fix_script = $(srcdir)/config/rs6000/convert-16bit-fp-fix float16_float_script = $(srcdir)/config/rs6000/convert-16bit-fp-float - -# Convert fix* functions for _Float16 -fp16x_fix_funcs = fixhfti fixhfdi fixhfsi -fp16x_fix_src = $(addprefix $(float16_prefix),$(addsuffix .c,$(fp16x_fix_funcs))) -fp16x_fix_obj = $(addprefix $(float16_prefix),$(addsuffix $(objext),$(fp16x_fix_funcs))) - -fp16x_fix_dep = $(float16_fix_orig) \ - $(float16_fix_script) \ - $(srcdir)/config/rs6000/t-float16 - -fp16x_fixuns_funcs = fixunshfti fixunshfdi fixunshfsi -fp16x_fixuns_src = $(addprefix $(float16_prefix),$(addsuffix .c,$(fp16x_fixuns_funcs))) -fp16x_fixuns_obj = $(addprefix $(float16_prefix),$(addsuffix $(objext),$(fp16x_fixuns_funcs))) - -fp16x_fixuns_dep = $(float16_fixuns_orig) \ +float16_extend_script = $(srcdir)/config/rs6000/convert-16bit-fp-extend + +float16_fix_ti_func = fixhfti fixbfti +float16_fix_di_func = fixhfti fixbfti +float16_fix_si_func = fixhfti fixbfti +float16_fixuns_ti_func = fixhfti fixbfti +float16_fixuns_di_func = fixhfti fixbfti +float16_fixuns_si_func = fixhfti fixbfti + +float16_fix_ti_src = $(addprefix $(float16_prefix),$(addsuffix .c,$(float16_fix_ti_funcs))) +float16_fix_di_src = $(addprefix $(float16_prefix),$(addsuffix .c,$(float16_fix_di_funcs))) +float16_fix_si_src = $(addprefix $(float16_prefix),$(addsuffix .c,$(float16_fix_si_funcs))) +float16_fixuns_ti_src = $(addprefix $(float16_prefix),$(addsuffix .c,$(float16_fixuns_ti_funcs))) +float16_fixuns_dti_src = $(addprefix $(float16_prefix),$(addsuffix .c,$(float16_fixuns_di_funcs))) +float16_fixuns_si_src = $(addprefix $(float16_prefix),$(addsuffix .c,$(float16_fixuns_si_funcs))) + +float16_fix_funcs = $(float_fix_ti_funcs) \ + $(float_fix_di_funcs) \ + $(float_fix_si_funcs) \ + $(float_fix_unsti_funcs) \ + $(float_fixuns_di_funcs) \ + $(float_fixuns_si_funcs) + +float16_fix_src = $(addprefix $(float16_prefix),$(addsuffix .c,$(float16_fix_funcs))) +float16_fix_dep = $(float16_fix_orig) \ $(float16_fix_script) \ - $(srcdir)/config/rs6000/t-float16 + $(float16_dep) -fp16x_float_funcs = floattihf floatdihf floatsihf -fp16x_float_src = $(addprefloat $(float16_prefloat),$(addsuffloat .c,$(fp16x_float_funcs))) -fp16x_float_obj = $(addprefloat $(float16_prefloat),$(addsuffloat $(objext),$(fp16x_float_funcs))) +float16_float_sign_funcs = floattihf floatdihf floatsihf \ + floattibf floatdibf floatsibf -fp16x_float_depi = $(float16_float_orig) \ - $(float16_float_script) \ - $(srcdir)/config/rs6000/t-float16 +float16_float_uns_funcs = floatuntihf floatundihf floatunsihf \ + floatuntibf floatundibf floatunsibf -fp16x_floatun_funcs = floatuntihf floatundihf floatunsihf -fp16x_floatun_src = $(addprefloat $(float16_prefloat),$(addsuffloat .c,$(fp16x_floatun_funcs))) -fp16x_floatun_obj = $(addprefloat $(float16_prefloat),$(addsuffloat $(objext),$(fp16x_floatun_funcs))) +float16_float_uns_obj = $(addprefix $(float16_prefix),$(addsuffix $(objext),$(float16_float_uns_funcs))) -fp16x_floatun_dep = $(float16_floatun_orig) \ - $(float16_float_script) \ - $(srcdir)/config/rs6000/t-float16 +float16_float_funcs = $(float16_float_sign_funcs) \ + $(float16_float_uns_funcs) -fp16x_all_funcs = $(fp16x_fix_funcs) $(fp16x_fixuns_funcs) \ - $(fp16x_float_funcs) $(fp16x_floatun_funcs) +float16_float_src = $(addprefix $(float16_prefix),$(addsuffix .c,$(float16_float_funcs))) +float16_float_dep = $(float16_float_script) \ -fp16x_all_src = $(fp16x_fix_src) $(fp16x_fixuns_src) \ - $(fp16x_float_src) $(fp16x_floatun_src) +float16_extend_funcs = extendhfsf2 extendhfdf2 extendbfsf2 extendbfdf2 +float16_extend_src = $(addprefix $(float16_prefix),$(addsuffix .c,$(float16_extend_funcs))) +float16_extend_dep = $(float16_extend_orig) \ + $(float16_extend_script) \ + $(float16_dep) -fp16x_all_obj = $(fp16x_fix_obj) $(fp16x_fixuns_obj) \ - $(fp16x_float_obj) $(fp16x_floatun_obj) +float16_all_funcs = $(float16_fix_funcs) \ + $(float16_float_funcs) \ + $(float16_extend_funcs) -$(fp16x_fix_src) : $(fp16x_fix_dep) - $(PERL) $(float16_fix_script) -h $(float16_fix_orig) > $@ +float16_all_src = $(float16_fix_src) \ + $(float16_float_src) \ + $(float16_extend_src) -$(fp16x_fixuns_src) : $(fp16x_fixuns_dep) - $(PERL) $(float16_fix_script) -h $(float16_fixuns_orig) > $@ +float16_all_obj = $(addprefix $(float16_prefix),$(addsuffix $(objext),$(float16_all_funcs))) -$(fp16x_float_src) : $(fp16x_float_dep) - $(PERL) $(float16_float_script) -h $(float16_float_orig) > $@ +$(float16_all_obj) : INTERNAL_CFLAGS += $(FP16_CFLAGS) -$(fp16x_floatun_src) : $(fp16x_floatun_dep) - $(PERL) $(float16_float_script) -h $(float16_floatun_orig) > $@ +# Turn off the unsigned comparison is always false warning in the +# conversion from unsigned int to float +$(float16_float_uns_obj) : INTERNAL_CFLAGS += -Wno-type-limits -$(fp16x_all_obj) : INTERNAL_CFLAGS += $(FP16_CFLAGS) +# Build the ppc-* sources +$(float16_fix_ti_src) : $(float16_fix_ti_orig) $(float16_fix_dep) + $(PERL) $(float16_fix_script) -t $@ $(float16_fix_ti_orig) > $@ -# Convert fix* functions for __bf12 -bfp16x_fix_funcs = fixbfti fixbfdi fixbfsi -bfp16x_fix_src = $(addprefix $(float16_prefix),$(addsuffix .c,$(bfp16x_fix_funcs))) -bfp16x_fix_obj = $(addprefix $(float16_prefix),$(addsuffix $(objext),$(bfp16x_fix_funcs))) +$(float16_fix_di_src) : $(float16_fix_di_orig) $(float16_fix_dep) + $(PERL) $(float16_fix_script) -t $@ $(float16_fix_di_orig) > $@ -bfp16x_fix_dep = $(float16_fix_orig) \ - $(float16_fix_script) \ - $(srcdir)/config/rs6000/t-float16 - -bfp16x_fixuns_funcs = fixunsbfti fixunsbfdi fixunsbfsi -bfp16x_fixuns_src = $(addprefix $(float16_prefix),$(addsuffix .c,$(bfp16x_fixuns_funcs))) -bfp16x_fixuns_obj = $(addprefix $(float16_prefix),$(addsuffix $(objext),$(bfp16x_fixuns_funcs))) - -bfp16x_fixuns_dep = $(float16_fixuns_orig) \ - $(float16_fix_script) \ - $(srcdir)/config/rs6000/t-float16 +$(float16_fix_si_src) : $(float16_fix_si_orig) $(float16_fix_dep) + $(PERL) $(float16_fix_script) -t $@ $(float16_fix_si_orig) > $@ -bfp16x_float_funcs = floattibf floatdibf floatsibf -bfp16x_float_src = $(addprefloat $(float16_prefloat),$(addsuffloat .c,$(bfp16x_float_funcs))) -bfp16x_float_obj = $(addprefloat $(float16_prefloat),$(addsuffloat $(objext),$(bfp16x_float_funcs))) +$(float16_fixuns_ti_src) : $(float16_fixuns_ti_orig) $(float16_fix_dep) + $(PERL) $(float16_fix_script) -t $@ $(float16_fixuns_ti_orig) > $@ -bfp16x_float_depi = $(float16_float_orig) \ - $(float16_float_script) \ - $(srcdir)/config/rs6000/t-float16 +$(float16_fixuns_di_src) : $(float16_fixuns_di_orig) $(float16_fix_dep) + $(PERL) $(float16_fix_script) -t $@ $(float16_fixuns_di_orig) > $@ -bfp16x_floatun_funcs = floatuntibf floatundibf floatunsibf -bfp16x_floatun_src = $(addprefloat $(float16_prefloat),$(addsuffloat .c,$(bfp16x_floatun_funcs))) -bfp16x_floatun_obj = $(addprefloat $(float16_prefloat),$(addsuffloat $(objext),$(bfp16x_floatun_funcs))) +$(float16_fixuns_si_src) : $(float16_fixuns_si_orig) $(float16_fix_dep) + $(PERL) $(float16_fix_script) -t $@ $(float16_fixuns_si_orig) > $@ -bfp16x_floatun_dep = $(float16_floatun_orig) \ - $(float16_float_script) \ - $(srcdir)/config/rs6000/t-float16 +$(float16_float_src) : $(subst $(float16_prefix),$(srcdir)/soft-fp/,$@) $(float16_float_dep) + $(PERL) $(float16_float_script) -t $@ $(subst $(float16_prefix),$(srcdir)/soft-fp/,$@) > $@ -bfp16x_all_funcs = $(bfp16x_fix_funcs) $(bfp16x_fixuns_funcs) \ - $(bfp16x_float_funcs) $(bfp16x_floatun_funcs) - -bfp16x_all_src = $(bfp16x_fix_src) $(bfp16x_fixuns_src) \ - $(bfp16x_float_src) $(bfp16x_floatun_src) - -bfp16x_all_obj = $(bfp16x_fix_obj) $(bfp16x_fixuns_obj) \ - $(bfp16x_float_obj) $(bfp16x_floatun_obj) - -$(bfp16x_fix_src) : $(bfp16x_fix_dep) - $(PERL) $(float16_fix_script) -b $(float16_fix_orig) > $@ - -$(bfp16x_fixuns_src) : $(bfp16x_fixuns_dep) - $(PERL) $(float16_fix_script) -b $(float16_fixuns_orig) > $@ - -$(bfp16x_float_src) : $(bfp16x_float_dep) - $(PERL) $(float16_float_script) -b $(float16_float_orig) > $@ - -$(bfp16x_floatun_src) : $(bfp16x_floatun_dep) - $(PERL) $(float16_float_script) -b $(float16_floatun_orig) > $@ - -$(bfp16x_all_obj) : INTERNAL_CFLAGS += $(FP16_CFLAGS) +$(float16_extend_src) : $(float16_extend_dep) + $(PERL) $(float16_extend_script) -t $@ $(float16_extend_orig) > $@ # For now, only put it in the static library -# LIB2ADD += $(fp16_src) $(bfp16_src) $(both_fp16_src) +# LIB2ADD += $(fp16_src) $(bfp16_src) $(both_fp16_src) $(float16_all_src) LIB2ADD_ST += $(fp16_src) $(bfp16_src) $(both_fp16_src) \ - $(fp16x_all_src) $(bfp16x_all_src) + $(float16_all_src) .PHONY: test-float16 clean-float16 ppc-srcfiles @@ -181,36 +164,35 @@ test-float16: echo "both_fp16_obj:"; \ for x in $(bfp16_obj); do echo " $$x"; done; \ echo; \ - echo "fp16x_all_funcs:"; \ - for x in $(fp16x_all_funcs); do echo " $$x"; done; \ - echo; \ - echo "fp16x_all_src:"; \ - for x in $(fp16x_all_src); do echo " $$x"; done; \ + echo "float16_all_funcs:"; \ + for x in $(float16_all_funcs); do echo " $$x"; done; \ echo; \ - echo "fp16x_all_obj:"; \ - for x in $(fp16x_all_obj); do echo " $$x"; done; \ + echo "float16_all_src:"; \ + for x in $(float16_all_src); do echo " $$x"; done; \ echo; \ - echo "bfp16x_all_funcs:"; \ - for x in $(bfp16x_all_funcs); do echo " $$x"; done; \ + echo "float16_all_obj:"; \ + for x in $(float16_all_obj); do echo " $$x"; done; \ echo; \ - echo "bfp16x_all_src:"; \ - for x in $(bfp16x_all_src); do echo " $$x"; done; \ + echo "LIB2ADD_ST:"; \ + for x in $(LIB2ADD_ST); do echo " $$x"; done; \ echo; \ - echo "bfp16x_all_obj:"; \ - for x in $(fp16x_all_obj); do echo " $$x"; done; \ + echo "float16_prefix = $(float16_prefix)"; \ + echo "float16_fix_ti_orig = $(float16_fix_ti_orig)"; \ + echo "float16_fix_di_orig = $(float16_fix_di_orig)"; \ + echo "float16_fix_si_orig = $(float16_fix_si_orig)"; \ + echo "float16_fixuns_ti_orig = $(float16_fixuns_ti_orig)"; \ + echo "float16_fixuns_di_orig = $(float16_fixuns_di_orig)"; \ + echo "float16_fixuns_si_orig = $(float16_fixuns_si_orig)"; \ + echo "float16_extend_orig = $(float16_extend_orig)"; \ echo; \ - echo "float16_prefix = $(float16_prefix)"; \ - echo "float16_fix_orig = $(float16_fix_orig)"; \ - echo "float16_fixuns_orig = $(float16_fixuns_orig)"; \ - echo "float16_fix_script = $(float16_fix_script)"; \ - echo "float16_float_orig = $(float16_float_orig)"; \ - echo "float16_floatun_orig = $(float16_floatun_orig)"; \ - echo "float16_float_script = $(float16_float_script)"; \ + echo "float16_fix_script = $(float16_fix_script)"; \ + echo "float16_float_script = $(float16_float_script)"; \ + echo "float16_extend_script = $(float16_extend_script)"; \ echo clean-float16: @$(MULTICLEAN) multi-clean DO=clean-float16 - rm -f $(fp16x_all_src) $(bfp16x_all_src) ppc-srcfiles + rm -f $(float16_all_src) ppc-srcfiles -ppc-srcfiles: $(fp16x_all_src) $(bfp16x_all_src) +ppc-srcfiles: $(float16_all_src) @touch ppc-srcfiles
