Support TI mode and soft float on PA64

This change implements TI mode on PA64.  Various new patterns are
added to pa.md.  The libgcc build needed modification to build both
DI and TI routines.  We also need various softfp routines to
convert to and from TImode.

I added full softfp for the -msoft-float option.  At the moment,
this doesn't completely eliminate all use of the floating-point
co-processor.  For this, libgcc needs to be built with -msoft-mult.
The floating-point exception support also needs a soft option.

2021-11-05  John David Anglin  <danglin@gcc.gnu.org>

	PR libgomp/96661

gcc/ChangeLog:

	* config/pa/pa-modes.def: Add OImode integer type.
	* config/pa/pa.c (pa_scalar_mode_supported_p): Allow TImode
	for TARGET_64BIT.
	* config/pa/pa.h (MIN_UNITS_PER_WORD) Define to MIN_UNITS_PER_WORD
	to UNITS_PER_WORD if IN_LIBGCC2.
	* config/pa/pa.md (addti3, addvti3, subti3, subvti3, negti2,
	negvti2, ashlti3, shrpd_internal): New patterns.
	Change some multi instruction types to multi.

libgcc/ChangeLog:

	* config.host (hppa*64*-*-linux*): Revise tmake_file.
	(hppa*64*-*-hpux11*): Likewise.
	* config/pa/sfp-exceptions.c: New.
	* config/pa/sfp-machine.h: New.
	* config/pa/t-dimode: New.
	* config/pa/t-softfp-sfdftf: New.
This commit is contained in:
John David Anglin 2021-11-05 16:07:35 +00:00
parent 858d7ee1a0
commit db89d474ad
9 changed files with 483 additions and 15 deletions

View File

@ -30,3 +30,6 @@ FLOAT_MODE (TF, 16, mips_quad_format);
/* HPPA floating comparisons produce distinct condition codes. */
CC_MODE (CCFP);
/* Mode used for signed overflow checking of TImode. */
INT_MODE (OI, 32);

View File

@ -6550,18 +6550,16 @@ hppa_gimplify_va_arg_expr (tree valist, tree type, gimple_seq *pre_p,
/* True if MODE is valid for the target. By "valid", we mean able to
be manipulated in non-trivial ways. In particular, this means all
the arithmetic is supported.
Currently, TImode is not valid as the HP 64-bit runtime documentation
doesn't document the alignment and calling conventions for this type.
Thus, we return false when PRECISION is 2 * BITS_PER_WORD and
2 * BITS_PER_WORD isn't equal LONG_LONG_TYPE_SIZE. */
the arithmetic is supported. */
static bool
pa_scalar_mode_supported_p (scalar_mode mode)
{
int precision = GET_MODE_PRECISION (mode);
if (TARGET_64BIT && mode == TImode)
return true;
switch (GET_MODE_CLASS (mode))
{
case MODE_PARTIAL_INT:

View File

@ -258,11 +258,17 @@ typedef struct GTY(()) machine_function
is UNITS_PER_WORD. Otherwise, it is the constant value that is the
smallest value that UNITS_PER_WORD can have at run-time.
FIXME: This needs to be 4 when TARGET_64BIT is true to suppress the
building of various TImode routines in libgcc. The HP runtime
specification doesn't provide the alignment requirements and calling
conventions for TImode variables. */
#define MIN_UNITS_PER_WORD 4
This needs to be 8 when TARGET_64BIT is true to allow building various
TImode routines in libgcc. However, we also need the DImode DIVMOD
routines because they are not currently implemented in pa.md.
The HP runtime specification doesn't provide the alignment requirements
and calling conventions for TImode variables. */
#ifdef IN_LIBGCC2
#define MIN_UNITS_PER_WORD UNITS_PER_WORD
#else
#define MIN_UNITS_PER_WORD 4
#endif
/* The widest floating point format supported by the hardware. Note that
setting this influences some Ada floating point type sizes, currently

View File

@ -5357,6 +5357,88 @@
[(set_attr "type" "binary,binary")
(set_attr "length" "4,4")])
(define_insn "addti3"
[(set (match_operand:TI 0 "register_operand" "=r")
(plus:TI (match_operand:TI 1 "register_operand" "r")
(match_operand:TI 2 "register_operand" "r")))]
"TARGET_64BIT"
"*
{
operands[3] = gen_lowpart (DImode, operands[0]);
operands[4] = gen_lowpart (DImode, operands[1]);
operands[5] = gen_lowpart (DImode, operands[2]);
operands[0] = gen_highpart (DImode, operands[0]);
operands[1] = gen_highpart (DImode, operands[1]);
operands[2] = gen_highpart (DImode, operands[2]);
return \"add %4,%5,%3\;add,dc %1,%2,%0\";
}"
[(set_attr "type" "multi")
(set_attr "length" "8")])
(define_insn "addvti3"
[(set (match_operand:TI 0 "register_operand" "=r")
(plus:TI (match_operand:TI 1 "register_operand" "r")
(match_operand:TI 2 "register_operand" "r")))
(trap_if (ne (plus:OI (sign_extend:OI (match_dup 1))
(sign_extend:OI (match_dup 2)))
(sign_extend:OI (plus:TI (match_dup 1)
(match_dup 2))))
(const_int 0))]
"TARGET_64BIT"
"*
{
operands[3] = gen_lowpart (DImode, operands[0]);
operands[4] = gen_lowpart (DImode, operands[1]);
operands[5] = gen_lowpart (DImode, operands[2]);
operands[0] = gen_highpart (DImode, operands[0]);
operands[1] = gen_highpart (DImode, operands[1]);
operands[2] = gen_highpart (DImode, operands[2]);
return \"add %4,%5,%3\;add,dc,tsv %1,%2,%0\";
}"
[(set_attr "type" "multi")
(set_attr "length" "8")])
(define_insn "subti3"
[(set (match_operand:TI 0 "register_operand" "=r")
(minus:TI (match_operand:TI 1 "register_operand" "r")
(match_operand:TI 2 "register_operand" "r")))]
"TARGET_64BIT"
"*
{
operands[3] = gen_lowpart (DImode, operands[0]);
operands[4] = gen_lowpart (DImode, operands[1]);
operands[5] = gen_lowpart (DImode, operands[2]);
operands[0] = gen_highpart (DImode, operands[0]);
operands[1] = gen_highpart (DImode, operands[1]);
operands[2] = gen_highpart (DImode, operands[2]);
return \"sub %4,%5,%3\;sub,db %1,%2,%0\";
}"
[(set_attr "type" "multi")
(set_attr "length" "8")])
(define_insn "subvti3"
[(set (match_operand:TI 0 "register_operand" "=r")
(minus:TI (match_operand:TI 1 "register_operand" "r")
(match_operand:TI 2 "register_operand" "r")))
(trap_if (ne (minus:OI (sign_extend:OI (match_dup 1))
(sign_extend:OI (match_dup 2)))
(sign_extend:OI (minus:TI (match_dup 1)
(match_dup 2))))
(const_int 0))]
"TARGET_64BIT"
"*
{
operands[3] = gen_lowpart (DImode, operands[0]);
operands[4] = gen_lowpart (DImode, operands[1]);
operands[5] = gen_lowpart (DImode, operands[2]);
operands[0] = gen_highpart (DImode, operands[0]);
operands[1] = gen_highpart (DImode, operands[1]);
operands[2] = gen_highpart (DImode, operands[2]);
return \"sub %4,%5,%3\;sub,db,tsv %1,%2,%0\";
}"
[(set_attr "type" "multi")
(set_attr "length" "8")])
;; Trap instructions.
(define_insn "trap"
@ -5897,7 +5979,7 @@
(neg:DI (match_operand:DI 1 "register_operand" "r")))]
"!TARGET_64BIT"
"sub %%r0,%R1,%R0\;{subb|sub,b} %%r0,%1,%0"
[(set_attr "type" "unary")
[(set_attr "type" "multi")
(set_attr "length" "8")])
(define_insn ""
@ -5908,6 +5990,21 @@
[(set_attr "type" "unary")
(set_attr "length" "4")])
(define_insn "negti2"
[(set (match_operand:TI 0 "register_operand" "=r")
(neg:TI (match_operand:TI 1 "register_operand" "r")))]
"TARGET_64BIT"
"*
{
operands[2] = gen_lowpart (DImode, operands[0]);
operands[3] = gen_lowpart (DImode, operands[1]);
operands[0] = gen_highpart (DImode, operands[0]);
operands[1] = gen_highpart (DImode, operands[1]);
return \"sub %%r0,%3,%2\;sub,db %%r0,%1,%0\";
}"
[(set_attr "type" "multi")
(set_attr "length" "8")])
(define_expand "negvdi2"
[(parallel [(set (match_operand:DI 0 "register_operand" "")
(neg:DI (match_operand:DI 1 "register_operand" "")))
@ -5925,7 +6022,7 @@
(const_int 0))]
"!TARGET_64BIT"
"sub %%r0,%R1,%R0\;{subbo|sub,b,tsv} %%r0,%1,%0"
[(set_attr "type" "unary")
[(set_attr "type" "multi")
(set_attr "length" "8")])
(define_insn ""
@ -5939,6 +6036,24 @@
[(set_attr "type" "unary")
(set_attr "length" "4")])
(define_insn "negvti2"
[(set (match_operand:TI 0 "register_operand" "=r")
(neg:TI (match_operand:TI 1 "register_operand" "r")))
(trap_if (ne (neg:OI (sign_extend:OI (match_dup 1)))
(sign_extend:OI (neg:TI (match_dup 1))))
(const_int 0))]
"TARGET_64BIT"
"*
{
operands[2] = gen_lowpart (DImode, operands[0]);
operands[3] = gen_lowpart (DImode, operands[1]);
operands[0] = gen_highpart (DImode, operands[0]);
operands[1] = gen_highpart (DImode, operands[1]);
return \"sub %%r0,%3,%2\;sub,db,tsv %%r0,%1,%0\";
}"
[(set_attr "type" "multi")
(set_attr "length" "8")])
(define_insn "negsi2"
[(set (match_operand:SI 0 "register_operand" "=r")
(neg:SI (match_operand:SI 1 "register_operand" "r")))]
@ -6566,6 +6681,42 @@
operands[1] = force_reg (DImode, operands[1]);
}")
(define_expand "ashlti3"
[(set (match_operand:TI 0 "register_operand" "")
(ashift:TI (match_operand:TI 1 "lhs_lshift_operand" "")
(match_operand:TI 2 "arith32_operand" "")))]
"TARGET_64BIT"
{
if (REG_P (operands[0]) && GET_CODE (operands[2]) == CONST_INT)
{
unsigned HOST_WIDE_INT shift = UINTVAL (operands[2]);
rtx dst = operands[0];
rtx src = force_reg (TImode, operands[1]);
if (shift >= 1 && shift <= 63)
{
emit_insn (gen_shrpd_internal (gen_highpart (DImode, dst),
gen_lowpart (DImode, src),
GEN_INT (64-shift),
gen_highpart (DImode, src),
GEN_INT (shift)));
emit_insn (gen_ashldi3 (gen_lowpart (DImode, dst),
gen_lowpart (DImode, src),
GEN_INT (shift)));
DONE;
}
else if (shift >= 64 && shift <= 127)
{
emit_insn (gen_ashldi3 (gen_highpart (DImode, dst),
gen_lowpart (DImode, src),
GEN_INT (shift - 64)));
emit_move_insn (gen_lowpart (DImode, dst), GEN_INT (0));
DONE;
}
}
/* Fallback to using optabs.c's expand_doubleword_shift. */
FAIL;
})
(define_insn ""
[(set (match_operand:DI 0 "register_operand" "=r")
(ashift:DI (match_operand:DI 1 "register_operand" "r")
@ -6944,6 +7095,15 @@
(match_operand:SI 4 "const_int_operand"))))]
"")
(define_expand "shrpd_internal"
[(set (match_operand:DI 0 "register_operand")
(ior:DI
(lshiftrt:DI (match_operand:DI 1 "register_operand")
(match_operand:DI 2 "const_int_operand"))
(ashift:DI (match_operand:DI 3 "register_operand")
(match_operand:DI 4 "const_int_operand"))))]
"TARGET_64BIT")
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r")
(and:SI (ashift:SI (match_operand:SI 1 "register_operand" "r")

View File

@ -619,7 +619,8 @@ h8300-*-linux*)
tm_file="$tm_file h8300/h8300-lib.h"
;;
hppa*64*-*-linux*)
tmake_file="$tmake_file pa/t-linux64"
tmake_file="$tmake_file pa/t-linux64 pa/t-dimode"
tmake_file="$tmake_file pa/t-softfp-sfdftf t-softfp"
extra_parts="crtbegin.o crtbeginS.o crtbeginT.o crtend.o crtendS.o"
;;
hppa*-*-linux*)
@ -645,7 +646,8 @@ hppa[12]*-*-hpux10*)
md_unwind_header=pa/hpux-unwind.h
;;
hppa*64*-*-hpux11*)
tmake_file="$tmake_file pa/t-hpux pa/t-pa64 pa/t-stublib t-libgcc-pic t-slibgcc"
tmake_file="$tmake_file pa/t-hpux pa/t-pa64 pa/t-dimode"
tmake_file="$tmake_file pa/t-stublib t-libgcc-pic t-slibgcc"
# Set the libgcc version number
if test x$ac_cv_sjlj_exceptions = xyes; then
tmake_file="$tmake_file pa/t-slibgcc-sjlj-ver"
@ -653,6 +655,7 @@ hppa*64*-*-hpux11*)
tmake_file="$tmake_file pa/t-slibgcc-dwarf-ver"
fi
tmake_file="$tmake_file pa/t-slibgcc-hpux t-slibgcc-hpux"
tmake_file="$tmake_file pa/t-softfp-sfdftf t-softfp"
tm_file="$tm_file pa/pa64-hpux-lib.h"
extra_parts="crtbegin.o crtend.o crtbeginS.o crtendS.o crtbeginT.o \
libgcc_stub.a"

View File

@ -0,0 +1,102 @@
/*
* Copyright (C) 1997-2021 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"
#define HUGE_VAL (__builtin_huge_val ())
/* Please see section 10,
page 10-5 "Delayed Trapping" in the PA-RISC 2.0 Architecture manual */
void
__sfp_handle_exceptions (int _fex)
{
/* Raise exceptions represented by _FEX. But we must raise only one
signal at a time. It is important that if the overflow/underflow
exception and the divide by zero exception are given at the same
time, the overflow/underflow exception follows the divide by zero
exception. */
/* We do these bits in assembly to be certain GCC doesn't optimize
away something important, and so we can force delayed traps to
occur. */
/* We use "fldd 0(%%sr0,%%sp),%0" to flush the delayed exception */
/* First: Invalid exception. */
if (_fex & FP_EX_INVALID)
{
/* One example of an invalid operation is 0 * Infinity. */
double d = HUGE_VAL;
__asm__ __volatile__ (
" fcpy,dbl %%fr0,%%fr22\n"
" fmpy,dbl %0,%%fr22,%0\n"
" fldd 0(%%sr0,%%sp),%0"
: "+f" (d) : : "%fr22" );
}
/* Second: Division by zero. */
if (_fex & FP_EX_DIVZERO)
{
double d = 1.0;
__asm__ __volatile__ (
" fcpy,dbl %%fr0,%%fr22\n"
" fdiv,dbl %0,%%fr22,%0\n"
" fldd 0(%%sr0,%%sp),%0"
: "+f" (d) : : "%fr22" );
}
/* Third: Overflow. */
if (_fex & FP_EX_OVERFLOW)
{
double d = __DBL_MAX__;
__asm__ __volatile__ (
" fadd,dbl %0,%0,%0\n"
" fldd 0(%%sr0,%%sp),%0"
: "+f" (d) );
}
/* Fourth: Underflow. */
if (_fex & FP_EX_UNDERFLOW)
{
double d = __DBL_MIN__;
double e = 3.0;
__asm__ __volatile__ (
" fdiv,dbl %0,%1,%0\n"
" fldd 0(%%sr0,%%sp),%0"
: "+f" (d) : "f" (e) );
}
/* Fifth: Inexact */
if (_fex & FP_EX_INEXACT)
{
double d = 3.14159265358979323846;
double e = 69.69;
__asm__ __volatile__ (
" fdiv,dbl %0,%1,%%fr22\n"
" fcnvfxt,dbl,sgl %%fr22,%%fr22L\n"
" fldd 0(%%sr0,%%sp),%%fr22"
: : "f" (d), "f" (e) : "%fr22" );
}
}

View File

@ -0,0 +1,155 @@
/* softfp machine description for PA-RISC.
Copyright (C) 2009-2021 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.
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/>. */
#ifdef __LP64__
#define _FP_W_TYPE_SIZE 64
#define _FP_W_TYPE unsigned long
#define _FP_WS_TYPE signed long
#define _FP_I_TYPE long
typedef int TItype __attribute__ ((mode (TI)));
typedef unsigned int UTItype __attribute__ ((mode (TI)));
#define TI_BITS (__CHAR_BIT__ * (int) sizeof (TItype))
#define _FP_MUL_MEAT_S(R,X,Y) \
_FP_MUL_MEAT_1_wide(_FP_WFRACBITS_S,R,X,Y,umul_ppmm)
#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)
#define _FP_DIV_MEAT_S(R,X,Y) _FP_DIV_MEAT_1_udiv_norm(S,R,X,Y)
#define _FP_DIV_MEAT_D(R,X,Y) _FP_DIV_MEAT_1_udiv_norm(D,R,X,Y)
#define _FP_DIV_MEAT_Q(R,X,Y) _FP_DIV_MEAT_2_udiv(Q,R,X,Y)
#define _FP_NANFRAC_S (_FP_QNANBIT_S - 1)
#define _FP_NANFRAC_D (_FP_QNANBIT_D - 1)
#define _FP_NANFRAC_Q (_FP_QNANBIT_Q - 1), -1
#else
#define _FP_W_TYPE_SIZE 32
#define _FP_W_TYPE unsigned int
#define _FP_WS_TYPE signed int
#define _FP_I_TYPE int
#define _FP_MUL_MEAT_S(R,X,Y) \
_FP_MUL_MEAT_1_wide(_FP_WFRACBITS_S,R,X,Y,umul_ppmm)
#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)
#define _FP_DIV_MEAT_S(R,X,Y) _FP_DIV_MEAT_1_udiv_norm(S,R,X,Y)
#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)
#define _FP_NANFRAC_S (_FP_QNANBIT_S - 1)
#define _FP_NANFRAC_D (_FP_QNANBIT_D - 1), -1
#define _FP_NANFRAC_Q (_FP_QNANBIT_Q - 1), -1, -1, -1
#endif
/* The type of the result of a floating point comparison. This must
match __libgcc_cmp_return__ in GCC for the target. */
typedef int __gcc_CMPtype __attribute__ ((mode (__libgcc_cmp_return__)));
#define CMPtype __gcc_CMPtype
#define _FP_NANSIGN_S 0
#define _FP_NANSIGN_D 0
#define _FP_NANSIGN_Q 0
#define _FP_KEEPNANFRACP 1
#define _FP_QNANNEGATEDP 1
/* Comment from glibc: */
/* From my experiments it seems X is chosen unless one of the
NaNs is sNaN, in which case the result is NANSIGN/NANFRAC. */
# define _FP_CHOOSENAN(fs, wc, R, X, Y, OP) \
do { \
if ((_FP_FRAC_HIGH_RAW_##fs(X) | \
_FP_FRAC_HIGH_RAW_##fs(Y)) & _FP_QNANBIT_##fs) \
{ \
R##_s = _FP_NANSIGN_##fs; \
_FP_FRAC_SET_##wc(R,_FP_NANFRAC_##fs); \
} \
else \
{ \
R##_s = X##_s; \
_FP_FRAC_COPY_##wc(R,X); \
} \
R##_c = FP_CLS_NAN; \
} while (0)
#define FP_RND_NEAREST (0 << 9)
#define FP_RND_ZERO (1 << 9)
#define FP_RND_PINF (2 << 9)
#define FP_RND_MINF (3 << 9)
#define FP_RND_MASK (3 << 9)
#define FP_EX_INEXACT 0x01
#define FP_EX_UNDERFLOW 0x02
#define FP_EX_OVERFLOW 0x04
#define FP_EX_DIVZERO 0x08
#define FP_EX_INVALID 0x10
#define FP_EX_ALL 0x1F
#define FP_EX_SHIFT 27
#define _FP_TININESS_AFTER_ROUNDING 1
#define _FP_DECL_EX \
unsigned int _fcsr __attribute__ ((unused)) = FP_RND_NEAREST
/* Get floating-point status. */
#define _FPU_GETCW(cw) \
({ \
union { unsigned long long __fpreg; \
unsigned int __halfreg[2]; } __fullfp; \
/* Get the current status word. */ \
__asm__ ("fstd %%fr0,0(%1)\n\t" \
"fldd 0(%1),%%fr0\n\t" \
: "=m" (__fullfp.__fpreg) \
: "r" (&__fullfp.__fpreg) \
: "%r0"); \
cw = __fullfp.__halfreg[0]; \
})
#define FP_INIT_ROUNDMODE _FPU_GETCW(_fcsr)
#define FP_ROUNDMODE (_fcsr & FP_RND_MASK)
#define FP_TRAPPING_EXCEPTIONS (_fcsr & FP_EX_ALL)
void __sfp_handle_exceptions (int);
#define FP_HANDLE_EXCEPTIONS \
do { \
if (__builtin_expect (_fex, 0)) \
__sfp_handle_exceptions (_fex); \
} while (0)
#define __LITTLE_ENDIAN 1234
#define __BIG_ENDIAN 4321
#define __BYTE_ORDER __BIG_ENDIAN
/* Define ALIASNAME as a strong alias for NAME. */
# define strong_alias(name, aliasname) _strong_alias(name, aliasname)
# define _strong_alias(name, aliasname) \
extern __typeof (name) aliasname __attribute__ ((alias (#name)));

33
libgcc/config/pa/t-dimode Normal file
View File

@ -0,0 +1,33 @@
# Extra DImode libgcc2 functions to build.
lib2difuncs = _muldi3 _negdi2 _lshrdi _ashldi3 _ashrdi3 _cmpdi2 _ucmpdi2
# Build lib2difuncs.
lib2difuncs-o = $(patsubst %,%_di$(objext),$(lib2difuncs))
$(lib2difuncs-o): %_di$(objext): $(srcdir)/libgcc2.c
$(gcc_compile) -DLIBGCC2_UNITS_PER_WORD=4 -DL$* -c $< $(vis_hide)
libgcc-objects += $(lib2difuncs-o)
ifeq ($(enable_shared),yes)
lib2difuncs-s-o = $(patsubst %,%_di_s$(objext),$(lib2difuncs))
$(lib2difuncs-s-o): %_di_s$(objext): $(srcdir)/libgcc2.c
$(gcc_s_compile) -DLIBGCC2_UNITS_PER_WORD=4 -DL$* -c $<
libgcc-s-objects += $(lib2difuncs-s-o)
endif
# Extra DImode divmod functions to build.
lib2didivmodfuncs = _divdi3 _moddi3 _udivdi3 _umoddi3
# Build lib2didivmodfuncs.
lib2didivmod-o = $(patsubst %,%_di$(objext),$(lib2didivmodfuncs))
$(lib2didivmod-o): %_di$(objext): $(srcdir)/libgcc2.c
$(gcc_compile) -DLIBGCC2_UNITS_PER_WORD=4 -DL$* -c $< \
$(LIB2_DIVMOD_EXCEPTION_FLAGS) $(vis_hide)
libgcc-objects += $(lib2didivmod-o)
ifeq ($(enable_shared),yes)
lib2didivmod-s-o = $(patsubst %,%_di_s$(objext),$(lib2didivmodfuncs))
$(lib2didivmod-s-o): %_di_s$(objext): $(srcdir)/libgcc2.c
$(gcc_s_compile) -DLIBGCC2_UNITS_PER_WORD=4 -DL$* -c $< \
$(LIB2_DIVMOD_EXCEPTION_FLAGS)
libgcc-s-objects += $(lib2didivmod-s-o)
endif

View File

@ -0,0 +1,8 @@
# Soft float configuration for PA64
LIB2ADD += $(srcdir)/config/pa/sfp-exceptions.c
softfp_float_modes := sf df tf
softfp_int_modes := si di ti
softfp_extensions := sfdf sftf dftf
softfp_truncations := dfsf tfsf tfdf
softfp_exclude_libgcc2 := n