From patchwork Fri Nov 5 17:16:18 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John David Anglin X-Patchwork-Id: 47126 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 3EFCE3858432 for ; Fri, 5 Nov 2021 17:16:38 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from cmx-mtlrgo002.bell.net (mta-mtl-004.bell.net [209.71.208.14]) by sourceware.org (Postfix) with ESMTP id E07BF3858D28 for ; Fri, 5 Nov 2021 17:16:19 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org E07BF3858D28 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=bell.net Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=bell.net X-RG-CM-BuS: 0 X-RG-CM-SC: 0 X-RG-CM: Clean X-Originating-IP: [67.71.8.137] X-RG-Env-Sender: dave.anglin@bell.net X-RG-Rigid: 60C894590B055B27 X-CM-Envelope: MS4xfBSqxpWWoglc9wmWscaAtOY2/UbtElkLP2brrGgL839r06W4V8Ba9UyXrhZw5AkCpaJOh41Z4skDLZEtR/qs7V7WkL6DFguZ6oU1fUKRwVK3QHf2Cuwe Z6h5hE/097oZkmnRbetJVQzkQCh2+ytT9IaKNDUCnihz49uWyYU4m1K3ERQAjBp61XkntPh6VF0I0qSFQ45m95R7dW4Yc6aUIJQWfH9Yl2WabOZc5jvyqtNl XzwcLcEME/tJPOWojBN7jQ== X-CM-Analysis: v=2.4 cv=ENdlb3VC c=1 sm=1 tr=0 ts=618566e3 a=jrdA9tB8yuRqUzQ1EpSZjA==:117 a=jrdA9tB8yuRqUzQ1EpSZjA==:17 a=IkcTkHD0fZMA:10 a=mDV3o1hIAAAA:8 a=J7r5o7U-GnRhoY_8c3YA:9 a=QEXdDO2ut3YA:10 a=_FVE-zBwftR9WsbkzFJk:22 Received: from [192.168.2.49] (67.71.8.137) by cmx-mtlrgo002.bell.net (5.8.716.03) (authenticated as dave.anglin@bell.net) id 60C894590B055B27; Fri, 5 Nov 2021 13:16:19 -0400 Message-ID: Date: Fri, 5 Nov 2021 13:16:18 -0400 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:91.0) Gecko/20100101 Thunderbird/91.2.1 Content-Language: en-US From: John David Anglin Subject: [committed] hppa: Support TI mode and soft float on PA64 To: GCC Patches X-Spam-Status: No, score=-9.0 required=5.0 tests=BAYES_00, GIT_PATCH_0, KAM_DMARC_STATUS, KAM_NUMSUBJECT, KAM_SHORT, RCVD_IN_DNSWL_LOW, RCVD_IN_MSPIKE_H2, SPF_HELO_PASS, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.org Sender: "Gcc-patches" Without TImode support on hppa64, it is necessary to disable building libgomp with fortran. Previously, we didn't support TImode because we need both DImode and TImode divmod routines from libgcc. The standard build only builds one of the two. This is nominally determined by MIN_UNITS_PER_WORD. I created a makefile fragment to build the needed DImode routines. Since the alignment requirements for TImode are not defined, I just assumed the standard alignment and calling convention for a structure containing a pair of 64-bit words. I also added softfp support based on early mips float format and hppa glibc exception support. Tested on hppa64-hp-hpux11.11 and hppa64-unknown-linux-gnu. Committed on trunk and gcc-11. Dave --- 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 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. diff --git a/gcc/config/pa/pa-modes.def b/gcc/config/pa/pa-modes.def index 769de66f6b6..6020233c171 100644 --- a/gcc/config/pa/pa-modes.def +++ b/gcc/config/pa/pa-modes.def @@ -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); diff --git a/gcc/config/pa/pa.c b/gcc/config/pa/pa.c index 21b812e9be7..f22d25a4066 100644 --- a/gcc/config/pa/pa.c +++ b/gcc/config/pa/pa.c @@ -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: diff --git a/gcc/config/pa/pa.h b/gcc/config/pa/pa.h index 7a313d617b0..96815ec69cb 100644 --- a/gcc/config/pa/pa.h +++ b/gcc/config/pa/pa.h @@ -255,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 diff --git a/gcc/config/pa/pa.md b/gcc/config/pa/pa.md index ea6da457fcb..f124c301b7a 100644 --- a/gcc/config/pa/pa.md +++ b/gcc/config/pa/pa.md @@ -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") diff --git a/libgcc/config.host b/libgcc/config.host index 85de83da766..168535b1780 100644 --- a/libgcc/config.host +++ b/libgcc/config.host @@ -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" diff --git a/libgcc/config/pa/sfp-exceptions.c b/libgcc/config/pa/sfp-exceptions.c new file mode 100644 index 00000000000..4dadaf43d17 --- /dev/null +++ b/libgcc/config/pa/sfp-exceptions.c @@ -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 + * . + */ + + +#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" ); + } +} diff --git a/libgcc/config/pa/sfp-machine.h b/libgcc/config/pa/sfp-machine.h new file mode 100644 index 00000000000..661b1cf2cf4 --- /dev/null +++ b/libgcc/config/pa/sfp-machine.h @@ -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 +. */ + +#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))); diff --git a/libgcc/config/pa/t-dimode b/libgcc/config/pa/t-dimode new file mode 100644 index 00000000000..1344e937644 --- /dev/null +++ b/libgcc/config/pa/t-dimode @@ -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 diff --git a/libgcc/config/pa/t-softfp-sfdftf b/libgcc/config/pa/t-softfp-sfdftf new file mode 100644 index 00000000000..51ff051ede2 --- /dev/null +++ b/libgcc/config/pa/t-softfp-sfdftf @@ -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