diff options
Diffstat (limited to 'sysdeps/hppa')
54 files changed, 4305 insertions, 0 deletions
diff --git a/sysdeps/hppa/Dist b/sysdeps/hppa/Dist new file mode 100644 index 0000000..5a0df47 --- /dev/null +++ b/sysdeps/hppa/Dist @@ -0,0 +1,5 @@ +libgcc-compat.c +dl-symaddr.c +dl-fptr.c +bits/link.h +elf/entry.h diff --git a/sysdeps/hppa/Makefile b/sysdeps/hppa/Makefile new file mode 100644 index 0000000..7394703 --- /dev/null +++ b/sysdeps/hppa/Makefile @@ -0,0 +1,41 @@ +# Copyright (C) 2000, 2001 Free Software Foundation, Inc. +# This file is part of the GNU C Library. +# Contributed by David Huggins-Daines (dhd@debian.org) + +# 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. + +# 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, write to the Free +# Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +# 02111-1307 USA. + +# We used to need this since the build process uses ld -r. Now we use +# ld -r --unique=.text* which does more or less the same thing, but better. +# CFLAGS-.os += -ffunction-sections +LDFLAGS-c_pic.os += -Wl,--unique=.text* + +ifeq ($(subdir),elf) +CFLAGS-rtld.c += -mdisable-fpregs +sysdep-dl-routines += dl-symaddr dl-fptr +sysdep_routines += $(sysdep-dl-routines) +sysdep-rtld-routines += $(sysdep-dl-routines) +endif + +ifeq ($(subdir),csu) +ifeq (yes,$(build-shared)) +# Compatibility +ifeq (yes,$(have-protected)) +CPPFLAGS-libgcc-compat.c = -DHAVE_DOT_HIDDEN +endif +sysdep_routines += libgcc-compat +shared-only-routines += libgcc-compat +endif +endif diff --git a/sysdeps/hppa/Versions b/sysdeps/hppa/Versions new file mode 100644 index 0000000..2ae3cbd --- /dev/null +++ b/sysdeps/hppa/Versions @@ -0,0 +1,12 @@ +ld { + GLIBC_PRIVATE { + # hppa specific functions in the dynamic linker, but used by libc.so. + _dl_symbol_address; _dl_unmap; _dl_lookup_address; + _dl_function_address; + } +} +libc { + GLIBC_2.2 { + __clz_tab; + } +} diff --git a/sysdeps/hppa/__longjmp.S b/sysdeps/hppa/__longjmp.S new file mode 100644 index 0000000..dee4d9f --- /dev/null +++ b/sysdeps/hppa/__longjmp.S @@ -0,0 +1,72 @@ +/* longjmp for PA-RISC. + Copyright (C) 1997, 1998 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. + + 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <sysdep.h> +#define _SETJMP_H +#define _ASM +#include <bits/setjmp.h> + +/* __longjmp(jmpbuf, val) */ + + .text + .align 4 + .globl __longjmp + .export __longjmp, code + .proc + .callinfo +__longjmp: + /* set return value */ + copy %r25, %r28 + + ldw 0(%r26), %r3 + ldw 8(%r26), %r4 + ldw 12(%r26), %r5 + ldw 16(%r26), %r6 + ldw 20(%r26), %r7 + ldw 24(%r26), %r8 + ldw 28(%r26), %r9 + ldw 32(%r26), %r10 + ldw 36(%r26), %r11 + ldw 40(%r26), %r12 + ldw 44(%r26), %r13 + ldw 48(%r26), %r14 + ldw 52(%r26), %r15 + ldw 56(%r26), %r16 + ldw 60(%r26), %r17 + ldw 64(%r26), %r18 + ldw 68(%r26), %r19 + ldw 72(%r26), %r27 + ldw 76(%r26), %r30 + + ldw 80(%r26), %rp + + ldo 88(%r26),%r20 + fldds,ma 8(%r20), %fr12 + fldds,ma 8(%r20), %fr13 + fldds,ma 8(%r20), %fr14 + fldds,ma 8(%r20), %fr15 + fldds,ma 8(%r20), %fr16 + fldds,ma 8(%r20), %fr17 + fldds,ma 8(%r20), %fr18 + fldds,ma 8(%r20), %fr19 + fldds,ma 8(%r20), %fr20 + fldds 0(%r20), %fr21 + + bv,n %r0(%r2) + .procend diff --git a/sysdeps/hppa/abort-instr.h b/sysdeps/hppa/abort-instr.h new file mode 100644 index 0000000..f1afea4 --- /dev/null +++ b/sysdeps/hppa/abort-instr.h @@ -0,0 +1,6 @@ +/* An instruction privileged instruction to crash a userspace program. + + We go with iitlbp because it has a history of being used to crash + programs. */ + +#define ABORT_INSTRUCTION asm ("iitlbp %r0,(%r0)") diff --git a/sysdeps/hppa/add_n.s b/sysdeps/hppa/add_n.s new file mode 100644 index 0000000..aaabd72 --- /dev/null +++ b/sysdeps/hppa/add_n.s @@ -0,0 +1,58 @@ +;! HP-PA __mpn_add_n -- Add two limb vectors of the same length > 0 and store +;! sum in a third limb vector. + +;! Copyright (C) 1992, 1994 Free Software Foundation, Inc. + +;! This file is part of the GNU MP Library. + +;! The GNU MP 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. + +;! The GNU MP 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 MP Library; see the file COPYING.LIB. If not, write to +;! the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, +;! MA 02111-1307, USA. + + +;! INPUT PARAMETERS +;! res_ptr gr26 +;! s1_ptr gr25 +;! s2_ptr gr24 +;! size gr23 + +;! One might want to unroll this as for other processors, but it turns +;! out that the data cache contention after a store makes such +;! unrolling useless. We can't come under 5 cycles/limb anyway. + + .text + .export __mpn_add_n +__mpn_add_n: + .proc + .callinfo frame=0,no_calls + .entry + + ldws,ma 4(0,%r25),%r21 + ldws,ma 4(0,%r24),%r20 + + addib,= -1,%r23,L$end ;! check for (SIZE == 1) + add %r21,%r20,%r28 ;! add first limbs ignoring cy + +L$loop: ldws,ma 4(0,%r25),%r21 + ldws,ma 4(0,%r24),%r20 + stws,ma %r28,4(0,%r26) + addib,<> -1,%r23,L$loop + addc %r21,%r20,%r28 + +L$end: stws %r28,0(0,%r26) + bv 0(%r2) + addc %r0,%r0,%r28 + + .exit + .procend diff --git a/sysdeps/hppa/bits/endian.h b/sysdeps/hppa/bits/endian.h new file mode 100644 index 0000000..585db0c --- /dev/null +++ b/sysdeps/hppa/bits/endian.h @@ -0,0 +1,7 @@ +/* hppa1.1 big-endian. */ + +#ifndef _ENDIAN_H +# error "Never use <bits/endian.h> directly; include <endian.h> instead." +#endif + +#define __BYTE_ORDER __BIG_ENDIAN diff --git a/sysdeps/hppa/bits/link.h b/sysdeps/hppa/bits/link.h new file mode 100644 index 0000000..54842b2 --- /dev/null +++ b/sysdeps/hppa/bits/link.h @@ -0,0 +1,6 @@ +/* Used to store the function descriptor table */ +struct link_map_machine + { + size_t fptr_table_len; + ElfW(Addr) *fptr_table; + }; diff --git a/sysdeps/hppa/bits/setjmp.h b/sysdeps/hppa/bits/setjmp.h new file mode 100644 index 0000000..7fb2af7 --- /dev/null +++ b/sysdeps/hppa/bits/setjmp.h @@ -0,0 +1,41 @@ +/* Copyright (C) 2000 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. + + 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +/* Define the machine-dependent type `jmp_buf'. HPPA version. */ + +#ifndef _SETJMP_H +# error "Never include <bits/setjmp.h> directly; use <setjmp.h> instead." +#endif + +/* The previous bits/setjmp.h had __jmp_buf defined as a structure. + We use an array of 'double' instead, to make writing the assembler + easier, and to ensure proper alignment. Naturally, user code should + not depend on either representation. */ + +#if defined __USE_MISC || defined _ASM +#define JB_SP (76/4) +#endif + +#ifndef _ASM +typedef double __jmp_buf[21]; +#endif + +/* Test if longjmp to JMPBUF would unwind the frame containing a local + variable at ADDRESS. */ +#define _JMPBUF_UNWINDS(_jmpbuf, _address) \ + ((void *)(_address) > (void *)(((unsigned long *) _jmpbuf)[JB_SP])) diff --git a/sysdeps/hppa/bsd-_setjmp.S b/sysdeps/hppa/bsd-_setjmp.S new file mode 100644 index 0000000..e5ec94c --- /dev/null +++ b/sysdeps/hppa/bsd-_setjmp.S @@ -0,0 +1,39 @@ +/* BSD `_setjmp' entry point to `sigsetjmp (..., 0)'. HPPA version. + Copyright (C) 2001, 2002 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. + + 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <sysdep.h> + +/* This just does a tail-call to `__sigsetjmp (ARG, 1)'. + We cannot do it in C because it must be a tail-call, so frame-unwinding + in setjmp doesn't clobber the state restored by longjmp. */ + + .text + .align 4 + .globl _setjmp + .export _setjmp, code + .level 2.0 + .proc + .callinfo + .import __sigsetjmp +_setjmp: + b __sigsetjmp + ldi 0, %r25 + + .procend +libc_hidden_def (_setjmp) diff --git a/sysdeps/hppa/bsd-setjmp.S b/sysdeps/hppa/bsd-setjmp.S new file mode 100644 index 0000000..04ddba4 --- /dev/null +++ b/sysdeps/hppa/bsd-setjmp.S @@ -0,0 +1,36 @@ +/* BSD `setjmp' entry point to `sigsetjmp (..., 1)'. HPPA version. + Copyright (C) 2001 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. + + 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +/* This just does a tail-call to `__sigsetjmp (ARG, 1)'. + We cannot do it in C because it must be a tail-call, so frame-unwinding + in setjmp doesn't clobber the state restored by longjmp. */ + + .text + .align 4 + .globl setjmp + .export setjmp, code + .level 2.0 + .proc + .callinfo + .import __sigsetjmp +setjmp: + b __sigsetjmp + ldi 1, %r25 + + .procend diff --git a/sysdeps/hppa/configure b/sysdeps/hppa/configure new file mode 100755 index 0000000..07bde0e --- /dev/null +++ b/sysdeps/hppa/configure @@ -0,0 +1,34 @@ +# This file is generated from configure.in by Autoconf. DO NOT EDIT! + +hppa*linux*) +echo "$as_me:$LINENO: checking for assembler line separator" >&5 +echo $ECHO_N "checking for assembler line separator... $ECHO_C" >&6 +if test "${libc_cv_asm_line_sep+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat > conftest.s <<EOF +nop ; is_old_puffin +EOF +if { ac_try='${CC-cc} -c $ASFLAGS conftest.s 1>&5' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + libc_cv_asm_line_sep='!' +else + if test -z "$enable_hacker_mode"; then + echo "*** You need a newer assembler to compile glibc" + rm -f conftest* + exit 1 + fi + libc_cv_asm_line_sep=';' +fi +rm -f conftest* +fi +echo "$as_me:$LINENO: result: $libc_cv_asm_line_sep" >&5 +echo "${ECHO_T}$libc_cv_asm_line_sep" >&6 +cat >>confdefs.h <<_ACEOF +#define ASM_LINE_SEP $libc_cv_asm_line_sep +_ACEOF + diff --git a/sysdeps/hppa/configure.in b/sysdeps/hppa/configure.in new file mode 100644 index 0000000..1ec6780 --- /dev/null +++ b/sysdeps/hppa/configure.in @@ -0,0 +1,22 @@ +GLIBC_PROVIDES dnl See aclocal.m4 in the top level source directory. + +dnl The standard hppa assembler uses `;' to start comments and `!' +dnl as a line separator. +hppa*linux*) +AC_CACHE_CHECK(for assembler line separator, + libc_cv_asm_line_sep, [dnl +cat > conftest.s <<EOF +nop ; is_old_puffin +EOF +if AC_TRY_COMMAND(${CC-cc} -c $ASFLAGS conftest.s 1>&AS_MESSAGE_LOG_FD); then + libc_cv_asm_line_sep='!' +else + if test -z "$enable_hacker_mode"; then + echo "*** You need a newer assembler to compile glibc" + rm -f conftest* + exit 1 + fi + libc_cv_asm_line_sep=';' +fi +rm -f conftest*]) +AC_DEFINE_UNQUOTED(ASM_LINE_SEP, $libc_cv_asm_line_sep) diff --git a/sysdeps/hppa/dl-fptr.h b/sysdeps/hppa/dl-fptr.h new file mode 100644 index 0000000..2ac9740 --- /dev/null +++ b/sysdeps/hppa/dl-fptr.h @@ -0,0 +1,35 @@ +/* Function descriptors. HPPA version. + Copyright (C) 2003 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. + + 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#ifndef dl_hppa_fptr_h +#define dl_hppa_fptr_h 1 + +#include <sysdeps/generic/dl-fptr.h> + +/* There are currently 20 dynamic symbols in ld.so. + ELF_MACHINE_BOOT_FPTR_TABLE_LEN needs to be at least that big. */ +#define ELF_MACHINE_BOOT_FPTR_TABLE_LEN 200 + +#define ELF_MACHINE_LOAD_ADDRESS(var, symbol) \ + asm (" addil LT%%" #symbol ", %%r19\n" \ + " ldw RT%%" #symbol "(%%sr0,%%r1), %0\n" \ + : "=&r" (var)); + + +#endif /* !dl_hppa_fptr_h */ diff --git a/sysdeps/hppa/dl-lookupcfg.h b/sysdeps/hppa/dl-lookupcfg.h new file mode 100644 index 0000000..d393b3e --- /dev/null +++ b/sysdeps/hppa/dl-lookupcfg.h @@ -0,0 +1,69 @@ +/* Configuration of lookup functions. + Copyright (C) 2000 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. + + 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +/* Like IA-64, PA-RISC needs more information from the symbol lookup + function than just the address. */ +#define DL_LOOKUP_RETURNS_MAP +#define ELF_FUNCTION_PTR_IS_SPECIAL +#define DL_UNMAP_IS_SPECIAL + +/* Forward declaration. */ +struct link_map; + +void *_dl_symbol_address (struct link_map *map, const ElfW(Sym) *ref); + +#define DL_SYMBOL_ADDRESS(map, ref) _dl_symbol_address(map, ref) + +Elf32_Addr _dl_lookup_address (const void *address); + +/* Clear the bottom two bits so generic code can find the fdesc entry */ +#define DL_LOOKUP_ADDRESS(addr) \ + (_dl_lookup_address ((void *)((unsigned long)addr & ~3))) + +void _dl_unmap (struct link_map *map); + +#define DL_UNMAP(map) _dl_unmap (map) + +#define DL_AUTO_FUNCTION_ADDRESS(map, addr) \ +({ \ + unsigned int fptr[2]; \ + fptr[0] = (unsigned int) (addr); \ + fptr[1] = (map)->l_info[DT_PLTGOT]->d_un.d_ptr; \ + /* Set bit 30 to indicate to $$dyncall that this is a PLABEL. */ \ + (ElfW(Addr))((unsigned int)fptr | 2); \ +}) + +#define DL_STATIC_FUNCTION_ADDRESS(map, addr) \ +({ \ + static unsigned int fptr[2]; \ + fptr[0] = (unsigned int) (addr); \ + fptr[1] = (map)->l_info[DT_PLTGOT]->d_un.d_ptr; \ + /* Set bit 30 to indicate to $$dyncall that this is a PLABEL. */ \ + (ElfW(Addr))((unsigned int)fptr | 2); \ +}) + + +/* The test for "addr & 2" below is to accomodate old binaries which + violated the ELF ABI by pointing DT_INIT and DT_FINI at a function + descriptor. */ +#define DL_DT_INIT_ADDRESS(map, addr) \ + ((Elf32_Addr)(addr) & 2 ? (addr) : DL_AUTO_FUNCTION_ADDRESS (map, addr)) +#define DL_DT_FINI_ADDRESS(map, addr) \ + ((Elf32_Addr)(addr) & 2 ? (addr) : DL_AUTO_FUNCTION_ADDRESS (map, addr)) + diff --git a/sysdeps/hppa/dl-machine.h b/sysdeps/hppa/dl-machine.h new file mode 100644 index 0000000..d29501d --- /dev/null +++ b/sysdeps/hppa/dl-machine.h @@ -0,0 +1,762 @@ +/* Machine-dependent ELF dynamic relocation inline functions. PA-RISC version. + Copyright (C) 1995-1997,1999-2003 + Free Software Foundation, Inc. + Contributed by David Huggins-Daines <dhd@debian.org> + 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. + + 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#ifndef dl_machine_h +#define dl_machine_h 1 + +#define ELF_MACHINE_NAME "hppa" + +#include <sys/param.h> +#include <assert.h> +#include <string.h> +#include <link.h> +#include <errno.h> +#include <dl-fptr.h> +#include <abort-instr.h> + +# define VALID_ELF_OSABI(osabi) ((osabi == ELFOSABI_SYSV) || (osabi == ELFOSABI_LINUX)) +# define VALID_ELF_ABIVERSION(ver) (ver == 0) +# define VALID_ELF_HEADER(hdr,exp,size) \ + memcmp (hdr,exp,size-2) == 0 \ + && VALID_ELF_OSABI (hdr[EI_OSABI]) \ + && VALID_ELF_ABIVERSION (hdr[EI_ABIVERSION]) + +/* These two definitions must match the definition of the stub in + bfd/elf32-hppa.c (see plt_stub[]). + + a. Define the size of the *entire* stub we place at the end of the PLT + table (right up against the GOT). + + b. Define the number of bytes back from the GOT to the entry point of + the PLT stub. You see the PLT stub must be entered in the middle + so it can depwi to find it's own address (long jump stub) + + c. Define the size of a single PLT entry so we can jump over the + last entry to get the stub address */ + +#define SIZEOF_PLT_STUB (7*4) +#define GOT_FROM_PLT_STUB (4*4) +#define PLT_ENTRY_SIZE (2*4) + +/* Initialize the function descriptor table before relocations */ +static inline void +__hppa_init_bootstrap_fdesc_table (struct link_map *map) +{ + ElfW(Addr) *boot_table; + + /* Careful: this will be called before got has been relocated... */ + ELF_MACHINE_LOAD_ADDRESS(boot_table,_dl_boot_fptr_table); + + map->l_mach.fptr_table_len = ELF_MACHINE_BOOT_FPTR_TABLE_LEN; + map->l_mach.fptr_table = boot_table; +} + +#define ELF_MACHINE_BEFORE_RTLD_RELOC(dynamic_info) \ + __hppa_init_bootstrap_fdesc_table (&bootstrap_map); + +/* Return nonzero iff ELF header is compatible with the running host. */ +static inline int +elf_machine_matches_host (const Elf32_Ehdr *ehdr) +{ + return ehdr->e_machine == EM_PARISC; +} + +/* Return the link-time address of _DYNAMIC. */ +static inline Elf32_Addr +elf_machine_dynamic (void) __attribute__ ((const)); + +static inline Elf32_Addr +elf_machine_dynamic (void) +{ + Elf32_Addr dynamic; + + asm ("b,l 1f,%0\n" +" depi 0,31,2,%0\n" +"1: addil L'_GLOBAL_OFFSET_TABLE_ - ($PIC_pcrel$0 - 8),%0\n" +" ldw R'_GLOBAL_OFFSET_TABLE_ - ($PIC_pcrel$0 - 12)(%%r1),%0\n" + : "=r" (dynamic) : : "r1"); + + return dynamic; +} + +/* Return the run-time load address of the shared object. */ +static inline Elf32_Addr +elf_machine_load_address (void) __attribute__ ((const)); + +static inline Elf32_Addr +elf_machine_load_address (void) +{ + Elf32_Addr dynamic; + + asm ( +" b,l 1f,%0\n" +" depi 0,31,2,%0\n" +"1: addil L'_DYNAMIC - ($PIC_pcrel$0 - 8),%0\n" +" ldo R'_DYNAMIC - ($PIC_pcrel$0 - 12)(%%r1),%0\n" + : "=r" (dynamic) : : "r1"); + + return dynamic - elf_machine_dynamic (); +} + +/* Fixup a PLT entry to bounce directly to the function at VALUE. + Optimized non-profile version. */ +static inline Elf32_Addr +elf_machine_fixup_plt (struct link_map *map, lookup_t t, + const Elf32_Rela *reloc, + Elf32_Addr *reloc_addr, Elf32_Addr value) +{ + /* map is the link_map for the caller, t is the link_map for the object + being called */ + reloc_addr[1] = D_PTR (t, l_info[DT_PLTGOT]); + reloc_addr[0] = value; + /* Return the PLT slot rather than the function value so that the + trampoline can load the new LTP. */ + return (Elf32_Addr) reloc_addr; +} + +/* Fixup a PLT entry to bounce directly to the function at VALUE. */ +#define ELF_MACHINE_PROFILE_FIXUP_PLT elf_machine_profile_fixup_plt +static inline Elf32_Addr +elf_machine_profile_fixup_plt (struct link_map *map, lookup_t t, + const Elf32_Rela *reloc, + Elf32_Addr *reloc_addr, Elf32_Addr value) +{ + if(__builtin_expect (t == NULL, 1)) + return (Elf32_Addr) reloc_addr; + /* Return the PLT slot rather than the function value so that the + trampoline can load the new LTP. */ + return (Elf32_Addr) elf_machine_fixup_plt(map, t, reloc, reloc_addr, value); +} + +/* Return the final value of a plt relocation. */ +static inline Elf32_Addr +elf_machine_plt_value (struct link_map *map, const Elf32_Rela *reloc, + Elf32_Addr value) +{ + /* We are rela only */ + return value + reloc->r_addend; +} + +/* Set up the loaded object described by L so its unrelocated PLT + entries will jump to the on-demand fixup code in dl-runtime.c. */ + +static inline int +elf_machine_runtime_setup (struct link_map *l, int lazy, int profile) +{ + Elf32_Addr *got = NULL; + Elf32_Addr l_addr, iplt, jmprel, end_jmprel, r_type, r_sym; + const Elf32_Rela *reloc; + struct fdesc *fptr; + static union { + unsigned char c[8]; + Elf32_Addr i[2]; + } sig = {{0x00,0xc0,0xff,0xee, 0xde,0xad,0xbe,0xef}}; + + /* If we don't have a PLT we can just skip all this... */ + if (__builtin_expect (l->l_info[DT_JMPREL] == NULL,0)) + return lazy; + + /* All paths use these values */ + l_addr = l->l_addr; + jmprel = D_PTR(l, l_info[DT_JMPREL]); + end_jmprel = jmprel + l->l_info[DT_PLTRELSZ]->d_un.d_val; + + extern void _dl_runtime_resolve (void); + extern void _dl_runtime_profile (void); + + /* Linking lazily */ + if (lazy) + { + /* FIXME: Search for the got, but backwards through the relocs, technically we should + find it on the first try. However, assuming the relocs got out of order the + routine is made a bit more robust by searching them all in case of failure. */ + for (iplt = (end_jmprel - sizeof(Elf32_Rela)); iplt >= jmprel; iplt -= sizeof (Elf32_Rela)) + { + + reloc = (const Elf32_Rela *) iplt; + r_type = ELF32_R_TYPE (reloc->r_info); + r_sym = ELF32_R_SYM (reloc->r_info); + + got = (Elf32_Addr *) (reloc->r_offset + l_addr + PLT_ENTRY_SIZE + SIZEOF_PLT_STUB); + + /* If we aren't an IPLT, and we aren't NONE then it's a bad reloc */ + if (__builtin_expect (r_type != R_PARISC_IPLT, 0)) + { + if (__builtin_expect (r_type != R_PARISC_NONE, 0)) + _dl_reloc_bad_type (l, r_type, 1); + continue; + } + + /* Check for the plt_stub that binutils placed here for us + to use with _dl_runtime_resolve */ + if (got[-2] != sig.i[0] || got[-1] != sig.i[1]) + { + got = NULL; /* Not the stub... keep looking */ + } + else + { + /* Found the GOT! */ + register Elf32_Addr ltp __asm__ ("%r19"); + /* Identify this shared object. */ + got[1] = (Elf32_Addr) l; + + /* This function will be called to perform the relocation. */ + if (__builtin_expect (!profile, 1)) + { + /* If a static application called us, then _dl_runtime_resolve is not + a function descriptor, but the *real* address of the function... */ + if((unsigned long) &_dl_runtime_resolve & 3) + { + got[-2] = (Elf32_Addr) ((struct fdesc *) + ((unsigned long) &_dl_runtime_resolve & ~3))->ip; + } + else + { + /* Static executable! */ + got[-2] = (Elf32_Addr) &_dl_runtime_resolve; + } + } + else + { + if (_dl_name_match_p (GLRO(dl_profile), l)) + { + /* This is the object we are looking for. Say that + we really want profiling and the timers are + started. */ + GL(dl_profile_map) = l; + } + + if((unsigned long) &_dl_runtime_resolve & 3) + { + got[-2] = (Elf32_Addr) ((struct fdesc *) + ((unsigned long) &_dl_runtime_profile & ~3))->ip; + } + else + { + /* Static executable */ + got[-2] = (Elf32_Addr) &_dl_runtime_profile; + } + } + /* Plunk in the gp of this function descriptor so we + can make the call to _dl_runtime_xxxxxx */ + got[-1] = ltp; + break; + /* Done looking for the GOT, and stub is setup */ + } /* else we found the GOT */ + } /* for, walk the relocs backwards */ + + if(!got) + return 0; /* No lazy linking for you! */ + + /* Process all the relocs, now that we know the GOT... */ + for (iplt = jmprel; iplt < end_jmprel; iplt += sizeof (Elf32_Rela)) + { + reloc = (const Elf32_Rela *) iplt; + r_type = ELF32_R_TYPE (reloc->r_info); + r_sym = ELF32_R_SYM (reloc->r_info); + + if (__builtin_expect (r_type == R_PARISC_IPLT, 1)) + { + fptr = (struct fdesc *) (reloc->r_offset + l_addr); + if (r_sym != 0) + { + /* Relocate the pointer to the stub. */ + fptr->ip = (Elf32_Addr) got - GOT_FROM_PLT_STUB; + + /* Instead of the LTP value, we put the reloc offset + here. The trampoline code will load the proper + LTP and pass the reloc offset to the fixup + function. */ + fptr->gp = iplt - jmprel; + } /* r_sym != 0 */ + else + { + /* Relocate this *ABS* entry. */ + fptr->ip = reloc->r_addend + l_addr; + fptr->gp = D_PTR (l, l_info[DT_PLTGOT]); + } + } /* r_type == R_PARISC_IPLT */ + } /* for all the relocations */ + } /* if lazy */ + else + { + for (iplt = jmprel; iplt < end_jmprel; iplt += sizeof (Elf32_Rela)) + { + reloc = (const Elf32_Rela *) iplt; + r_type = ELF32_R_TYPE (reloc->r_info); + r_sym = ELF32_R_SYM (reloc->r_info); + + if (__builtin_expect ((r_type == R_PARISC_IPLT) && (r_sym == 0), 1)) + { + fptr = (struct fdesc *) (reloc->r_offset + l_addr); + /* Relocate this *ABS* entry, set only the gp, the rest is set later + when elf_machine_rela_relative is called (WITHOUT the linkmap) */ + fptr->gp = D_PTR (l, l_info[DT_PLTGOT]); + } /* r_type == R_PARISC_IPLT */ + } /* for all the relocations */ + } + return lazy; +} + +/* Initial entry point code for the dynamic linker. + The C function `_dl_start' is the real entry point; + its return value is the user program's entry point. */ + +#define RTLD_START \ +/* Set up dp for any non-PIC lib constructors that may be called. */ \ +static struct link_map * __attribute__((used)) \ +set_dp (struct link_map *map) \ +{ \ + register Elf32_Addr dp asm ("%r27"); \ + dp = D_PTR (map, l_info[DT_PLTGOT]); \ + asm volatile ("" : : "r" (dp)); \ + return map; \ +} \ + \ +asm ( \ +" .text\n" \ +" .globl _start\n" \ +" .type _start,@function\n" \ +"_start:\n" \ + /* The kernel does not give us an initial stack frame. */ \ +" ldo 64(%sp),%sp\n" \ + /* Save the relevant arguments (yes, those are the correct \ + registers, the kernel is weird) in their stack slots. */ \ +" stw %r25,-40(%sp)\n" /* argc */ \ +" stw %r24,-44(%sp)\n" /* argv */ \ + \ + /* We need the LTP, and we need it now. \ + $PIC_pcrel$0 points 8 bytes past the current instruction, \ + just like a branch reloc. This sequence gets us the \ + runtime address of _DYNAMIC. */ \ +" bl 0f,%r19\n" \ +" depi 0,31,2,%r19\n" /* clear priviledge bits */ \ +"0: addil L'_DYNAMIC - ($PIC_pcrel$0 - 8),%r19\n" \ +" ldo R'_DYNAMIC - ($PIC_pcrel$0 - 12)(%r1),%r26\n" \ + \ + /* The link time address is stored in the first entry of the \ + GOT. */ \ +" addil L'_GLOBAL_OFFSET_TABLE_ - ($PIC_pcrel$0 - 16),%r19\n" \ +" ldw R'_GLOBAL_OFFSET_TABLE_ - ($PIC_pcrel$0 - 20)(%r1),%r20\n" \ + \ +" sub %r26,%r20,%r20\n" /* Calculate load offset */ \ + \ + /* Rummage through the dynamic entries, looking for \ + DT_PLTGOT. */ \ +" ldw,ma 8(%r26),%r19\n" \ +"1: cmpib,=,n 3,%r19,2f\n" /* tag == DT_PLTGOT? */ \ +" cmpib,<>,n 0,%r19,1b\n" \ +" ldw,ma 8(%r26),%r19\n" \ + \ + /* Uh oh! We didn't find one. Abort. */ \ +" iitlbp %r0,(%r0)\n" \ + \ +"2: ldw -4(%r26),%r19\n" /* Found it, load value. */ \ +" add %r19,%r20,%r19\n" /* And add the load offset. */ \ + \ + /* Our initial stack layout is rather different from everyone \ + else's due to the unique PA-RISC ABI. As far as I know it \ + looks like this: \ + \ + ----------------------------------- (this frame created above) \ + | 32 bytes of magic | \ + |---------------------------------| \ + | 32 bytes argument/sp save area | \ + |---------------------------------| ((current->mm->env_end) \ + | N bytes of slack | + 63 & ~63) \ + |---------------------------------| \ + | envvar and arg strings | \ + |---------------------------------| \ + | ELF auxiliary info | \ + | (up to 28 words) | \ + |---------------------------------| \ + | Environment variable pointers | \ + | upwards to NULL | \ + |---------------------------------| \ + | Argument pointers | \ + | upwards to NULL | \ + |---------------------------------| \ + | argc (1 word) | \ + ----------------------------------- \ + \ + So, obviously, we can't just pass %sp to _dl_start. That's \ + okay, argv-4 will do just fine. \ + \ + The pleasant part of this is that if we need to skip \ + arguments we can just decrement argc and move argv, because \ + the stack pointer is utterly unrelated to the location of \ + the environment and argument vectors. */ \ + \ + /* This is always within range so we'll be okay. */ \ +" bl _dl_start,%rp\n" \ +" ldo -4(%r24),%r26\n" \ + \ +" .globl _dl_start_user\n" \ +" .type _dl_start_user,@function\n" \ +"_dl_start_user:\n" \ + /* Save the entry point in %r3. */ \ +" copy %ret0,%r3\n" \ + \ + /* Remember the lowest stack address. */ \ +" addil LT'__libc_stack_end,%r19\n" \ +" ldw RT'__libc_stack_end(%r1),%r20\n" \ +" stw %sp,0(%r20)\n" \ + \ + /* See if we were called as a command with the executable file \ + name as an extra leading argument. */ \ +" addil LT'_dl_skip_args,%r19\n" \ +" ldw RT'_dl_skip_args(%r1),%r20\n" \ +" ldw 0(%r20),%r20\n" \ + \ +" ldw -40(%sp),%r25\n" /* argc */ \ +" comib,= 0,%r20,.Lnofix\n" /* FIXME: Mispredicted branch */\ +" ldw -44(%sp),%r24\n" /* argv (delay slot) */ \ + \ +" sub %r25,%r20,%r25\n" \ +" stw %r25,-40(%sp)\n" \ +" sh2add %r20,%r24,%r24\n" \ +" stw %r24,-44(%sp)\n" \ + \ +".Lnofix:\n" \ +" addil LT'_rtld_local,%r19\n" \ +" ldw RT'_rtld_local(%r1),%r26\n" \ +" bl set_dp, %r2\n" \ +" ldw 0(%r26),%r26\n" \ + \ + /* Call _dl_init(_dl_loaded, argc, argv, envp). */ \ +" copy %r28,%r26\n" \ + \ + /* envp = argv + argc + 1 */ \ +" sh2add %r25,%r24,%r23\n" \ +" bl _dl_init_internal,%r2\n" \ +" ldo 4(%r23),%r23\n" /* delay slot */ \ + \ + /* Reload argc, argv to the registers start.S expects. */ \ +" ldw -40(%sp),%r25\n" \ +" ldw -44(%sp),%r24\n" \ + \ + /* _dl_fini does have a PLT slot now. I don't know how to get \ + to it though, so this hack will remain. */ \ +" .section .data\n" \ +"__dl_fini_plabel:\n" \ +" .word _dl_fini\n" \ +" .word 0xdeadbeef\n" \ +" .previous\n" \ + \ + /* %r3 contains a function pointer, we need to mask out the \ + lower bits and load the gp and jump address. */ \ +" depi 0,31,2,%r3\n" \ +" ldw 0(%r3),%r2\n" \ +" addil LT'__dl_fini_plabel,%r19\n" \ +" ldw RT'__dl_fini_plabel(%r1),%r23\n" \ +" stw %r19,4(%r23)\n" \ +" ldw 4(%r3),%r19\n" /* load the object's gp */ \ +" bv %r0(%r2)\n" \ +" depi 2,31,2,%r23\n" /* delay slot */ \ + ); + + +/* This code gets called via the .plt stub, and is used in + dl-runtime.c to call the `fixup' function and then redirect to the + address it returns. + + WARNING: This template is also used by gcc's __cffc, and expects + that the "bl" for fixup() exist at a particular offset. + Do not change this template without changing gcc, while the prefix + "bl" should fix everything so gcc finds the right spot, it will + slow down __cffc when it attempts to call fixup to resolve function + descriptor references. Please refer to gcc/gcc/config/pa/fptr.c + + Enter with r19 = reloc offset, r20 = got-8, r21 = fixup ltp. */ +#define TRAMPOLINE_TEMPLATE(tramp_name, fixup_name) \ + extern void tramp_name (void); \ + asm ( \ + " .text\n" \ + /* FAKE bl to provide gcc's __cffc with fixup's address */ \ + " bl " #fixup_name ",%r2\n" /* Runtime address of fixup */ \ + " .globl " #tramp_name "\n" \ + " .type " #tramp_name ",@function\n" \ + #tramp_name ":\n" \ + " .proc\n" \ + " .callinfo frame=64,calls,save_rp\n" \ + " .entry\n" \ + /* Save return pointer */ \ + " stw %r2,-20(%sp)\n" \ + /* Save argument registers in the call stack frame. */ \ + " stw %r26,-36(%sp)\n" \ + " stw %r25,-40(%sp)\n" \ + " stw %r24,-44(%sp)\n" \ + " stw %r23,-48(%sp)\n" \ + /* Build a call frame, and save structure pointer. */ \ + " stwm %r28,64(%sp)\n" \ + \ + /* Set up args to fixup func. */ \ + " ldw 8+4(%r20),%r26\n" /* (1) got[1] == struct link_map */ \ + " copy %r19,%r25\n" /* (2) reloc offset */ \ + " copy %r2,%r24\n" /* (3) profile_fixup needs rp */ \ + \ + /* Call the real address resolver. */ \ + " bl " #fixup_name ",%r2\n" \ + " copy %r21,%r19\n" /* set fixup func ltp (DELAY SLOT)*/ \ + \ + " ldw 0(%r28),%r22\n" /* load up the returned func ptr */ \ + " ldw 4(%r28),%r19\n" \ + " ldwm -64(%sp),%r28\n" \ + /* Arguments. */ \ + " ldw -36(%sp),%r26\n" \ + " ldw -40(%sp),%r25\n" \ + " ldw -44(%sp),%r24\n" \ + " ldw -48(%sp),%r23\n" \ + /* Call the real function. */ \ + " bv %r0(%r22)\n" \ + /* Return pointer. */ \ + " ldw -20(%sp),%r2\n" \ + " .exit\n" \ + " .procend\n"); + +#ifndef PROF +#define ELF_MACHINE_RUNTIME_TRAMPOLINE \ + TRAMPOLINE_TEMPLATE (_dl_runtime_resolve, fixup); \ + TRAMPOLINE_TEMPLATE (_dl_runtime_profile, profile_fixup); +#else +#define ELF_MACHINE_RUNTIME_TRAMPOLINE \ + TRAMPOLINE_TEMPLATE (_dl_runtime_resolve, fixup); \ + strong_alias (_dl_runtime_resolve, _dl_runtime_profile); +#endif + +/* ELF_RTYPE_CLASS_PLT iff TYPE describes relocation of a PLT entry, so + PLT entries should not be allowed to define the value. + ELF_RTYPE_CLASS_NOCOPY iff TYPE should not be allowed to resolve to one + of the main executable's symbols, as for a COPY reloc. */ +#define elf_machine_type_class(type) \ + ((((type) == R_PARISC_IPLT || (type) == R_PARISC_EPLT) \ + * ELF_RTYPE_CLASS_PLT) \ + | (((type) == R_PARISC_COPY) * ELF_RTYPE_CLASS_COPY)) + +/* Used by the runtime in fixup to figure out if reloc is *really* PLT */ +#define ELF_MACHINE_JMP_SLOT R_PARISC_IPLT +#define ELF_MACHINE_SIZEOF_JMP_SLOT PLT_ENTRY_SIZE + +/* We only use RELA. */ +#define ELF_MACHINE_NO_REL 1 + +/* Return the address of the entry point. */ +#define ELF_MACHINE_START_ADDRESS(map, start) \ + DL_STATIC_FUNCTION_ADDRESS (map, start) + +/* We define an initialization functions. This is called very early in + * _dl_sysdep_start. */ +#define DL_PLATFORM_INIT dl_platform_init () + +static inline void __attribute__ ((unused)) +dl_platform_init (void) +{ + if (GLRO(dl_platform) != NULL && *GLRO(dl_platform) == '\0') + /* Avoid an empty string which would disturb us. */ + GLRO(dl_platform) = NULL; +} + +#endif /* !dl_machine_h */ + +/* These are only actually used where RESOLVE_MAP is defined, anyway. */ +#ifdef RESOLVE_MAP + +auto void __attribute__((always_inline)) +elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc, + const Elf32_Sym *sym, const struct r_found_version *version, + void *const reloc_addr_arg) +{ + Elf32_Addr *const reloc_addr = reloc_addr_arg; + const Elf32_Sym *const refsym = sym; + unsigned long const r_type = ELF32_R_TYPE (reloc->r_info); + struct link_map *sym_map; + Elf32_Addr value; + +# if !defined RTLD_BOOTSTRAP && !defined SHARED + /* This is defined in rtld.c, but nowhere in the static libc.a; make the + reference weak so static programs can still link. This declaration + cannot be done when compiling rtld.c (i.e. #ifdef RTLD_BOOTSTRAP) + because rtld.c contains the common defn for _dl_rtld_map, which is + incompatible with a weak decl in the same file. */ + weak_extern (GL(dl_rtld_map)); +# endif + + /* RESOLVE_MAP will return a null value for undefined syms, and + non-null for all other syms. In particular, relocs with no + symbol (symbol index of zero), also called *ABS* relocs, will be + resolved to MAP. (The first entry in a symbol table is all + zeros, and an all zero Elf32_Sym has a binding of STB_LOCAL.) + See RESOLVE_MAP definition in elf/dl-reloc.c */ +# ifdef RTLD_BOOTSTRAP + /* RESOLVE_MAP in rtld.c doesn't have the local sym test. */ + sym_map = (ELF32_ST_BIND (sym->st_info) != STB_LOCAL + ? RESOLVE_MAP (&sym, version, r_type) : map); +# else + sym_map = RESOLVE_MAP (&sym, version, r_type); +# endif + if (sym_map) + { + value = sym ? sym_map->l_addr + sym->st_value : 0; + value += reloc->r_addend; + } + else + value = 0; + + switch (r_type) + { + case R_PARISC_DIR32: + /* .eh_frame can have unaligned relocs. */ + if ((unsigned long) reloc_addr_arg & 3) + { + char *rel_addr = (char *) reloc_addr_arg; + rel_addr[0] = value >> 24; + rel_addr[1] = value >> 16; + rel_addr[2] = value >> 8; + rel_addr[3] = value; + return; + } + break; + + case R_PARISC_PLABEL32: + /* Easy rule: If there is a symbol and it is global, then we + need to make a dynamic function descriptor. Otherwise we + have the address of a PLT slot for a local symbol which we + know to be unique. */ + if (sym == NULL + || sym_map == NULL + || ELF32_ST_BIND (sym->st_info) == STB_LOCAL) + { + break; + } + /* Set bit 30 to indicate to $$dyncall that this is a PLABEL. + We have to do this outside of the generic function descriptor + code, since it doesn't know about our requirement for setting + protection bits */ + value = (Elf32_Addr)((unsigned int)_dl_make_fptr (sym_map, sym, value) | 2); + break; + + case R_PARISC_IPLT: + if (__builtin_expect (sym_map != NULL, 1)) + { + elf_machine_fixup_plt (NULL, sym_map, reloc, reloc_addr, value); + } + else + { + /* If we get here, it's a (weak) undefined sym. */ + elf_machine_fixup_plt (NULL, map, reloc, reloc_addr, value); + } + return; + + case R_PARISC_COPY: + if (__builtin_expect (sym == NULL, 0)) + /* This can happen in trace mode if an object could not be + found. */ + break; + if (__builtin_expect (sym->st_size > refsym->st_size, 0) + || (__builtin_expect (sym->st_size < refsym->st_size, 0) + && __builtin_expect (GLRO(dl_verbose), 0))) + { + const char *strtab; + + strtab = (const char *) D_PTR (map, l_info[DT_STRTAB]); + _dl_error_printf ("%s: Symbol `%s' has different size in shared object, " + "consider re-linking\n", + rtld_progname ?: "<program name unknown>", + strtab + refsym->st_name); + } + memcpy (reloc_addr_arg, (void *) value, + MIN (sym->st_size, refsym->st_size)); + return; + + case R_PARISC_NONE: /* Alright, Wilbur. */ + return; + + default: + _dl_reloc_bad_type (map, r_type, 0); + } + + *reloc_addr = value; +} + +/* hppa doesn't have an R_PARISC_RELATIVE reloc, but uses relocs with + ELF32_R_SYM (info) == 0 for a similar purpose. */ +auto void __attribute__((always_inline)) +elf_machine_rela_relative (Elf32_Addr l_addr, + const Elf32_Rela *reloc, + void *const reloc_addr_arg) +{ + unsigned long const r_type = ELF32_R_TYPE (reloc->r_info); + Elf32_Addr *const reloc_addr = reloc_addr_arg; + static char msgbuf[] = { "Unknown" }; + struct link_map map; + Elf32_Addr value; + + value = l_addr + reloc->r_addend; + + if (ELF32_R_SYM (reloc->r_info) != 0){ + _dl_error_printf ("%s: In elf_machine_rela_relative " + "ELF32_R_SYM (reloc->r_info) != 0. Aborting.", + rtld_progname ?: "<program name unknown>"); + ABORT_INSTRUCTION; /* Crash. */ + } + + switch (r_type) + { + case R_PARISC_DIR32: + /* .eh_frame can have unaligned relocs. */ + if ((unsigned long) reloc_addr_arg & 3) + { + char *rel_addr = (char *) reloc_addr_arg; + rel_addr[0] = value >> 24; + rel_addr[1] = value >> 16; + rel_addr[2] = value >> 8; + rel_addr[3] = value; + return; + } + break; + + case R_PARISC_PLABEL32: + break; + + case R_PARISC_IPLT: /* elf_machine_runtime_setup already set gp */ + break; + + case R_PARISC_NONE: + return; + + default: /* Bad reloc, map unknown (really it's the current map) */ + map.l_name = msgbuf; + _dl_reloc_bad_type (&map, r_type, 0); + return; + } + + *reloc_addr = value; +} + +auto void __attribute__((always_inline)) +elf_machine_lazy_rel (struct link_map *map, + Elf32_Addr l_addr, const Elf32_Rela *reloc) +{ + /* We don't have anything to do here. elf_machine_runtime_setup has + done all the relocs already. */ +} + +#endif /* RESOLVE_MAP */ diff --git a/sysdeps/hppa/dl-symaddr.c b/sysdeps/hppa/dl-symaddr.c new file mode 100644 index 0000000..e5ce6a9 --- /dev/null +++ b/sysdeps/hppa/dl-symaddr.c @@ -0,0 +1,36 @@ +/* Get the symbol address. HPPA version. + Copyright (C) 1999, 2000 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. + + 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <ldsodefs.h> +#include <dl-machine.h> + +void * +_dl_symbol_address (struct link_map *map, const ElfW(Sym) *ref) +{ + /* Find the "ip" from the "map" and symbol "ref" */ + Elf32_Addr value = (map ? map->l_addr : 0) + ref->st_value; + + /* On hppa, we have to return the pointer to function descriptor. + This involves an "| 2" to inform $$dyncall that this is a plabel32 */ + if (ELFW(ST_TYPE) (ref->st_info) == STT_FUNC){ + return (void *)((unsigned long)_dl_make_fptr (map, ref, value) | 2); + } + else + return (void *) value; +} diff --git a/sysdeps/hppa/elf/entry.h b/sysdeps/hppa/elf/entry.h new file mode 100644 index 0000000..b024db2 --- /dev/null +++ b/sysdeps/hppa/elf/entry.h @@ -0,0 +1,10 @@ +#ifndef __ASSEMBLY__ +extern void _start (void); +#endif + +/* The function's entry point is stored in the first word of the + function descriptor (plabel) of _start(). */ +#define ENTRY_POINT __canonicalize_funcptr_for_compare(_start) + +/* We have to provide a special declaration. */ +#define ENTRY_POINT_DECL(class) class void _start (void); diff --git a/sysdeps/hppa/elf/initfini.c b/sysdeps/hppa/elf/initfini.c new file mode 100644 index 0000000..35f5dd5 --- /dev/null +++ b/sysdeps/hppa/elf/initfini.c @@ -0,0 +1,139 @@ +/* Special .init and .fini section support for HPPA + Copyright (C) 2000, 2002 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 with other + programs, and to distribute those programs without any restriction + coming from the use of this file. (The GNU Lesser General Public + License restrictions do apply in other respects; for example, they + cover modification of the file, and distribution when not linked + into another program.) + + Note that people who make modified versions of this file are not + obligated to grant this special exception for their modified + versions; it is their choice whether to do so. The GNU Lesser + General Public License gives permission to release a modified + version without this exception; this exception also makes it + possible to release a modified version which carries forward this + exception. + + 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +/* This file is compiled into assembly code which is then munged by a sed + script into two files: crti.s and crtn.s. + + * crti.s puts a function prologue at the beginning of the + .init and .fini sections and defines global symbols for + those addresses, so they can be called as functions. + + * crtn.s puts the corresponding function epilogues + in the .init and .fini sections. */ + +/* If we use the standard C version, the linkage table pointer won't + be properly preserved due to the splitting up of function prologues + and epilogues. Therefore we write these in assembly to make sure + they do the right thing. + + Note that we cannot have a weak undefined __gmon_start__, because + that would require this to be PIC, and the linker is currently not + able to generate a proper procedure descriptor for _init. Sad but + true. Anyway, HPPA is one of those horrible architectures where + making the comparison and indirect call is quite expensive (see the + comment in sysdeps/generic/initfini.c). */ + +__asm__ ("\ +\n\ +#include \"defs.h\"\n\ +\n\ +/*@HEADER_ENDS*/\n\ +\n\ +/*@_init_PROLOG_BEGINS*/\n\ + .section .init\n\ + .align 4\n\ + .globl _init\n\ + .type _init,@function\n\ +_init:\n\ + stw %rp,-20(%sp)\n\ + stwm %r4,64(%sp)\n\ + stw %r19,-32(%sp)\n\ + bl __gmon_start__,%rp\n\ + copy %r19,%r4 /* delay slot */\n\ + copy %r4,%r19\n\ +/*@_init_PROLOG_ENDS*/\n\ +\n\ +/*@_init_EPILOG_BEGINS*/\n\ + .text\n\ + .align 4\n\ + .weak __gmon_start__\n\ + .type __gmon_start__,@function\n\ +__gmon_start__:\n\ + .proc\n\ + .callinfo\n\ + .entry\n\ + bv,n %r0(%r2)\n\ + .exit\n\ + .procend\n\ +\n\ +/* Here is the tail end of _init. We put __gmon_start before this so\n\ + that the assembler creates the .PARISC.unwind section for us, ie.\n\ + with the right attributes. */\n\ + .section .init\n\ + ldw -84(%sp),%rp\n\ + copy %r4,%r19\n\ + bv %r0(%rp)\n\ +_end_init:\n\ + ldwm -64(%sp),%r4\n\ +\n\ +/* Our very own unwind info, because the assembler can't handle\n\ + functions split into two or more pieces. */\n\ + .section .PARISC.unwind\n\ + .extern _init\n\ + .word _init, _end_init\n\ + .byte 0x08, 0x01, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08\n\ +\n\ +/*@_init_EPILOG_ENDS*/\n\ +\n\ +/*@_fini_PROLOG_BEGINS*/\n\ + .section .fini\n\ + .align 4\n\ + .globl _fini\n\ + .type _fini,@function\n\ +_fini:\n\ + stw %rp,-20(%sp)\n\ + stwm %r4,64(%sp)\n\ + stw %r19,-32(%sp)\n\ + copy %r19,%r4\n\ +/*@_fini_PROLOG_ENDS*/\n\ +\n\ +/*@_fini_EPILOG_BEGINS*/\n\ + .section .fini\n\ + ldw -84(%sp),%rp\n\ + copy %r4,%r19\n\ + bv %r0(%rp)\n\ +_end_fini:\n\ + ldwm -64(%sp),%r4\n\ +\n\ + .section .PARISC.unwind\n\ + .extern _fini\n\ + .word _fini, _end_fini\n\ + .byte 0x08, 0x01, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08\n\ +\n\ +/*@_fini_EPILOG_ENDS*/\n\ +\n\ +/*@TRAILER_BEGINS*/\ +"); diff --git a/sysdeps/hppa/elf/start.S b/sysdeps/hppa/elf/start.S new file mode 100644 index 0000000..4cf832a --- /dev/null +++ b/sysdeps/hppa/elf/start.S @@ -0,0 +1,97 @@ +/* ELF startup code for HPPA. + Copyright (C) 2002 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 with other + programs, and to distribute those programs without any restriction + coming from the use of this file. (The GNU Lesser General Public + License restrictions do apply in other respects; for example, they + cover modification of the file, and distribution when not linked + into another program.) + + Note that people who make modified versions of this file are not + obligated to grant this special exception for their modified + versions; it is their choice whether to do so. The GNU Lesser + General Public License gives permission to release a modified + version without this exception; this exception also makes it + possible to release a modified version which carries forward this + exception. + + 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + + .text + + .align 4 + + .import main, code + .import $global$, data + .import __libc_start_main, code + .import __libc_csu_fini, code + .import __libc_csu_init, code + + .globl _start + .export _start, ENTRY + .type _start,@function +_start: + + .proc + .callinfo + + /* load main */ + ldil LP%main, %r26 + ldo RP%main(%r26), %r26 + + /* argc and argv should be in 25 and 24 */ + + /* Expand the stack to store the 5th through 7th args */ + ldo 64(%sp), %sp + + /* void (*rtld_fini) (void) (actually the 6th arg) */ + stw %r23, -56(%sp) + + /* void (*init) (void) */ + ldil LP%__libc_csu_init, %r23 + ldo RP%__libc_csu_init(%r23), %r23 + + /* void (*fini) (void) */ + ldil LP%__libc_csu_fini, %r22 + ldo RP%__libc_csu_fini(%r22), %r22 + stw %r22, -52(%sp) + + /* void *stack_end */ + stw %sp, -60(%sp) + + /* load global */ + ldil L%$global$, %dp + ldo R%$global$(%dp), %dp + + bl __libc_start_main,%r2 + nop + /* die horribly if it returned (it shouldn't) */ + iitlbp %r0,(%r0) + nop + + .procend + +/* Define a symbol for the first piece of initialized data. */ + .data + .globl __data_start +__data_start: + .long 0 + .weak data_start + data_start = __data_start diff --git a/sysdeps/hppa/fpu/bits/fenv.h b/sysdeps/hppa/fpu/bits/fenv.h new file mode 100644 index 0000000..c5f8c43 --- /dev/null +++ b/sysdeps/hppa/fpu/bits/fenv.h @@ -0,0 +1,78 @@ +/* Copyright (C) 2000 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by David Huggins-Daines <dhd@debian.org> + + 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. + + 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#ifndef _FENV_H +# error "Never use <bits/fenv.h> directly; include <fenv.h> instead." +#endif + +/* Define bits representing the exception. We use the values of the + appropriate enable bits in the FPU status word (which, + coincidentally, are the same as the flag bits, but shifted right by + 27 bits). */ +enum +{ + FE_INVALID = 1<<4, /* V */ +#define FE_INVALID FE_INVALID + FE_DIVBYZERO = 1<<3, /* Z */ +#define FE_DIVBYZERO FE_DIVBYZERO + FE_OVERFLOW = 1<<2, /* O */ +#define FE_OVERFLOW FE_OVERFLOW + FE_UNDERFLOW = 1<<1, /* U */ +#define FE_UNDERFLOW FE_UNDERFLOW + FE_INEXACT = 1<<0, /* I */ +#define FE_INEXACT FE_INEXACT +}; + +#define FE_ALL_EXCEPT \ + (FE_INEXACT | FE_DIVBYZERO | FE_UNDERFLOW | FE_OVERFLOW | FE_INVALID) + +/* The PA-RISC FPU supports all of the four defined rounding modes. + We use the values of the RM field in the floating point status + register for the appropriate macros. */ +enum + { + FE_TONEAREST = 0 << 9, +#define FE_TONEAREST FE_TONEAREST + FE_TOWARDZERO = 1 << 9, +#define FE_TOWARDZERO FE_TOWARDZERO + FE_UPWARD = 2 << 9, +#define FE_UPWARD FE_UPWARD + FE_DOWNWARD = 3 << 9, +#define FE_DOWNWARD FE_DOWNWARD + }; + +/* Type representing exception flags. */ +typedef unsigned int fexcept_t; + +/* Type representing floating-point environment. This structure + corresponds to the layout of the status and exception words in the + register file. */ +typedef struct +{ + unsigned int __status_word; + unsigned int __exception[7]; +} fenv_t; + +/* If the default argument is used we use this value. */ +#define FE_DFL_ENV ((fenv_t *) -1) + +#ifdef __USE_GNU +/* Floating-point environment where none of the exceptions are masked. */ +# define FE_NOMASK_ENV ((fenv_t *) -2) +#endif diff --git a/sysdeps/hppa/fpu/fclrexcpt.c b/sysdeps/hppa/fpu/fclrexcpt.c new file mode 100644 index 0000000..a7c6982 --- /dev/null +++ b/sysdeps/hppa/fpu/fclrexcpt.c @@ -0,0 +1,37 @@ +/* Clear given exceptions in current floating-point environment. + Copyright (C) 2000 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by David Huggins-Daines <dhd@debian.org>, 2000 + + 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. + + 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <fenv.h> + +int +feclearexcept (int excepts) +{ + unsigned int sw[2]; + + /* Get the current status word. */ + __asm__ ("fstd %%fr0,0(%1)" : "=m" (*sw) : "r" (sw)); + + /* Clear all the relevant bits. */ + sw[0] &= ~((excepts & FE_ALL_EXCEPT) << 27); + __asm__ ("fldd 0(%0),%%fr0" : : "r" (sw)); + + /* Success. */ + return 0; +} diff --git a/sysdeps/hppa/fpu/fedisblxcpt.c b/sysdeps/hppa/fpu/fedisblxcpt.c new file mode 100644 index 0000000..aac6bbf --- /dev/null +++ b/sysdeps/hppa/fpu/fedisblxcpt.c @@ -0,0 +1,37 @@ +/* Disable floating-point exceptions. + Copyright (C) 2000 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by David Huggins-Daines <dhd@debian.org>, 2000 + + 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. + + 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <fenv.h> + +int +fedisableexcept (int excepts) +{ + unsigned int sw[2], old_exc; + + /* Get the current status word. */ + __asm__ ("fstd %%fr0,0(%1)" : "=m" (*sw) : "r" (sw)); + + old_exc = sw[0] & FE_ALL_EXCEPT; + + sw[0] &= ~(excepts & FE_ALL_EXCEPT); + __asm__ ("fldd 0(%0),%%fr0" : : "r" (sw)); + + return old_exc; +} diff --git a/sysdeps/hppa/fpu/feenablxcpt.c b/sysdeps/hppa/fpu/feenablxcpt.c new file mode 100644 index 0000000..9ce3ca8 --- /dev/null +++ b/sysdeps/hppa/fpu/feenablxcpt.c @@ -0,0 +1,37 @@ +/* Enable floating-point exceptions. + Copyright (C) 2000 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by David Huggins-Daines <dhd@debian.org>, 2000 + + 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. + + 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <fenv.h> + +int +feenableexcept (int excepts) +{ + unsigned int sw[2], old_exc; + + /* Get the current status word. */ + __asm__ ("fstd %%fr0,0(%1)" : "=m" (*sw) : "r" (sw)); + + old_exc = sw[0] & FE_ALL_EXCEPT; + + sw[0] |= (excepts & FE_ALL_EXCEPT); + __asm__ ("fldd 0(%0),%%fr0" : : "r" (sw)); + + return old_exc; +} diff --git a/sysdeps/hppa/fpu/fegetenv.c b/sysdeps/hppa/fpu/fegetenv.c new file mode 100644 index 0000000..b87317b --- /dev/null +++ b/sysdeps/hppa/fpu/fegetenv.c @@ -0,0 +1,33 @@ +/* Store current floating-point environment. + Copyright (C) 2000 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by David Huggins-Daines <dhd@debian.org>, 2000 + + 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. + + 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <fenv.h> + +int +fegetenv (fenv_t *envp) +{ + __asm__ ( + "fstd,ma %%fr0,8(%1)\n" + "fstd,ma %%fr1,8(%1)\n" + "fstd,ma %%fr2,8(%1)\n" + "fstd %%fr3,0(%1)\n" + : "=m" (*envp), "+r" (envp)); + return 0; +} diff --git a/sysdeps/hppa/fpu/fegetexcept.c b/sysdeps/hppa/fpu/fegetexcept.c new file mode 100644 index 0000000..efd1d7d --- /dev/null +++ b/sysdeps/hppa/fpu/fegetexcept.c @@ -0,0 +1,32 @@ +/* Get enabled floating-point exceptions. + Copyright (C) 2000 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by David Huggins-Daines <dhd@debian.org>, 2000 + + 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. + + 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <fenv.h> + +int +fegetexcept (void) +{ + unsigned int sw[2]; + + /* Get the current status word. */ + __asm__ ("fstd %%fr0,0(%1)" : "=m" (*sw) : "r" (sw)); + + return sw[0] & FE_ALL_EXCEPT; +} diff --git a/sysdeps/hppa/fpu/fegetround.c b/sysdeps/hppa/fpu/fegetround.c new file mode 100644 index 0000000..aefedbc --- /dev/null +++ b/sysdeps/hppa/fpu/fegetround.c @@ -0,0 +1,32 @@ +/* Return current rounding direction. + Copyright (C) 2000 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by David Huggins-Daines <dhd@debian.org>, 2000 + + 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. + + 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <fenv.h> + +int +fegetround (void) +{ + unsigned int sw[2]; + + /* Get the current status word. */ + __asm__ ("fstd %%fr0,0(%1)" : "=m" (*sw) : "r" (sw)); + + return sw[0] & FE_DOWNWARD; +} diff --git a/sysdeps/hppa/fpu/feholdexcpt.c b/sysdeps/hppa/fpu/feholdexcpt.c new file mode 100644 index 0000000..5aec015 --- /dev/null +++ b/sysdeps/hppa/fpu/feholdexcpt.c @@ -0,0 +1,56 @@ +/* Store current floating-point environment and clear exceptions. + Copyright (C) 2000 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by David Huggins-Daines <dhd@debian.org>, 2000 + + 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. + + 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <fenv.h> +#include <string.h> + +int +feholdexcept (fenv_t *envp) +{ + fenv_t clear; + fenv_t * _regs = envp; + + /* Store the environment. */ + __asm__ ( + "fstd,ma %%fr0,8(%1)\n" + "fstd,ma %%fr1,8(%1)\n" + "fstd,ma %%fr2,8(%1)\n" + "fstd %%fr3,0(%1)\n" + : "=m" (*_regs), "+r" (_regs)); + memcpy (&clear, envp, sizeof (clear)); + + /* Now clear all exceptions. */ + clear.__status_word &= ~(FE_ALL_EXCEPT << 27); + memset (clear.__exception, 0, sizeof (clear.__exception)); + + /* And set all exceptions to non-stop. */ + clear.__status_word &= ~FE_ALL_EXCEPT; + + /* Load the new environment. */ + _regs = &clear; + __asm__ ( + "fldd,ma 8(%0),%%fr0\n" + "fldd,ma 8(%0),%%fr1\n" + "fldd,ma 8(%0),%%fr2\n" + "fldd 0(%0),%%fr3\n" + : : "r" (_regs)); + + return 0; +} diff --git a/sysdeps/hppa/fpu/fesetenv.c b/sysdeps/hppa/fpu/fesetenv.c new file mode 100644 index 0000000..5267732 --- /dev/null +++ b/sysdeps/hppa/fpu/fesetenv.c @@ -0,0 +1,66 @@ +/* Install given floating-point environment. + Copyright (C) 1997, 1999, 2000, 2002 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by David Huggins-Daines <dhd@debian.org>, 2000 + Based on the m68k version by + Andreas Schwab <schwab@suse.de> + + 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. + + 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <fenv.h> + +int +fesetenv (const fenv_t *envp) +{ + fenv_t temp; + fenv_t * _regs = &temp; + + /* Install the environment specified by ENVP. But there are a few + values which we do not want to come from the saved environment. + Therefore, we get the current environment and replace the values + we want to use from the environment specified by the parameter. */ + __asm__ ( + "fstd,ma %%fr0,8(%1)\n" + "fstd,ma %%fr1,8(%1)\n" + "fstd,ma %%fr2,8(%1)\n" + "fstd %%fr3,0(%1)\n" + : "=m" (*_regs), "+r" (_regs)); + + temp.__status_word &= ~(FE_ALL_EXCEPT + | (FE_ALL_EXCEPT << 27) + | FE_DOWNWARD); + if (envp == FE_DFL_ENV) + ; + else if (envp == FE_NOMASK_ENV) + temp.__status_word |= FE_ALL_EXCEPT; + else + temp.__status_word |= (envp->__status_word + & (FE_ALL_EXCEPT + | FE_DOWNWARD + | (FE_ALL_EXCEPT << 27))); + + /* Load the new environment. */ + __asm__ ( + "fldd,ma -8(%1),%%fr3\n" + "fldd,ma -8(%1),%%fr2\n" + "fldd,ma -8(%1),%%fr1\n" + "fldd 0(%1),%%fr0\n" + : "=m" (*_regs), "+r" (_regs)); + + /* Success. */ + return 0; +} +libm_hidden_def (fesetenv) diff --git a/sysdeps/hppa/fpu/fesetround.c b/sysdeps/hppa/fpu/fesetround.c new file mode 100644 index 0000000..3687624 --- /dev/null +++ b/sysdeps/hppa/fpu/fesetround.c @@ -0,0 +1,39 @@ +/* Set current rounding direction. + Copyright (C) 2000 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by David Huggins-Daines <dhd@debian.org>, 2000 + + 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. + + 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <fenv.h> + +int +fesetround (int round) +{ + unsigned int sw[2]; + + if (round & ~FE_DOWNWARD) + /* ROUND is not a valid rounding mode. */ + return 1; + + /* Get the current status word. */ + __asm__ ("fstd %%fr0,0(%1)" : "=m" (*sw) : "r" (sw)); + sw[0] &= ~FE_DOWNWARD; + sw[0] |= round; + __asm__ ("fldd 0(%0),%%fr0" : : "r" (sw)); + + return 0; +} diff --git a/sysdeps/hppa/fpu/feupdateenv.c b/sysdeps/hppa/fpu/feupdateenv.c new file mode 100644 index 0000000..7d50282 --- /dev/null +++ b/sysdeps/hppa/fpu/feupdateenv.c @@ -0,0 +1,37 @@ +/* Install given floating-point environment and raise exceptions. + Copyright (C) 2000 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by David Huggins-Daines <dhd@debian.org>, 2000 + + 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. + + 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <fenv.h> + +int +feupdateenv (const fenv_t *envp) +{ + unsigned int sw[2]; + + /* Get the current exception status. */ + __asm__ ("fstd %%fr0,0(%1)" : "=m" (*sw) : "r" (sw)); + /* Install new environment. */ + fesetenv (envp); + /* Raise the saved exceptions */ + feraiseexcept(sw[0] & FE_ALL_EXCEPT); + + /* Success. */ + return 0; +} diff --git a/sysdeps/hppa/fpu/fgetexcptflg.c b/sysdeps/hppa/fpu/fgetexcptflg.c new file mode 100644 index 0000000..27766ec --- /dev/null +++ b/sysdeps/hppa/fpu/fgetexcptflg.c @@ -0,0 +1,36 @@ +/* Store current representation for exceptions. + Copyright (C) 2000 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by David Huggins-Daines <dhd@debian.org>, 2000 + + 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. + + 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <fenv.h> + +int +fegetexceptflag (fexcept_t *flagp, int excepts) +{ + unsigned int sw[2]; + + /* Get the current status word. */ + __asm__ ("fstd %%fr0,0(%1)" : "=m" (*sw) : "r" (sw)); + + *flagp = (sw[0] >> 27) & excepts & FE_ALL_EXCEPT; + + /* Success. */ + return 0; +} + diff --git a/sysdeps/hppa/fpu/fraiseexcpt.c b/sysdeps/hppa/fpu/fraiseexcpt.c new file mode 100644 index 0000000..b064dc1 --- /dev/null +++ b/sysdeps/hppa/fpu/fraiseexcpt.c @@ -0,0 +1,102 @@ +/* Raise given exceptions. + Copyright (C) 1997, 1999, 2000, 2002 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by David Huggins-Daines <dhd@debian.org> + + 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. + + 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <fenv.h> +#include <float.h> +#include <math.h> + +/* Please see section 10, + page 10-5 "Delayed Trapping" in the PA-RISC 2.0 Architecture manual */ + +int +feraiseexcept (int excepts) +{ + /* Raise exceptions represented by EXCEPTS. 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 (excepts & FE_INVALID) + { + /* One example of a 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 (excepts & FE_DIVBYZERO) + { + 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 (excepts & FE_OVERFLOW) + { + double d = DBL_MAX; + __asm__ __volatile__ ( + " fadd,dbl %0,%0,%0\n" + " fldd 0(%%sr0,%%sp),%0" + : "+f" (d) ); + } + + /* Fourth: Underflow. */ + if (excepts & FE_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 (excepts & FE_INEXACT) + { + double d = M_PI; + 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" ); + } + + /* Success. */ + return 0; +} +libm_hidden_def (feraiseexcept) diff --git a/sysdeps/hppa/fpu/fsetexcptflg.c b/sysdeps/hppa/fpu/fsetexcptflg.c new file mode 100644 index 0000000..af35f5a --- /dev/null +++ b/sysdeps/hppa/fpu/fsetexcptflg.c @@ -0,0 +1,40 @@ +/* Set floating-point environment exception handling. + Copyright (C) 1997, 1999, 2000 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by David Huggins-Daines <dhd@debian.org>, 2000 + + 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. + + 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <fenv.h> +#include <math.h> + +int +fesetexceptflag (const fexcept_t *flagp, int excepts) +{ + unsigned int sw[2]; + + /* Get the current status word. */ + __asm__ ("fstd %%fr0,0(%1)" : "=m" (*sw) : "r" (sw)); + + /* Install new enable trap bits */ + sw[0] |= (*flagp & excepts & FE_ALL_EXCEPT) << 27; + + /* Store the new status word. */ + __asm__ ("fldd 0(%0),%%fr0" : : "r" (sw)); + + /* Success. */ + return 0; +} diff --git a/sysdeps/hppa/fpu/ftestexcept.c b/sysdeps/hppa/fpu/ftestexcept.c new file mode 100644 index 0000000..d08d4d6 --- /dev/null +++ b/sysdeps/hppa/fpu/ftestexcept.c @@ -0,0 +1,32 @@ +/* Test exception in current environment. + Copyright (C) 2000 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by David Huggins-Daines <dhd@debian.org>, 2000 + + 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. + + 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <fenv.h> + +int +fetestexcept (int excepts) +{ + unsigned int sw[2]; + + /* Get the current status word. */ + __asm__ ("fstd %%fr0,0(%1)" : "=m" (*sw) : "r" (sw)); + + return (sw[0] >> 27) & excepts & FE_ALL_EXCEPT; +} diff --git a/sysdeps/hppa/fpu/libm-test-ulps b/sysdeps/hppa/fpu/libm-test-ulps new file mode 100644 index 0000000..73172b4 --- /dev/null +++ b/sysdeps/hppa/fpu/libm-test-ulps @@ -0,0 +1,890 @@ +# Begin of automatic generation + +# atan2 +Test "atan2 (-0.75, -1.0) == -2.49809154479650885165983415456218025": +float: 3 +ifloat: 3 +Test "atan2 (0.75, -1.0) == 2.49809154479650885165983415456218025": +float: 3 +ifloat: 3 +Test "atan2 (1.390625, 0.9296875) == 0.981498387184244311516296577615519772": +float: 1 +ifloat: 1 + +# atanh +Test "atanh (0.75) == 0.972955074527656652552676371721589865": +float: 1 +ifloat: 1 + +# cacosh +Test "Real part of: cacosh (-2 - 3 i) == -1.9833870299165354323470769028940395 + 2.1414491111159960199416055713254211 i": +double: 1 +float: 7 +idouble: 1 +ifloat: 7 +Test "Imaginary part of: cacosh (-2 - 3 i) == -1.9833870299165354323470769028940395 + 2.1414491111159960199416055713254211 i": +double: 1 +float: 3 +idouble: 1 +ifloat: 3 + +# casin +Test "Real part of: casin (0.75 + 1.25 i) == 0.453276177638793913448921196101971749 + 1.13239363160530819522266333696834467 i": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 + +# casinh +Test "Real part of: casinh (-2 - 3 i) == -1.9686379257930962917886650952454982 - 0.96465850440760279204541105949953237 i": +double: 5 +float: 1 +idouble: 5 +ifloat: 1 +Test "Imaginary part of: casinh (-2 - 3 i) == -1.9686379257930962917886650952454982 - 0.96465850440760279204541105949953237 i": +double: 3 +float: 6 +idouble: 3 +ifloat: 6 +Test "Real part of: casinh (0.75 + 1.25 i) == 1.03171853444778027336364058631006594 + 0.911738290968487636358489564316731207 i": +float: 1 +ifloat: 1 +Test "Imaginary part of: casinh (0.75 + 1.25 i) == 1.03171853444778027336364058631006594 + 0.911738290968487636358489564316731207 i": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 + +# catan +Test "Real part of: catan (-2 - 3 i) == -1.4099210495965755225306193844604208 - 0.22907268296853876629588180294200276 i": +float: 3 +ifloat: 3 +Test "Imaginary part of: catan (-2 - 3 i) == -1.4099210495965755225306193844604208 - 0.22907268296853876629588180294200276 i": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +Test "Real part of: catan (0.75 + 1.25 i) == 1.10714871779409050301706546017853704 + 0.549306144334054845697622618461262852 i": +float: 4 +ifloat: 4 + +# catanh +Test "Real part of: catanh (-2 - 3 i) == -0.14694666622552975204743278515471595 - 1.3389725222944935611241935759091443 i": +double: 4 +idouble: 4 +Test "Imaginary part of: catanh (-2 - 3 i) == -0.14694666622552975204743278515471595 - 1.3389725222944935611241935759091443 i": +float: 4 +ifloat: 4 +Test "Real part of: catanh (0.75 + 1.25 i) == 0.261492138795671927078652057366532140 + 0.996825126463918666098902241310446708 i": +double: 1 +idouble: 1 +Test "Imaginary part of: catanh (0.75 + 1.25 i) == 0.261492138795671927078652057366532140 + 0.996825126463918666098902241310446708 i": +float: 6 +ifloat: 6 + +# cbrt +Test "cbrt (-27.0) == -3.0": +double: 1 +idouble: 1 +Test "cbrt (0.75) == 0.908560296416069829445605878163630251": +double: 1 +idouble: 1 +Test "cbrt (0.9921875) == 0.997389022060725270579075195353955217": +double: 1 +idouble: 1 + +# ccos +Test "Imaginary part of: ccos (-2 - 3 i) == -4.18962569096880723013255501961597373 - 9.10922789375533659797919726277886212 i": +float: 1 +ifloat: 1 +Test "Real part of: ccos (0.75 + 1.25 i) == 1.38173873063425888530729933139078645 - 1.09193013555397466170919531722024128 i": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +Test "Imaginary part of: ccos (0.75 + 1.25 i) == 1.38173873063425888530729933139078645 - 1.09193013555397466170919531722024128 i": +float: 1 +ifloat: 1 + +# ccosh +Test "Real part of: ccosh (-2 - 3 i) == -3.72454550491532256547397070325597253 + 0.511822569987384608834463849801875634 i": +float: 1 +ifloat: 1 +Test "Imaginary part of: ccosh (-2 - 3 i) == -3.72454550491532256547397070325597253 + 0.511822569987384608834463849801875634 i": +float: 1 +ifloat: 1 +Test "Real part of: ccosh (0.75 + 1.25 i) == 0.408242591877968807788852146397499084 + 0.780365930845853240391326216300863152 i": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +Test "Imaginary part of: ccosh (0.75 + 1.25 i) == 0.408242591877968807788852146397499084 + 0.780365930845853240391326216300863152 i": +float: 1 +ifloat: 1 + +# cexp +Test "Imaginary part of: cexp (-2.0 - 3.0 i) == -0.13398091492954261346140525546115575 - 0.019098516261135196432576240858800925 i": +float: 1 +ifloat: 1 +Test "Real part of: cexp (0.75 + 1.25 i) == 0.667537446429131586942201977015932112 + 2.00900045494094876258347228145863909 i": +float: 1 +ifloat: 1 + +# clog +Test "Imaginary part of: clog (-2 - 3 i) == 1.2824746787307683680267437207826593 - 2.1587989303424641704769327722648368 i": +float: 3 +ifloat: 3 +Test "Real part of: clog (0.75 + 1.25 i) == 0.376885901188190075998919126749298416 + 1.03037682652431246378774332703115153 i": +float: 1 +ifloat: 1 + +# clog10 +Test "Imaginary part of: clog10 (-0 + inf i) == inf + pi/2*log10(e) i": +float: 1 +ifloat: 1 +Test "Imaginary part of: clog10 (-0 - inf i) == inf - pi/2*log10(e) i": +float: 1 +ifloat: 1 +Test "Imaginary part of: clog10 (-2 - 3 i) == 0.556971676153418384603252578971164214 - 0.937554462986374708541507952140189646 i": +double: 1 +float: 5 +idouble: 1 +ifloat: 5 +Test "Imaginary part of: clog10 (-3 + inf i) == inf + pi/2*log10(e) i": +float: 1 +ifloat: 1 +Test "Imaginary part of: clog10 (-3 - inf i) == inf - pi/2*log10(e) i": +float: 1 +ifloat: 1 +Test "Imaginary part of: clog10 (-inf + 0 i) == inf + pi*log10(e) i": +float: 1 +ifloat: 1 +Test "Imaginary part of: clog10 (-inf + 1 i) == inf + pi*log10(e) i": +float: 1 +ifloat: 1 +Test "Imaginary part of: clog10 (-inf - 0 i) == inf - pi*log10(e) i": +float: 1 +ifloat: 1 +Test "Imaginary part of: clog10 (-inf - 1 i) == inf - pi*log10(e) i": +float: 1 +ifloat: 1 +Test "Imaginary part of: clog10 (0 + inf i) == inf + pi/2*log10(e) i": +float: 1 +ifloat: 1 +Test "Imaginary part of: clog10 (0 - inf i) == inf - pi/2*log10(e) i": +float: 1 +ifloat: 1 +Test "Real part of: clog10 (0.75 + 1.25 i) == 0.163679467193165171449476605077428975 + 0.447486970040493067069984724340855636 i": +float: 1 +ifloat: 1 +Test "Imaginary part of: clog10 (3 + inf i) == inf + pi/2*log10(e) i": +float: 1 +ifloat: 1 +Test "Imaginary part of: clog10 (3 - inf i) == inf - pi/2*log10(e) i": +float: 1 +ifloat: 1 +Test "Imaginary part of: clog10 (inf + inf i) == inf + pi/4*log10(e) i": +float: 1 +ifloat: 1 +Test "Imaginary part of: clog10 (inf - inf i) == inf - pi/4*log10(e) i": +float: 1 +ifloat: 1 + +# cos +Test "cos (M_PI_6l * 2.0) == 0.5": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +Test "cos (M_PI_6l * 4.0) == -0.5": +double: 2 +float: 1 +idouble: 2 +ifloat: 1 +Test "cos (pi/2) == 0": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 + +# cpow +Test "Real part of: cpow (0.75 + 1.25 i, 0.0 + 1.0 i) == 0.331825439177608832276067945276730566 + 0.131338600281188544930936345230903032 i": +float: 1 +ifloat: 1 +Test "Imaginary part of: cpow (0.75 + 1.25 i, 0.0 + 1.0 i) == 0.331825439177608832276067945276730566 + 0.131338600281188544930936345230903032 i": +float: 1 +ifloat: 1 +Test "Real part of: cpow (0.75 + 1.25 i, 0.75 + 1.25 i) == 0.117506293914473555420279832210420483 + 0.346552747708338676483025352060418001 i": +double: 1 +float: 4 +idouble: 1 +ifloat: 4 +Test "Real part of: cpow (0.75 + 1.25 i, 1.0 + 1.0 i) == 0.0846958290317209430433805274189191353 + 0.513285749182902449043287190519090481 i": +double: 2 +float: 3 +idouble: 2 +ifloat: 3 +Test "Real part of: cpow (2 + 3 i, 4 + 0 i) == -119.0 - 120.0 i": +double: 1 +float: 4 +idouble: 1 +ifloat: 4 +Test "Imaginary part of: cpow (2 + 3 i, 4 + 0 i) == -119.0 - 120.0 i": +float: 2 +ifloat: 2 +Test "Imaginary part of: cpow (e + 0 i, 0 + 2 * M_PIl i) == 1.0 + 0.0 i": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 + +# csinh +Test "Imaginary part of: csinh (-2 - 3 i) == 3.59056458998577995201256544779481679 - 0.530921086248519805267040090660676560 i": +double: 1 +idouble: 1 +Test "Real part of: csinh (0.75 + 1.25 i) == 0.259294854551162779153349830618433028 + 1.22863452409509552219214606515777594 i": +float: 1 +ifloat: 1 +Test "Imaginary part of: csinh (0.75 + 1.25 i) == 0.259294854551162779153349830618433028 + 1.22863452409509552219214606515777594 i": +float: 1 +ifloat: 1 + +# csqrt +Test "Real part of: csqrt (-2 + 3 i) == 0.89597747612983812471573375529004348 + 1.6741492280355400404480393008490519 i": +float: 1 +ifloat: 1 +Test "Real part of: csqrt (-2 - 3 i) == 0.89597747612983812471573375529004348 - 1.6741492280355400404480393008490519 i": +float: 1 +ifloat: 1 + +# ctan +Test "Real part of: ctan (-2 - 3 i) == 0.376402564150424829275122113032269084e-2 - 1.00323862735360980144635859782192726 i": +double: 1 +idouble: 1 +Test "Imaginary part of: ctan (0.75 + 1.25 i) == 0.160807785916206426725166058173438663 + 0.975363285031235646193581759755216379 i": +double: 1 +idouble: 1 + +# ctanh +Test "Real part of: ctanh (-2 - 3 i) == -0.965385879022133124278480269394560686 + 0.988437503832249372031403430350121098e-2 i": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 +Test "Imaginary part of: ctanh (0 + pi/4 i) == 0.0 + 1.0 i": +float: 1 +ifloat: 1 +Test "Real part of: ctanh (0.75 + 1.25 i) == 1.37260757053378320258048606571226857 + 0.385795952609750664177596760720790220 i": +double: 1 +idouble: 1 + +# erf +Test "erf (1.25) == 0.922900128256458230136523481197281140": +double: 1 +idouble: 1 + +# erfc +Test "erfc (2.0) == 0.00467773498104726583793074363274707139": +double: 1 +idouble: 1 +Test "erfc (4.125) == 0.542340079956506600531223408575531062e-8": +double: 1 +idouble: 1 + +# exp10 +Test "exp10 (-1) == 0.1": +double: 2 +float: 1 +idouble: 2 +ifloat: 1 +Test "exp10 (0.75) == 5.62341325190349080394951039776481231": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +Test "exp10 (3) == 1000": +double: 6 +float: 2 +idouble: 6 +ifloat: 2 + +# expm1 +Test "expm1 (0.75) == 1.11700001661267466854536981983709561": +double: 1 +idouble: 1 +Test "expm1 (1) == M_El - 1.0": +float: 1 +ifloat: 1 + +# hypot +Test "hypot (-0.7, -12.4) == 12.419742348374220601176836866763271": +float: 1 +ifloat: 1 +Test "hypot (-0.7, 12.4) == 12.419742348374220601176836866763271": +float: 1 +ifloat: 1 +Test "hypot (-12.4, -0.7) == 12.419742348374220601176836866763271": +float: 1 +ifloat: 1 +Test "hypot (-12.4, 0.7) == 12.419742348374220601176836866763271": +float: 1 +ifloat: 1 +Test "hypot (0.7, -12.4) == 12.419742348374220601176836866763271": +float: 1 +ifloat: 1 +Test "hypot (0.7, 12.4) == 12.419742348374220601176836866763271": +float: 1 +ifloat: 1 +Test "hypot (12.4, -0.7) == 12.419742348374220601176836866763271": +float: 1 +ifloat: 1 +Test "hypot (12.4, 0.7) == 12.419742348374220601176836866763271": +float: 1 +ifloat: 1 + +# j0 +Test "j0 (-4.0) == -3.9714980986384737228659076845169804197562E-1": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +Test "j0 (0.75) == 0.864242275166648623555731103820923211": +float: 1 +ifloat: 1 +Test "j0 (10.0) == -0.245935764451348335197760862485328754": +double: 2 +float: 1 +idouble: 2 +ifloat: 1 +Test "j0 (2.0) == 0.223890779141235668051827454649948626": +float: 2 +ifloat: 2 +Test "j0 (4.0) == -3.9714980986384737228659076845169804197562E-1": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +Test "j0 (8.0) == 0.171650807137553906090869407851972001": +float: 1 +ifloat: 1 + +# j1 +Test "j1 (10.0) == 0.0434727461688614366697487680258592883": +float: 2 +ifloat: 2 +Test "j1 (2.0) == 0.576724807756873387202448242269137087": +double: 1 +idouble: 1 +Test "j1 (8.0) == 0.234636346853914624381276651590454612": +double: 1 +idouble: 1 + +# jn +Test "jn (0, -4.0) == -3.9714980986384737228659076845169804197562E-1": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +Test "jn (0, 0.75) == 0.864242275166648623555731103820923211": +float: 1 +ifloat: 1 +Test "jn (0, 10.0) == -0.245935764451348335197760862485328754": +double: 2 +float: 1 +idouble: 2 +ifloat: 1 +Test "jn (0, 2.0) == 0.223890779141235668051827454649948626": +float: 2 +ifloat: 2 +Test "jn (0, 4.0) == -3.9714980986384737228659076845169804197562E-1": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +Test "jn (0, 8.0) == 0.171650807137553906090869407851972001": +float: 1 +ifloat: 1 +Test "jn (1, 10.0) == 0.0434727461688614366697487680258592883": +float: 2 +ifloat: 2 +Test "jn (1, 2.0) == 0.576724807756873387202448242269137087": +double: 1 +idouble: 1 +Test "jn (1, 8.0) == 0.234636346853914624381276651590454612": +double: 1 +idouble: 1 +Test "jn (10, 0.125) == 0.250543369809369890173993791865771547e-18": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +Test "jn (10, 0.75) == 0.149621713117596814698712483621682835e-10": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +Test "jn (10, 10.0) == 0.207486106633358857697278723518753428": +double: 4 +float: 3 +idouble: 4 +ifloat: 3 +Test "jn (10, 2.0) == 0.251538628271673670963516093751820639e-6": +float: 4 +ifloat: 4 +Test "jn (3, 0.125) == 0.406503832554912875023029337653442868e-4": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +Test "jn (3, 0.75) == 0.848438342327410884392755236884386804e-2": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +Test "jn (3, 10.0) == 0.0583793793051868123429354784103409563": +double: 3 +float: 1 +idouble: 3 +ifloat: 1 +Test "jn (3, 2.0) == 0.128943249474402051098793332969239835": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 + +# lgamma +Test "lgamma (0.7) == 0.260867246531666514385732417016759578": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +Test "lgamma (1.2) == -0.853740900033158497197028392998854470e-1": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 + +# log10 +Test "log10 (0.75) == -0.124938736608299953132449886193870744": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 +Test "log10 (e) == log10(e)": +float: 1 +ifloat: 1 + +# log1p +Test "log1p (-0.25) == -0.287682072451780927439219005993827432": +float: 1 +ifloat: 1 + +# sincos +Test "sincos (M_PI_6l*2.0, &sin_res, &cos_res) puts 0.5 in cos_res": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +Test "sincos (M_PI_6l*2.0, &sin_res, &cos_res) puts 0.86602540378443864676372317075293616 in sin_res": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +Test "sincos (pi/2, &sin_res, &cos_res) puts 0 in cos_res": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +Test "sincos (pi/6, &sin_res, &cos_res) puts 0.86602540378443864676372317075293616 in cos_res": +float: 1 +ifloat: 1 + +# tan +Test "tan (pi/4) == 1": +double: 1 +idouble: 1 + +# tgamma +Test "tgamma (-0.5) == -2 sqrt (pi)": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +Test "tgamma (0.5) == sqrt (pi)": +float: 1 +ifloat: 1 +Test "tgamma (0.7) == 1.29805533264755778568117117915281162": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 + +# y0 +Test "y0 (1.0) == 0.0882569642156769579829267660235151628": +double: 2 +float: 1 +idouble: 2 +ifloat: 1 +Test "y0 (1.5) == 0.382448923797758843955068554978089862": +double: 2 +float: 1 +idouble: 2 +ifloat: 1 +Test "y0 (10.0) == 0.0556711672835993914244598774101900481": +float: 1 +ifloat: 1 +Test "y0 (8.0) == 0.223521489387566220527323400498620359": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 + +# y1 +Test "y1 (0.125) == -5.19993611253477499595928744876579921": +double: 1 +idouble: 1 +Test "y1 (1.5) == -0.412308626973911295952829820633445323": +float: 1 +ifloat: 1 +Test "y1 (10.0) == 0.249015424206953883923283474663222803": +double: 3 +float: 1 +idouble: 3 +ifloat: 1 +Test "y1 (2.0) == -0.107032431540937546888370772277476637": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +Test "y1 (8.0) == -0.158060461731247494255555266187483550": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 + +# yn +Test "yn (0, 1.0) == 0.0882569642156769579829267660235151628": +double: 2 +float: 1 +idouble: 2 +ifloat: 1 +Test "yn (0, 1.5) == 0.382448923797758843955068554978089862": +double: 2 +float: 1 +idouble: 2 +ifloat: 1 +Test "yn (0, 10.0) == 0.0556711672835993914244598774101900481": +float: 1 +ifloat: 1 +Test "yn (0, 8.0) == 0.223521489387566220527323400498620359": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +Test "yn (1, 0.125) == -5.19993611253477499595928744876579921": +double: 1 +idouble: 1 +Test "yn (1, 1.5) == -0.412308626973911295952829820633445323": +float: 1 +ifloat: 1 +Test "yn (1, 10.0) == 0.249015424206953883923283474663222803": +double: 3 +float: 1 +idouble: 3 +ifloat: 1 +Test "yn (1, 2.0) == -0.107032431540937546888370772277476637": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +Test "yn (1, 8.0) == -0.158060461731247494255555266187483550": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 +Test "yn (10, 0.125) == -127057845771019398.252538486899753195": +double: 1 +idouble: 1 +Test "yn (10, 0.75) == -2133501638.90573424452445412893839236": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +Test "yn (10, 1.0) == -121618014.278689189288130426667971145": +double: 1 +idouble: 1 +Test "yn (10, 10.0) == -0.359814152183402722051986577343560609": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +Test "yn (10, 2.0) == -129184.542208039282635913145923304214": +double: 2 +idouble: 2 +Test "yn (3, 0.125) == -2612.69757350066712600220955744091741": +double: 1 +idouble: 1 +Test "yn (3, 0.75) == -12.9877176234475433186319774484809207": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +Test "yn (3, 10.0) == -0.251362657183837329779204747654240998": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +Test "yn (3, 2.0) == -1.12778377684042778608158395773179238": +double: 1 +idouble: 1 + +# Maximal error of functions: +Function: "atan2": +float: 3 +ifloat: 3 + +Function: "atanh": +float: 1 +ifloat: 1 + +Function: Real part of "cacosh": +double: 1 +float: 7 +idouble: 1 +ifloat: 7 + +Function: Imaginary part of "cacosh": +double: 1 +float: 3 +idouble: 1 +ifloat: 3 + +Function: Real part of "casin": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 + +Function: Real part of "casinh": +double: 5 +float: 1 +idouble: 5 +ifloat: 1 + +Function: Imaginary part of "casinh": +double: 3 +float: 6 +idouble: 3 +ifloat: 6 + +Function: Real part of "catan": +float: 4 +ifloat: 4 + +Function: Imaginary part of "catan": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 + +Function: Real part of "catanh": +double: 4 +idouble: 4 + +Function: Imaginary part of "catanh": +float: 6 +ifloat: 6 + +Function: "cbrt": +double: 1 +idouble: 1 + +Function: Real part of "ccos": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 + +Function: Imaginary part of "ccos": +float: 1 +ifloat: 1 + +Function: Real part of "ccosh": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 + +Function: Imaginary part of "ccosh": +float: 1 +ifloat: 1 + +Function: Real part of "cexp": +float: 1 +ifloat: 1 + +Function: Imaginary part of "cexp": +float: 1 +ifloat: 1 + +Function: Real part of "clog": +float: 1 +ifloat: 1 + +Function: Imaginary part of "clog": +float: 3 +ifloat: 3 + +Function: Real part of "clog10": +float: 1 +ifloat: 1 + +Function: Imaginary part of "clog10": +double: 1 +float: 5 +idouble: 1 +ifloat: 5 + +Function: "cos": +double: 2 +float: 1 +idouble: 2 +ifloat: 1 + +Function: Real part of "cpow": +double: 2 +float: 4 +idouble: 2 +ifloat: 4 + +Function: Imaginary part of "cpow": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 + +Function: Real part of "csinh": +float: 1 +ifloat: 1 + +Function: Imaginary part of "csinh": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 + +Function: Real part of "csqrt": +float: 1 +ifloat: 1 + +Function: Real part of "ctan": +double: 1 +idouble: 1 + +Function: Imaginary part of "ctan": +double: 1 +idouble: 1 + +Function: Real part of "ctanh": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 + +Function: Imaginary part of "ctanh": +float: 1 +ifloat: 1 + +Function: "erf": +double: 1 +idouble: 1 + +Function: "erfc": +double: 1 +idouble: 1 + +Function: "exp10": +double: 6 +float: 2 +idouble: 6 +ifloat: 2 + +Function: "expm1": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 + +Function: "hypot": +float: 1 +ifloat: 1 + +Function: "j0": +double: 2 +float: 2 +idouble: 2 +ifloat: 2 + +Function: "j1": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 + +Function: "jn": +double: 4 +float: 4 +idouble: 4 +ifloat: 4 + +Function: "lgamma": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 + +Function: "log10": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 + +Function: "log1p": +float: 1 +ifloat: 1 + +Function: "sincos": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 + +Function: "tan": +double: 1 +idouble: 1 + +Function: "tgamma": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 + +Function: "y0": +double: 2 +float: 1 +idouble: 2 +ifloat: 1 + +Function: "y1": +double: 3 +float: 2 +idouble: 3 +ifloat: 2 + +Function: "yn": +double: 3 +float: 2 +idouble: 3 +ifloat: 2 + +# end of automatic generation diff --git a/sysdeps/hppa/frame.h b/sysdeps/hppa/frame.h new file mode 100644 index 0000000..0a234f1 --- /dev/null +++ b/sysdeps/hppa/frame.h @@ -0,0 +1,28 @@ +/* Definition of stack frame structure. HPPA version. + Copyright (C) 2000 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. + + 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +/* PA stacks grow upwards. */ +#define INNER_THAN > + +/* FIXME: will verify this later */ +struct layout +{ + void *next; + void *return_address; +}; diff --git a/sysdeps/hppa/gccframe.h b/sysdeps/hppa/gccframe.h new file mode 100644 index 0000000..65e44df --- /dev/null +++ b/sysdeps/hppa/gccframe.h @@ -0,0 +1,23 @@ +/* Definition of object in frame unwind info. hppa version. + Copyright (C) 2001 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. + + 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +/* Note: For hppa64 this is 61 */ +#define DWARF_FRAME_REGISTERS 89 + +#include <sysdeps/generic/gccframe.h> diff --git a/sysdeps/hppa/hppa1.1/Implies b/sysdeps/hppa/hppa1.1/Implies new file mode 100644 index 0000000..5f935a2 --- /dev/null +++ b/sysdeps/hppa/hppa1.1/Implies @@ -0,0 +1,4 @@ +wordsize-32 +ieee754/flt-32 +ieee754/dbl-64 +ieee754/ldbl-128 diff --git a/sysdeps/hppa/hppa1.1/addmul_1.s b/sysdeps/hppa/hppa1.1/addmul_1.s new file mode 100644 index 0000000..a1fb083 --- /dev/null +++ b/sysdeps/hppa/hppa1.1/addmul_1.s @@ -0,0 +1,104 @@ +;! HP-PA-1.1 __mpn_addmul_1 -- Multiply a limb vector with a limb and +;! add the result to a second limb vector. + +;! Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc. + +;! This file is part of the GNU MP Library. + +;! The GNU MP 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. + +;! The GNU MP 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 MP Library; see the file COPYING.LIB. If not, write to +;! the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, +;! MA 02111-1307, USA. + + +;! INPUT PARAMETERS +;! res_ptr r26 +;! s1_ptr r25 +;! size r24 +;! s2_limb r23 + +;! This runs at 11 cycles/limb on a PA7000. With the used instructions, it +;! can not become faster due to data cache contention after a store. On the +;! PA7100 it runs at 10 cycles/limb, and that can not be improved either, +;! since only the xmpyu does not need the integer pipeline, so the only +;! dual-issue we will get are addc+xmpyu. Unrolling could gain a cycle/limb +;! on the PA7100. + +;! There are some ideas described in mul_1.s that applies to this code too. + + .text + .export __mpn_addmul_1 +__mpn_addmul_1: + .proc + .callinfo frame=64,no_calls + .entry + + ldo 64(%r30),%r30 + fldws,ma 4(%r25),%fr5 + stw %r23,-16(%r30) ;! move s2_limb ... + addib,= -1,%r24,L$just_one_limb + fldws -16(%r30),%fr4 ;! ... into fr4 + add %r0,%r0,%r0 ;! clear carry + xmpyu %fr4,%fr5,%fr6 + fldws,ma 4(%r25),%fr7 + fstds %fr6,-16(%r30) + xmpyu %fr4,%fr7,%fr8 + ldw -12(%r30),%r20 ;! least significant limb in product + ldw -16(%r30),%r28 + + fstds %fr8,-16(%r30) + addib,= -1,%r24,L$end + ldw -12(%r30),%r1 + +;! Main loop +L$loop: + ldws 0(%r26),%r29 + fldws,ma 4(%r25),%fr5 + add %r29,%r20,%r20 + stws,ma %r20,4(%r26) + addc %r28,%r1,%r20 + xmpyu %fr4,%fr5,%fr6 + ldw -16(%r30),%r28 + fstds %fr6,-16(%r30) + addc %r0,%r28,%r28 + addib,<> -1,%r24,L$loop + ldw -12(%r30),%r1 + +L$end: + ldw 0(%r26),%r29 + add %r29,%r20,%r20 + stws,ma %r20,4(%r26) + addc %r28,%r1,%r20 + ldw -16(%r30),%r28 + ldws 0(%r26),%r29 + addc %r0,%r28,%r28 + add %r29,%r20,%r20 + stws,ma %r20,4(%r26) + addc %r0,%r28,%r28 + bv 0(%r2) + ldo -64(%r30),%r30 + +L$just_one_limb: + xmpyu %fr4,%fr5,%fr6 + ldw 0(%r26),%r29 + fstds %fr6,-16(%r30) + ldw -12(%r30),%r1 + ldw -16(%r30),%r28 + add %r29,%r1,%r20 + stw %r20,0(%r26) + addc %r0,%r28,%r28 + bv 0(%r2) + ldo -64(%r30),%r30 + + .exit + .procend diff --git a/sysdeps/hppa/hppa1.1/mul_1.s b/sysdeps/hppa/hppa1.1/mul_1.s new file mode 100644 index 0000000..00c770f --- /dev/null +++ b/sysdeps/hppa/hppa1.1/mul_1.s @@ -0,0 +1,100 @@ +;! HP-PA-1.1 __mpn_mul_1 -- Multiply a limb vector with a limb and store +;! the result in a second limb vector. + +;! Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc. + +;! This file is part of the GNU MP Library. + +;! The GNU MP 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. + +;! The GNU MP 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 MP Library; see the file COPYING.LIB. If not, write to +;! the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, +;! MA 02111-1307, USA. + + +;! INPUT PARAMETERS +;! res_ptr r26 +;! s1_ptr r25 +;! size r24 +;! s2_limb r23 + +;! This runs at 9 cycles/limb on a PA7000. With the used instructions, it can +;! not become faster due to data cache contention after a store. On the +;! PA7100 it runs at 7 cycles/limb, and that can not be improved either, since +;! only the xmpyu does not need the integer pipeline, so the only dual-issue +;! we will get are addc+xmpyu. Unrolling would not help either CPU. + +;! We could use fldds to read two limbs at a time from the S1 array, and that +;! could bring down the times to 8.5 and 6.5 cycles/limb for the PA7000 and +;! PA7100, respectively. We don't do that since it does not seem worth the +;! (alignment) troubles... + +;! At least the PA7100 is rumored to be able to deal with cache-misses +;! without stalling instruction issue. If this is true, and the cache is +;! actually also lockup-free, we should use a deeper software pipeline, and +;! load from S1 very early; (The loads and stores to -12(sp) will surely be +;! in the cache.) + + .text + .export __mpn_mul_1 +__mpn_mul_1: + .proc + .callinfo frame=64,no_calls + .entry + + ldo 64(%r30),%r30 + fldws,ma 4(%r25),%fr5 + stw %r23,-16(%r30) ;! move s2_limb ... + addib,= -1,%r24,L$just_one_limb + fldws -16(%r30),%fr4 ;! ... into fr4 + add %r0,%r0,%r0 ;! clear carry + xmpyu %fr4,%fr5,%fr6 + fldws,ma 4(%r25),%fr7 + fstds %fr6,-16(%r30) + xmpyu %fr4,%fr7,%fr8 + ldw -12(%r30),%r20 ;! least significant limb in product + ldw -16(%r30),%r28 + + fstds %fr8,-16(%r30) + addib,= -1,%r24,L$end + ldw -12(%r30),%r1 + +;! Main loop +L$loop: + fldws,ma 4(%r25),%fr5 + stws,ma %r20,4(%r26) + addc %r28,%r1,%r20 + xmpyu %fr4,%fr5,%fr6 + ldw -16(%r30),%r28 + fstds %fr6,-16(%r30) + addib,<> -1,%r24,L$loop + ldw -12(%r30),%r1 + +L$end: + stws,ma %r20,4(%r26) + addc %r28,%r1,%r20 + ldw -16(%r30),%r28 + stws,ma %r20,4(%r26) + addc %r0,%r28,%r28 + bv 0(%r2) + ldo -64(%r30),%r30 + +L$just_one_limb: + xmpyu %fr4,%fr5,%fr6 + fstds %fr6,-16(%r30) + ldw -16(%r30),%r28 + ldo -64(%r30),%r30 + bv 0(%r2) + fstws %fr6R,0(%r26) + + .exit + .procend diff --git a/sysdeps/hppa/hppa1.1/submul_1.s b/sysdeps/hppa/hppa1.1/submul_1.s new file mode 100644 index 0000000..997bd6d --- /dev/null +++ b/sysdeps/hppa/hppa1.1/submul_1.s @@ -0,0 +1,113 @@ +;! HP-PA-1.1 __mpn_submul_1 -- Multiply a limb vector with a limb and +;! subtract the result from a second limb vector. + +;! Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc. + +;! This file is part of the GNU MP Library. + +;! The GNU MP 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. + +;! The GNU MP 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 MP Library; see the file COPYING.LIB. If not, write to +;! the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, +;! MA 02111-1307, USA. + + +;! INPUT PARAMETERS +;! res_ptr r26 +;! s1_ptr r25 +;! size r24 +;! s2_limb r23 + +;! This runs at 12 cycles/limb on a PA7000. With the used instructions, it +;! can not become faster due to data cache contention after a store. On the +;! PA7100 it runs at 11 cycles/limb, and that can not be improved either, +;! since only the xmpyu does not need the integer pipeline, so the only +;! dual-issue we will get are addc+xmpyu. Unrolling could gain a cycle/limb +;! on the PA7100. + +;! There are some ideas described in mul_1.s that applies to this code too. + +;! It seems possible to make this run as fast as __mpn_addmul_1, if we use +;! sub,>>= %r29,%r20,%r22 +;! addi 1,%r28,%r28 +;! but that requires reworking the hairy software pipeline... + + .text + .export __mpn_submul_1 +__mpn_submul_1: + .proc + .callinfo frame=64,no_calls + .entry + + ldo 64(%r30),%r30 + fldws,ma 4(%r25),%fr5 + stw %r23,-16(%r30) ;! move s2_limb ... + addib,= -1,%r24,L$just_one_limb + fldws -16(%r30),%fr4 ;! ... into fr4 + add %r0,%r0,%r0 ;! clear carry + xmpyu %fr4,%fr5,%fr6 + fldws,ma 4(%r25),%fr7 + fstds %fr6,-16(%r30) + xmpyu %fr4,%fr7,%fr8 + ldw -12(%r30),%r20 ;! least significant limb in product + ldw -16(%r30),%r28 + + fstds %fr8,-16(%r30) + addib,= -1,%r24,L$end + ldw -12(%r30),%r1 + +;! Main loop +L$loop: + ldws 0(%r26),%r29 + fldws,ma 4(%r25),%fr5 + sub %r29,%r20,%r22 + add %r22,%r20,%r0 + stws,ma %r22,4(%r26) + addc %r28,%r1,%r20 + xmpyu %fr4,%fr5,%fr6 + ldw -16(%r30),%r28 + fstds %fr6,-16(%r30) + addc %r0,%r28,%r28 + addib,<> -1,%r24,L$loop + ldw -12(%r30),%r1 + +L$end: + ldw 0(%r26),%r29 + sub %r29,%r20,%r22 + add %r22,%r20,%r0 + stws,ma %r22,4(%r26) + addc %r28,%r1,%r20 + ldw -16(%r30),%r28 + ldws 0(%r26),%r29 + addc %r0,%r28,%r28 + sub %r29,%r20,%r22 + add %r22,%r20,%r0 + stws,ma %r22,4(%r26) + addc %r0,%r28,%r28 + bv 0(%r2) + ldo -64(%r30),%r30 + +L$just_one_limb: + xmpyu %fr4,%fr5,%fr6 + ldw 0(%r26),%r29 + fstds %fr6,-16(%r30) + ldw -12(%r30),%r1 + ldw -16(%r30),%r28 + sub %r29,%r1,%r22 + add %r22,%r1,%r0 + stw %r22,0(%r26) + addc %r0,%r28,%r28 + bv 0(%r2) + ldo -64(%r30),%r30 + + .exit + .procend diff --git a/sysdeps/hppa/hppa1.1/udiv_qrnnd.s b/sysdeps/hppa/hppa1.1/udiv_qrnnd.s new file mode 100644 index 0000000..fdc63e5 --- /dev/null +++ b/sysdeps/hppa/hppa1.1/udiv_qrnnd.s @@ -0,0 +1,78 @@ +;! HP-PA __udiv_qrnnd division support, used from longlong.h. +;! This version runs fast on PA 7000 and later. + +;! Copyright (C) 1993, 1994 Free Software Foundation, Inc. + +;! This file is part of the GNU MP Library. + +;! The GNU MP 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. + +;! The GNU MP 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 MP Library; see the file COPYING.LIB. If not, write to +;! the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, +;! MA 02111-1307, USA. + + +;! INPUT PARAMETERS +;! rem_ptr gr26 +;! n1 gr25 +;! n0 gr24 +;! d gr23 + + .text +L$0000: + .word 0x43f00000 + .word 0x0 + .export __udiv_qrnnd +__udiv_qrnnd: + .proc + .callinfo frame=64,no_calls + .entry + ldo 64(%r30),%r30 + + stws %r25,-16(0,%r30) ;! n_hi + stws %r24,-12(0,%r30) ;! n_lo + b,l L$0,%r1 + ldo L$0000-L$0(%r1),%r1 +L$0: + fldds -16(0,%r30),%fr5 + stws %r23,-12(0,%r30) + comib,<= 0,%r25,L$1 + fcnvxf,dbl,dbl %fr5,%fr5 + fldds 0(0,%r1),%fr4 + fadd,dbl %fr4,%fr5,%fr5 +L$1: + fcpy,sgl %fr0,%fr6L + fldws -12(0,%r30),%fr6R + fcnvxf,dbl,dbl %fr6,%fr4 + + fdiv,dbl %fr5,%fr4,%fr5 + + fcnvfx,dbl,dbl %fr5,%fr4 + fstws %fr4R,-16(%r30) + xmpyu %fr4R,%fr6R,%fr6 + ldws -16(%r30),%r28 + fstds %fr6,-16(0,%r30) + ldws -12(0,%r30),%r21 + ldws -16(0,%r30),%r20 + sub %r24,%r21,%r22 + subb %r25,%r20,%r1 + comib,= 0,%r1,L$2 + ldo -64(%r30),%r30 + + add %r22,%r23,%r22 + ldo -1(%r28),%r28 +L$2: + bv 0(%r2) + stws %r22,0(0,%r26) + + .exit + .procend diff --git a/sysdeps/hppa/libgcc-compat.c b/sysdeps/hppa/libgcc-compat.c new file mode 100644 index 0000000..2957eba --- /dev/null +++ b/sysdeps/hppa/libgcc-compat.c @@ -0,0 +1,43 @@ +/* pre-.hidden libgcc compatibility + Copyright (C) 2002 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Randolph Chung + + 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. + + 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + + +#include <stdint.h> +#include <shlib-compat.h> + +#if SHLIB_COMPAT(libc, GLIBC_2_0, GLIBC_2_2_6) + +symbol_version (__clz_tab_internal, __clz_tab, GLIBC_2.2); + +typedef unsigned int UQItype __attribute__ ((mode (QI))); + +const UQItype __clz_tab_internal[] = +{ + 0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, + 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, +}; + +#endif diff --git a/sysdeps/hppa/lshift.s b/sysdeps/hppa/lshift.s new file mode 100644 index 0000000..400fbcf --- /dev/null +++ b/sysdeps/hppa/lshift.s @@ -0,0 +1,66 @@ +;! HP-PA __mpn_lshift -- + +;! Copyright (C) 1992, 1994 Free Software Foundation, Inc. + +;! This file is part of the GNU MP Library. + +;! The GNU MP 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. + +;! The GNU MP 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 MP Library; see the file COPYING.LIB. If not, write to +;! the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, +;! MA 02111-1307, USA. + + +;! INPUT PARAMETERS +;! res_ptr gr26 +;! s_ptr gr25 +;! size gr24 +;! cnt gr23 + + .text + .export __mpn_lshift +__mpn_lshift: + .proc + .callinfo frame=64,no_calls + .entry + + sh2add %r24,%r25,%r25 + sh2add %r24,%r26,%r26 + ldws,mb -4(0,%r25),%r22 + subi 32,%r23,%r1 + mtsar %r1 + addib,= -1,%r24,L$0004 + vshd %r0,%r22,%r28 ;! compute carry out limb + ldws,mb -4(0,%r25),%r29 + addib,= -1,%r24,L$0002 + vshd %r22,%r29,%r20 + +L$loop: ldws,mb -4(0,%r25),%r22 + stws,mb %r20,-4(0,%r26) + addib,= -1,%r24,L$0003 + vshd %r29,%r22,%r20 + ldws,mb -4(0,%r25),%r29 + stws,mb %r20,-4(0,%r26) + addib,<> -1,%r24,L$loop + vshd %r22,%r29,%r20 + +L$0002: stws,mb %r20,-4(0,%r26) + vshd %r29,%r0,%r20 + bv 0(%r2) + stw %r20,-4(0,%r26) +L$0003: stws,mb %r20,-4(0,%r26) +L$0004: vshd %r22,%r0,%r20 + bv 0(%r2) + stw %r20,-4(0,%r26) + + .exit + .procend diff --git a/sysdeps/hppa/machine-gmon.h b/sysdeps/hppa/machine-gmon.h new file mode 100644 index 0000000..3eeef67 --- /dev/null +++ b/sysdeps/hppa/machine-gmon.h @@ -0,0 +1,25 @@ +/* Machine-specific calling sequence for `mcount' profiling function. PA-RISC + Copyright (C) 1995, 1996, 1997, 2000 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. + + 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +/* We can call _mcount directly since gcc supplies the correct + * arguments */ +#define _MCOUNT_DECL(from, self) \ + void _mcount (u_long from, u_long self) + +#define MCOUNT diff --git a/sysdeps/hppa/memusage.h b/sysdeps/hppa/memusage.h new file mode 100644 index 0000000..d3dd10e --- /dev/null +++ b/sysdeps/hppa/memusage.h @@ -0,0 +1,22 @@ +/* Copyright (C) 2000 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. + + 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#define GETSP() ({ register uintptr_t stack_ptr asm ("%r30"); stack_ptr; }) +#define STACK_GROWS_UPWARD 1 + +#include <sysdeps/generic/memusage.h> diff --git a/sysdeps/hppa/mp_clz_tab.c b/sysdeps/hppa/mp_clz_tab.c new file mode 100644 index 0000000..52d0638 --- /dev/null +++ b/sysdeps/hppa/mp_clz_tab.c @@ -0,0 +1 @@ +/* __clz_tab not needed on hppa. */ diff --git a/sysdeps/hppa/rshift.s b/sysdeps/hppa/rshift.s new file mode 100644 index 0000000..acb772f --- /dev/null +++ b/sysdeps/hppa/rshift.s @@ -0,0 +1,63 @@ +;! HP-PA __mpn_rshift -- + +;! Copyright (C) 1992, 1994 Free Software Foundation, Inc. + +;! This file is part of the GNU MP Library. + +;! The GNU MP 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. + +;! The GNU MP 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 MP Library; see the file COPYING.LIB. If not, write to +;! the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, +;! MA 02111-1307, USA. + + +;! INPUT PARAMETERS +;! res_ptr gr26 +;! s_ptr gr25 +;! size gr24 +;! cnt gr23 + + .text + .export __mpn_rshift +__mpn_rshift: + .proc + .callinfo frame=64,no_calls + .entry + + ldws,ma 4(0,%r25),%r22 + mtsar %r23 + addib,= -1,%r24,L$0004 + vshd %r22,%r0,%r28 ;! compute carry out limb + ldws,ma 4(0,%r25),%r29 + addib,= -1,%r24,L$0002 + vshd %r29,%r22,%r20 + +L$loop: ldws,ma 4(0,%r25),%r22 + stws,ma %r20,4(0,%r26) + addib,= -1,%r24,L$0003 + vshd %r22,%r29,%r20 + ldws,ma 4(0,%r25),%r29 + stws,ma %r20,4(0,%r26) + addib,<> -1,%r24,L$loop + vshd %r29,%r22,%r20 + +L$0002: stws,ma %r20,4(0,%r26) + vshd %r0,%r29,%r20 + bv 0(%r2) + stw %r20,0(0,%r26) +L$0003: stws,ma %r20,4(0,%r26) +L$0004: vshd %r0,%r22,%r20 + bv 0(%r2) + stw %r20,0(0,%r26) + + .exit + .procend diff --git a/sysdeps/hppa/setjmp.S b/sysdeps/hppa/setjmp.S new file mode 100644 index 0000000..f10a7a3 --- /dev/null +++ b/sysdeps/hppa/setjmp.S @@ -0,0 +1,69 @@ +/* setjmp for HPPA. + Copyright (C) 1995, 1996, 1997, 1999 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. + + 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <sysdep.h> +#define _ASM +#define _SETJMP_H +#include <bits/setjmp.h> + + + .text + .align 4 + .import __sigjmp_save, code + .globl __sigsetjmp + .export __sigsetjmp, code + .proc + .callinfo +__sigsetjmp: + stw %r3, 0(%r26) + stw %r4, 8(%r26) + stw %r5, 12(%r26) + stw %r6, 16(%r26) + stw %r7, 20(%r26) + stw %r8, 24(%r26) + stw %r9, 28(%r26) + stw %r10, 32(%r26) + stw %r11, 36(%r26) + stw %r12, 40(%r26) + stw %r13, 44(%r26) + stw %r14, 48(%r26) + stw %r15, 52(%r26) + stw %r16, 56(%r26) + stw %r17, 60(%r26) + stw %r18, 64(%r26) + stw %r19, 68(%r26) + stw %r27, 72(%r26) + stw %r30, 76(%r26) + + stw %rp, 80(%r26) + + ldo 88(%r26),%r19 + fstds,ma %fr12, 8(%r19) /* 88 */ + fstds,ma %fr13, 8(%r19) /* 96 */ + fstds,ma %fr14, 8(%r19) /* 104 */ + fstds,ma %fr15, 8(%r19) /* 112 */ + fstds,ma %fr16, 8(%r19) /* 120 */ + fstds,ma %fr17, 8(%r19) /* 128 */ + fstds,ma %fr18, 8(%r19) /* 136 */ + fstds,ma %fr19, 8(%r19) /* 144 */ + fstds,ma %fr20, 8(%r19) /* 152 */ + fstds %fr21, 0(%r19) /* 160 */ + b __sigjmp_save + nop + .procend diff --git a/sysdeps/hppa/stackinfo.h b/sysdeps/hppa/stackinfo.h new file mode 100644 index 0000000..318de71 --- /dev/null +++ b/sysdeps/hppa/stackinfo.h @@ -0,0 +1,28 @@ +/* Copyright (C) 1999 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. + + 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +/* This file contains a bit of information about the stack allocation + of the processor. */ + +#ifndef _STACKINFO_H +#define _STACKINFO_H 1 + +/* On PA the stack grows up. */ +#define _STACK_GROWS_UP 1 + +#endif /* stackinfo.h */ diff --git a/sysdeps/hppa/sub_n.s b/sysdeps/hppa/sub_n.s new file mode 100644 index 0000000..34f1968 --- /dev/null +++ b/sysdeps/hppa/sub_n.s @@ -0,0 +1,59 @@ +;! HP-PA __mpn_sub_n -- Subtract two limb vectors of the same length > 0 and +;! store difference in a third limb vector. + +;! Copyright (C) 1992, 1994 Free Software Foundation, Inc. + +;! This file is part of the GNU MP Library. + +;! The GNU MP 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. + +;! The GNU MP 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 MP Library; see the file COPYING.LIB. If not, write to +;! the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, +;! MA 02111-1307, USA. + + +;! INPUT PARAMETERS +;! res_ptr gr26 +;! s1_ptr gr25 +;! s2_ptr gr24 +;! size gr23 + +;! One might want to unroll this as for other processors, but it turns +;! out that the data cache contention after a store makes such +;! unrolling useless. We can't come under 5 cycles/limb anyway. + + .text + .export __mpn_sub_n +__mpn_sub_n: + .proc + .callinfo frame=0,no_calls + .entry + + ldws,ma 4(0,%r25),%r21 + ldws,ma 4(0,%r24),%r20 + + addib,= -1,%r23,L$end ;! check for (SIZE == 1) + sub %r21,%r20,%r28 ;! subtract first limbs ignoring cy + +L$loop: ldws,ma 4(0,%r25),%r21 + ldws,ma 4(0,%r24),%r20 + stws,ma %r28,4(0,%r26) + addib,<> -1,%r23,L$loop + subb %r21,%r20,%r28 + +L$end: stws %r28,0(0,%r26) + addc %r0,%r0,%r28 + bv 0(%r2) + subi 1,%r28,%r28 + + .exit + .procend diff --git a/sysdeps/hppa/sysdep.h b/sysdeps/hppa/sysdep.h new file mode 100644 index 0000000..be36567 --- /dev/null +++ b/sysdeps/hppa/sysdep.h @@ -0,0 +1,82 @@ +/* Assembler macros for HP/PA. + Copyright (C) 1999, 2003 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper, <drepper@cygnus.com>, August 1999. + + 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. + + 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <sysdeps/generic/sysdep.h> +#include <sys/syscall.h> +#include "config.h" + +#ifndef ASM_LINE_SEP +#define ASM_LINE_SEP ; +#endif + +#ifdef __ASSEMBLER__ + +/* Syntactic details of assembler. */ + +#define ALIGNARG(log2) log2 + + +/* Define an entry point visible from C. + + There is currently a bug in gdb which prevents us from specifying + incomplete stabs information. Fake some entries here which specify + the current source file. */ +#define ENTRY(name) \ + .SPACE $TEXT$ ASM_LINE_SEP \ + .SUBSPA $CODE$,QUAD=0,ALIGN=8,ACCESS=44,CODE_ONLY ASM_LINE_SEP \ + .align ALIGNARG(4) ASM_LINE_SEP \ + .NSUBSPA $CODE$,QUAD=0,ALIGN=8,ACCESS=44,CODE_ONLY ASM_LINE_SEP \ + .EXPORT C_SYMBOL_NAME(name),ENTRY,PRIV_LEV=3,ARGW0=GR,RTNVAL=GR ASM_LINE_SEP\ + C_LABEL(name) \ + CALL_MCOUNT + +#undef END +#define END(name) \ + .PROCEND + + +/* If compiled for profiling, call `mcount' at the start of each function. */ +#ifdef PROF +/* The mcount code relies on a normal frame pointer being on the stack + to locate our caller, so push one just for its benefit. */ +#define CALL_MCOUNT \ + XXX ASM_LINE_SEP +#else +#define CALL_MCOUNT /* Do nothing. */ +#endif + +#define PSEUDO(name, syscall_name, args) \ + ENTRY (name) \ + DO_CALL (syscall_name, args) + +#undef PSEUDO_END +#define PSEUDO_END(name) \ + END (name) + +#undef JUMPTARGET +#define JUMPTARGET(name) name +#define SYSCALL_PIC_SETUP /* Nothing. */ + +/* Local label name for asm code. */ +#ifndef L +#define L(name) name +#endif + +#endif /* __ASSEMBLER__ */ diff --git a/sysdeps/hppa/udiv_qrnnd.s b/sysdeps/hppa/udiv_qrnnd.s new file mode 100644 index 0000000..cd2b58d --- /dev/null +++ b/sysdeps/hppa/udiv_qrnnd.s @@ -0,0 +1,286 @@ +;! HP-PA __udiv_qrnnd division support, used from longlong.h. +;! This version runs fast on pre-PA7000 CPUs. + +;! Copyright (C) 1993, 1994 Free Software Foundation, Inc. + +;! This file is part of the GNU MP Library. + +;! The GNU MP 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. + +;! The GNU MP 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 MP Library; see the file COPYING.LIB. If not, write to +;! the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, +;! MA 02111-1307, USA. + + +;! INPUT PARAMETERS +;! rem_ptr gr26 +;! n1 gr25 +;! n0 gr24 +;! d gr23 + +;! The code size is a bit excessive. We could merge the last two ds;addc +;! sequences by simply moving the "bb,< Odd" instruction down. The only +;! trouble is the FFFFFFFF code that would need some hacking. + + .text + .export __udiv_qrnnd +__udiv_qrnnd: + .proc + .callinfo frame=0,no_calls + .entry + + comb,< %r23,0,L$largedivisor + sub %r0,%r23,%r1 ;! clear cy as side-effect + ds %r0,%r1,%r0 + addc %r24,%r24,%r24 + ds %r25,%r23,%r25 + addc %r24,%r24,%r24 + ds %r25,%r23,%r25 + addc %r24,%r24,%r24 + ds %r25,%r23,%r25 + addc %r24,%r24,%r24 + ds %r25,%r23,%r25 + addc %r24,%r24,%r24 + ds %r25,%r23,%r25 + addc %r24,%r24,%r24 + ds %r25,%r23,%r25 + addc %r24,%r24,%r24 + ds %r25,%r23,%r25 + addc %r24,%r24,%r24 + ds %r25,%r23,%r25 + addc %r24,%r24,%r24 + ds %r25,%r23,%r25 + addc %r24,%r24,%r24 + ds %r25,%r23,%r25 + addc %r24,%r24,%r24 + ds %r25,%r23,%r25 + addc %r24,%r24,%r24 + ds %r25,%r23,%r25 + addc %r24,%r24,%r24 + ds %r25,%r23,%r25 + addc %r24,%r24,%r24 + ds %r25,%r23,%r25 + addc %r24,%r24,%r24 + ds %r25,%r23,%r25 + addc %r24,%r24,%r24 + ds %r25,%r23,%r25 + addc %r24,%r24,%r24 + ds %r25,%r23,%r25 + addc %r24,%r24,%r24 + ds %r25,%r23,%r25 + addc %r24,%r24,%r24 + ds %r25,%r23,%r25 + addc %r24,%r24,%r24 + ds %r25,%r23,%r25 + addc %r24,%r24,%r24 + ds %r25,%r23,%r25 + addc %r24,%r24,%r24 + ds %r25,%r23,%r25 + addc %r24,%r24,%r24 + ds %r25,%r23,%r25 + addc %r24,%r24,%r24 + ds %r25,%r23,%r25 + addc %r24,%r24,%r24 + ds %r25,%r23,%r25 + addc %r24,%r24,%r24 + ds %r25,%r23,%r25 + addc %r24,%r24,%r24 + ds %r25,%r23,%r25 + addc %r24,%r24,%r24 + ds %r25,%r23,%r25 + addc %r24,%r24,%r24 + ds %r25,%r23,%r25 + addc %r24,%r24,%r24 + ds %r25,%r23,%r25 + addc %r24,%r24,%r24 + ds %r25,%r23,%r25 + addc %r24,%r24,%r28 + ds %r25,%r23,%r25 + comclr,>= %r25,%r0,%r0 + addl %r25,%r23,%r25 + stws %r25,0(0,%r26) + bv 0(%r2) + addc %r28,%r28,%r28 + +L$largedivisor: + extru %r24,31,1,%r20 ;! r20 = n0 & 1 + bb,< %r23,31,L$odd + extru %r23,30,31,%r22 ;! r22 = d >> 1 + shd %r25,%r24,1,%r24 ;! r24 = new n0 + extru %r25,30,31,%r25 ;! r25 = new n1 + sub %r0,%r22,%r21 + ds %r0,%r21,%r0 + addc %r24,%r24,%r24 + ds %r25,%r22,%r25 + addc %r24,%r24,%r24 + ds %r25,%r22,%r25 + addc %r24,%r24,%r24 + ds %r25,%r22,%r25 + addc %r24,%r24,%r24 + ds %r25,%r22,%r25 + addc %r24,%r24,%r24 + ds %r25,%r22,%r25 + addc %r24,%r24,%r24 + ds %r25,%r22,%r25 + addc %r24,%r24,%r24 + ds %r25,%r22,%r25 + addc %r24,%r24,%r24 + ds %r25,%r22,%r25 + addc %r24,%r24,%r24 + ds %r25,%r22,%r25 + addc %r24,%r24,%r24 + ds %r25,%r22,%r25 + addc %r24,%r24,%r24 + ds %r25,%r22,%r25 + addc %r24,%r24,%r24 + ds %r25,%r22,%r25 + addc %r24,%r24,%r24 + ds %r25,%r22,%r25 + addc %r24,%r24,%r24 + ds %r25,%r22,%r25 + addc %r24,%r24,%r24 + ds %r25,%r22,%r25 + addc %r24,%r24,%r24 + ds %r25,%r22,%r25 + addc %r24,%r24,%r24 + ds %r25,%r22,%r25 + addc %r24,%r24,%r24 + ds %r25,%r22,%r25 + addc %r24,%r24,%r24 + ds %r25,%r22,%r25 + addc %r24,%r24,%r24 + ds %r25,%r22,%r25 + addc %r24,%r24,%r24 + ds %r25,%r22,%r25 + addc %r24,%r24,%r24 + ds %r25,%r22,%r25 + addc %r24,%r24,%r24 + ds %r25,%r22,%r25 + addc %r24,%r24,%r24 + ds %r25,%r22,%r25 + addc %r24,%r24,%r24 + ds %r25,%r22,%r25 + addc %r24,%r24,%r24 + ds %r25,%r22,%r25 + addc %r24,%r24,%r24 + ds %r25,%r22,%r25 + addc %r24,%r24,%r24 + ds %r25,%r22,%r25 + addc %r24,%r24,%r24 + ds %r25,%r22,%r25 + addc %r24,%r24,%r24 + ds %r25,%r22,%r25 + addc %r24,%r24,%r24 + ds %r25,%r22,%r25 + addc %r24,%r24,%r24 + ds %r25,%r22,%r25 + comclr,>= %r25,%r0,%r0 + addl %r25,%r22,%r25 + sh1addl %r25,%r20,%r25 + stws %r25,0(0,%r26) + bv 0(%r2) + addc %r24,%r24,%r28 + +L$odd: addib,sv,n 1,%r22,L$FF.. ;! r22 = (d / 2 + 1) + shd %r25,%r24,1,%r24 ;! r24 = new n0 + extru %r25,30,31,%r25 ;! r25 = new n1 + sub %r0,%r22,%r21 + ds %r0,%r21,%r0 + addc %r24,%r24,%r24 + ds %r25,%r22,%r25 + addc %r24,%r24,%r24 + ds %r25,%r22,%r25 + addc %r24,%r24,%r24 + ds %r25,%r22,%r25 + addc %r24,%r24,%r24 + ds %r25,%r22,%r25 + addc %r24,%r24,%r24 + ds %r25,%r22,%r25 + addc %r24,%r24,%r24 + ds %r25,%r22,%r25 + addc %r24,%r24,%r24 + ds %r25,%r22,%r25 + addc %r24,%r24,%r24 + ds %r25,%r22,%r25 + addc %r24,%r24,%r24 + ds %r25,%r22,%r25 + addc %r24,%r24,%r24 + ds %r25,%r22,%r25 + addc %r24,%r24,%r24 + ds %r25,%r22,%r25 + addc %r24,%r24,%r24 + ds %r25,%r22,%r25 + addc %r24,%r24,%r24 + ds %r25,%r22,%r25 + addc %r24,%r24,%r24 + ds %r25,%r22,%r25 + addc %r24,%r24,%r24 + ds %r25,%r22,%r25 + addc %r24,%r24,%r24 + ds %r25,%r22,%r25 + addc %r24,%r24,%r24 + ds %r25,%r22,%r25 + addc %r24,%r24,%r24 + ds %r25,%r22,%r25 + addc %r24,%r24,%r24 + ds %r25,%r22,%r25 + addc %r24,%r24,%r24 + ds %r25,%r22,%r25 + addc %r24,%r24,%r24 + ds %r25,%r22,%r25 + addc %r24,%r24,%r24 + ds %r25,%r22,%r25 + addc %r24,%r24,%r24 + ds %r25,%r22,%r25 + addc %r24,%r24,%r24 + ds %r25,%r22,%r25 + addc %r24,%r24,%r24 + ds %r25,%r22,%r25 + addc %r24,%r24,%r24 + ds %r25,%r22,%r25 + addc %r24,%r24,%r24 + ds %r25,%r22,%r25 + addc %r24,%r24,%r24 + ds %r25,%r22,%r25 + addc %r24,%r24,%r24 + ds %r25,%r22,%r25 + addc %r24,%r24,%r24 + ds %r25,%r22,%r25 + addc %r24,%r24,%r24 + ds %r25,%r22,%r25 + addc %r24,%r24,%r24 + ds %r25,%r22,%r25 + addc %r24,%r24,%r28 + comclr,>= %r25,%r0,%r0 + addl %r25,%r22,%r25 + sh1addl %r25,%r20,%r25 +;! We have computed (n1,,n0) / (d + 1), q' = r28, r' = r25 + add,nuv %r28,%r25,%r25 + addl %r25,%r1,%r25 + addc %r0,%r28,%r28 + sub,<< %r25,%r23,%r0 + addl %r25,%r1,%r25 + stws %r25,0(0,%r26) + bv 0(%r2) + addc %r0,%r28,%r28 + +;! This is just a special case of the code above. +;! We come here when d == 0xFFFFFFFF +L$FF..: add,uv %r25,%r24,%r24 + sub,<< %r24,%r23,%r0 + ldo 1(%r24),%r24 + stws %r24,0(0,%r26) + bv 0(%r2) + addc %r0,%r25,%r28 + + .exit + .procend |