From d78f11c5eeabd79f798399a345e92b065c4e7e75 Mon Sep 17 00:00:00 2001 From: swcompiler Date: Mon, 25 Nov 2024 16:51:15 +0800 Subject: [PATCH 06/16] Sw64 Port: libgcc --- libgcc/config.host | 18 +++ libgcc/config/sw_64/crtfastmath.c | 36 +++++ libgcc/config/sw_64/libgcc-sw_64-ldbl.ver | 50 ++++++ libgcc/config/sw_64/linux-unwind.h | 103 ++++++++++++ libgcc/config/sw_64/qrnnd.S | 181 ++++++++++++++++++++++ libgcc/config/sw_64/t-ieee | 2 + libgcc/config/sw_64/t-linux | 1 + libgcc/config/sw_64/t-sw_64 | 6 + libgcc/libgcc2.c | 2 +- 9 files changed, 398 insertions(+), 1 deletion(-) create mode 100644 libgcc/config/sw_64/crtfastmath.c create mode 100644 libgcc/config/sw_64/libgcc-sw_64-ldbl.ver create mode 100644 libgcc/config/sw_64/linux-unwind.h create mode 100644 libgcc/config/sw_64/qrnnd.S create mode 100644 libgcc/config/sw_64/t-ieee create mode 100644 libgcc/config/sw_64/t-linux create mode 100644 libgcc/config/sw_64/t-sw_64 diff --git a/libgcc/config.host b/libgcc/config.host index 8c56fcae5..01cb28d2e 100644 --- a/libgcc/config.host +++ b/libgcc/config.host @@ -212,6 +212,9 @@ s390*-*-*) sh[123456789lbe]*-*-*) cpu_type=sh ;; +sw_64*-*-*) + cpu_type=sw_64 + ;; tilegx*-*-*) cpu_type=tilegx ;; @@ -1467,6 +1470,21 @@ sparc64-*-linux*) # 64-bit SPARC's running GNU/Linux ;; sparc64-*-netbsd*) ;; +sw_64*-*-linux*) + tmake_file="${tmake_file} sw_64/t-sw_64 sw_64/t-ieee t-crtfm sw_64/t-linux" + extra_parts="$extra_parts crtfastmath.o" + md_unwind_header=sw_64/linux-unwind.h + ;; +sw_64*-*-freebsd*) + tmake_file="${tmake_file} sw_64/t-sw_64 sw_64/t-ieee t-crtfm" + extra_parts="$extra_parts crtbeginT.o crtfastmath.o" + ;; +sw_64*-*-netbsd*) + tmake_file="${tmake_file} sw_64/t-sw_64 sw_64/t-ieee" + ;; +sw_64*-*-openbsd*) + tmake_file="${tmake_file} sw_64/t-sw_64 sw_64/t-ieee" + ;; tic6x-*-uclinux) tmake_file="${tmake_file} t-softfp-sfdf t-softfp-excl t-softfp \ c6x/t-elf c6x/t-uclinux t-crtstuff-pic t-libgcc-pic \ diff --git a/libgcc/config/sw_64/crtfastmath.c b/libgcc/config/sw_64/crtfastmath.c new file mode 100644 index 000000000..aec92c819 --- /dev/null +++ b/libgcc/config/sw_64/crtfastmath.c @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2001-2022 Free Software Foundation, Inc. + * Contributed by Richard Henderson (rth@redhat.com) + * + * 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 + * . + */ + +/* Assume SYSV/1 compatible interfaces. */ + +extern void +__ieee_set_fp_control (unsigned long int); + +#define IEEE_MAP_DMZ (1UL << 12) /* Map denorm inputs to zero */ +#define IEEE_MAP_UMZ (1UL << 13) /* Map underflowed outputs to zero */ + +static void __attribute__ ((constructor)) set_fast_math (void) +{ + __ieee_set_fp_control (IEEE_MAP_DMZ | IEEE_MAP_UMZ); +} diff --git a/libgcc/config/sw_64/libgcc-sw_64-ldbl.ver b/libgcc/config/sw_64/libgcc-sw_64-ldbl.ver new file mode 100644 index 000000000..6666bc639 --- /dev/null +++ b/libgcc/config/sw_64/libgcc-sw_64-ldbl.ver @@ -0,0 +1,50 @@ +# Copyright (C) 2006-2019 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 +# . + +%ifdef __LONG_DOUBLE_128__ + +# long double 128 bit support in libgcc_s.so.1 is only available +# when configured with --with-long-double-128. Make sure all the +# symbols are available at @@GCC_LDBL_* versions to make it clear +# there is a configurable symbol set. + +%exclude { + __fixtfdi + __fixunstfdi + __floatditf + + __divtc3 + __multc3 + __powitf2 +} + +%inherit GCC_LDBL_3.0 GCC_3.0 +GCC_LDBL_3.0 { + __fixtfdi + __fixunstfdi + __floatditf +} + +%inherit GCC_LDBL_4.0.0 GCC_4.0.0 +GCC_LDBL_4.0.0 { + __divtc3 + __multc3 + __powitf2 +} + +%endif diff --git a/libgcc/config/sw_64/linux-unwind.h b/libgcc/config/sw_64/linux-unwind.h new file mode 100644 index 000000000..d446c123f --- /dev/null +++ b/libgcc/config/sw_64/linux-unwind.h @@ -0,0 +1,103 @@ +/* DWARF2 EH unwinding support for Sw_64 Linux. + Copyright (C) 2004-2022 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 +. */ + +#ifndef inhibit_libc +/* Do code reading to identify a signal frame, and set the frame + state data appropriately. See unwind-dw2.c for the structs. */ + +#include +#include + +#define MD_FALLBACK_FRAME_STATE_FOR sw_64_fallback_frame_state + +static _Unwind_Reason_Code +sw_64_fallback_frame_state (struct _Unwind_Context *context, + _Unwind_FrameState *fs) +{ + unsigned int *pc = context->ra; + struct sigcontext *sc; + long new_cfa; + int i; + + if (pc[0] != 0x47fe0410 /* mov $30,$16 */ + || pc[2] != 0x00000083) /* callsys */ + return _URC_END_OF_STACK; + if (context->cfa == 0) + return _URC_END_OF_STACK; + if (pc[1] == 0x201f0067) /* lda $0,NR_sigreturn */ + sc = context->cfa; + else if (pc[1] == 0x201f015f) /* lda $0,NR_rt_sigreturn */ + { + struct rt_sigframe + { + siginfo_t info; + ucontext_t uc; + } *rt_ = context->cfa; + /* The void * cast is necessary to avoid an aliasing warning. + The aliasing warning is correct, but should not be a problem + because it does not alias anything. */ + sc = (struct sigcontext *) (void *) &rt_->uc.uc_mcontext; + } + else + return _URC_END_OF_STACK; + + new_cfa = sc->sc_regs[30]; + fs->regs.cfa_how = CFA_REG_OFFSET; + fs->regs.cfa_reg = 30; + fs->regs.cfa_offset = new_cfa - (long) context->cfa; + for (i = 0; i < 30; ++i) + { + fs->regs.reg[i].how = REG_SAVED_OFFSET; + fs->regs.reg[i].loc.offset = (long) &sc->sc_regs[i] - new_cfa; + } + for (i = 0; i < 31; ++i) + { + fs->regs.reg[i + 32].how = REG_SAVED_OFFSET; + fs->regs.reg[i + 32].loc.offset = (long) &sc->sc_fpregs[i] - new_cfa; + } + fs->regs.reg[64].how = REG_SAVED_OFFSET; + fs->regs.reg[64].loc.offset = (long) &sc->sc_pc - new_cfa; + fs->retaddr_column = 64; + fs->signal_frame = 1; + + return _URC_NO_REASON; +} + +#define MD_FROB_UPDATE_CONTEXT sw_64_frob_update_context + +/* Fix up for signal handlers that don't have S flag set. */ + +static void +sw_64_frob_update_context (struct _Unwind_Context *context, + _Unwind_FrameState *fs ATTRIBUTE_UNUSED) +{ + unsigned int *pc = context->ra; + + if (pc[0] == 0x47fe0410 /* mov $30,$16 */ + && pc[2] == 0x00000083 /* callsys */ + && (pc[1] == 0x201f0067 /* lda $0,NR_sigreturn */ + || pc[1] == 0x201f015f)) /* lda $0,NR_rt_sigreturn */ + _Unwind_SetSignalFrame (context, 1); +} +#endif diff --git a/libgcc/config/sw_64/qrnnd.S b/libgcc/config/sw_64/qrnnd.S new file mode 100644 index 000000000..ab2e3d0bc --- /dev/null +++ b/libgcc/config/sw_64/qrnnd.S @@ -0,0 +1,181 @@ + # Sw_64 __udiv_qrnnd + # Copyright (C) 1992-2022 Free Software Foundation, Inc. + + # This file is part of GCC. + + # The GNU MP Library 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 of the License, 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 Library 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 __ELF__ +.section .note.GNU-stack,"" +#endif + + .set noreorder + .set noat + + .text + + .globl __udiv_qrnnd + .ent __udiv_qrnnd +#ifdef __VMS__ +__udiv_qrnnd..en: + .frame $29,0,$26,0 + .prologue +#else +__udiv_qrnnd: + .frame $30,0,$26,0 + .prologue 0 +#endif +/* + ldiq -> ldi + addq->addl + subq->subl + cmovne qb,tmp,n1->selne qb,tmp,n1,n1 + stq ->stl + cmoveq tmp,AT,n1(n0)->seleq tmp,AT,n1,n1(n0,n0) */ +#define cnt $2 +#define tmp $3 +#define rem_ptr $16 +#define n1 $17 +#define n0 $18 +#define d $19 +#define qb $20 +#define AT $at + + ldi cnt,16 + blt d,$largedivisor + +$loop1: cmplt n0,0,tmp + addl n1,n1,n1 + bis n1,tmp,n1 + addl n0,n0,n0 + cmpule d,n1,qb + subl n1,d,tmp + selne qb,tmp,n1,n1 + bis n0,qb,n0 + cmplt n0,0,tmp + addl n1,n1,n1 + bis n1,tmp,n1 + addl n0,n0,n0 + cmpule d,n1,qb + subl n1,d,tmp + selne qb,tmp,n1,n1 + bis n0,qb,n0 + cmplt n0,0,tmp + addl n1,n1,n1 + bis n1,tmp,n1 + addl n0,n0,n0 + cmpule d,n1,qb + subl n1,d,tmp + selne qb,tmp,n1,n1 + bis n0,qb,n0 + cmplt n0,0,tmp + addl n1,n1,n1 + bis n1,tmp,n1 + addl n0,n0,n0 + cmpule d,n1,qb + subl n1,d,tmp + selne qb,tmp,n1,n1 + bis n0,qb,n0 + subl cnt,1,cnt + bgt cnt,$loop1 + stl n1,0(rem_ptr) + bis $31,n0,$0 + ret $31,($26),1 + +$largedivisor: + and n0,1,$4 + + srl n0,1,n0 + sll n1,63,tmp + or tmp,n0,n0 + srl n1,1,n1 + + and d,1,$6 + srl d,1,$5 + addl $5,$6,$5 + +$loop2: cmplt n0,0,tmp + addl n1,n1,n1 + bis n1,tmp,n1 + addl n0,n0,n0 + cmpule $5,n1,qb + subl n1,$5,tmp + selne qb,tmp,n1,n1 + bis n0,qb,n0 + cmplt n0,0,tmp + addl n1,n1,n1 + bis n1,tmp,n1 + addl n0,n0,n0 + cmpule $5,n1,qb + subl n1,$5,tmp + selne qb,tmp,n1,n1 + bis n0,qb,n0 + cmplt n0,0,tmp + addl n1,n1,n1 + bis n1,tmp,n1 + addl n0,n0,n0 + cmpule $5,n1,qb + subl n1,$5,tmp + selne qb,tmp,n1,n1 + bis n0,qb,n0 + cmplt n0,0,tmp + addl n1,n1,n1 + bis n1,tmp,n1 + addl n0,n0,n0 + cmpule $5,n1,qb + subl n1,$5,tmp + selne qb,tmp,n1,n1 + bis n0,qb,n0 + subl cnt,1,cnt + bgt cnt,$loop2 + + addl n1,n1,n1 + addl $4,n1,n1 + bne $6,$Odd + stl n1,0(rem_ptr) + bis $31,n0,$0 + ret $31,($26),1 + +$Odd: + /* q' in n0. r' in n1 */ + addl n1,n0,n1 + + cmpult n1,n0,tmp # tmp := carry from addl + subl n1,d,AT + addl n0,tmp,n0 + selne tmp,AT,n1,n1 + + cmpult n1,d,tmp + addl n0,1,AT + seleq tmp,AT,n0,n0 + subl n1,d,AT + seleq tmp,AT,n1,n1 + + stl n1,0(rem_ptr) + bis $31,n0,$0 + ret $31,($26),1 + +#ifdef __VMS__ + .link + .align 3 +__udiv_qrnnd: + .pdesc __udiv_qrnnd..en,null +#endif + .end __udiv_qrnnd diff --git a/libgcc/config/sw_64/t-ieee b/libgcc/config/sw_64/t-ieee new file mode 100644 index 000000000..9b66e50ac --- /dev/null +++ b/libgcc/config/sw_64/t-ieee @@ -0,0 +1,2 @@ +# All sw_64s get an IEEE complaint set of libraries. +#HOST_LIBGCC2_CFLAGS += -mieee diff --git a/libgcc/config/sw_64/t-linux b/libgcc/config/sw_64/t-linux new file mode 100644 index 000000000..fe9d20e9a --- /dev/null +++ b/libgcc/config/sw_64/t-linux @@ -0,0 +1 @@ +SHLIB_MAPFILES += $(srcdir)/config/sw_64/libgcc-sw_64-ldbl.ver diff --git a/libgcc/config/sw_64/t-sw_64 b/libgcc/config/sw_64/t-sw_64 new file mode 100644 index 000000000..dffba8ee7 --- /dev/null +++ b/libgcc/config/sw_64/t-sw_64 @@ -0,0 +1,6 @@ +# This is a support routine for longlong.h, used by libgcc2.c. +LIB2ADD += $(srcdir)/config/sw_64/qrnnd.S + +# When GAS-generated unwind tables are created, they get created +# after the __FRAME_END__ terminator, which causes an ld error. +CRTSTUFF_T_CFLAGS = -fno-unwind-tables diff --git a/libgcc/libgcc2.c b/libgcc/libgcc2.c index 3ebfcc83f..f01a150c4 100644 --- a/libgcc/libgcc2.c +++ b/libgcc/libgcc2.c @@ -2280,7 +2280,7 @@ int mprotect (char *,int, int); int getpagesize (void) { -#ifdef _ALPHA_ +#ifdef _ALPHA_ || defined _SW_64_ return 8192; #else return 4096; -- 2.25.1