diff options
author | Jakub Jelinek <jakub@redhat.com> | 2007-07-12 18:26:36 +0000 |
---|---|---|
committer | Jakub Jelinek <jakub@redhat.com> | 2007-07-12 18:26:36 +0000 |
commit | 0ecb606cb6cf65de1d9fc8a919bceb4be476c602 (patch) | |
tree | 2ea1f8305970753e4a657acb2ccc15ca3eec8e2c /sysdeps/powerpc/powerpc32 | |
parent | 7d58530341304d403a6626d7f7a1913165fe2f32 (diff) | |
download | glibc-0ecb606cb6cf65de1d9fc8a919bceb4be476c602.tar glibc-0ecb606cb6cf65de1d9fc8a919bceb4be476c602.tar.gz glibc-0ecb606cb6cf65de1d9fc8a919bceb4be476c602.tar.bz2 glibc-0ecb606cb6cf65de1d9fc8a919bceb4be476c602.zip |
2.5-18.1
Diffstat (limited to 'sysdeps/powerpc/powerpc32')
54 files changed, 1195 insertions, 732 deletions
diff --git a/sysdeps/powerpc/powerpc32/Dist b/sysdeps/powerpc/powerpc32/Dist deleted file mode 100644 index ada834f7c3..0000000000 --- a/sysdeps/powerpc/powerpc32/Dist +++ /dev/null @@ -1,9 +0,0 @@ -dl-machine.c -dl-start.S -libgcc-compat.S -ppc-mcount.S -gprsave1.S -gprsave0.S -gprrest1.S -gprrest0.S -bp-asm.h diff --git a/sysdeps/powerpc/powerpc32/Implies b/sysdeps/powerpc/powerpc32/Implies index 9ef3ac175b..39a34c5f57 100644 --- a/sysdeps/powerpc/powerpc32/Implies +++ b/sysdeps/powerpc/powerpc32/Implies @@ -1,2 +1 @@ wordsize-32 -powerpc/soft-fp diff --git a/sysdeps/powerpc/powerpc32/Makefile b/sysdeps/powerpc/powerpc32/Makefile index 82b4fc95f9..1d58a063d6 100644 --- a/sysdeps/powerpc/powerpc32/Makefile +++ b/sysdeps/powerpc/powerpc32/Makefile @@ -21,7 +21,7 @@ ifeq ($(subdir),csu) ifneq ($(elf),no) # The initfini generation code doesn't work in the presence of -fPIC, so # we use -fpic instead which is much better. -CFLAGS-initfini.s = -g0 -fpic -O1 +CFLAGS-initfini.s += -fpic -O1 # There is no benefit to using sdata for these objects, and the user # of the library should be able to control what goes into sdata. diff --git a/sysdeps/powerpc/powerpc32/__longjmp-common.S b/sysdeps/powerpc/powerpc32/__longjmp-common.S index 82531ad6b3..2093b7e337 100644 --- a/sysdeps/powerpc/powerpc32/__longjmp-common.S +++ b/sysdeps/powerpc/powerpc32/__longjmp-common.S @@ -1,5 +1,6 @@ /* longjmp for PowerPC. - Copyright (C) 1995-1997,1999-2001,2003,2004 Free Software Foundation, Inc. + Copyright (C) 1995-1997, 1999-2001, 2003, 2004, 2005, 2006 + 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 @@ -19,11 +20,10 @@ #include <sysdep.h> #define _ASM -#define _SETJMP_H #ifdef __NO_VMX__ # include <novmxsetjmp.h> #else -# include <bits/setjmp.h> +# include <jmpbuf-offsets.h> #endif #include <bp-sym.h> #include <bp-asm.h> @@ -31,7 +31,11 @@ ENTRY (BP_SYM (__longjmp)) CHECK_BOUNDS_BOTH_WIDE_LIT (r3, r8, r9, JB_SIZE) +#ifdef PTR_DEMANGLE + lwz r24,(JB_GPR1*4)(r3) +#else lwz r1,(JB_GPR1*4)(r3) +#endif lwz r0,(JB_LR*4)(r3) lwz r14,((JB_GPRS+0)*4)(r3) lwz r15,((JB_GPRS+1)*4)(r3) @@ -40,6 +44,10 @@ ENTRY (BP_SYM (__longjmp)) lwz r18,((JB_GPRS+4)*4)(r3) lwz r19,((JB_GPRS+5)*4)(r3) lwz r20,((JB_GPRS+6)*4)(r3) +#ifdef PTR_DEMANGLE + PTR_DEMANGLE3 (r1, r24, r25) + PTR_DEMANGLE2 (r0, r25) +#endif mtlr r0 lwz r21,((JB_GPRS+7)*4)(r3) lwz r22,((JB_GPRS+8)*4)(r3) diff --git a/sysdeps/powerpc/powerpc32/backtrace.c b/sysdeps/powerpc/powerpc32/backtrace.c index 118f0d6175..e7e12544c5 100644 --- a/sysdeps/powerpc/powerpc32/backtrace.c +++ b/sysdeps/powerpc/powerpc32/backtrace.c @@ -1,5 +1,5 @@ /* Return backtrace of current program state. - Copyright (C) 1998, 2000 Free Software Foundation, Inc. + Copyright (C) 1998, 2000, 2005 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 @@ -64,3 +64,4 @@ __backtrace (void **array, int size) return count; } weak_alias (__backtrace, backtrace) +libc_hidden_def (__backtrace) diff --git a/sysdeps/powerpc/powerpc32/bits/atomic.h b/sysdeps/powerpc/powerpc32/bits/atomic.h index 0f1a72335f..6fcc669fb1 100644 --- a/sysdeps/powerpc/powerpc32/bits/atomic.h +++ b/sysdeps/powerpc/powerpc32/bits/atomic.h @@ -89,12 +89,27 @@ # define __arch_atomic_decrement_if_positive_64(mem) \ ({ abort (); (*mem)--; }) +#ifdef _ARCH_PWR4 +/* + * Newer powerpc64 processors support the new "light weight" sync (lwsync) + * So if the build is using -mcpu=[power4,power5,power5+,970] we can + * safely use lwsync. + */ +# define atomic_read_barrier() __asm ("lwsync" ::: "memory") +/* + * "light weight" sync can also be used for the release barrier. + */ +# ifndef UP +# define __ARCH_REL_INSTR "lwsync" +# endif +#else /* * Older powerpc32 processors don't support the new "light weight" * sync (lwsync). So the only safe option is to use normal sync * for all powerpc32 applications. */ # define atomic_read_barrier() __asm ("sync" ::: "memory") +#endif /* * Include the rest of the atomic ops macros which are common to both diff --git a/sysdeps/powerpc/powerpc32/bsd-_setjmp.S b/sysdeps/powerpc/powerpc32/bsd-_setjmp.S index 50deda8c90..4c28c2e547 100644 --- a/sysdeps/powerpc/powerpc32/bsd-_setjmp.S +++ b/sysdeps/powerpc/powerpc32/bsd-_setjmp.S @@ -26,7 +26,7 @@ /* Build a non-versioned object for rtld-*. */ ENTRY (BP_SYM (_setjmp)) li r4,0 /* Set second argument to 0. */ - b JUMPTARGET(BP_SYM (__sigsetjmp)) + b BP_SYM (__sigsetjmp@local) END (BP_SYM (_setjmp)) libc_hidden_def (_setjmp) #else @@ -37,7 +37,7 @@ symbol_version (__novmx_setjmp,_setjmp,GLIBC_2.0); ENTRY (BP_SYM (__novmx_setjmp)) li r4,0 /* Set second argument to 0. */ - b JUMPTARGET(BP_SYM (__novmx__sigsetjmp)) + b BP_SYM (__novmx__sigsetjmp@local) END (BP_SYM (__novmx_setjmp)) libc_hidden_def (__novmx_setjmp) # endif /* defined SHARED && SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_3_4) */ @@ -48,12 +48,12 @@ default_symbol_version (__vmx_setjmp,_setjmp,GLIBC_2.3.4) if HAVE_CLEANUP_JMP_BUF is defined */ ENTRY (BP_SYM (__GI__setjmp)) li r4,0 /* Set second argument to 0. */ - b JUMPTARGET(BP_SYM (__vmx__sigsetjmp)) + b BP_SYM (__vmx__sigsetjmp@local) END (BP_SYM (__GI__setjmp)) ENTRY (BP_SYM (__vmx_setjmp)) li r4,0 /* Set second argument to 0. */ - b JUMPTARGET(BP_SYM (__vmx__sigsetjmp)) + b BP_SYM (__vmx__sigsetjmp@local) END (BP_SYM (__vmx_setjmp)) libc_hidden_def (__vmx_setjmp) #endif /* !NOT_IN_libc */ diff --git a/sysdeps/powerpc/powerpc32/bsd-setjmp.S b/sysdeps/powerpc/powerpc32/bsd-setjmp.S index 159b122ca5..01b195d832 100644 --- a/sysdeps/powerpc/powerpc32/bsd-setjmp.S +++ b/sysdeps/powerpc/powerpc32/bsd-setjmp.S @@ -25,7 +25,7 @@ ENTRY (__novmxsetjmp) li r4,1 /* Set second argument to 1. */ - b JUMPTARGET (__novmx__sigsetjmp) + b __novmx__sigsetjmp@local END (__novmxsetjmp) strong_alias (__novmxsetjmp, __novmx__setjmp) symbol_version (__novmxsetjmp, setjmp, GLIBC_2.0) @@ -34,7 +34,7 @@ symbol_version (__novmxsetjmp, setjmp, GLIBC_2.0) ENTRY (__vmxsetjmp) li r4,1 /* Set second argument to 1. */ - b JUMPTARGET (__vmx__sigsetjmp) + b __vmx__sigsetjmp@local END (__vmxsetjmp) strong_alias (__vmxsetjmp, __vmx__setjmp) strong_alias (__vmx__setjmp, __setjmp) diff --git a/sysdeps/powerpc/powerpc32/configure b/sysdeps/powerpc/powerpc32/configure new file mode 100644 index 0000000000..0ff56c936a --- /dev/null +++ b/sysdeps/powerpc/powerpc32/configure @@ -0,0 +1,62 @@ +# This file is generated from configure.in by Autoconf. DO NOT EDIT! + # Local configure fragment for sysdeps/powerpc/powerpc32. + +# See whether gas has R_PPC_REL16 relocs. +echo "$as_me:$LINENO: checking for R_PPC_REL16 gas support" >&5 +echo $ECHO_N "checking for R_PPC_REL16 gas support... $ECHO_C" >&6 +if test "${libc_cv_ppc_rel16+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat > conftest.s <<\EOF + .text + addis 11,30,_GLOBAL_OFFSET_TABLE_-.@ha +EOF +if { ac_try='${CC-cc} -c $CFLAGS 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_ppc_rel16=yes +else + libc_cv_ppc_rel16=no +fi +rm -f conftest* +fi +echo "$as_me:$LINENO: result: $libc_cv_ppc_rel16" >&5 +echo "${ECHO_T}$libc_cv_ppc_rel16" >&6 +if test $libc_cv_ppc_rel16 = yes; then + cat >>confdefs.h <<\_ACEOF +#define HAVE_ASM_PPC_REL16 1 +_ACEOF + +fi + +# See whether GCC uses -msecure-plt. +echo "$as_me:$LINENO: checking for -msecure-plt by default" >&5 +echo $ECHO_N "checking for -msecure-plt by default... $ECHO_C" >&6 +if test "${libc_cv_ppc_secure_plt+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + echo 'int foo (void) { extern int bar; return bar; }' > conftest.c +libc_cv_ppc_secure_plt=no +if { ac_try='${CC-cc} -S $CFLAGS conftest.c -fpic -o 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 + if grep '_GLOBAL_OFFSET_TABLE_-.*@ha' conftest.s > /dev/null 2>&1; then + libc_cv_ppc_secure_plt=yes + fi +fi +rm -rf conftest* +fi +echo "$as_me:$LINENO: result: $libc_cv_ppc_secure_plt" >&5 +echo "${ECHO_T}$libc_cv_ppc_secure_plt" >&6 +if test $libc_cv_ppc_secure_plt = yes; then + cat >>confdefs.h <<\_ACEOF +#define HAVE_PPC_SECURE_PLT 1 +_ACEOF + +fi diff --git a/sysdeps/powerpc/powerpc32/configure.in b/sysdeps/powerpc/powerpc32/configure.in new file mode 100644 index 0000000000..7219ad993e --- /dev/null +++ b/sysdeps/powerpc/powerpc32/configure.in @@ -0,0 +1,32 @@ +GLIBC_PROVIDES dnl See aclocal.m4 in the top level source directory. +# Local configure fragment for sysdeps/powerpc/powerpc32. + +# See whether gas has R_PPC_REL16 relocs. +AC_CACHE_CHECK(for R_PPC_REL16 gas support, libc_cv_ppc_rel16, [dnl +cat > conftest.s <<\EOF + .text + addis 11,30,_GLOBAL_OFFSET_TABLE_-.@ha +EOF +if AC_TRY_COMMAND(${CC-cc} -c $CFLAGS conftest.s 1>&AS_MESSAGE_LOG_FD); then + libc_cv_ppc_rel16=yes +else + libc_cv_ppc_rel16=no +fi +rm -f conftest*]) +if test $libc_cv_ppc_rel16 = yes; then + AC_DEFINE(HAVE_ASM_PPC_REL16) +fi + +# See whether GCC uses -msecure-plt. +AC_CACHE_CHECK(for -msecure-plt by default, libc_cv_ppc_secure_plt, [dnl +echo 'int foo (void) { extern int bar; return bar; }' > conftest.c +libc_cv_ppc_secure_plt=no +if AC_TRY_COMMAND(${CC-cc} -S $CFLAGS conftest.c -fpic -o conftest.s 1>&AS_MESSAGE_LOG_FD); then + if grep '_GLOBAL_OFFSET_TABLE_-.*@ha' conftest.s > /dev/null 2>&1; then + libc_cv_ppc_secure_plt=yes + fi +fi +rm -rf conftest*]) +if test $libc_cv_ppc_secure_plt = yes; then + AC_DEFINE(HAVE_PPC_SECURE_PLT) +fi diff --git a/sysdeps/powerpc/powerpc32/dl-dtprocnum.h b/sysdeps/powerpc/powerpc32/dl-dtprocnum.h new file mode 100644 index 0000000000..7fe2be7939 --- /dev/null +++ b/sysdeps/powerpc/powerpc32/dl-dtprocnum.h @@ -0,0 +1,3 @@ +/* Number of extra dynamic section entries for this architecture. By + default there are none. */ +#define DT_THISPROCNUM DT_PPC_NUM diff --git a/sysdeps/powerpc/powerpc32/dl-machine.c b/sysdeps/powerpc/powerpc32/dl-machine.c index 06960716b9..4120a02382 100644 --- a/sysdeps/powerpc/powerpc32/dl-machine.c +++ b/sysdeps/powerpc/powerpc32/dl-machine.c @@ -1,5 +1,5 @@ /* Machine-dependent ELF dynamic relocation functions. PowerPC version. - Copyright (C) 1995-2003, 2004 Free Software Foundation, Inc. + Copyright (C) 1995-2003, 2004, 2005 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 @@ -242,7 +242,8 @@ __elf_machine_runtime_setup (struct link_map *map, int lazy, int profile) : _dl_runtime_resolve); Elf32_Word offset; - if (profile && _dl_name_match_p (GLRO(dl_profile), map)) + if (profile && GLRO(dl_profile) != NULL + && _dl_name_match_p (GLRO(dl_profile), map)) /* This is the object we are looking for. Say that we really want profiling and the timers are started. */ GL(dl_profile_map) = map; diff --git a/sysdeps/powerpc/powerpc32/dl-machine.h b/sysdeps/powerpc/powerpc32/dl-machine.h index a8c1e3e490..496fa71ecc 100644 --- a/sysdeps/powerpc/powerpc32/dl-machine.h +++ b/sysdeps/powerpc/powerpc32/dl-machine.h @@ -1,5 +1,5 @@ /* Machine-dependent ELF dynamic relocation inline functions. PowerPC version. - Copyright (C) 1995-2002, 2003 Free Software Foundation, Inc. + Copyright (C) 1995-2002, 2003, 2005 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 @@ -25,6 +25,10 @@ #include <assert.h> #include <dl-tls.h> +/* Translate a processor specific dynamic tag to the index + in l_info array. */ +#define DT_PPC(x) (DT_PPC_##x - DT_LOPROC + DT_NUM) + /* Return nonzero iff ELF header is compatible with the running host. */ static inline int elf_machine_matches_host (const Elf32_Ehdr *ehdr) @@ -32,24 +36,38 @@ elf_machine_matches_host (const Elf32_Ehdr *ehdr) return ehdr->e_machine == EM_PPC; } +/* Return the value of the GOT pointer. */ +static inline Elf32_Addr * __attribute__ ((const)) +ppc_got (void) +{ + Elf32_Addr *got; +#ifdef HAVE_ASM_PPC_REL16 + asm ("bcl 20,31,1f\n" + "1: mflr %0\n" + " addis %0,%0,_GLOBAL_OFFSET_TABLE_-1b@ha\n" + " addi %0,%0,_GLOBAL_OFFSET_TABLE_-1b@l\n" + : "=b" (got) : : "lr"); +#else + asm (" bl _GLOBAL_OFFSET_TABLE_-4@local" + : "=l" (got)); +#endif + return got; +} /* Return the link-time address of _DYNAMIC, stored as the first value in the GOT. */ -static inline Elf32_Addr +static inline Elf32_Addr __attribute__ ((const)) elf_machine_dynamic (void) { - Elf32_Addr *got; - asm (" bl _GLOBAL_OFFSET_TABLE_-4@local" - : "=l"(got)); - return *got; + return *ppc_got (); } /* Return the run-time load address of the shared object. */ -static inline Elf32_Addr +static inline Elf32_Addr __attribute__ ((const)) elf_machine_load_address (void) { - unsigned int *got; - unsigned int *branchaddr; + Elf32_Addr *branchaddr; + Elf32_Addr runtime_dynamic; /* This is much harder than you'd expect. Possibly I'm missing something. The 'obvious' way: @@ -80,19 +98,17 @@ elf_machine_load_address (void) the address ourselves. That gives us the following code: */ /* Get address of the 'b _DYNAMIC@local'... */ - asm ("bl 0f ;" + asm ("bcl 20,31,0f;" "b _DYNAMIC@local;" "0:" - : "=l"(branchaddr)); - - /* ... and the address of the GOT. */ - asm (" bl _GLOBAL_OFFSET_TABLE_-4@local" - : "=l"(got)); + : "=l" (branchaddr)); /* So now work out the difference between where the branch actually points, and the offset of that location in memory from the start of the file. */ - return ((Elf32_Addr)branchaddr - *got - + ((int)(*branchaddr << 6 & 0xffffff00) >> 6)); + runtime_dynamic = ((Elf32_Addr) branchaddr + + ((Elf32_Sword) (*branchaddr << 6 & 0xffffff00) >> 6)); + + return runtime_dynamic - elf_machine_dynamic (); } #define ELF_MACHINE_BEFORE_RTLD_RELOC(dynamic_info) /* nothing */ @@ -100,160 +116,6 @@ elf_machine_load_address (void) /* The PLT uses Elf32_Rela relocs. */ #define elf_machine_relplt elf_machine_rela -/* This code is used in dl-runtime.c to call the `fixup' function - and then redirect to the address it returns. It is called - from code built in the PLT by elf_machine_runtime_setup. */ -#if !defined PROF -#define ELF_MACHINE_RUNTIME_TRAMPOLINE asm ("\n\ - .section \".text\" \n\ - .align 2 \n\ - .globl _dl_runtime_resolve \n\ - .type _dl_runtime_resolve,@function \n\ -_dl_runtime_resolve: \n\ - # We need to save the registers used to pass parameters, and register 0,\n\ - # which is used by _mcount; the registers are saved in a stack frame.\n\ - stwu 1,-64(1) \n\ - stw 0,12(1) \n\ - stw 3,16(1) \n\ - stw 4,20(1) \n\ - # The code that calls this has put parameters for `fixup' in r12 and r11.\n\ - mr 3,12 \n\ - stw 5,24(1) \n\ - mr 4,11 \n\ - stw 6,28(1) \n\ - mflr 0 \n\ - # We also need to save some of the condition register fields.\n\ - stw 7,32(1) \n\ - stw 0,48(1) \n\ - stw 8,36(1) \n\ - mfcr 0 \n\ - stw 9,40(1) \n\ - stw 10,44(1) \n\ - stw 0,8(1) \n\ - bl fixup@local \n\ - # 'fixup' returns the address we want to branch to.\n\ - mtctr 3 \n\ - # Put the registers back...\n\ - lwz 0,48(1) \n\ - lwz 10,44(1) \n\ - lwz 9,40(1) \n\ - mtlr 0 \n\ - lwz 8,36(1) \n\ - lwz 0,8(1) \n\ - lwz 7,32(1) \n\ - lwz 6,28(1) \n\ - mtcrf 0xFF,0 \n\ - lwz 5,24(1) \n\ - lwz 4,20(1) \n\ - lwz 3,16(1) \n\ - lwz 0,12(1) \n\ - # ...unwind the stack frame, and jump to the PLT entry we updated.\n\ - addi 1,1,64 \n\ - bctr \n\ - .size _dl_runtime_resolve,.-_dl_runtime_resolve \n\ - \n\ - .align 2 \n\ - .globl _dl_prof_resolve \n\ - .type _dl_prof_resolve,@function \n\ -_dl_prof_resolve: \n\ - # We need to save the registers used to pass parameters, and register 0,\n\ - # which is used by _mcount; the registers are saved in a stack frame.\n\ - stwu 1,-64(1) \n\ - stw 0,12(1) \n\ - stw 3,16(1) \n\ - stw 4,20(1) \n\ - # The code that calls this has put parameters for `fixup' in r12 and r11.\n\ - mr 3,12 \n\ - stw 5,24(1) \n\ - mr 4,11 \n\ - stw 6,28(1) \n\ - mflr 5 \n\ - # We also need to save some of the condition register fields.\n\ - stw 7,32(1) \n\ - stw 5,48(1) \n\ - stw 8,36(1) \n\ - mfcr 0 \n\ - stw 9,40(1) \n\ - stw 10,44(1) \n\ - stw 0,8(1) \n\ - bl profile_fixup@local \n\ - # 'fixup' returns the address we want to branch to.\n\ - mtctr 3 \n\ - # Put the registers back...\n\ - lwz 0,48(1) \n\ - lwz 10,44(1) \n\ - lwz 9,40(1) \n\ - mtlr 0 \n\ - lwz 8,36(1) \n\ - lwz 0,8(1) \n\ - lwz 7,32(1) \n\ - lwz 6,28(1) \n\ - mtcrf 0xFF,0 \n\ - lwz 5,24(1) \n\ - lwz 4,20(1) \n\ - lwz 3,16(1) \n\ - lwz 0,12(1) \n\ - # ...unwind the stack frame, and jump to the PLT entry we updated.\n\ - addi 1,1,64 \n\ - bctr \n\ - .size _dl_prof_resolve,.-_dl_prof_resolve \n\ - # Undo '.section text'.\n\ - .previous \n\ -"); -#else -# define ELF_MACHINE_RUNTIME_TRAMPOLINE asm ("\n\ - .section \".text\" \n\ - .align 2 \n\ - .globl _dl_runtime_resolve \n\ - .globl _dl_prof_resolve \n\ - .type _dl_runtime_resolve,@function \n\ - .type _dl_prof_resolve,@function \n\ -_dl_runtime_resolve: \n\ -_dl_prof_resolve: \n\ - # We need to save the registers used to pass parameters, and register 0,\n\ - # which is used by _mcount; the registers are saved in a stack frame.\n\ - stwu 1,-64(1) \n\ - stw 0,12(1) \n\ - stw 3,16(1) \n\ - stw 4,20(1) \n\ - # The code that calls this has put parameters for `fixup' in r12 and r11.\n\ - mr 3,12 \n\ - stw 5,24(1) \n\ - mr 4,11 \n\ - stw 6,28(1) \n\ - mflr 0 \n\ - # We also need to save some of the condition register fields.\n\ - stw 7,32(1) \n\ - stw 0,48(1) \n\ - stw 8,36(1) \n\ - mfcr 0 \n\ - stw 9,40(1) \n\ - stw 10,44(1) \n\ - stw 0,8(1) \n\ - bl fixup@local \n\ - # 'fixup' returns the address we want to branch to.\n\ - mtctr 3 \n\ - # Put the registers back...\n\ - lwz 0,48(1) \n\ - lwz 10,44(1) \n\ - lwz 9,40(1) \n\ - mtlr 0 \n\ - lwz 8,36(1) \n\ - lwz 0,8(1) \n\ - lwz 7,32(1) \n\ - lwz 6,28(1) \n\ - mtcrf 0xFF,0 \n\ - lwz 5,24(1) \n\ - lwz 4,20(1) \n\ - lwz 3,16(1) \n\ - lwz 0,12(1) \n\ - # ...unwind the stack frame, and jump to the PLT entry we updated.\n\ - addi 1,1,64 \n\ - bctr \n\ - .size _dl_runtime_resolve,.-_dl_runtime_resolve \n\ -"); -#endif - /* Mask identifying addresses reserved for the user program, where the dynamic linker should not map anything. */ #define ELF_MACHINE_USER_ADDRESS_MASK 0xf0000000UL @@ -298,13 +160,69 @@ __elf_preferred_address(struct link_map *loader, size_t maplength, /* The PowerPC never uses REL relocations. */ #define ELF_MACHINE_NO_REL 1 -/* Set up the loaded object described by L so its unrelocated PLT +/* Set up the loaded object described by MAP so its unrelocated PLT entries will jump to the on-demand fixup code in dl-runtime.c. Also install a small trampoline to be used by entries that have been relocated to an address too far away for a single branch. */ extern int __elf_machine_runtime_setup (struct link_map *map, int lazy, int profile); -#define elf_machine_runtime_setup __elf_machine_runtime_setup + +static inline int +elf_machine_runtime_setup (struct link_map *map, + int lazy, int profile) +{ + if (map->l_info[DT_JMPREL] == 0) + return lazy; + + if (map->l_info[DT_PPC(GOT)] == 0) + /* Handle old style PLT. */ + return __elf_machine_runtime_setup (map, lazy, profile); + + /* New style non-exec PLT consisting of an array of addresses. */ + map->l_info[DT_PPC(GOT)]->d_un.d_ptr += map->l_addr; + if (lazy) + { + Elf32_Addr *plt, *got, glink; + Elf32_Word num_plt_entries; + void (*dlrr) (void); + extern void _dl_runtime_resolve (void); + extern void _dl_prof_resolve (void); + + if (__builtin_expect (!profile, 1)) + dlrr = _dl_runtime_resolve; + else + { + if (GLRO(dl_profile) != NULL + &&_dl_name_match_p (GLRO(dl_profile), map)) + GL(dl_profile_map) = map; + dlrr = _dl_prof_resolve; + } + got = (Elf32_Addr *) map->l_info[DT_PPC(GOT)]->d_un.d_ptr; + glink = got[1]; + got[1] = (Elf32_Addr) dlrr; + got[2] = (Elf32_Addr) map; + + /* Relocate everything in .plt by the load address offset. */ + plt = (Elf32_Addr *) D_PTR (map, l_info[DT_PLTGOT]); + num_plt_entries = (map->l_info[DT_PLTRELSZ]->d_un.d_val + / sizeof (Elf32_Rela)); + + /* If a library is prelinked but we have to relocate anyway, + we have to be able to undo the prelinking of .plt section. + The prelinker saved us at got[1] address of .glink + section's start. */ + if (glink) + { + glink += map->l_addr; + while (num_plt_entries-- != 0) + *plt++ = glink, glink += 4; + } + else + while (num_plt_entries-- != 0) + *plt++ += map->l_addr; + } + return lazy; +} /* Change the PLT entry whose reloc is 'reloc' to call the actual routine. */ extern Elf32_Addr __elf_machine_fixup_plt (struct link_map *map, @@ -317,7 +235,12 @@ elf_machine_fixup_plt (struct link_map *map, lookup_t t, const Elf32_Rela *reloc, Elf32_Addr *reloc_addr, Elf64_Addr finaladdr) { - return __elf_machine_fixup_plt (map, reloc, reloc_addr, finaladdr); + if (map->l_info[DT_PPC(GOT)] == 0) + /* Handle old style PLT. */ + return __elf_machine_fixup_plt (map, reloc, reloc_addr, finaladdr); + + *reloc_addr = finaladdr; + return finaladdr; } /* Return the final value of a plt relocation. */ @@ -328,9 +251,14 @@ elf_machine_plt_value (struct link_map *map, const Elf32_Rela *reloc, return value + reloc->r_addend; } + +/* Names of the architecture-specific auditing callback functions. */ +#define ARCH_LA_PLTENTER ppc32_gnu_pltenter +#define ARCH_LA_PLTEXIT ppc32_gnu_pltexit + #endif /* dl_machine_h */ -#ifdef RESOLVE +#ifdef RESOLVE_MAP /* Do the actual processing of a reloc, once its target address has been determined. */ @@ -353,7 +281,7 @@ extern void _dl_reloc_overflow (struct link_map *map, LOADADDR is the load address of the object; INFO is an array indexed by DT_* of the .dynamic section info. */ -inline void +auto inline 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) @@ -381,16 +309,8 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc, value = map->l_addr; else { -# if defined USE_TLS && !defined RTLD_BOOTSTRAP sym_map = RESOLVE_MAP (&sym, version, r_type); - value = sym == NULL ? 0 : sym_map->l_addr + sym->st_value; -# else - value = RESOLVE (&sym, version, r_type); -# ifndef RTLD_BOOTSTRAP - if (sym != NULL) -# endif - value += sym->st_value; -# endif + value = sym_map == NULL ? 0 : sym_map->l_addr + sym->st_value; } value += reloc->r_addend; #else @@ -443,11 +363,16 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc, break; #endif /* USE_TLS etc. */ -#ifdef RESOLVE_CONFLICT_FIND_MAP case R_PPC_JMP_SLOT: +#ifdef RESOLVE_CONFLICT_FIND_MAP RESOLVE_CONFLICT_FIND_MAP (map, reloc_addr); - /* FALLTHROUGH */ #endif + if (map->l_info[DT_PPC(GOT)] != 0) + { + *reloc_addr = value; + break; + } + /* FALLTHROUGH */ default: __process_machine_rela (map, reloc, sym_map, sym, refsym, @@ -455,7 +380,7 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc, } } -static inline void +auto inline void __attribute__ ((always_inline)) elf_machine_rela_relative (Elf32_Addr l_addr, const Elf32_Rela *reloc, void *const reloc_addr_arg) { @@ -463,7 +388,7 @@ elf_machine_rela_relative (Elf32_Addr l_addr, const Elf32_Rela *reloc, *reloc_addr = l_addr + reloc->r_addend; } -static inline void +auto inline void __attribute__ ((always_inline)) elf_machine_lazy_rel (struct link_map *map, Elf32_Addr l_addr, const Elf32_Rela *reloc) { @@ -474,4 +399,4 @@ elf_machine_lazy_rel (struct link_map *map, DT_RELA table. */ #define ELF_MACHINE_PLTREL_OVERLAP 1 -#endif /* RESOLVE */ +#endif /* RESOLVE_MAP */ diff --git a/sysdeps/powerpc/powerpc32/dl-start.S b/sysdeps/powerpc/powerpc32/dl-start.S index d72202d4a4..c77c4de198 100644 --- a/sysdeps/powerpc/powerpc32/dl-start.S +++ b/sysdeps/powerpc/powerpc32/dl-start.S @@ -1,5 +1,5 @@ /* Machine-dependent ELF startup code. PowerPC version. - Copyright (C) 1995-2000, 2002, 2004 Free Software Foundation, Inc. + Copyright (C) 1995-2000, 2002, 2004, 2005, 2006 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 @@ -14,8 +14,8 @@ 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. */ + Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA + 02110-1301 USA. */ #include <sysdep.h> @@ -39,7 +39,7 @@ ENTRY(_start) bl _dl_start@local /* FALLTHRU */ -ENTRY(_dl_start_user) +_dl_start_user: /* Now, we do our main work of calling initialisation procedures. The ELF ABI doesn't say anything about parameters for these, so we just pass argc, argv, and the environment. @@ -47,8 +47,15 @@ ENTRY(_dl_start_user) passed by value!). */ /* Put our GOT pointer in r31, */ +#ifdef HAVE_ASM_PPC_REL16 + bcl 20,31,1f +1: mflr r31 + addis r31,r31,_GLOBAL_OFFSET_TABLE_-1b@ha + addi r31,r31,_GLOBAL_OFFSET_TABLE_-1b@l +#else bl _GLOBAL_OFFSET_TABLE_-4@local mflr r31 +#endif /* the address of _start in r30, */ mr r30,r3 /* &_dl_argc in 29, &_dl_argv in 27, and _dl_loaded in 28. */ @@ -91,6 +98,7 @@ ENTRY(_dl_start_user) Take the opportunity to clear LR, so anyone who accidentally returns from _start gets SEGV. Also clear the next few words of the stack. */ +_dl_main_dispatch: li r31,0 stw r31,0(r1) mtlr r31 diff --git a/sysdeps/powerpc/powerpc32/dl-trampoline.S b/sysdeps/powerpc/powerpc32/dl-trampoline.S new file mode 100644 index 0000000000..6a158c3fff --- /dev/null +++ b/sysdeps/powerpc/powerpc32/dl-trampoline.S @@ -0,0 +1,186 @@ +/* PLT trampolines. PPC32 version. + Copyright (C) 2005, 2006 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., 51 Franklin Street, Fifth Floor, Boston MA + 02110-1301 USA. */ + +#include <sysdep.h> + + .section ".text" + .align 2 + .globl _dl_runtime_resolve + .type _dl_runtime_resolve,@function +_dl_runtime_resolve: + cfi_startproc + # We need to save the registers used to pass parameters, and register 0, + # which is used by _mcount; the registers are saved in a stack frame. + stwu r1,-64(r1) + cfi_adjust_cfa_offset (64) + stw r0,12(r1) + stw r3,16(r1) + stw r4,20(r1) + # The code that calls this has put parameters for `fixup' in r12 and r11. + mr r3,r12 + stw r5,24(r1) + mr r4,r11 + stw r6,28(r1) + mflr r0 + # We also need to save some of the condition register fields + stw r7,32(r1) + # Don't clobber the caller's LRSAVE, it is needed by _mcount. + stw r0,48(r1) + cfi_offset (lr, -16) + stw r8,36(r1) + mfcr r0 + stw r9,40(r1) + stw r10,44(r1) + stw r0,8(r1) + bl _dl_fixup@local + # 'fixup' returns the address we want to branch to. + mtctr r3 + # Put the registers back... + lwz r0,48(r1) + lwz r10,44(r1) + lwz r9,40(r1) + mtlr r0 + lwz r8,36(r1) + lwz r0,8(r1) + lwz r7,32(r1) + lwz r6,28(r1) + mtcrf 0xFF,r0 + lwz r5,24(r1) + lwz r4,20(r1) + lwz r3,16(r1) + lwz r0,12(r1) + # ...unwind the stack frame, and jump to the PLT entry we updated. + addi r1,r1,64 + bctr + cfi_endproc + .size _dl_runtime_resolve,.-_dl_runtime_resolve + +#ifndef PROF + .align 2 + .globl _dl_prof_resolve + .type _dl_prof_resolve,@function +_dl_prof_resolve: + cfi_startproc + # We need to save the registers used to pass parameters, and register 0, + # which is used by _mcount; the registers are saved in a stack frame. + stwu r1,-320(r1) + cfi_adjust_cfa_offset (320) + /* Stack layout: + + +312 stackframe + +308 lr + +304 r1 + +288 v12 + +272 v11 + +256 v10 + +240 v9 + +224 v8 + +208 v7 + +192 v6 + +176 v5 + +160 v4 + +144 v3 + +128 v2 + +112 v1 + +104 fp8 + +96 fp7 + +88 fp6 + +80 fp5 + +72 fp4 + +64 fp3 + +56 fp2 + +48 fp1 + +44 r10 + +40 r9 + +36 r8 + +32 r7 + +28 r6 + +24 r5 + +20 r4 + +16 r3 + +12 r0 + +8 cr + r1 link + */ + stw r0,12(r1) + stw r3,16(r1) + stw r4,20(r1) + # The code that calls this has put parameters for `fixup' in r12 and r11. + mr r3,r12 + stw r5,24(r1) + mr r4,r11 + stw r6,28(r1) + mflr r5 + # We also need to save some of the condition register fields. + stw r7,32(r1) + # Don't clobber the caller's LRSAVE, it is needed by _mcount. + stw r5,308(r1) + cfi_offset (lr, -12) + stw r8,36(r1) + mfcr r0 + stw r9,40(r1) + stw r10,44(r1) + stw r0,8(r1) + # Save the floating point registers + stfd fp1,48(r1) + stfd fp2,56(r1) + stfd fp3,64(r1) + stfd fp4,72(r1) + stfd fp5,80(r1) + stfd fp6,88(r1) + stfd fp7,96(r1) + stfd fp8,104(r1) + # XXX TODO: store vmx registers + # Load the extra parameters. + addi r6,r1,16 + addi r7,r1,312 + li r0,-1 + stw r0,0(r7) + bl _dl_profile_fixup@local + # 'fixup' returns the address we want to branch to. + mtctr r3 + # Put the registers back... + lwz r0,308(r1) + lwz r10,44(r1) + lwz r9,40(r1) + mtlr r0 + lwz r8,36(r1) + lwz r0,8(r1) + lwz r7,32(r1) + lwz r6,28(r1) + mtcrf 0xFF,r0 + lwz r5,24(r1) + lwz r4,20(r1) + lwz r3,16(r1) + lwz r0,12(r1) + # Load the floating point registers. + lfd fp1,48(r1) + lfd fp2,56(r1) + lfd fp3,64(r1) + lfd fp4,72(r1) + lfd fp5,80(r1) + lfd fp6,88(r1) + lfd fp7,96(r1) + lfd fp8,104(r1) + # ...unwind the stack frame, and jump to the PLT entry we updated. + addi r1,r1,320 + bctr + cfi_endproc + .size _dl_prof_resolve,.-_dl_prof_resolve +#endif diff --git a/sysdeps/powerpc/powerpc32/elf/start.S b/sysdeps/powerpc/powerpc32/elf/start.S index 7827357a6c..bafd2ae001 100644 --- a/sysdeps/powerpc/powerpc32/elf/start.S +++ b/sysdeps/powerpc/powerpc32/elf/start.S @@ -52,7 +52,7 @@ L(start_addresses): ASM_SIZE_DIRECTIVE(L(start_addresses)) .section ".text" -#ifdef PIC +#if defined PIC && !defined HAVE_ASM_PPC_REL16 L(start_addressesp): .long L(start_addresses)-L(branch) #endif @@ -73,11 +73,19 @@ L(branch): mtlr r0 stw r0,0(r1) /* Set r13 to point at the 'small data area', and put the address of - start_addresses in r8... */ + start_addresses in r8. Also load the GOT pointer so that new PLT + calls work, like the one to __libc_start_main. */ #ifdef PIC +# ifdef HAVE_ASM_PPC_REL16 + addis r30,r13,_GLOBAL_OFFSET_TABLE_-L(branch)@ha + addis r8,r13,L(start_addresses)-L(branch)@ha + addi r30,r30,_GLOBAL_OFFSET_TABLE_-L(branch)@l + lwzu r13,L(start_addresses)-L(branch)@l(r8) +# else lwz r8,L(start_addressesp)-L(branch)(r13) add r8,r13,r8 lwz r13,0(r8) +# endif #else lis r8,L(start_addresses)@ha lwzu r13,L(start_addresses)@l(r8) diff --git a/sysdeps/powerpc/powerpc32/fpu/Dist b/sysdeps/powerpc/powerpc32/fpu/Dist deleted file mode 100644 index 375e57172e..0000000000 --- a/sysdeps/powerpc/powerpc32/fpu/Dist +++ /dev/null @@ -1,2 +0,0 @@ -fprrest.S -fprsave.S diff --git a/sysdeps/powerpc/powerpc32/fpu/__longjmp-common.S b/sysdeps/powerpc/powerpc32/fpu/__longjmp-common.S index a2415b9542..404f403855 100644 --- a/sysdeps/powerpc/powerpc32/fpu/__longjmp-common.S +++ b/sysdeps/powerpc/powerpc32/fpu/__longjmp-common.S @@ -1,5 +1,5 @@ /* longjmp for PowerPC. - Copyright (C) 1995-99, 2000, 2003, 2004 Free Software Foundation, Inc. + Copyright (C) 1995-99, 2000, 2003-2005, 2006 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 @@ -14,16 +14,15 @@ 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. */ + Software Foundation, Inc., 1 Franklin Street, Fifth Floor, Boston MA + 02110-1301 USA. */ #include <sysdep.h> #define _ASM -#define _SETJMP_H #ifdef __NO_VMX__ # include <novmxsetjmp.h> #else -# include <bits/setjmp.h> +# include <jmpbuf-offsets.h> #endif #include <bp-sym.h> #include <bp-asm.h> @@ -34,15 +33,25 @@ ENTRY (BP_SYM (__longjmp)) #ifndef __NO_VMX__ # ifdef PIC mflr r6 + cfi_register (lr,r6) +# ifdef HAVE_ASM_PPC_REL16 + bcl 20,31,1f +1: mflr r5 + addis r5,r5,_GLOBAL_OFFSET_TABLE_-1b@ha + addi r5,r5,_GLOBAL_OFFSET_TABLE_-1b@l +# else bl _GLOBAL_OFFSET_TABLE_@local-4 mflr r5 +# endif # ifdef SHARED lwz r5,_rtld_global_ro@got(r5) mtlr r6 + cfi_same_value (lr) lwz r5,RTLD_GLOBAL_RO_DL_HWCAP_OFFSET(r5) # else - lwz r5,_rtld_global_ro@got(r5) + lwz r5,_dl_hwcap@got(r5) mtlr r6 + cfi_same_value (lr) lwz r5,0(r5) # endif # else @@ -105,7 +114,11 @@ aligned_restore_vmx: lvx v31,0,r6 L(no_vmx): #endif +#ifdef PTR_DEMANGLE + lwz r24,(JB_GPR1*4)(r3) +#else lwz r1,(JB_GPR1*4)(r3) +#endif lwz r0,(JB_LR*4)(r3) lwz r14,((JB_GPRS+0)*4)(r3) lfd fp14,((JB_FPRS+0*2)*4)(r3) @@ -121,6 +134,10 @@ L(no_vmx): lfd fp19,((JB_FPRS+5*2)*4)(r3) lwz r20,((JB_GPRS+6)*4)(r3) lfd fp20,((JB_FPRS+6*2)*4)(r3) +#ifdef PTR_DEMANGLE + PTR_DEMANGLE3 (r1, r24, r25) + PTR_DEMANGLE2 (r0, r25) +#endif mtlr r0 lwz r21,((JB_GPRS+7)*4)(r3) lfd fp21,((JB_FPRS+7*2)*4)(r3) diff --git a/sysdeps/powerpc/powerpc32/fpu/fprrest.S b/sysdeps/powerpc/powerpc32/fpu/fprrest.S index 42317809eb..2f6c6deb2e 100644 --- a/sysdeps/powerpc/powerpc32/fpu/fprrest.S +++ b/sysdeps/powerpc/powerpc32/fpu/fprrest.S @@ -1,4 +1,4 @@ -/* Copyright (C) 2000, 2001 Free Software Foundation, Inc. +/* Copyright (C) 2000, 2001, 2006 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 @@ -13,8 +13,8 @@ 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. */ + Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA + 02110-1301 USA. */ /* Floating Point Registers (FPRs) restore routine @@ -92,3 +92,4 @@ C_TEXT(_restfpr_29): lwz r0,8(r1) #get return address from frame lfd fp30,-16(r1) #restore f30 lfd fp31,-8(r1) #restore f31 blr #return +END (_restfpr_all) diff --git a/sysdeps/powerpc/powerpc32/fpu/fprsave.S b/sysdeps/powerpc/powerpc32/fpu/fprsave.S index d7bc1ab7dc..c05178775d 100644 --- a/sysdeps/powerpc/powerpc32/fpu/fprsave.S +++ b/sysdeps/powerpc/powerpc32/fpu/fprsave.S @@ -1,4 +1,4 @@ -/* Copyright (C) 2000, 2001 Free Software Foundation, Inc. +/* Copyright (C) 2000, 2001, 2006 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 @@ -13,8 +13,8 @@ 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. */ + Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA + 02110-1301 USA. */ /* Floating Point Registers (FPRs) save routine @@ -27,67 +27,86 @@ ENTRY(_savefpr_all) ASM_GLOBAL_DIRECTIVE C_TEXT(_savefpr_14) C_TEXT(_savef14): C_TEXT(_savefpr_14): stfd fp14,-144(r1) + cfi_offset(fp14,-144) ASM_GLOBAL_DIRECTIVE C_TEXT(_savef15) ASM_GLOBAL_DIRECTIVE C_TEXT(_savefpr_15) C_TEXT(_savef15): C_TEXT(_savefpr_15): stfd fp15,-136(r1) + cfi_offset(fp15,-136) ASM_GLOBAL_DIRECTIVE C_TEXT(_savef16) ASM_GLOBAL_DIRECTIVE C_TEXT(_savefpr_16) C_TEXT(_savef16): C_TEXT(_savefpr_16): stfd fp16,-128(r1) + cfi_offset(fp16,-128) ASM_GLOBAL_DIRECTIVE C_TEXT(_savef17) ASM_GLOBAL_DIRECTIVE C_TEXT(_savefpr_17) C_TEXT(_savef17): C_TEXT(_savefpr_17): stfd fp17,-120(r1) + cfi_offset(fp17,-120) ASM_GLOBAL_DIRECTIVE C_TEXT(_savef18) ASM_GLOBAL_DIRECTIVE C_TEXT(_savefpr_18) C_TEXT(_savef18): C_TEXT(_savefpr_18): stfd fp18,-112(r1) + cfi_offset(fp18,-112) ASM_GLOBAL_DIRECTIVE C_TEXT(_savef19) ASM_GLOBAL_DIRECTIVE C_TEXT(_savefpr_19) C_TEXT(_savef19): C_TEXT(_savefpr_19): stfd fp19,-104(r1) + cfi_offset(fp19,-104) ASM_GLOBAL_DIRECTIVE C_TEXT(_savef20) ASM_GLOBAL_DIRECTIVE C_TEXT(_savefpr_20) C_TEXT(_savef20): C_TEXT(_savefpr_20): stfd fp20,-96(r1) + cfi_offset(fp20,-96) ASM_GLOBAL_DIRECTIVE C_TEXT(_savef21) ASM_GLOBAL_DIRECTIVE C_TEXT(_savefpr_21) C_TEXT(_savef21): C_TEXT(_savefpr_21): stfd fp21,-88(r1) + cfi_offset(fp21,-88) ASM_GLOBAL_DIRECTIVE C_TEXT(_savef22) ASM_GLOBAL_DIRECTIVE C_TEXT(_savefpr_22) C_TEXT(_savef22): C_TEXT(_savefpr_22): stfd fp22,-80(r1) + cfi_offset(fp22,-80) ASM_GLOBAL_DIRECTIVE C_TEXT(_savef23) ASM_GLOBAL_DIRECTIVE C_TEXT(_savefpr_23) C_TEXT(_savef23): C_TEXT(_savefpr_23): stfd fp23,-72(r1) + cfi_offset(fp23,-72) ASM_GLOBAL_DIRECTIVE C_TEXT(_savef24) ASM_GLOBAL_DIRECTIVE C_TEXT(_savefpr_24) C_TEXT(_savef24): C_TEXT(_savefpr_24): stfd fp24,-64(r1) + cfi_offset(fp24,-64) ASM_GLOBAL_DIRECTIVE C_TEXT(_savef25) ASM_GLOBAL_DIRECTIVE C_TEXT(_savefpr_25) C_TEXT(_savef25): C_TEXT(_savefpr_25): stfd fp25,-56(r1) + cfi_offset(fp25,-56) ASM_GLOBAL_DIRECTIVE C_TEXT(_savef26) ASM_GLOBAL_DIRECTIVE C_TEXT(_savefpr_26) C_TEXT(_savef26): C_TEXT(_savefpr_26): stfd fp26,-48(r1) + cfi_offset(fp26,-48) ASM_GLOBAL_DIRECTIVE C_TEXT(_savef27) ASM_GLOBAL_DIRECTIVE C_TEXT(_savefpr_27) C_TEXT(_savef27): C_TEXT(_savefpr_27): stfd fp27,-40(r1) + cfi_offset(fp27,-40) ASM_GLOBAL_DIRECTIVE C_TEXT(_savef28) ASM_GLOBAL_DIRECTIVE C_TEXT(_savefpr_28) C_TEXT(_savef28): C_TEXT(_savefpr_28): stfd fp28,-32(r1) + cfi_offset(fp28,-32) ASM_GLOBAL_DIRECTIVE C_TEXT(_savef29) ASM_GLOBAL_DIRECTIVE C_TEXT(_savefpr_29) C_TEXT(_savef29): C_TEXT(_savefpr_29): stfd fp29,-24(r1) #save f29 stfd fp30,-16(r1) #save f30 stfd fp31,-8(r1) #save f31 + cfi_offset(fp29,-24) + cfi_offset(fp30,-16) + cfi_offset(fp31,-8) stw r0,8(r1) #save LR in callers frame blr #return +END (_savefpr_all) diff --git a/sysdeps/powerpc/powerpc32/fpu/s_ceil.S b/sysdeps/powerpc/powerpc32/fpu/s_ceil.S index d211314bbf..bc74d302fb 100644 --- a/sysdeps/powerpc/powerpc32/fpu/s_ceil.S +++ b/sysdeps/powerpc/powerpc32/fpu/s_ceil.S @@ -1,5 +1,5 @@ /* ceil function. PowerPC32 version. - Copyright (C) 2004 Free Software Foundation, Inc. + Copyright (C) 2004, 2006 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 @@ -14,46 +14,39 @@ 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. */ + Software Foundation, Inc., 1 Franklin Street, Fifth Floor, Boston MA + 02110-1301 USA. */ #include <sysdep.h> +#include <math_ldbl_opt.h> - .section .rodata - .align 3 - .type TWO52.0,@object - .size TWO52.0,8 -TWO52.0: - .long 0x43300000 - .long 0 - .type NEGZERO.0,@object - .size NEGZERO.0,8 -NEGZERO.0: - .long 0x80000000 - .long 0 - - .section .rodata.cst8,"aM",@progbits,8 - .align 3 + .section .rodata.cst4,"aM",@progbits,4 + .align 2 .LC0: /* 2**52 */ - .long 0x43300000 - .long 0 -.LC1: /* -0.0 */ - .long 0x80000000 - .long 0 + .long 0x59800000 .section ".text" ENTRY (__ceil) mffs fp11 /* Save current FPU rounding mode. */ #ifdef SHARED mflr r11 + cfi_register(lr,r11) +# ifdef HAVE_ASM_PPC_REL16 + bcl 20,31,1f +1: mflr r9 + addis r9,r9,.LC0-1b@ha + lfs fp13,.LC0-1b@l(r9) +# else bl _GLOBAL_OFFSET_TABLE_@local-4 mflr r10 lwz r9,.LC0@got(10) + lfs fp13,0(r9) +# endif mtlr r11 - lfd fp13,0(r9) + cfi_same_value (lr) #else lis r9,.LC0@ha - lfd fp13,.LC0@l(r9) + lfs fp13,.LC0@l(r9) #endif fabs fp0,fp1 fsub fp12,fp13,fp13 /* generate 0.0 */ @@ -64,27 +57,18 @@ ENTRY (__ceil) ble- cr6,.L4 fadd fp1,fp1,fp13 /* x+= TWO52; */ fsub fp1,fp1,fp13 /* x-= TWO52; */ -.L9: + fabs fp1,fp1 /* if (x == 0.0) */ + /* x = 0.0; */ mtfsf 0x01,fp11 /* restore previous rounding mode. */ blr .L4: bge- cr6,.L9 /* if (x < 0.0) */ fsub fp1,fp1,fp13 /* x-= TWO52; */ fadd fp1,fp1,fp13 /* x+= TWO52; */ - fcmpu cr5,fp1,fp12 /* if (x > 0.0) */ + fnabs fp1,fp1 /* if (x == 0.0) */ + /* x = -0.0; */ +.L9: mtfsf 0x01,fp11 /* restore previous rounding mode. */ - bnelr+ cr5 -#ifdef SHARED - mflr r11 - bl _GLOBAL_OFFSET_TABLE_@local-4 - mflr r10 - lwz r9,.LC1@got(10) - mtlr r11 - lfd fp1,0(r9) -#else - lis r9,.LC1@ha - lfd fp1,.LC1@l(r9) -#endif blr END (__ceil) @@ -94,3 +78,6 @@ weak_alias (__ceil, ceil) weak_alias (__ceil, ceill) strong_alias (__ceil, __ceill) #endif +#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_0) +compat_symbol (libm, __ceil, ceill, GLIBC_2_0) +#endif diff --git a/sysdeps/powerpc/powerpc32/fpu/s_ceilf.S b/sysdeps/powerpc/powerpc32/fpu/s_ceilf.S index 4439dc2338..47a75ec0c3 100644 --- a/sysdeps/powerpc/powerpc32/fpu/s_ceilf.S +++ b/sysdeps/powerpc/powerpc32/fpu/s_ceilf.S @@ -1,5 +1,5 @@ /* float ceil function. PowerPC32 version. - Copyright (C) 2004 Free Software Foundation, Inc. + Copyright (C) 2004, 2006 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 @@ -14,46 +14,38 @@ 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. */ + Software Foundation, Inc., 1 Franklin Street, Fifth Floor, Boston MA + 02110-1301 USA. */ #include <sysdep.h> - .section .rodata - .align 3 - .type TWO52.0,@object - .size TWO52.0,8 -TWO52.0: - .long 0x43300000 - .long 0 - .type NEGZERO.0,@object - .size NEGZERO.0,8 -NEGZERO.0: - .long 0x80000000 - .long 0 - - .section .rodata.cst8,"aM",@progbits,8 - .align 3 + .section .rodata.cst4,"aM",@progbits,4 + .align 2 .LC0: /* 2**23 */ - .long 0x41600000 - .long 0 -.LC1: /* -0.0 */ - .long 0x80000000 - .long 0 + .long 0x4b000000 .section ".text" ENTRY (__ceilf) mffs fp11 /* Save current FPU rounding mode. */ #ifdef SHARED mflr r11 + cfi_register(lr,r11) +# ifdef HAVE_ASM_PPC_REL16 + bcl 20,31,1f +1: mflr r9 + addis r9,r9,.LC0-1b@ha + lfs fp13,.LC0-1b@l(r9) +# else bl _GLOBAL_OFFSET_TABLE_@local-4 mflr r10 lwz r9,.LC0@got(10) + lfs fp13,0(r9) +# endif mtlr r11 - lfd fp13,0(r9) + cfi_same_value (lr) #else lis r9,.LC0@ha - lfd fp13,.LC0@l(r9) + lfs fp13,.LC0@l(r9) #endif fabs fp0,fp1 fsubs fp12,fp13,fp13 /* generate 0.0 */ @@ -64,27 +56,18 @@ ENTRY (__ceilf) ble- cr6,.L4 fadds fp1,fp1,fp13 /* x+= TWO23; */ fsubs fp1,fp1,fp13 /* x-= TWO23; */ -.L9: + fabs fp1,fp1 /* if (x == 0.0) */ + /* x = 0.0; */ mtfsf 0x01,fp11 /* restore previous rounding mode. */ blr .L4: bge- cr6,.L9 /* if (x < 0.0) */ fsubs fp1,fp1,fp13 /* x-= TWO23; */ fadds fp1,fp1,fp13 /* x+= TWO23; */ - fcmpu cr5,fp1,fp12 /* if (x > 0.0) */ + fnabs fp1,fp1 /* if (x == 0.0) */ + /* x = -0.0; */ +.L9: mtfsf 0x01,fp11 /* restore previous rounding mode. */ - bnelr+ cr5 -#ifdef SHARED - mflr r11 - bl _GLOBAL_OFFSET_TABLE_@local-4 - mflr r10 - lwz r9,.LC1@got(10) - mtlr r11 - lfd fp1,0(r9) -#else - lis r9,.LC1@ha - lfd fp1,.LC1@l(r9) -#endif blr END (__ceilf) diff --git a/sysdeps/powerpc/powerpc32/fpu/s_copysign.S b/sysdeps/powerpc/powerpc32/fpu/s_copysign.S index 933435da3d..dd68b0869c 100644 --- a/sysdeps/powerpc/powerpc32/fpu/s_copysign.S +++ b/sysdeps/powerpc/powerpc32/fpu/s_copysign.S @@ -1,5 +1,5 @@ /* Copy a sign bit between floating-point values. - Copyright (C) 1997, 1999, 2000 Free Software Foundation, Inc. + Copyright (C) 1997, 1999, 2000, 2006 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 @@ -14,23 +14,26 @@ 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. */ + Software Foundation, Inc., 1 Franklin Street, Fifth Floor, Boston MA + 02110-1301 USA. */ /* This has been coded in assembler because GCC makes such a mess of it when it's coded in C. */ #include <sysdep.h> +#include <math_ldbl_opt.h> ENTRY(__copysign) /* double [f1] copysign (double [f1] x, double [f2] y); copysign(x,y) returns a value with the magnitude of x and with the sign bit of y. */ stwu r1,-16(r1) + cfi_adjust_cfa_offset (16) stfd fp2,8(r1) lwz r3,8(r1) cmpwi r3,0 addi r1,r1,16 + cfi_adjust_cfa_offset (-16) blt L(0) fabs fp1,fp1 blr @@ -38,13 +41,20 @@ L(0): fnabs fp1,fp1 blr END (__copysign) -weak_alias(__copysign,copysign) +weak_alias (__copysign,copysign) /* It turns out that it's safe to use this code even for single-precision. */ -weak_alias(__copysign,copysignf) +weak_alias (__copysign,copysignf) strong_alias(__copysign,__copysignf) #ifdef NO_LONG_DOUBLE -weak_alias(__copysign,copysignl) +weak_alias (__copysign,copysignl) strong_alias(__copysign,__copysignl) #endif +#ifdef IS_IN_libm +# if LONG_DOUBLE_COMPAT(libm, GLIBC_2_0) +compat_symbol (libm, __copysign, copysignl, GLIBC_2_0) +# endif +#elif LONG_DOUBLE_COMPAT(libc, GLIBC_2_0) +compat_symbol (libc, __copysign, copysignl, GLIBC_2_0) +#endif diff --git a/sysdeps/powerpc/powerpc32/fpu/s_copysignl.S b/sysdeps/powerpc/powerpc32/fpu/s_copysignl.S new file mode 100644 index 0000000000..64b6a45437 --- /dev/null +++ b/sysdeps/powerpc/powerpc32/fpu/s_copysignl.S @@ -0,0 +1,50 @@ +/* Copy a sign bit between floating-point values. + IBM extended format long double version. + Copyright (C) 2006 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> +#include <math_ldbl_opt.h> + +ENTRY(__copysignl) +/* long double [f1,f2] copysign (long double [f1,f2] x, long double [f3,f4] y); + copysign(x,y) returns a value with the magnitude of x and + with the sign bit of y. */ + stwu r1,-16(r1) + cfi_adjust_cfa_offset (16) + stfd fp3,8(r1) + fmr fp0,fp1 + fabs fp1,fp1 + fcmpu cr7,fp0,fp1 + lwz r3,8(r1) + cmpwi cr6,r3,0 + addi r1,r1,16 + cfi_adjust_cfa_offset (-16) + beq cr7,L(0) + fneg fp2,fp2 +L(0): bgelr cr6 + fneg fp1,fp1 + fneg fp2,fp2 + blr +END (__copysignl) + +#ifdef IS_IN_libm +long_double_symbol (libm, __copysignl, copysignl) +#else +long_double_symbol (libc, __copysignl, copysignl) +#endif diff --git a/sysdeps/powerpc/powerpc32/fpu/s_fabs.S b/sysdeps/powerpc/powerpc32/fpu/s_fabs.S new file mode 100644 index 0000000000..53d21301ee --- /dev/null +++ b/sysdeps/powerpc/powerpc32/fpu/s_fabs.S @@ -0,0 +1,5 @@ +#include <math_ldbl_opt.h> +#include <sysdeps/powerpc/fpu/s_fabs.S> +#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_0) +compat_symbol (libm, __fabs, fabsl, GLIBC_2_0) +#endif diff --git a/sysdeps/powerpc/powerpc32/fpu/s_fabsl.S b/sysdeps/powerpc/powerpc32/fpu/s_fabsl.S new file mode 100644 index 0000000000..3655e5b2f3 --- /dev/null +++ b/sysdeps/powerpc/powerpc32/fpu/s_fabsl.S @@ -0,0 +1,36 @@ +/* Copy a sign bit between floating-point values. + IBM extended format long double version. + Copyright (C) 2004, 2006 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> +#include <math_ldbl_opt.h> + +ENTRY(__fabsl) +/* long double [f1,f2] fabs (long double [f1,f2] x); + fabs(x,y) returns a value with the magnitude of x and + with the sign bit of y. */ + fmr fp0,fp1 + fabs fp1,fp1 + fcmpu cr1,fp0,fp1 + beqlr cr1 + fneg fp2,fp2 + blr +END (__fabsl) + +long_double_symbol (libm, __fabsl, fabsl) diff --git a/sysdeps/powerpc/powerpc32/fpu/s_fdim.c b/sysdeps/powerpc/powerpc32/fpu/s_fdim.c new file mode 100644 index 0000000000..e34b51ee54 --- /dev/null +++ b/sysdeps/powerpc/powerpc32/fpu/s_fdim.c @@ -0,0 +1,5 @@ +#include <math_ldbl_opt.h> +#include <sysdeps/powerpc/fpu/s_fdim.c> +#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_1) +compat_symbol (libm, __fdim, fdiml, GLIBC_2_1); +#endif diff --git a/sysdeps/powerpc/powerpc32/fpu/s_floor.S b/sysdeps/powerpc/powerpc32/fpu/s_floor.S index 143f907b18..a29e4791ea 100644 --- a/sysdeps/powerpc/powerpc32/fpu/s_floor.S +++ b/sysdeps/powerpc/powerpc32/fpu/s_floor.S @@ -1,5 +1,5 @@ /* Floor function. PowerPC32 version. - Copyright (C) 2004 Free Software Foundation, Inc. + Copyright (C) 2004, 2006 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 @@ -14,38 +14,39 @@ 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. */ + Software Foundation, Inc., 1 Franklin Street, Fifth Floor, Boston MA + 02110-1301 USA. */ #include <sysdep.h> +#include <math_ldbl_opt.h> - .section .rodata - .align 3 - .type TWO52.0,@object - .size TWO52.0,8 -TWO52.0: - .long 0x43300000 - .long 0 - - .section .rodata.cst8,"aM",@progbits,8 - .align 3 + .section .rodata.cst4,"aM",@progbits,4 + .align 2 .LC0: /* 2**52 */ - .long 0x43300000 - .long 0 + .long 0x59800000 .section ".text" ENTRY (__floor) mffs fp11 /* Save current FPU rounding mode. */ #ifdef SHARED mflr r11 + cfi_register(lr,r11) +# ifdef HAVE_ASM_PPC_REL16 + bcl 20,31,1f +1: mflr r9 + addis r9,r9,.LC0-1b@ha + lfs fp13,.LC0-1b@l(r9) +# else bl _GLOBAL_OFFSET_TABLE_@local-4 mflr r10 lwz r9,.LC0@got(10) + lfs fp13,0(r9) +# endif mtlr r11 - lfd fp13,0(r9) + cfi_same_value (lr) #else lis r9,.LC0@ha - lfd fp13,.LC0@l(r9) + lfs fp13,.LC0@l(r9) #endif fabs fp0,fp1 fsub fp12,fp13,fp13 /* generate 0.0 */ @@ -56,15 +57,16 @@ ENTRY (__floor) ble- cr6,.L4 fadd fp1,fp1,fp13 /* x+= TWO52; */ fsub fp1,fp1,fp13 /* x-= TWO52; */ - fcmpu cr5,fp1,fp12 /* if (x > 0.0) */ + fabs fp1,fp1 /* if (x == 0.0) */ + /* x = 0.0; */ mtfsf 0x01,fp11 /* restore previous rounding mode. */ - bnelr+ cr5 - fmr fp1,fp12 /* x must be +0.0 for the 0.0 case. */ blr .L4: bge- cr6,.L9 /* if (x < 0.0) */ fsub fp1,fp1,fp13 /* x-= TWO52; */ fadd fp1,fp1,fp13 /* x+= TWO52; */ + fnabs fp1,fp1 /* if (x == 0.0) */ + /* x = -0.0; */ .L9: mtfsf 0x01,fp11 /* restore previous rounding mode. */ blr @@ -76,3 +78,6 @@ weak_alias (__floor, floor) weak_alias (__floor, floorl) strong_alias (__floor, __floorl) #endif +#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_0) +compat_symbol (libm, __floor, floorl, GLIBC_2_0) +#endif diff --git a/sysdeps/powerpc/powerpc32/fpu/s_floorf.S b/sysdeps/powerpc/powerpc32/fpu/s_floorf.S index 154bc30ff7..99fbdc5f86 100644 --- a/sysdeps/powerpc/powerpc32/fpu/s_floorf.S +++ b/sysdeps/powerpc/powerpc32/fpu/s_floorf.S @@ -1,5 +1,5 @@ /* float Floor function. PowerPC32 version. - Copyright (C) 2004 Free Software Foundation, Inc. + Copyright (C) 2004, 2006 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 @@ -14,38 +14,38 @@ 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. */ + Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA + 02110-1301 USA. */ #include <sysdep.h> - .section .rodata - .align 3 - .type TWO23.0,@object - .size TWO23.0,8 -TWO23.0: - .long 0x41600000 - .long 0 - - .section .rodata.cst8,"aM",@progbits,8 - .align 3 + .section .rodata.cst4,"aM",@progbits,4 + .align 2 .LC0: /* 2**23 */ - .long 0x41600000 - .long 0 + .long 0x4b000000 .section ".text" ENTRY (__floorf) mffs fp11 /* Save current FPU rounding mode. */ #ifdef SHARED mflr r11 + cfi_register(lr,r11) +# ifdef HAVE_ASM_PPC_REL16 + bcl 20,31,1f +1: mflr r9 + addis r9,r9,.LC0-1b@ha + lfs fp13,.LC0-1b@l(r9) +# else bl _GLOBAL_OFFSET_TABLE_@local-4 mflr r10 lwz r9,.LC0@got(10) + lfs fp13,0(r9) +# endif mtlr r11 - lfd fp13,0(r9) + cfi_same_value (lr) #else lis r9,.LC0@ha - lfd fp13,.LC0@l(r9) + lfs fp13,.LC0@l(r9) #endif fabs fp0,fp1 fsubs fp12,fp13,fp13 /* generate 0.0 */ @@ -56,15 +56,16 @@ ENTRY (__floorf) ble- cr6,.L4 fadds fp1,fp1,fp13 /* x+= TWO23; */ fsubs fp1,fp1,fp13 /* x-= TWO23; */ - fcmpu cr5,fp1,fp12 /* if (x > 0.0) */ + fabs fp1,fp1 /* if (x == 0.0) */ + /* x = 0.0; */ mtfsf 0x01,fp11 /* restore previous rounding mode. */ - bnelr+ cr5 - fmr fp1,fp12 /* x must be +0.0 for the 0.0 case. */ blr .L4: bge- cr6,.L9 /* if (x < 0.0) */ fsubs fp1,fp1,fp13 /* x-= TWO23; */ fadds fp1,fp1,fp13 /* x+= TWO23; */ + fnabs fp1,fp1 /* if (x == 0.0) */ + /* x = -0.0; */ .L9: mtfsf 0x01,fp11 /* restore previous rounding mode. */ blr diff --git a/sysdeps/powerpc/powerpc32/fpu/s_fmax.S b/sysdeps/powerpc/powerpc32/fpu/s_fmax.S new file mode 100644 index 0000000000..69735761ab --- /dev/null +++ b/sysdeps/powerpc/powerpc32/fpu/s_fmax.S @@ -0,0 +1,5 @@ +#include <math_ldbl_opt.h> +#include <sysdeps/powerpc/fpu/s_fmax.S> +#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_1) +compat_symbol (libm, __fmax, fmaxl, GLIBC_2_1) +#endif diff --git a/sysdeps/powerpc/powerpc32/fpu/s_fmin.S b/sysdeps/powerpc/powerpc32/fpu/s_fmin.S new file mode 100644 index 0000000000..6d4a0a946c --- /dev/null +++ b/sysdeps/powerpc/powerpc32/fpu/s_fmin.S @@ -0,0 +1,5 @@ +#include <math_ldbl_opt.h> +#include <sysdeps/powerpc/fpu/s_fmin.S> +#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_1) +compat_symbol (libm, __fmin, fminl, GLIBC_2_1) +#endif diff --git a/sysdeps/powerpc/powerpc32/fpu/s_isnan.c b/sysdeps/powerpc/powerpc32/fpu/s_isnan.c new file mode 100644 index 0000000000..397717ba9c --- /dev/null +++ b/sysdeps/powerpc/powerpc32/fpu/s_isnan.c @@ -0,0 +1,7 @@ +#include <sysdeps/powerpc/fpu/s_isnan.c> +#ifndef IS_IN_libm +# if LONG_DOUBLE_COMPAT(libc, GLIBC_2_0) +compat_symbol (libc, __isnan, __isnanl, GLIBC_2_0); +compat_symbol (libc, isnan, isnanl, GLIBC_2_0); +# endif +#endif diff --git a/sysdeps/powerpc/powerpc32/fpu/s_llrint.c b/sysdeps/powerpc/powerpc32/fpu/s_llrint.c index 7fdc296b0b..cb96be7c9b 100644 --- a/sysdeps/powerpc/powerpc32/fpu/s_llrint.c +++ b/sysdeps/powerpc/powerpc32/fpu/s_llrint.c @@ -1,5 +1,5 @@ /* Round a double value to a long long in the current rounding mode. - Copyright (C) 1997 Free Software Foundation, Inc. + Copyright (C) 1997, 2006 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 @@ -17,7 +17,8 @@ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -#include "math.h" +#include <math.h> +#include <math_ldbl_opt.h> long long int __llrint (double x) @@ -29,3 +30,6 @@ weak_alias (__llrint, llrint) strong_alias (__llrint, __llrintl) weak_alias (__llrint, llrintl) #endif +#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_1) +compat_symbol (libm, __llrint, llrintl, GLIBC_2_1); +#endif diff --git a/sysdeps/powerpc/powerpc32/fpu/s_lrint.S b/sysdeps/powerpc/powerpc32/fpu/s_lrint.S index 57d56c48cd..da0a1e505a 100644 --- a/sysdeps/powerpc/powerpc32/fpu/s_lrint.S +++ b/sysdeps/powerpc/powerpc32/fpu/s_lrint.S @@ -1,5 +1,5 @@ /* Round double to long int. PowerPC32 version. - Copyright (C) 2004 Free Software Foundation, Inc. + Copyright (C) 2004, 2006 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 @@ -18,15 +18,18 @@ 02111-1307 USA. */ #include <sysdep.h> +#include <math_ldbl_opt.h> /* long int[r3] __lrint (double x[fp1]) */ -ENTRY (__lrint) +ENTRY (__lrint) + stwu r1,-16(r1) fctiw fp13,fp1 - stfd fp13,-8(r1) + stfd fp13,8(r1) nop /* Insure the following load is in a different dispatch group */ nop /* to avoid pipe stall on POWER4&5. */ nop - lwz r3,-4(r1) + lwz r3,12(r1) + addi r1,r1,16 blr END (__lrint) @@ -39,3 +42,6 @@ weak_alias (__lrint, lrintf) strong_alias (__lrint, __lrintl) weak_alias (__lrint, lrintl) #endif +#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_1) +compat_symbol (libm, __lrint, lrintl, GLIBC_2_1) +#endif diff --git a/sysdeps/powerpc/powerpc32/fpu/s_lround.S b/sysdeps/powerpc/powerpc32/fpu/s_lround.S index dcb97e373b..9c534ec2be 100644 --- a/sysdeps/powerpc/powerpc32/fpu/s_lround.S +++ b/sysdeps/powerpc/powerpc32/fpu/s_lround.S @@ -1,5 +1,5 @@ /* lround function. PowerPC32 version. - Copyright (C) 2004 Free Software Foundation, Inc. + Copyright (C) 2004, 2006 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 @@ -14,32 +14,18 @@ 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. */ + Software Foundation, Inc., 1 Franklin Street, Fifth Floor, Boston MA + 02110-1301 USA. */ #include <sysdep.h> - - .section .rodata - .align 3 - .type NEGZERO.0,@object - .size NEGZERO.0,8 -NEGZERO.0: - .long 0x00000000 - .long 0 - .type POINTFIVE.0,@object - .size POINTFIVE.0,8 -POINTFIVE.0: - .long 0x3fe00000 - .long 0 +#include <math_ldbl_opt.h> .section .rodata.cst8,"aM",@progbits,8 - .align 3 + .align 2 .LC0: /* 0.0 */ .long 0x00000000 - .long 0 .LC1: /* 0.5 */ - .long 0x3fe00000 - .long 0 + .long 0x3f000000 .section ".text" @@ -54,41 +40,51 @@ POINTFIVE.0: to the integer value. */ ENTRY (__lround) + stwu r1,-16(r1) + cfi_adjust_cfa_offset (16) #ifdef SHARED mflr r11 + cfi_register(lr,r11) +# ifdef HAVE_ASM_PPC_REL16 + bcl 20,31,1f +1: mflr r9 + addis r9,r9,.LC0-1b@ha + addi r9,r9,.LC0-1b@l +# else bl _GLOBAL_OFFSET_TABLE_@local-4 mflr r10 lwz r9,.LC0@got(10) +# endif mtlr r11 - lfd fp12,0(r9) + cfi_same_value (lr) + lfs fp12,0(r9) #else lis r9,.LC0@ha - lfd fp12,.LC0@l(r9) + lfs fp12,.LC0@l(r9) #endif #ifdef SHARED - lwz r9,.LC1@got(10) - lfd fp10,0(r9) + lfs fp10,.LC1-.LC0(r9) #else lis r9,.LC1@ha - lfd fp10,.LC1@l(r9) + lfs fp10,.LC1@l(r9) #endif fcmpu cr6,fp1,fp12 /* if (x > 0.0) */ ble- cr6,.L4 fadd fp1,fp1,fp10 /* x+= 0.5; */ .L9: fctiwz fp2,fp1 /* Convert To Integer DW lround toward 0. */ - stfd fp2,-8(r1) - nop /* Insure the following load is in a different dispatch group */ - nop /* to avoid pipe stall on POWER4&5. */ + stfd fp2,8(r1) + nop /* Ensure the following load is in a different dispatch */ + nop /* group to avoid pipe stall on POWER4&5. */ nop - lwz r3,-4(r1) + lwz r3,12(r1) + addi r1,r1,16 blr .L4: fsub fp1,fp1,fp10 /* x-= 0.5; */ b .L9 END (__lround) -strong_alias (__lround, __lround) weak_alias (__lround, lround) strong_alias (__lround, __lroundf) @@ -98,3 +94,6 @@ weak_alias (__lround, lroundf) weak_alias (__lround, lroundl) strong_alias (__lround, __lroundl) #endif +#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_1) +compat_symbol (libm, __lround, lroundl, GLIBC_2_1) +#endif diff --git a/sysdeps/powerpc/powerpc32/fpu/s_rint.S b/sysdeps/powerpc/powerpc32/fpu/s_rint.S index dee25f204f..c8dca313ae 100644 --- a/sysdeps/powerpc/powerpc32/fpu/s_rint.S +++ b/sysdeps/powerpc/powerpc32/fpu/s_rint.S @@ -1,5 +1,5 @@ /* Round to int floating-point values. PowerPC32 version. - Copyright (C) 2004 Free Software Foundation, Inc. + Copyright (C) 2004, 2006 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 @@ -14,40 +14,41 @@ 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. */ + Software Foundation, Inc., 1 Franklin Street, Fifth Floor, Boston MA + 02110-1301 USA. */ /* This has been coded in assembler because GCC makes such a mess of it when it's coded in C. */ #include <sysdep.h> +#include <math_ldbl_opt.h> - .section .rodata - .align 3 - .type TWO52.0,@object - .size TWO52.0,8 -TWO52.0: - .long 0x43300000 - .long 0 - - .section .rodata.cst8,"aM",@progbits,8 - .align 3 + .section .rodata.cst4,"aM",@progbits,4 + .align 2 .LC0: /* 2**52 */ - .long 0x43300000 - .long 0 + .long 0x59800000 .section ".text" ENTRY (__rint) #ifdef SHARED mflr r11 + cfi_register(lr,r11) +# ifdef HAVE_ASM_PPC_REL16 + bcl 20,31,1f +1: mflr r9 + addis r9,r9,.LC0-1b@ha + lfs fp13,.LC0-1b@l(r9) +# else bl _GLOBAL_OFFSET_TABLE_@local-4 mflr r10 lwz r9,.LC0@got(10) + lfs fp13,0(r9) +# endif mtlr r11 - lfd fp13,0(r9) + cfi_same_value (lr) #else lis r9,.LC0@ha - lfd fp13,.LC0@l(r9) + lfs fp13,.LC0@l(r9) #endif fabs fp0,fp1 fsub fp12,fp13,fp13 /* generate 0.0 */ @@ -57,13 +58,14 @@ ENTRY (__rint) bng- cr6,.L4 fadd fp1,fp1,fp13 /* x+= TWO52; */ fsub fp1,fp1,fp13 /* x-= TWO52; */ - blr + fabs fp1,fp1 /* if (x == 0.0) */ + blr /* x = 0.0; */ .L4: bnllr- cr6 /* if (x < 0.0) */ - fsub fp1,fp13,fp1 /* x = TWO52 - x; */ - fsub fp0,fp1,fp13 /* x = - (x - TWO52); */ - fneg fp1,fp0 - blr + fsub fp1,fp1,fp13 /* x-= TWO52; */ + fadd fp1,fp1,fp13 /* x+= TWO52; */ + fnabs fp1,fp1 /* if (x == 0.0) */ + blr /* x = -0.0; */ END (__rint) weak_alias (__rint, rint) @@ -72,3 +74,6 @@ weak_alias (__rint, rint) weak_alias (__rint, rintl) strong_alias (__rint, __rintl) #endif +#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_0) +compat_symbol (libm, __rint, rintl, GLIBC_2_0) +#endif diff --git a/sysdeps/powerpc/powerpc32/fpu/s_rintf.S b/sysdeps/powerpc/powerpc32/fpu/s_rintf.S index cebf6423af..7771cb2bc8 100644 --- a/sysdeps/powerpc/powerpc32/fpu/s_rintf.S +++ b/sysdeps/powerpc/powerpc32/fpu/s_rintf.S @@ -1,5 +1,5 @@ /* Round float to int floating-point values. PowerPC32 version. - Copyright (C) 2004 Free Software Foundation, Inc. + Copyright (C) 2004, 2006 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 @@ -14,38 +14,37 @@ 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. */ + Software Foundation, Inc., 1 Franklin Street, Fifth Floor, Boston MA + 02110-1301 USA. */ #include <sysdep.h> - - .section .rodata - .align 3 - .type TWO23.0,@object - .size TWO23.0,8 -TWO23.0: - .long 0x41600000 - .long 0 - - .section .rodata.cst8,"aM",@progbits,8 - .align 3 + .section .rodata.cst4,"aM",@progbits,4 + .align 2 .LC0: /* 2**23 */ - .long 0x41600000 - .long 0 + .long 0x4b000000 .section ".text" ENTRY (__rintf) #ifdef SHARED mflr r11 + cfi_register(lr,r11) +# ifdef HAVE_ASM_PPC_REL16 + bcl 20,31,1f +1: mflr r9 + addis r9,r9,.LC0-1b@ha + lfs fp13,.LC0-1b@l(r9) +# else bl _GLOBAL_OFFSET_TABLE_@local-4 mflr r10 lwz r9,.LC0@got(10) + lfs fp13,0(r9) +# endif mtlr r11 - lfd fp13,0(r9) + cfi_same_value (lr) #else lis r9,.LC0@ha - lfd fp13,.LC0@l(r9) + lfs fp13,.LC0@l(r9) #endif fabs fp0,fp1 fsubs fp12,fp13,fp13 /* generate 0.0 */ @@ -55,13 +54,14 @@ ENTRY (__rintf) bng- cr6,.L4 fadds fp1,fp1,fp13 /* x+= TWO23; */ fsubs fp1,fp1,fp13 /* x-= TWO23; */ - blr + fabs fp1,fp1 /* if (x == 0.0) */ + blr /* x = 0.0; */ .L4: bnllr- cr6 /* if (x < 0.0) */ - fsubs fp1,fp13,fp1 /* x = TWO23 - x; */ - fsubs fp0,fp1,fp13 /* x = - (x - TWO23); */ - fneg fp1,fp0 - blr + fsubs fp1,fp1,fp13 /* x-= TWO23; */ + fadds fp1,fp1,fp13 /* x+= TWO23; */ + fnabs fp1,fp1 /* if (x == 0.0) */ + blr /* x = -0.0; */ END (__rintf) weak_alias (__rintf, rintf) diff --git a/sysdeps/powerpc/powerpc32/fpu/s_round.S b/sysdeps/powerpc/powerpc32/fpu/s_round.S index 13fc74f001..590c87ad8c 100644 --- a/sysdeps/powerpc/powerpc32/fpu/s_round.S +++ b/sysdeps/powerpc/powerpc32/fpu/s_round.S @@ -1,5 +1,5 @@ /* round function. PowerPC32 version. - Copyright (C) 2004 Free Software Foundation, Inc. + Copyright (C) 2004, 2006 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 @@ -14,40 +14,18 @@ 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. */ + Software Foundation, Inc., 1 Franklin Street, Fifth Floor, Boston MA + 02110-1301 USA. */ #include <sysdep.h> - - .section .rodata - .align 3 - .type TWO52.0,@object - .size TWO52.0,8 -TWO52.0: - .long 0x43300000 - .long 0 - .type POINTFIVE.0,@object - .size POINTFIVE.0,8 -POINTFIVE.0: - .long 0x3fe00000 - .long 0 - .type NEGZERO.0,@object - .size NEGZERO.0,8 -NEGZERO.0: - .long 0x80000000 - .long 0 +#include <math_ldbl_opt.h> .section .rodata.cst8,"aM",@progbits,8 - .align 3 + .align 2 .LC0: /* 2**52 */ - .long 0x43300000 - .long 0 + .long 0x59800000 .LC1: /* 0.5 */ - .long 0x3fe00000 - .long 0 -.LC2: /* -0.0 */ - .long 0x80000000 - .long 0 + .long 0x3f000000 /* double [fp1] round (double x [fp1]) IEEE 1003.1 round function. IEEE specifies "round to the nearest @@ -59,18 +37,28 @@ NEGZERO.0: "Round toward Zero" mode and round by adding +-0.5 before rounding to the integer value. */ + .section ".text" ENTRY (__round) mffs fp11 /* Save current FPU rounding mode. */ #ifdef SHARED mflr r11 + cfi_register(lr,r11) +# ifdef HAVE_ASM_PPC_REL16 + bcl 20,31,1f +1: mflr r9 + addis r9,r9,.LC0-1b@ha + addi r9,r9,.LC0-1b@l +# else bl _GLOBAL_OFFSET_TABLE_@local-4 mflr r10 lwz r9,.LC0@got(10) +# endif mtlr r11 - lfd fp13,0(r9) + cfi_same_value (lr) + lfs fp13,0(r9) #else lis r9,.LC0@ha - lfd fp13,.LC0@l(r9) + lfs fp13,.LC0@l(r9) #endif fabs fp0,fp1 fsub fp12,fp13,fp13 /* generate 0.0 */ @@ -79,17 +67,17 @@ ENTRY (__round) bnllr- cr7 mtfsfi 7,1 /* Set rounding mode toward 0. */ #ifdef SHARED - lwz r9,.LC1@got(10) - lfd fp10,0(r9) + lfs fp10,.LC1-.LC0(r9) #else lis r9,.LC1@ha - lfd fp10,.LC1@l(r9) + lfs fp10,.LC1@l(r9) #endif ble- cr6,.L4 fadd fp1,fp1,fp10 /* x+= 0.5; */ fadd fp1,fp1,fp13 /* x+= TWO52; */ fsub fp1,fp1,fp13 /* x-= TWO52; */ -.L9: + fabs fp1,fp1 /* if (x == 0.0) */ + /* x = 0.0; */ mtfsf 0x01,fp11 /* restore previous rounding mode. */ blr .L4: @@ -97,16 +85,10 @@ ENTRY (__round) bge- cr6,.L9 /* if (x < 0.0) */ fsub fp1,fp9,fp13 /* x-= TWO52; */ fadd fp1,fp1,fp13 /* x+= TWO52; */ - fcmpu cr5,fp1,fp12 /* if (x > 0.0) */ + fnabs fp1,fp1 /* if (x == 0.0) */ + /* x = -0.0; */ +.L9: mtfsf 0x01,fp11 /* restore previous rounding mode. */ - bnelr+ cr5 -#ifdef SHARED - lwz r9,.LC2@got(10) - lfd fp1,0(r9) -#else - lis r9,.LC2@ha - lfd fp1,.LC2@l(r9) -#endif blr END (__round) @@ -116,3 +98,6 @@ weak_alias (__round, round) weak_alias (__round, roundl) strong_alias (__round, __roundl) #endif +#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_1) +compat_symbol (libm, __round, roundl, GLIBC_2_1) +#endif diff --git a/sysdeps/powerpc/powerpc32/fpu/s_roundf.S b/sysdeps/powerpc/powerpc32/fpu/s_roundf.S index ea8aaf3add..7e99bca315 100644 --- a/sysdeps/powerpc/powerpc32/fpu/s_roundf.S +++ b/sysdeps/powerpc/powerpc32/fpu/s_roundf.S @@ -1,5 +1,5 @@ /* roundf function. PowerPC32 version. - Copyright (C) 2004 Free Software Foundation, Inc. + Copyright (C) 2004, 2006 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 @@ -14,40 +14,17 @@ 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. */ + Software Foundation, Inc., 1 Franklin Street, Fifth Floor, Boston MA + 02110-1301 USA. */ #include <sysdep.h> - .section .rodata - .align 3 - .type TWO23.0,@object - .size TWO23.0,8 -TWO23.0: - .long 0x43300000 - .long 0 - .type POINTFIVE.0,@object - .size POINTFIVE.0,8 -POINTFIVE.0: - .long 0x3fe00000 - .long 0 - .type NEGZERO.0,@object - .size NEGZERO.0,8 -NEGZERO.0: - .long 0x80000000 - .long 0 - .section .rodata.cst8,"aM",@progbits,8 - .align 3 + .align 2 .LC0: /* 2**23 */ - .long 0x41600000 - .long 0 + .long 0x4b000000 .LC1: /* 0.5 */ - .long 0x3fe00000 - .long 0 -.LC2: /* -0.0 */ - .long 0x80000000 - .long 0 + .long 0x3f000000 /* float [fp1] roundf (float x [fp1]) IEEE 1003.1 round function. IEEE specifies "round to the nearest @@ -59,18 +36,28 @@ NEGZERO.0: "Round toward Zero" mode and round by adding +-0.5 before rounding to the integer value. */ + .section ".text" ENTRY (__roundf ) mffs fp11 /* Save current FPU rounding mode. */ #ifdef SHARED mflr r11 + cfi_register(lr,r11) +# ifdef HAVE_ASM_PPC_REL16 + bcl 20,31,1f +1: mflr r9 + addis r9,r9,.LC0-1b@ha + addi r9,r9,.LC0-1b@l +# else bl _GLOBAL_OFFSET_TABLE_@local-4 mflr r10 lwz r9,.LC0@got(10) +# endif mtlr r11 - lfd fp13,0(r9) + cfi_same_value (lr) + lfs fp13,0(r9) #else lis r9,.LC0@ha - lfd fp13,.LC0@l(r9) + lfs fp13,.LC0@l(r9) #endif fabs fp0,fp1 fsubs fp12,fp13,fp13 /* generate 0.0 */ @@ -79,17 +66,17 @@ ENTRY (__roundf ) bnllr- cr7 mtfsfi 7,1 /* Set rounding mode toward 0. */ #ifdef SHARED - lwz r9,.LC1@got(10) - lfd fp10,0(r9) + lfs fp10,.LC1-.LC0(r9) #else lis r9,.LC1@ha - lfd fp10,.LC1@l(r9) + lfs fp10,.LC1@l(r9) #endif ble- cr6,.L4 fadds fp1,fp1,fp10 /* x+= 0.5; */ fadds fp1,fp1,fp13 /* x+= TWO23; */ fsubs fp1,fp1,fp13 /* x-= TWO23; */ -.L9: + fabs fp1,fp1 /* if (x == 0.0) */ + /* x = 0.0; */ mtfsf 0x01,fp11 /* restore previous rounding mode. */ blr .L4: @@ -97,16 +84,10 @@ ENTRY (__roundf ) bge- cr6,.L9 /* if (x < 0.0) */ fsubs fp1,fp9,fp13 /* x-= TWO23; */ fadds fp1,fp1,fp13 /* x+= TWO23; */ - fcmpu cr5,fp1,fp12 /* if (x > 0.0) */ + fnabs fp1,fp1 /* if (x == 0.0) */ + /* x = -0.0; */ +.L9: mtfsf 0x01,fp11 /* restore previous rounding mode. */ - bnelr+ cr5 -#ifdef SHARED - lwz r9,.LC2@got(10) - lfd fp1,0(r9) -#else - lis r9,.LC2@ha - lfd fp1,.LC2@l(r9) -#endif blr END (__roundf) diff --git a/sysdeps/powerpc/powerpc32/fpu/s_trunc.S b/sysdeps/powerpc/powerpc32/fpu/s_trunc.S index a4be651f8c..5bc0856b9f 100644 --- a/sysdeps/powerpc/powerpc32/fpu/s_trunc.S +++ b/sysdeps/powerpc/powerpc32/fpu/s_trunc.S @@ -1,5 +1,5 @@ /* trunc function. PowerPC32 version. - Copyright (C) 2004 Free Software Foundation, Inc. + Copyright (C) 2004, 2006 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 @@ -14,32 +14,16 @@ 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. */ + Software Foundation, Inc., 1 Franklin Street, Fifth Floor, Boston MA + 02110-1301 USA. */ #include <sysdep.h> +#include <math_ldbl_opt.h> - .section .rodata - .align 3 - .type TWO52.0,@object - .size TWO52.0,8 -TWO52.0: - .long 0x43300000 - .long 0 - .type NEGZERO.0,@object - .size NEGZERO.0,8 -NEGZERO.0: - .long 0x80000000 - .long 0 - - .section .rodata.cst8,"aM",@progbits,8 - .align 3 + .section .rodata.cst4,"aM",@progbits,4 + .align 2 .LC0: /* 2**52 */ - .long 0x43300000 - .long 0 -.LC1: /* -0.0 */ - .long 0x80000000 - .long 0 + .long 0x59800000 /* double [fp1] trunc (double x [fp1]) IEEE 1003.1 trunc function. IEEE specifies "trunc to the integer @@ -48,18 +32,28 @@ NEGZERO.0: We set "round toward Zero" mode and trunc by adding +-2**52 then subtracting +-2**52. */ + .section ".text" ENTRY (__trunc) mffs fp11 /* Save current FPU rounding mode. */ #ifdef SHARED mflr r11 + cfi_register(lr,r11) +# ifdef HAVE_ASM_PPC_REL16 + bcl 20,31,1f +1: mflr r9 + addis r9,r9,.LC0-1b@ha + lfs fp13,.LC0-1b@l(r9) +# else bl _GLOBAL_OFFSET_TABLE_@local-4 mflr r10 lwz r9,.LC0@got(10) + lfs fp13,0(r9) +# endif mtlr r11 - lfd fp13,0(r9) + cfi_same_value (lr) #else lis r9,.LC0@ha - lfd fp13,.LC0@l(r9) + lfs fp13,.LC0@l(r9) #endif fabs fp0,fp1 fsub fp12,fp13,fp13 /* generate 0.0 */ @@ -70,23 +64,18 @@ ENTRY (__trunc) ble- cr6,.L4 fadd fp1,fp1,fp13 /* x+= TWO52; */ fsub fp1,fp1,fp13 /* x-= TWO52; */ -.L9: - mtfsf 0x01,fp11 /* restore previous truncing mode. */ + fabs fp1,fp1 /* if (x == 0.0) */ + /* x = 0.0; */ + mtfsf 0x01,fp11 /* restore previous rounding mode. */ blr .L4: bge- cr6,.L9 /* if (x < 0.0) */ fsub fp1,fp1,fp13 /* x-= TWO52; */ fadd fp1,fp1,fp13 /* x+= TWO52; */ - fcmpu cr5,fp1,fp12 /* if (x > 0.0) */ + fnabs fp1,fp1 /* if (x == 0.0) */ + /* x = -0.0; */ +.L9: mtfsf 0x01,fp11 /* restore previous rounding mode. */ - bnelr+ cr5 -#ifdef SHARED - lwz r9,.LC1@got(10) - lfd fp1,0(r9) -#else - lis r9,.LC1@ha - lfd fp1,.LC1@l(r9) -#endif blr END (__trunc) @@ -96,3 +85,6 @@ weak_alias (__trunc, trunc) weak_alias (__trunc, truncl) strong_alias (__trunc, __truncl) #endif +#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_1) +compat_symbol (libm, __trunc, truncl, GLIBC_2_1) +#endif diff --git a/sysdeps/powerpc/powerpc32/fpu/s_truncf.S b/sysdeps/powerpc/powerpc32/fpu/s_truncf.S index 9a8dae931b..e2e3bd6740 100644 --- a/sysdeps/powerpc/powerpc32/fpu/s_truncf.S +++ b/sysdeps/powerpc/powerpc32/fpu/s_truncf.S @@ -1,5 +1,5 @@ /* truncf function. PowerPC32 version. - Copyright (C) 2004 Free Software Foundation, Inc. + Copyright (C) 2004, 2006 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 @@ -14,32 +14,15 @@ 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. */ + Software Foundation, Inc., 1 Franklin Street, Fifth Floor, Boston MA + 02110-1301 USA. */ #include <sysdep.h> - .section .rodata - .align 3 - .type TWO23.0,@object - .size TWO23.0,8 -TWO23.0: - .long 0x41600000 - .long 0 - .type NEGZERO.0,@object - .size NEGZERO.0,8 -NEGZERO.0: - .long 0x80000000 - .long 0 - - .section .rodata.cst8,"aM",@progbits,8 - .align 3 + .section .rodata.cst4,"aM",@progbits,4 + .align 2 .LC0: /* 2**23 */ - .long 0x41600000 - .long 0 -.LC1: /* -0.0 */ - .long 0x80000000 - .long 0 + .long 0x4b000000 /* float [fp1] truncf (float x [fp1]) IEEE 1003.1 trunc function. IEEE specifies "trunc to the integer @@ -48,18 +31,28 @@ NEGZERO.0: We set "round toward Zero" mode and trunc by adding +-2**23 then subtracting +-2**23. */ + .section ".text" ENTRY (__truncf) mffs fp11 /* Save current FPU rounding mode. */ #ifdef SHARED mflr r11 + cfi_register(lr,r11) +# ifdef HAVE_ASM_PPC_REL16 + bcl 20,31,1f +1: mflr r9 + addis r9,r9,.LC0-1b@ha + lfs fp13,.LC0-1b@l(r9) +# else bl _GLOBAL_OFFSET_TABLE_@local-4 mflr r10 lwz r9,.LC0@got(10) + lfs fp13,0(r9) +# endif mtlr r11 - lfd fp13,0(r9) + cfi_same_value (lr) #else lis r9,.LC0@ha - lfd fp13,.LC0@l(r9) + lfs fp13,.LC0@l(r9) #endif fabs fp0,fp1 fsubs fp12,fp13,fp13 /* generate 0.0 */ @@ -70,23 +63,18 @@ ENTRY (__truncf) ble- cr6,.L4 fadds fp1,fp1,fp13 /* x+= TWO23; */ fsubs fp1,fp1,fp13 /* x-= TWO23; */ -.L9: - mtfsf 0x01,fp11 /* restore previous truncing mode. */ + fabs fp1,fp1 /* if (x == 0.0) */ + /* x = 0.0; */ + mtfsf 0x01,fp11 /* restore previous rounding mode. */ blr .L4: bge- cr6,.L9 /* if (x < 0.0) */ fsubs fp1,fp1,fp13 /* x-= TWO23; */ fadds fp1,fp1,fp13 /* x+= TWO23; */ - fcmpu cr5,fp1,fp12 /* if (x > 0.0) */ + fnabs fp1,fp1 /* if (x == 0.0) */ + /* x = -0.0; */ +.L9: mtfsf 0x01,fp11 /* restore previous rounding mode. */ - bnelr+ cr5 -#ifdef SHARED - lwz r9,.LC1@got(10) - lfd fp1,0(r9) -#else - lis r9,.LC1@ha - lfd fp1,.LC1@l(r9) -#endif blr END (__truncf) diff --git a/sysdeps/powerpc/powerpc32/fpu/setjmp-common.S b/sysdeps/powerpc/powerpc32/fpu/setjmp-common.S index 77ee05f487..851480d2ef 100644 --- a/sysdeps/powerpc/powerpc32/fpu/setjmp-common.S +++ b/sysdeps/powerpc/powerpc32/fpu/setjmp-common.S @@ -1,5 +1,5 @@ /* setjmp for PowerPC. - Copyright (C) 1995-99, 2000, 2003, 2004 Free Software Foundation, Inc. + Copyright (C) 1995-2000, 2003-2005, 2006 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 @@ -14,16 +14,15 @@ 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. */ + Software Foundation, Inc., 1 Franklin Street, Fifth Floor, Boston MA + 02110-1301 USA. */ #include <sysdep.h> #define _ASM -#define _SETJMP_H #ifdef __NO_VMX__ # include <novmxsetjmp.h> #else -# include <bits/setjmp.h> +# include <jmpbuf-offsets.h> #endif #include <bp-sym.h> #include <bp-asm.h> @@ -32,10 +31,19 @@ ENTRY (BP_SYM (__sigsetjmp)) CHECK_BOUNDS_BOTH_WIDE_LIT (r3, r8, r9, JB_SIZE) +#ifdef PTR_MANGLE + mr r5,r1 + PTR_MANGLE(r5, r6) + stw r5,(JB_GPR1*4)(3) +#else stw r1,(JB_GPR1*4)(3) +#endif mflr r0 stw r14,((JB_GPRS+0)*4)(3) stfd fp14,((JB_FPRS+0*2)*4)(3) +#ifdef PTR_MANGLE + PTR_MANGLE2 (r0, r6) +#endif stw r0,(JB_LR*4)(3) stw r15,((JB_GPRS+1)*4)(3) stfd fp15,((JB_FPRS+1*2)*4)(3) @@ -74,23 +82,31 @@ ENTRY (BP_SYM (__sigsetjmp)) stw r31,((JB_GPRS+17)*4)(3) stfd fp31,((JB_FPRS+17*2)*4)(3) #ifndef __NO_VMX__ -#ifdef PIC +# ifdef PIC mflr r6 + cfi_register(lr,r6) +# ifdef HAVE_ASM_PPC_REL16 + bcl 20,31,1f +1: mflr r5 + addis r5,r5,_GLOBAL_OFFSET_TABLE_-1b@ha + addi r5,r5,_GLOBAL_OFFSET_TABLE_-1b@l +# else bl _GLOBAL_OFFSET_TABLE_@local-4 mflr r5 -#ifdef SHARED +# endif + mtlr r6 + cfi_same_value (lr) +# ifdef SHARED lwz r5,_rtld_global_ro@got(r5) - mtlr r6 lwz r5,RTLD_GLOBAL_RO_DL_HWCAP_OFFSET(r5) -#else - lwz r5,_rtld_global_ro@got(r5) - mtlr r6 +# else + lwz r5,_dl_hwcap@got(r5) lwz r5,0(r5) -#endif -#else - lis r5,_dl_hwcap@ha - lwz r5,_dl_hwcap@l(r5) -#endif +# endif +# else + lis r6,_dl_hwcap@ha + lwz r5,_dl_hwcap@l(r6) +# endif andis. r5,r5,(PPC_FEATURE_HAS_ALTIVEC >> 16) beq L(no_vmx) la r5,((JB_VRS)*4)(3) @@ -164,5 +180,5 @@ L(aligned_save_vmx): stvx 31,0,r6 L(no_vmx): #endif - b JUMPTARGET (BP_SYM (__sigjmp_save)) + b BP_SYM (__sigjmp_save@local) END (BP_SYM (__sigsetjmp)) diff --git a/sysdeps/powerpc/powerpc32/gprrest0.S b/sysdeps/powerpc/powerpc32/gprrest0.S index cf493f0c47..90eb4a0c4c 100644 --- a/sysdeps/powerpc/powerpc32/gprrest0.S +++ b/sysdeps/powerpc/powerpc32/gprrest0.S @@ -1,4 +1,4 @@ -/* Copyright (C) 2000, 2001 Free Software Foundation, Inc. +/* Copyright (C) 2000, 2001, 2006 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 @@ -13,8 +13,8 @@ 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. */ + Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA + 02110-1301 USA. */ /* General Purpose Register (GPR) restore routine @@ -67,3 +67,4 @@ C_TEXT(_restgpr0_29): lwz r0,8(r1) #get return address from frame lwz r30,-8(r1) #restore r30 lwz r31,-4(r1) #restore r31 blr #return +END (_restgpr0_all) diff --git a/sysdeps/powerpc/powerpc32/gprrest1.S b/sysdeps/powerpc/powerpc32/gprrest1.S index 5ac18606f8..ca00b8f133 100644 --- a/sysdeps/powerpc/powerpc32/gprrest1.S +++ b/sysdeps/powerpc/powerpc32/gprrest1.S @@ -1,4 +1,4 @@ -/* Copyright (C) 2000, 2001 Free Software Foundation, Inc. +/* Copyright (C) 2000, 2001, 2006 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 @@ -13,8 +13,8 @@ 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. */ + Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA + 02110-1301 USA. */ /* General Purpose Register (GPR) restore routine @@ -61,3 +61,4 @@ C_TEXT(_restgpr1_29): lwz r29,-12(r12) #restore r29 lwz r30,-8(r12) #restore r30 lwz r31,-4(r12) #restore r31 blr #return +END (_restgpr1_all) diff --git a/sysdeps/powerpc/powerpc32/gprsave0.S b/sysdeps/powerpc/powerpc32/gprsave0.S index a09f1e569a..c74272b56d 100644 --- a/sysdeps/powerpc/powerpc32/gprsave0.S +++ b/sysdeps/powerpc/powerpc32/gprsave0.S @@ -1,4 +1,4 @@ -/* Copyright (C) 2000, 2001 Free Software Foundation, Inc. +/* Copyright (C) 2000, 2001, 2006 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 @@ -13,8 +13,8 @@ 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. */ + Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA + 02110-1301 USA. */ /* General Purpose Register (GPR) save routine @@ -30,39 +30,59 @@ ENTRY(_savegpr0_all) ASM_GLOBAL_DIRECTIVE C_TEXT(_savegpr0_13) C_TEXT(_savegpr0_13): stw r13,-76(r1) + cfi_offset(r13,-76) ASM_GLOBAL_DIRECTIVE C_TEXT(_savegpr0_14) C_TEXT(_savegpr0_14): stw r14,-72(r1) + cfi_offset(r14,-72) ASM_GLOBAL_DIRECTIVE C_TEXT(_savegpr0_15) C_TEXT(_savegpr0_15): stw r15,-68(r1) + cfi_offset(r15,-68) ASM_GLOBAL_DIRECTIVE C_TEXT(_savegpr0_16) C_TEXT(_savegpr0_16): stw r16,-64(r1) + cfi_offset(r16,-64) ASM_GLOBAL_DIRECTIVE C_TEXT(_savegpr0_17) C_TEXT(_savegpr0_17): stw r17,-60(r1) + cfi_offset(r17,-60) ASM_GLOBAL_DIRECTIVE C_TEXT(_savegpr0_18) C_TEXT(_savegpr0_18): stw r18,-56(r1) + cfi_offset(r18,-56) ASM_GLOBAL_DIRECTIVE C_TEXT(_savegpr0_19) C_TEXT(_savegpr0_19): stw r19,-52(r1) + cfi_offset(r19,-52) ASM_GLOBAL_DIRECTIVE C_TEXT(_savegpr0_20) C_TEXT(_savegpr0_20): stw r20,-48(r1) + cfi_offset(r20,-48) ASM_GLOBAL_DIRECTIVE C_TEXT(_savegpr0_21) C_TEXT(_savegpr0_21): stw r21,-44(r1) + cfi_offset(r21,-44) ASM_GLOBAL_DIRECTIVE C_TEXT(_savegpr0_22) C_TEXT(_savegpr0_22): stw r22,-40(r1) + cfi_offset(r22,-40) ASM_GLOBAL_DIRECTIVE C_TEXT(_savegpr0_23) C_TEXT(_savegpr0_23): stw r23,-36(r1) + cfi_offset(r23,-36) ASM_GLOBAL_DIRECTIVE C_TEXT(_savegpr0_24) C_TEXT(_savegpr0_24): stw r24,-32(r1) + cfi_offset(r24,-32) ASM_GLOBAL_DIRECTIVE C_TEXT(_savegpr0_25) C_TEXT(_savegpr0_25): stw r25,-28(r1) + cfi_offset(r25,-28) ASM_GLOBAL_DIRECTIVE C_TEXT(_savegpr0_26) C_TEXT(_savegpr0_26): stw r26,-24(r1) + cfi_offset(r26,-24) ASM_GLOBAL_DIRECTIVE C_TEXT(_savegpr0_27) C_TEXT(_savegpr0_27): stw r27,-20(r1) + cfi_offset(r27,-20) ASM_GLOBAL_DIRECTIVE C_TEXT(_savegpr0_28) C_TEXT(_savegpr0_28): stw r28,-16(r1) + cfi_offset(r28,-16) ASM_GLOBAL_DIRECTIVE C_TEXT(_savegpr0_29) C_TEXT(_savegpr0_29): stw r29,-12(r1) #save r29 stw r30,-8(r1) #save r30 stw r31,-4(r1) #save r31 + cfi_offset(r29,-12) + cfi_offset(r30,-8) + cfi_offset(r31,-4) stw r0,8(r1) #save LR in callers frame blr #return +END (_savegpr0_all) diff --git a/sysdeps/powerpc/powerpc32/gprsave1.S b/sysdeps/powerpc/powerpc32/gprsave1.S index 06ee4a69d3..6c1790129e 100644 --- a/sysdeps/powerpc/powerpc32/gprsave1.S +++ b/sysdeps/powerpc/powerpc32/gprsave1.S @@ -1,4 +1,4 @@ -/* Copyright (C) 2000, 2001 Free Software Foundation, Inc. +/* Copyright (C) 2000, 2001, 2006 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 @@ -13,8 +13,8 @@ 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. */ + Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA + 02110-1301 USA. */ /* General Purpose Register (GPR) save routine @@ -61,3 +61,4 @@ C_TEXT(_savegpr1_29): stw r29,-12(r12) #save r29 stw r30,-8(r12) #save r30 stw r31,-4(r12) #save r31 blr #return +END (_savegpr1_all) diff --git a/sysdeps/powerpc/powerpc32/hp-timing.h b/sysdeps/powerpc/powerpc32/hp-timing.h new file mode 100644 index 0000000000..b62b0f2138 --- /dev/null +++ b/sysdeps/powerpc/powerpc32/hp-timing.h @@ -0,0 +1,82 @@ +/* High precision, low overhead timing functions. Linux/PPC32 version. + Copyright (C) 2005 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 _HP_TIMING_H +#define _HP_TIMING_H 1 + + +/* There are no generic definitions for the times. We could write something + using the `gettimeofday' system call where available but the overhead of + the system call might be too high. + + In case a platform supports timers in the hardware the following macros + and types must be defined: + + - HP_TIMING_AVAIL: test for availability. + + - HP_TIMING_INLINE: this macro is non-zero if the functionality is not + implemented using function calls but instead uses some inlined code + which might simply consist of a few assembler instructions. We have to + know this since we might want to use the macros here in places where we + cannot make function calls. + + - hp_timing_t: This is the type for variables used to store the time + values. + + - HP_TIMING_ZERO: clear `hp_timing_t' object. + + - HP_TIMING_NOW: place timestamp for current time in variable given as + parameter. + + - HP_TIMING_DIFF_INIT: do whatever is necessary to be able to use the + HP_TIMING_DIFF macro. + + - HP_TIMING_DIFF: compute difference between two times and store it + in a third. Source and destination might overlap. + + - HP_TIMING_ACCUM: add time difference to another variable. This might + be a bit more complicated to implement for some platforms as the + operation should be thread-safe and 64bit arithmetic on 32bit platforms + is not. + + - HP_TIMING_ACCUM_NT: this is the variant for situations where we know + there are no threads involved. + + - HP_TIMING_PRINT: write decimal representation of the timing value into + the given string. This operation need not be inline even though + HP_TIMING_INLINE is specified. + +*/ + +/* Provide dummy definitions. */ +#define HP_TIMING_AVAIL (0) +#define HP_TIMING_INLINE (0) +typedef unsigned long long int hp_timing_t; +#define HP_TIMING_ZERO(Var) +#define HP_TIMING_NOW(var) +#define HP_TIMING_DIFF_INIT() +#define HP_TIMING_DIFF(Diff, Start, End) +#define HP_TIMING_ACCUM(Sum, Diff) +#define HP_TIMING_ACCUM_NT(Sum, Diff) +#define HP_TIMING_PRINT(Buf, Len, Val) + +/* Since this implementation is not available we tell the user about it. */ +#define HP_TIMING_NONAVAIL 1 + +#endif /* hp-timing.h */ diff --git a/sysdeps/powerpc/powerpc32/lshift.S b/sysdeps/powerpc/powerpc32/lshift.S index 9f5870d828..65054f229d 100644 --- a/sysdeps/powerpc/powerpc32/lshift.S +++ b/sysdeps/powerpc/powerpc32/lshift.S @@ -1,5 +1,5 @@ /* Shift a limb left, low level routine. - Copyright (C) 1996, 1997, 1999, 2000 Free Software Foundation, Inc. + Copyright (C) 1996, 1997, 1999, 2000, 2006 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 @@ -14,8 +14,8 @@ 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. */ + Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA + 02110-1301 USA. */ #include <sysdep.h> #include <bp-sym.h> @@ -67,6 +67,7 @@ L(boom): tweq r0,r0 /* We imitate a case statement, by using (yuk!) fixed-length code chunks, of size 4*12 bytes. We have to do this (or something) to make this PIC. */ L(big): mflr r9 + cfi_register(lr,r9) bltl- cr0,L(boom) # Never taken, only used to set LR. slwi r10,r6,4 mflr r12 @@ -75,7 +76,8 @@ L(big): mflr r9 add r10,r8,r10 mtctr r10 addi r5,r5,-1 - mtlr r9 + mtlr r9 + cfi_same_value (lr) bctr L(end2):slw r0,r10,r6 diff --git a/sysdeps/powerpc/powerpc32/memset.S b/sysdeps/powerpc/powerpc32/memset.S index 53f1143320..f09c294674 100644 --- a/sysdeps/powerpc/powerpc32/memset.S +++ b/sysdeps/powerpc/powerpc32/memset.S @@ -140,7 +140,7 @@ L(nondcbz): /* We can't use dcbz here as we don't know the cache line size. We can use "data cache block touch for store", which is safe. */ -L(c3): dcbtst rNEG64, rMEMP +L(c3): dcbtst rNEG64, rMEMP stw rCHR, -4(rMEMP) stw rCHR, -8(rMEMP) stw rCHR, -12(rMEMP) @@ -166,7 +166,7 @@ L(cloopdone): add rMEMP, rMEMP, rALIGN b L(medium_tail2) /* 72nd instruction from .align */ - .align 5 + .align 5 nop /* Clear cache lines of memory in 128-byte chunks. This code is optimized for processors with 32-byte cache lines. @@ -200,7 +200,7 @@ L(zloop): beqlr cr5 b L(medium_tail2) - .align 5 + .align 5 L(small): /* Memset of 4 bytes or less. */ cmplwi cr5, rLEN, 1 @@ -218,7 +218,7 @@ L(small): blr /* Memset of 0-31 bytes. */ - .align 5 + .align 5 L(medium): cmplwi cr1, rLEN, 16 L(medium_tail2): @@ -258,70 +258,77 @@ L(medium_28t): L(checklinesize): #ifdef SHARED - mflr rTMP + mflr rTMP /* If the remaining length is less the 32 bytes then don't bother getting - the cache line size. */ + the cache line size. */ beq L(medium) /* Establishes GOT addressability so we can load __cache_line_size from static. This value was set from the aux vector during startup. */ - bl _GLOBAL_OFFSET_TABLE_@local-4 - mflr rGOT - lwz rGOT,__cache_line_size@got(rGOT) - lwz rCLS,0(rGOT) - mtlr rTMP +# ifdef HAVE_ASM_PPC_REL16 + bcl 20,31,1f +1: mflr rGOT + addis rGOT,rGOT,__cache_line_size-1b@ha + lwz rCLS,__cache_line_size-1b@l(rGOT) +# else + bl _GLOBAL_OFFSET_TABLE_@local-4 + mflr rGOT + lwz rGOT,__cache_line_size@got(rGOT) + lwz rCLS,0(rGOT) +# endif + mtlr rTMP #else /* Load __cache_line_size from static. This value was set from the aux vector during startup. */ - lis rCLS,__cache_line_size@ha + lis rCLS,__cache_line_size@ha /* If the remaining length is less the 32 bytes then don't bother getting - the cache line size. */ + the cache line size. */ beq L(medium) - lwz rCLS,__cache_line_size@l(rCLS) + lwz rCLS,__cache_line_size@l(rCLS) #endif -/*If the cache line size was not set then goto to L(nondcbz), which is - safe for any cache line size. */ - cmplwi cr1,rCLS,0 +/* If the cache line size was not set then goto to L(nondcbz), which is + safe for any cache line size. */ + cmplwi cr1,rCLS,0 beq cr1,L(nondcbz) /* If the cache line size is 32 bytes then goto to L(zloopstart), - which is coded specificly for 32-byte lines (and 601). */ - cmplwi cr1,rCLS,32 + which is coded specificly for 32-byte lines (and 601). */ + cmplwi cr1,rCLS,32 beq cr1,L(zloopstart) /* Now we know the cache line size and it is not 32-bytes. However - we may not yet be aligned to the cache line and may have a partial - line to fill. Touch it 1st to fetch the cache line. */ - dcbtst 0,rMEMP + we may not yet be aligned to the cache line and may have a partial + line to fill. Touch it 1st to fetch the cache line. */ + dcbtst 0,rMEMP - addi rCLM,rCLS,-1 + addi rCLM,rCLS,-1 L(getCacheAligned): - cmplwi cr1,rLEN,32 - and. rTMP,rCLM,rMEMP - blt cr1,L(handletail32) - beq L(cacheAligned) + cmplwi cr1,rLEN,32 + and. rTMP,rCLM,rMEMP + blt cr1,L(handletail32) + beq L(cacheAligned) /* We are not aligned to start of a cache line yet. Store 32-byte of data and test again. */ - addi rMEMP,rMEMP,32 - addi rLEN,rLEN,-32 - stw rCHR,-32(rMEMP) - stw rCHR,-28(rMEMP) - stw rCHR,-24(rMEMP) - stw rCHR,-20(rMEMP) - stw rCHR,-16(rMEMP) - stw rCHR,-12(rMEMP) - stw rCHR,-8(rMEMP) - stw rCHR,-4(rMEMP) - b L(getCacheAligned) + addi rMEMP,rMEMP,32 + addi rLEN,rLEN,-32 + stw rCHR,-32(rMEMP) + stw rCHR,-28(rMEMP) + stw rCHR,-24(rMEMP) + stw rCHR,-20(rMEMP) + stw rCHR,-16(rMEMP) + stw rCHR,-12(rMEMP) + stw rCHR,-8(rMEMP) + stw rCHR,-4(rMEMP) + b L(getCacheAligned) /* Now we are aligned to the cache line and can use dcbz. */ L(cacheAligned): - cmplw cr1,rLEN,rCLS - blt cr1,L(handletail32) - dcbz 0,rMEMP - subf rLEN,rCLS,rLEN - add rMEMP,rMEMP,rCLS - b L(cacheAligned) + cmplw cr1,rLEN,rCLS + blt cr1,L(handletail32) + dcbz 0,rMEMP + subf rLEN,rCLS,rLEN + add rMEMP,rMEMP,rCLS + b L(cacheAligned) /* We are here because; the cache line size was set, it was not 32-bytes, and the remainder (rLEN) is now less than the actual cache @@ -329,7 +336,7 @@ L(cacheAligned): store the remaining bytes. */ L(handletail32): clrrwi. rALIGN, rLEN, 5 - b L(nondcbz) + b L(nondcbz) END (BP_SYM (memset)) libc_hidden_builtin_def (memset) diff --git a/sysdeps/powerpc/powerpc32/ppc-mcount.S b/sysdeps/powerpc/powerpc32/ppc-mcount.S index a72d676bbe..7e39acb55b 100644 --- a/sysdeps/powerpc/powerpc32/ppc-mcount.S +++ b/sysdeps/powerpc/powerpc32/ppc-mcount.S @@ -1,5 +1,5 @@ /* PowerPC-specific implementation of profiling support. - Copyright (C) 1997, 1999 Free Software Foundation, Inc. + Copyright (C) 1997, 1999, 2005, 2006 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 @@ -14,8 +14,8 @@ 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. */ + Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA + 02110-1301 USA. */ /* This would be bad. */ #ifdef PROF @@ -24,30 +24,25 @@ #include <sysdep.h> -/* We do profiling as described in the SYSV ELF ABI, _mcount is called - with the address of a data word in r0 (that is different for every - routine, initialised to 0, and otherwise unused). The caller has put - the address the caller will return to in the usual place on the stack, - 4(r1). _mcount is responsible for ensuring that when it returns no - argument-passing registers are disturbed, and that the LR is set back - to (what the caller sees as) 4(r1). +/* We do profiling as described in the SYSV ELF ABI, except that glibc + _mcount manages its own counters. The caller has put the address the + caller will return to in the usual place on the stack, 4(r1). _mcount + is responsible for ensuring that when it returns no argument-passing + registers are disturbed, and that the LR is set back to (what the + caller sees as) 4(r1). This is intended so that the following code can be inserted at the front of any routine without changing the routine: .data - .align 2 - 0: .long 0 - .previous mflr r0 - lis r11,0b@ha stw r0,4(r1) - addi r0,r11,0b@l bl _mcount */ ENTRY(_mcount) stwu r1,-48(r1) + cfi_adjust_cfa_offset (48) /* We need to save the parameter-passing registers. */ stw r3, 12(r1) stw r4, 16(r1) @@ -61,8 +56,9 @@ ENTRY(_mcount) stw r9, 36(r1) stw r10,40(r1) stw r4, 44(r1) + cfi_offset (lr, -4) stw r5, 8(r1) - bl JUMPTARGET(__mcount_internal) + bl __mcount_internal@local nop /* Restore the registers... */ lwz r6, 8(r1) diff --git a/sysdeps/powerpc/powerpc32/register-dump.h b/sysdeps/powerpc/powerpc32/register-dump.h index d341eea8ff..7071632083 100644 --- a/sysdeps/powerpc/powerpc32/register-dump.h +++ b/sysdeps/powerpc/powerpc32/register-dump.h @@ -1,5 +1,5 @@ /* Dump registers. - Copyright (C) 1998 Free Software Foundation, Inc. + Copyright (C) 1998, 2006 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 @@ -113,7 +113,7 @@ register_dump (int fd, struct sigcontext *ctx) } /* Write the output. */ - write (fd, buffer, sizeof(buffer)); + write (fd, buffer, sizeof(buffer) - 1); } diff --git a/sysdeps/powerpc/powerpc32/setjmp-common.S b/sysdeps/powerpc/powerpc32/setjmp-common.S index 40f626498c..12ee14d788 100644 --- a/sysdeps/powerpc/powerpc32/setjmp-common.S +++ b/sysdeps/powerpc/powerpc32/setjmp-common.S @@ -1,5 +1,6 @@ /* setjmp for PowerPC. - Copyright (C) 1995-1997,1999-2001,2003,2004 Free Software Foundation, Inc. + Copyright (C) 1995-1997,1999-2001,2003,2004,2005, 2006 + 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 @@ -19,11 +20,10 @@ #include <sysdep.h> #define _ASM -#define _SETJMP_H #ifdef __NO_VMX__ # include <novmxsetjmp.h> #else -# include <bits/setjmp.h> +# include <jmpbuf-offsets.h> #endif #include <bp-sym.h> #include <bp-asm.h> @@ -32,9 +32,19 @@ ENTRY (BP_SYM (__sigsetjmp)) CHECK_BOUNDS_BOTH_WIDE_LIT (r3, r8, r9, JB_SIZE) +#ifdef PTR_MANGLE + mr r5,r1 + PTR_MANGLE(r5, r10) + stw r5,(JB_GPR1*4)(3) +#else stw r1,(JB_GPR1*4)(3) +#endif mflr r0 stw r14,((JB_GPRS+0)*4)(3) +#ifdef PTR_MANGLE + PTR_MANGLE2 (r0, r10) + li r10,0 +#endif stw r0,(JB_LR*4)(3) stw r15,((JB_GPRS+1)*4)(3) mfcr r0 @@ -55,5 +65,10 @@ ENTRY (BP_SYM (__sigsetjmp)) stw r29,((JB_GPRS+15)*4)(3) stw r30,((JB_GPRS+16)*4)(3) stw r31,((JB_GPRS+17)*4)(3) - b JUMPTARGET (BP_SYM (__sigjmp_save)) +#if defined NOT_IN_libc && defined IS_IN_rtld + li r3,0 + blr +#else + b BP_SYM (__sigjmp_save@local) +#endif END (BP_SYM (__sigsetjmp)) diff --git a/sysdeps/powerpc/powerpc32/strncmp.S b/sysdeps/powerpc/powerpc32/strncmp.S index 3b33bb921f..3e0fff5ac2 100644 --- a/sysdeps/powerpc/powerpc32/strncmp.S +++ b/sysdeps/powerpc/powerpc32/strncmp.S @@ -47,6 +47,7 @@ EALIGN (BP_SYM(strncmp), 4, 0) lis r7F7F, 0x7f7f dcbt 0,rSTR2 clrlwi. rTMP, rTMP, 30 + cmplwi cr1, rN, 0 lis rFEFE, -0x101 bne L(unaligned) /* We are word alligned so set up for two loops. first a word @@ -54,7 +55,8 @@ EALIGN (BP_SYM(strncmp), 4, 0) srwi. rTMP, rN, 2 clrlwi rN, rN, 30 addi rFEFE, rFEFE, -0x101 - addi r7F7F, r7F7F, 0x7f7f + addi r7F7F, r7F7F, 0x7f7f + cmplwi cr1, rN, 0 beq L(unaligned) mtctr rTMP /* Power4 wants mtctr 1st in dispatch group. */ @@ -122,16 +124,19 @@ L(tail): addi rSTR1, rSTR1, 4 bne- cr1, L(different) addi rSTR2, rSTR2, 4 + cmplwi cr1, rN, 0 L(unaligned): mtctr rN /* Power4 wants mtctr 1st in dispatch group */ - cmpwi rN,0 - lbz rWORD1, 0(rSTR1) - lbz rWORD2, 0(rSTR2) - bgt L(u1) + bgt cr1, L(uz) L(ux): li rRTN, 0 blr - + .align 4 +L(uz): + lbz rWORD1, 0(rSTR1) + lbz rWORD2, 0(rSTR2) + nop + b L(u1) L(u0): lbzu rWORD2, 1(rSTR2) L(u1): diff --git a/sysdeps/powerpc/powerpc32/sysdep.h b/sysdeps/powerpc/powerpc32/sysdep.h index 59761f75b9..8fc624ebd9 100644 --- a/sysdeps/powerpc/powerpc32/sysdep.h +++ b/sysdeps/powerpc/powerpc32/sysdep.h @@ -1,5 +1,5 @@ /* Assembly macros for 32-bit PowerPC. - Copyright (C) 1999, 2001, 2002, 2003 Free Software Foundation, Inc. + Copyright (C) 1999, 2001, 2002, 2003, 2006 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 @@ -14,8 +14,8 @@ 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. */ + Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA + 02110-1301 USA. */ #include <sysdeps/powerpc/sysdep.h> @@ -29,31 +29,11 @@ /* The mcount code relies on a the return address being on the stack to locate our caller and so it can restore it; so store one just for its benefit. */ -# ifdef PIC -# define CALL_MCOUNT \ - .pushsection; \ - .section ".data"; \ - .align ALIGNARG(2); \ -0:.long 0; \ - .previous; \ +# define CALL_MCOUNT \ mflr r0; \ - stw r0,4(r1); \ - bl _GLOBAL_OFFSET_TABLE_@local-4; \ - mflr r11; \ - lwz r0,0b@got(r11); \ + stw r0,4(r1); \ + cfi_offset (lr, 4); \ bl JUMPTARGET(_mcount); -# else /* PIC */ -# define CALL_MCOUNT \ - .section ".data"; \ - .align ALIGNARG(2); \ -0:.long 0; \ - .previous; \ - mflr r0; \ - lis r11,0b@ha; \ - stw r0,4(r1); \ - addi r0,r11,0b@l; \ - bl JUMPTARGET(_mcount); -# endif /* PIC */ #else /* PROF */ # define CALL_MCOUNT /* Do nothing. */ #endif /* PROF */ @@ -63,6 +43,7 @@ ASM_TYPE_DIRECTIVE (C_SYMBOL_NAME(name),@function) \ .align ALIGNARG(2); \ C_LABEL(name) \ + cfi_startproc; \ CALL_MCOUNT #define EALIGN_W_0 /* No words to insert. */ @@ -82,6 +63,7 @@ ASM_TYPE_DIRECTIVE (C_SYMBOL_NAME(name),@function) \ .align ALIGNARG(2); \ C_LABEL(name) \ + cfi_startproc; \ CALL_MCOUNT \ b 0f; \ .align ALIGNARG(alignt); \ @@ -93,11 +75,13 @@ ASM_TYPE_DIRECTIVE (C_SYMBOL_NAME(name),@function) \ .align ALIGNARG(alignt); \ EALIGN_W_##words; \ - C_LABEL(name) + C_LABEL(name) \ + cfi_startproc; #endif #undef END #define END(name) \ + cfi_endproc; \ ASM_SIZE_DIRECTIVE(name) #define DO_CALL(syscall) \ @@ -124,7 +108,7 @@ #define PSEUDO_RET \ bnslr+; \ - b JUMPTARGET(__syscall_error) + b __syscall_error@local #define ret PSEUDO_RET #undef PSEUDO_END |