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:
parent
858d7ee1a0
commit
db89d474ad
|
@ -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);
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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" );
|
||||
}
|
||||
}
|
|
@ -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)));
|
|
@ -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
|
|
@ -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
|
Loading…
Reference in New Issue