diff options
Diffstat (limited to 'sysdeps/powerpc')
157 files changed, 4051 insertions, 2744 deletions
diff --git a/sysdeps/powerpc/Dist b/sysdeps/powerpc/Dist deleted file mode 100644 index ba909df..0000000 --- a/sysdeps/powerpc/Dist +++ /dev/null @@ -1,2 +0,0 @@ -novmx-longjmp.c -novmx-sigjmp.c diff --git a/sysdeps/powerpc/Implies b/sysdeps/powerpc/Implies index 12ca48b..7ccf9a7 100644 --- a/sysdeps/powerpc/Implies +++ b/sysdeps/powerpc/Implies @@ -1,2 +1,4 @@ -ieee754/flt-32 +# On PowerPC we use the IBM extended long double format. +ieee754/ldbl-128ibm ieee754/dbl-64 +ieee754/flt-32 diff --git a/sysdeps/powerpc/bits/link.h b/sysdeps/powerpc/bits/link.h new file mode 100644 index 0000000..6c6f604 --- /dev/null +++ b/sysdeps/powerpc/bits/link.h @@ -0,0 +1,111 @@ +/* Machine-specific declarations for dynamic linker interface. PowerPC version + Copyright (C) 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 + 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 _LINK_H +# error "Never include <bits/link.h> directly; use <link.h> instead." +#endif + + +#if __ELF_NATIVE_CLASS == 32 + +/* Registers for entry into PLT on PPC32. */ +typedef struct La_ppc32_regs +{ + uint32_t lr_reg[8]; + double lr_fp[8]; + uint32_t lr_vreg[12][4]; + uint32_t lr_r1; + uint32_t lr_lr; +} La_ppc32_regs; + +/* Return values for calls from PLT on PPC32. */ +typedef struct La_ppc32_retval +{ + uint32_t lrv_r3; + uint32_t lrv_r4; + double lrv_fp[8]; + uint32_t lrv_v2[4]; +} La_ppc32_retval; + + +__BEGIN_DECLS + +extern Elf32_Addr la_ppc32_gnu_pltenter (Elf32_Sym *__sym, + unsigned int __ndx, + uintptr_t *__refcook, + uintptr_t *__defcook, + La_ppc32_regs *__regs, + unsigned int *__flags, + const char *__symname, + long int *__framesizep); +extern unsigned int la_ppc32_gnu_pltexit (Elf32_Sym *__sym, + unsigned int __ndx, + uintptr_t *__refcook, + uintptr_t *__defcook, + const La_ppc32_regs *__inregs, + La_ppc32_retval *__outregs, + const char *symname); + +__END_DECLS + +#else + +/* Registers for entry into PLT on PPC64. */ +typedef struct La_ppc64_regs +{ + uint64_t lr_reg[8]; + double lr_fp[13]; + uint32_t __padding; + uint32_t lr_vrsave; + uint32_t lr_vreg[12][4]; + uint64_t lr_r1; + uint64_t lr_lr; +} La_ppc64_regs; + +/* Return values for calls from PLT on PPC64. */ +typedef struct La_ppc64_retval +{ + uint64_t lrv_r3; + uint64_t lrv_r4; + double lrv_fp[4]; /* f1-f4, float - complex long double. */ + uint32_t lrv_v2[4]; /* v2. */ +} La_ppc64_retval; + + +__BEGIN_DECLS + +extern Elf64_Addr la_ppc64_gnu_pltenter (Elf64_Sym *__sym, + unsigned int __ndx, + uintptr_t *__refcook, + uintptr_t *__defcook, + La_ppc64_regs *__regs, + unsigned int *__flags, + const char *__symname, + long int *__framesizep); +extern unsigned int la_ppc64_gnu_pltexit (Elf64_Sym *__sym, + unsigned int __ndx, + uintptr_t *__refcook, + uintptr_t *__defcook, + const La_ppc64_regs *__inregs, + La_ppc64_retval *__outregs, + const char *symname); + +__END_DECLS + +#endif diff --git a/sysdeps/powerpc/fpu/bits/mathdef.h b/sysdeps/powerpc/bits/mathdef.h index 3a9d538..b79cc6f 100644 --- a/sysdeps/powerpc/fpu/bits/mathdef.h +++ b/sysdeps/powerpc/bits/mathdef.h @@ -1,4 +1,5 @@ -/* Copyright (C) 1997,1998,1999,2000,2003,2004 Free Software Foundation, Inc. +/* Copyright (C) 1997,1998,1999,2000,2003,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 @@ -61,9 +62,3 @@ typedef double double_t; # define FP_ILOGBNAN (2147483647) #endif /* ISO C99 */ - -#ifndef __NO_LONG_DOUBLE_MATH -/* Signal that we do not really have a `long double'. The disables the - declaration of all the `long double' function variants. */ -# define __NO_LONG_DOUBLE_MATH 1 -#endif diff --git a/sysdeps/powerpc/bits/setjmp.h b/sysdeps/powerpc/bits/setjmp.h index 3134916..9c3e22a 100644 --- a/sysdeps/powerpc/bits/setjmp.h +++ b/sysdeps/powerpc/bits/setjmp.h @@ -1,4 +1,5 @@ -/* Copyright (C) 1997, 1998, 2000, 2003, 2004 Free Software Foundation, Inc. +/* Copyright (C) 1997,1998,2000,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 @@ -31,30 +32,6 @@ #include <bits/wordsize.h> -#if defined __USE_MISC || defined _ASM -# define JB_GPR1 0 /* Also known as the stack pointer */ -# define JB_GPR2 1 -# define JB_LR 2 /* The address we will return to */ -# if __WORDSIZE == 64 -# define JB_GPRS 3 /* GPRs 14 through 31 are saved, 18*2 words total. */ -# define JB_CR 21 /* Condition code registers with the VRSAVE at */ - /* offset 172 (low half of the double word. */ -# define JB_FPRS 22 /* FPRs 14 through 31 are saved, 18*2 words total. */ -# define JB_SIZE (64 * 8) /* As per PPC64-VMX ABI. */ -# define JB_VRSAVE 21 /* VRSAVE shares a double word with the CR at offset */ - /* 168 (high half of the double word). */ -# define JB_VRS 40 /* VRs 20 through 31 are saved, 12*4 words total. */ -# else -# define JB_GPRS 3 /* GPRs 14 through 31 are saved, 18 in total. */ -# define JB_CR 21 /* Condition code registers. */ -# define JB_FPRS 22 /* FPRs 14 through 31 are saved, 18*2 words total. */ -# define JB_SIZE ((64 + (12 * 4)) * 4) -# define JB_VRSAVE 62 -# define JB_VRS 64 -# endif -#endif - - /* The current powerpc 32-bit Altivec ABI specifies for SVR4 ABI and EABI the vrsave must be at byte 248 & v20 at byte 256. So we must pad this correctly on 32 bit. It also insists that vecregs are only gauranteed @@ -72,9 +49,4 @@ typedef long int __jmp_buf[64 + (12 * 4)] __attribute__ ((__aligned__ (16))); # endif #endif -/* Test if longjmp to JMPBUF would unwind the frame - containing a local variable at ADDRESS. */ -#define _JMPBUF_UNWINDS(jmpbuf, address) \ - ((void *) (address) < (void *) (jmpbuf)[JB_GPR1]) - #endif /* bits/setjmp.h */ diff --git a/sysdeps/powerpc/dl-procinfo.c b/sysdeps/powerpc/dl-procinfo.c new file mode 100644 index 0000000..a732e94 --- /dev/null +++ b/sysdeps/powerpc/dl-procinfo.c @@ -0,0 +1,90 @@ +/* Data for processor capability information. PowerPC 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., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +/* This information must be kept in sync with the _DL_HWCAP_COUNT and + _DL_PLATFORM_COUNT definitions in procinfo.h. + + If anything should be added here check whether the size of each string + is still ok with the given array size. + + All the #ifdefs in the definitions are quite irritating but + necessary if we want to avoid duplicating the information. There + are three different modes: + + - PROCINFO_DECL is defined. This means we are only interested in + declarations. + + - PROCINFO_DECL is not defined: + + + if SHARED is defined the file is included in an array + initializer. The .element = { ... } syntax is needed. + + + if SHARED is not defined a normal array initialization is + needed. + */ + +#ifndef PROCINFO_CLASS +# define PROCINFO_CLASS +#endif + +#if !defined PROCINFO_DECL && defined SHARED + ._dl_powerpc_cap_flags +#else +PROCINFO_CLASS const char _dl_powerpc_cap_flags[23][10] +#endif +#ifndef PROCINFO_DECL += { + "power6x", "dfp", "pa6t", + "arch_2_05", "ic_snoop", "smt", "booke", + "cellbe", "power5+", "power5", "power4", + "notb", "efpdouble", "efpsingle", "spe", + "ucache", "4xxmac", "mmu", "fpu", + "altivec", "ppc601", "ppc64", "ppc32", + } +#endif +#if !defined SHARED || defined PROCINFO_DECL +; +#else +, +#endif + +#if !defined PROCINFO_DECL && defined SHARED + ._dl_powerpc_platforms +#else +PROCINFO_CLASS const char _dl_powerpc_platforms[7][12] +#endif +#ifndef PROCINFO_DECL += { + [PPC_PLATFORM_POWER4] = "power4", + [PPC_PLATFORM_PPC970] = "ppc970", + [PPC_PLATFORM_POWER5] = "power5", + [PPC_PLATFORM_POWER5_PLUS] = "power5+", + [PPC_PLATFORM_POWER6] = "power6", + [PPC_PLATFORM_CELL_BE] = "ppc-cell-be", + [PPC_PLATFORM_POWER6X] = "power6x" + } +#endif +#if !defined SHARED || defined PROCINFO_DECL +; +#else +, +#endif + +#undef PROCINFO_DECL +#undef PROCINFO_CLASS diff --git a/sysdeps/powerpc/dl-procinfo.h b/sysdeps/powerpc/dl-procinfo.h new file mode 100644 index 0000000..0bf9353 --- /dev/null +++ b/sysdeps/powerpc/dl-procinfo.h @@ -0,0 +1,144 @@ +/* Processor capability information handling macros. PowerPC 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., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#ifndef _DL_PROCINFO_H +#define _DL_PROCINFO_H 1 + +#include <ldsodefs.h> +#include <sysdep.h> /* This defines the PPC_FEATURE_* macros. */ + +/* There are 20 bits used, but they are bits 12..31. */ +#define _DL_HWCAP_FIRST 9 +#define _DL_HWCAP_COUNT 32 + +/* These bits influence library search. */ +#define HWCAP_IMPORTANT (PPC_FEATURE_HAS_ALTIVEC \ + + PPC_FEATURE_HAS_DFP) + +#define _DL_PLATFORMS_COUNT 7 + +#define _DL_FIRST_PLATFORM 32 +/* Mask to filter out platforms. */ +#define _DL_HWCAP_PLATFORM (((1ULL << _DL_PLATFORMS_COUNT) - 1) \ + << _DL_FIRST_PLATFORM) + +/* Platform bits (relative to _DL_FIRST_PLATFORM). */ +#define PPC_PLATFORM_POWER4 0 +#define PPC_PLATFORM_PPC970 1 +#define PPC_PLATFORM_POWER5 2 +#define PPC_PLATFORM_POWER5_PLUS 3 +#define PPC_PLATFORM_POWER6 4 +#define PPC_PLATFORM_CELL_BE 5 +#define PPC_PLATFORM_POWER6X 6 + +static inline const char * +__attribute__ ((unused)) +_dl_hwcap_string (int idx) +{ + return GLRO(dl_powerpc_cap_flags)[idx - _DL_HWCAP_FIRST]; +} + +static inline const char * +__attribute__ ((unused)) +_dl_platform_string (int idx) +{ + return GLRO(dl_powerpc_platforms)[idx - _DL_FIRST_PLATFORM]; +} + +static inline int +__attribute__ ((unused)) +_dl_string_hwcap (const char *str) +{ + for (int i = _DL_HWCAP_FIRST; i < _DL_HWCAP_COUNT; ++i) + if (strcmp (str, _dl_hwcap_string (i)) == 0) + return i; + return -1; +} + +static inline int +__attribute__ ((unused, always_inline)) +_dl_string_platform (const char *str) +{ + if (str == NULL) + return -1; + + if (strncmp (str, GLRO(dl_powerpc_platforms)[PPC_PLATFORM_POWER4], 5) == 0) + { + int ret; + str += 5; + switch (*str) + { + case '4': + ret = _DL_FIRST_PLATFORM + PPC_PLATFORM_POWER4; + break; + case '5': + ret = _DL_FIRST_PLATFORM + PPC_PLATFORM_POWER5; + if (str[1] == '+') + { + ret = _DL_FIRST_PLATFORM + PPC_PLATFORM_POWER5_PLUS; + ++str; + } + break; + case '6': + ret = _DL_FIRST_PLATFORM + PPC_PLATFORM_POWER6; + if (str[1] == 'x') + { + ret = _DL_FIRST_PLATFORM + PPC_PLATFORM_POWER6X; + ++str; + } + break; + default: + return -1; + } + if (str[1] == '\0') + return ret; + } + else if (strncmp (str, GLRO(dl_powerpc_platforms)[PPC_PLATFORM_PPC970], + 3) == 0) + { + if (strcmp (str + 3, GLRO(dl_powerpc_platforms)[PPC_PLATFORM_PPC970] + + 3) == 0) + return _DL_FIRST_PLATFORM + PPC_PLATFORM_PPC970; + else if (strcmp (str + 3, + GLRO(dl_powerpc_platforms)[PPC_PLATFORM_CELL_BE] + 3) + == 0) + return _DL_FIRST_PLATFORM + PPC_PLATFORM_CELL_BE; + } + + return -1; +} + +#ifdef IS_IN_rtld +static inline int +__attribute__ ((unused)) +_dl_procinfo (int word) +{ + _dl_printf ("AT_HWCAP: "); + + for (int i = _DL_HWCAP_FIRST; i < _DL_HWCAP_COUNT; ++i) + if (word & (1 << i)) + _dl_printf (" %s", _dl_hwcap_string (i)); + + _dl_printf ("\n"); + + return 0; +} +#endif + +#endif /* dl-procinfo.h */ diff --git a/sysdeps/powerpc/elf/libc-start.c b/sysdeps/powerpc/elf/libc-start.c deleted file mode 100644 index eed3e06..0000000 --- a/sysdeps/powerpc/elf/libc-start.c +++ /dev/null @@ -1,100 +0,0 @@ -/* Copyright (C) 1998,2000,2001,2002,2003,2004 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 <stdlib.h> -#include <unistd.h> -#include <ldsodefs.h> -#include <bp-start.h> -#include <bp-sym.h> - -extern int __cache_line_size; -weak_extern (__cache_line_size) - -/* The main work is done in the generic function. */ -#define LIBC_START_MAIN generic_start_main -#define LIBC_START_DISABLE_INLINE -#define LIBC_START_MAIN_AUXVEC_ARG -#define MAIN_AUXVEC_ARG -#define INIT_MAIN_ARGS -#include <sysdeps/generic/libc-start.c> - - -struct startup_info -{ - void *__unbounded sda_base; - int (*main) (int, char **, char **, void *); - int (*init) (int, char **, char **, void *); - void (*fini) (void); -}; - - -int -/* GKM FIXME: GCC: this should get __BP_ prefix by virtue of the - BPs in the arglist of startup_info.main and startup_info.init. */ -BP_SYM (__libc_start_main) (int argc, char *__unbounded *__unbounded ubp_av, - char *__unbounded *__unbounded ubp_ev, - ElfW(auxv_t) *__unbounded auxvec, - void (*rtld_fini) (void), - struct startup_info *__unbounded stinfo, - char *__unbounded *__unbounded stack_on_entry) -{ -#if __BOUNDED_POINTERS__ - char **argv; -#else -# define argv ubp_av -#endif - - /* the PPC SVR4 ABI says that the top thing on the stack will - be a NULL pointer, so if not we assume that we're being called - as a statically-linked program by Linux... */ - if (*stack_on_entry != NULL) - { - char *__unbounded *__unbounded temp; - /* ...in which case, we have argc as the top thing on the - stack, followed by argv (NULL-terminated), envp (likewise), - and the auxilary vector. */ - /* 32/64-bit agnostic load from stack */ - argc = *(long int *__unbounded) stack_on_entry; - ubp_av = stack_on_entry + 1; - ubp_ev = ubp_av + argc + 1; -#ifdef HAVE_AUX_VECTOR - temp = ubp_ev; - while (*temp != NULL) - ++temp; - auxvec = (ElfW(auxv_t) *)++temp; -#endif - rtld_fini = NULL; - } - - /* Initialize the __cache_line_size variable from the aux vector. */ - for (ElfW(auxv_t) *av = auxvec; av->a_type != AT_NULL; ++av) - switch (av->a_type) - { - case AT_DCACHEBSIZE: - { - int *cls = & __cache_line_size; - if (cls != NULL) - *cls = av->a_un.a_val; - } - break; - } - - return generic_start_main (stinfo->main, argc, ubp_av, auxvec, - stinfo->init, stinfo->fini, rtld_fini, - stack_on_entry); -} diff --git a/sysdeps/powerpc/ffs.c b/sysdeps/powerpc/ffs.c index f45b5ea..61d79c4 100644 --- a/sysdeps/powerpc/ffs.c +++ b/sysdeps/powerpc/ffs.c @@ -1,6 +1,6 @@ /* Find first set bit in a word, counted from least significant end. For PowerPC. - Copyright (C) 1991, 1992, 1997, 1998, 2004 Free Software Foundation, Inc. + Copyright (C) 1991, 1992, 1997, 1998, 2004, 2005 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Torbjorn Granlund (tege@sics.se). @@ -43,5 +43,5 @@ weak_alias (__ffs, ffsl) #endif #else -#include <sysdeps/generic/ffs.c> +#include <string/ffs.c> #endif diff --git a/sysdeps/powerpc/fpu/Dist b/sysdeps/powerpc/fpu/Dist deleted file mode 100644 index 948b04a..0000000 --- a/sysdeps/powerpc/fpu/Dist +++ /dev/null @@ -1,4 +0,0 @@ -fe_nomask.c -fenv_const.c -fenv_libc.h -t_sqrt.c diff --git a/sysdeps/powerpc/fpu/bits/fenvinline.h b/sysdeps/powerpc/fpu/bits/fenvinline.h index 552c8c9..f7700a4 100644 --- a/sysdeps/powerpc/fpu/bits/fenvinline.h +++ b/sysdeps/powerpc/fpu/bits/fenvinline.h @@ -1,5 +1,6 @@ /* Inline floating-point environment handling functions for powerpc. - Copyright (C) 1995, 1996, 1997, 1998, 1999 Free Software Foundation, Inc. + Copyright (C) 1995, 1996, 1997, 1998, 1999, 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 @@ -22,8 +23,9 @@ /* Inline definition for fegetround. */ # define fegetround() \ (__extension__ ({ int __fegetround_result; \ - __asm__ ("mcrfs 7,7 ; mfcr %0" \ - : "=r"(__fegetround_result) : : "cr7"); \ + __asm__ __volatile__ \ + ("mcrfs 7,7 ; mfcr %0" \ + : "=r"(__fegetround_result) : : "cr7"); \ __fegetround_result & 3; })) /* The weird 'i#*X' constraints on the following suppress a gcc diff --git a/sysdeps/powerpc/fpu/bits/mathinline.h b/sysdeps/powerpc/fpu/bits/mathinline.h index 44f7dbe..aed899e 100644 --- a/sysdeps/powerpc/fpu/bits/mathinline.h +++ b/sysdeps/powerpc/fpu/bits/mathinline.h @@ -1,5 +1,5 @@ /* Inline math functions for powerpc. - Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2004 + Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2004, 2006 Free Software Foundation, Inc. This file is part of the GNU C Library. @@ -123,20 +123,26 @@ __NTH (fdimf (float __x, float __y)) #endif /* !__NO_MATH_INLINES && __OPTIMIZE__ */ /* This code is used internally in the GNU libc. */ -# ifdef __LIBC_INTERNAL_MATH_INLINES +#ifdef __LIBC_INTERNAL_MATH_INLINES #include <sysdep.h> #include <ldsodefs.h> #include <dl-procinfo.h> +# if __WORDSIZE == 64 || defined _ARCH_PWR4 +# define __CPU_HAS_FSQRT 1 +# else +# define __CPU_HAS_FSQRT ((GLRO(dl_hwcap) & PPC_FEATURE_64) != 0) +# endif + extern double __slow_ieee754_sqrt (double); __MATH_INLINE double __NTH (__ieee754_sqrt (double __x)) { double __z; - /* If the CPU is 64-bit we can use the optional FP instructions we. */ - if ((GLRO(dl_hwcap) & PPC_FEATURE_64) != 0) + /* If the CPU is 64-bit we can use the optional FP instructions. */ + if (__CPU_HAS_FSQRT) { /* Volatile is required to prevent the compiler from moving the fsqrt instruction above the branch. */ @@ -157,8 +163,8 @@ __NTH (__ieee754_sqrtf (float __x)) { float __z; - /* If the CPU is 64-bit we can use the optional FP instructions we. */ - if ((GLRO(dl_hwcap) & PPC_FEATURE_64) != 0) + /* If the CPU is 64-bit we can use the optional FP instructions. */ + if (__CPU_HAS_FSQRT) { /* Volatile is required to prevent the compiler from moving the fsqrts instruction above the branch. */ @@ -172,5 +178,5 @@ __NTH (__ieee754_sqrtf (float __x)) return __z; } -# endif /* __LIBC_INTERNAL_MATH_INLINES */ +#endif /* __LIBC_INTERNAL_MATH_INLINES */ #endif /* __GNUC__ && !_SOFT_FLOAT */ diff --git a/sysdeps/powerpc/fpu/e_sqrt.c b/sysdeps/powerpc/fpu/e_sqrt.c index eb9984d..540b924 100644 --- a/sysdeps/powerpc/fpu/e_sqrt.c +++ b/sysdeps/powerpc/fpu/e_sqrt.c @@ -24,7 +24,6 @@ #include <sysdep.h> #include <ldsodefs.h> -#include <dl-procinfo.h> static const double almost_half = 0.5000000000000001; /* 0.5 + 2^-53 */ static const ieee_float_shape_type a_nan = {.word = 0x7fc00000 }; @@ -170,8 +169,8 @@ __ieee754_sqrt (x) { double z; - /* If the CPU is 64-bit we can use the optional FP instructions we. */ - if ((GLRO (dl_hwcap) & PPC_FEATURE_64) != 0) + /* If the CPU is 64-bit we can use the optional FP instructions. */ + if (__CPU_HAS_FSQRT) { /* Volatile is required to prevent the compiler from moving the fsqrt instruction above the branch. */ diff --git a/sysdeps/powerpc/fpu/e_sqrtf.c b/sysdeps/powerpc/fpu/e_sqrtf.c index 9b70101..b63d314 100644 --- a/sysdeps/powerpc/fpu/e_sqrtf.c +++ b/sysdeps/powerpc/fpu/e_sqrtf.c @@ -24,7 +24,6 @@ #include <sysdep.h> #include <ldsodefs.h> -#include <dl-procinfo.h> static const float almost_half = 0.50000006; /* 0.5 + 2^-24 */ static const ieee_float_shape_type a_nan = {.word = 0x7fc00000 }; @@ -147,8 +146,8 @@ __ieee754_sqrtf (x) { double z; - /* If the CPU is 64-bit we can use the optional FP instructions we. */ - if ((GLRO (dl_hwcap) & PPC_FEATURE_64) != 0) + /* If the CPU is 64-bit we can use the optional FP instructions. */ + if (__CPU_HAS_FSQRT) { /* Volatile is required to prevent the compiler from moving the fsqrt instruction above the branch. */ diff --git a/sysdeps/powerpc/fpu/fegetround.c b/sysdeps/powerpc/fpu/fegetround.c index ae521fd..93663ad 100644 --- a/sysdeps/powerpc/fpu/fegetround.c +++ b/sysdeps/powerpc/fpu/fegetround.c @@ -23,7 +23,5 @@ int fegetround (void) { - int result; - asm ("mcrfs 7,7 ; mfcr %0" : "=r"(result) : : "cr7"); \ - return result & 3; + return __fegetround(); } diff --git a/sysdeps/powerpc/fpu/feholdexcpt.c b/sysdeps/powerpc/fpu/feholdexcpt.c index 8ac875c..150becd 100644 --- a/sysdeps/powerpc/fpu/feholdexcpt.c +++ b/sysdeps/powerpc/fpu/feholdexcpt.c @@ -1,5 +1,5 @@ /* Store current floating-point environment and clear exceptions. - Copyright (C) 1997 Free Software Foundation, Inc. + Copyright (C) 1997, 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 @@ -36,3 +36,4 @@ feholdexcept (fenv_t *envp) return 0; } +libm_hidden_def (feholdexcept) diff --git a/sysdeps/powerpc/fpu/fenv_libc.h b/sysdeps/powerpc/fpu/fenv_libc.h index 7ae12a7..fd5fc0c 100644 --- a/sysdeps/powerpc/fpu/fenv_libc.h +++ b/sysdeps/powerpc/fpu/fenv_libc.h @@ -1,5 +1,5 @@ /* Internal libc stuff for floating point environment routines. - 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 @@ -54,6 +54,41 @@ typedef union unsigned int l[2]; } fenv_union_t; + +static inline int +__fegetround (void) +{ + int result; + asm volatile ("mcrfs 7,7\n\t" + "mfcr %0" : "=r"(result) : : "cr7"); + return result & 3; +} +#define fegetround() __fegetround() + +static inline int +__fesetround (int round) +{ + if ((unsigned int) round < 2) + { + asm volatile ("mtfsb0 30"); + if ((unsigned int) round == 0) + asm volatile ("mtfsb0 31"); + else + asm volatile ("mtfsb1 31"); + } + else + { + asm volatile ("mtfsb1 30"); + if ((unsigned int) round == 2) + asm volatile ("mtfsb0 31"); + else + asm volatile ("mtfsb1 31"); + } + + return 0; +} +#define fesetround(mode) __fesetround(mode) + /* Definitions of all the FPSCR bit numbers */ enum { FPSCR_FX = 0, /* exception summary */ diff --git a/sysdeps/powerpc/fpu/fesetround.c b/sysdeps/powerpc/fpu/fesetround.c index f7cd6af..a7efa3b 100644 --- a/sysdeps/powerpc/fpu/fesetround.c +++ b/sysdeps/powerpc/fpu/fesetround.c @@ -1,5 +1,5 @@ /* Set current rounding direction. - Copyright (C) 1997 Free Software Foundation, Inc. + Copyright (C) 1997, 2005, 2006 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997. @@ -20,22 +20,13 @@ #include <fenv_libc.h> +#undef fesetround int fesetround (int round) { - fenv_union_t u; - if ((unsigned int) round > 3) return 1; - - /* Get the current state. */ - u.fenv = fegetenv_register (); - - /* Set the relevant bits. */ - u.l[1] = (u.l[1] & ~3) | (round & 3); - - /* Put the new state in effect. */ - fesetenv_register (u.fenv); - - return 0; + else + return __fesetround(round); } +libm_hidden_def (fesetround) diff --git a/sysdeps/powerpc/fpu/libm-test-ulps b/sysdeps/powerpc/fpu/libm-test-ulps index 6dd3940..8516e91 100644 --- a/sysdeps/powerpc/fpu/libm-test-ulps +++ b/sysdeps/powerpc/fpu/libm-test-ulps @@ -1,37 +1,57 @@ # Begin of automatic generation +# acos +Test "acos (2e-17) == 1.57079632679489659923132169163975144": +ildouble: 1 +ldouble: 1 + +# asin +Test "asin (0.75) == 0.848062078981481008052944338998418080": +ildouble: 2 +ldouble: 2 + # atan2 +Test "atan2 (-0.00756827042671106339, -.001792735857538728036) == -1.80338464113663849327153994379639112": +ildouble: 1 +ldouble: 1 Test "atan2 (-0.75, -1.0) == -2.49809154479650885165983415456218025": -float: 3 -ifloat: 3 +float: 1 +ifloat: 1 Test "atan2 (0.75, -1.0) == 2.49809154479650885165983415456218025": -float: 3 -ifloat: 3 +float: 1 +ifloat: 1 Test "atan2 (1.390625, 0.9296875) == 0.981498387184244311516296577615519772": float: 1 ifloat: 1 -Test "atan2 (-0.00756827042671106339, -.001792735857538728036) == -1.80338464113663849327153994379639112": -float: 6 -ifloat: 6 +ildouble: 1 +ldouble: 1 # atanh Test "atanh (0.75) == 0.972955074527656652552676371721589865": float: 1 ifloat: 1 +# cabs +Test "cabs (0.75 + 1.25 i) == 1.45773797371132511771853821938639577": +ildouble: 1 +ldouble: 1 + # cacosh -Test "Real part of: cacosh (-2 - 3 i) == -1.9833870299165354323470769028940395 + 2.1414491111159960199416055713254211 i": +Test "Real part of: cacosh (-2 - 3 i) == 1.9833870299165354323470769028940395 - 2.1414491111159960199416055713254211 i": double: 1 float: 7 idouble: 1 ifloat: 7 -Test "Imaginary part of: cacosh (-2 - 3 i) == -1.9833870299165354323470769028940395 + 2.1414491111159960199416055713254211 i": +Test "Imaginary part of: cacosh (-2 - 3 i) == 1.9833870299165354323470769028940395 - 2.1414491111159960199416055713254211 i": double: 1 float: 3 idouble: 1 ifloat: 3 # casin +Test "Real part of: casin (-2 - 3 i) == -0.57065278432109940071028387968566963 - 1.9833870299165354323470769028940395 i": +ildouble: 1 +ldouble: 1 Test "Real part of: casin (0.75 + 1.25 i) == 0.453276177638793913448921196101971749 + 1.13239363160530819522266333696834467 i": double: 1 float: 1 @@ -44,11 +64,15 @@ double: 5 float: 1 idouble: 5 ifloat: 1 +ildouble: 4 +ldouble: 4 Test "Imaginary part of: casinh (-2 - 3 i) == -1.9686379257930962917886650952454982 - 0.96465850440760279204541105949953237 i": double: 3 float: 6 idouble: 3 ifloat: 6 +ildouble: 1 +ldouble: 1 Test "Real part of: casinh (0.75 + 1.25 i) == 1.03171853444778027336364058631006594 + 0.911738290968487636358489564316731207 i": float: 1 ifloat: 1 @@ -62,6 +86,8 @@ ifloat: 1 Test "Real part of: catan (-2 - 3 i) == -1.4099210495965755225306193844604208 - 0.22907268296853876629588180294200276 i": float: 3 ifloat: 3 +ildouble: 1 +ldouble: 1 Test "Imaginary part of: catan (-2 - 3 i) == -1.4099210495965755225306193844604208 - 0.22907268296853876629588180294200276 i": double: 1 float: 1 @@ -118,9 +144,13 @@ double: 1 float: 1 idouble: 1 ifloat: 1 +ildouble: 1 +ldouble: 1 Test "Imaginary part of: ccosh (0.75 + 1.25 i) == 0.408242591877968807788852146397499084 + 0.780365930845853240391326216300863152 i": float: 1 ifloat: 1 +ildouble: 2 +ldouble: 2 # cexp Test "Imaginary part of: cexp (-2.0 - 3.0 i) == -0.13398091492954261346140525546115575 - 0.019098516261135196432576240858800925 i": @@ -129,66 +159,141 @@ ifloat: 1 Test "Real part of: cexp (0.75 + 1.25 i) == 0.667537446429131586942201977015932112 + 2.00900045494094876258347228145863909 i": float: 1 ifloat: 1 +ildouble: 2 +ldouble: 2 +Test "Imaginary part of: cexp (0.75 + 1.25 i) == 0.667537446429131586942201977015932112 + 2.00900045494094876258347228145863909 i": +ildouble: 1 +ldouble: 1 # clog Test "Imaginary part of: clog (-2 - 3 i) == 1.2824746787307683680267437207826593 - 2.1587989303424641704769327722648368 i": float: 3 ifloat: 3 +ildouble: 1 +ldouble: 1 Test "Real part of: clog (0.75 + 1.25 i) == 0.376885901188190075998919126749298416 + 1.03037682652431246378774332703115153 i": float: 1 ifloat: 1 +ildouble: 2 +ldouble: 2 +Test "Imaginary part of: clog (0.75 + 1.25 i) == 0.376885901188190075998919126749298416 + 1.03037682652431246378774332703115153 i": +ildouble: 1 +ldouble: 1 # clog10 Test "Imaginary part of: clog10 (-0 + inf i) == inf + pi/2*log10(e) i": +double: 1 float: 1 +idouble: 1 ifloat: 1 +ildouble: 1 +ldouble: 1 Test "Imaginary part of: clog10 (-0 - inf i) == inf - pi/2*log10(e) i": +double: 1 float: 1 +idouble: 1 ifloat: 1 +ildouble: 1 +ldouble: 1 Test "Imaginary part of: clog10 (-2 - 3 i) == 0.556971676153418384603252578971164214 - 0.937554462986374708541507952140189646 i": double: 1 float: 5 idouble: 1 ifloat: 5 +ildouble: 1 +ldouble: 1 Test "Imaginary part of: clog10 (-3 + inf i) == inf + pi/2*log10(e) i": +double: 1 float: 1 +idouble: 1 ifloat: 1 +ildouble: 1 +ldouble: 1 Test "Imaginary part of: clog10 (-3 - inf i) == inf - pi/2*log10(e) i": +double: 1 float: 1 +idouble: 1 ifloat: 1 +ildouble: 1 +ldouble: 1 Test "Imaginary part of: clog10 (-inf + 0 i) == inf + pi*log10(e) i": +double: 1 float: 1 +idouble: 1 ifloat: 1 +ildouble: 1 +ldouble: 1 Test "Imaginary part of: clog10 (-inf + 1 i) == inf + pi*log10(e) i": +double: 1 float: 1 +idouble: 1 ifloat: 1 +ildouble: 1 +ldouble: 1 +Test "Imaginary part of: clog10 (-inf + inf i) == inf + 3/4 pi*log10(e) i": +double: 1 +idouble: 1 Test "Imaginary part of: clog10 (-inf - 0 i) == inf - pi*log10(e) i": +double: 1 float: 1 +idouble: 1 ifloat: 1 +ildouble: 1 +ldouble: 1 Test "Imaginary part of: clog10 (-inf - 1 i) == inf - pi*log10(e) i": +double: 1 float: 1 +idouble: 1 ifloat: 1 +ildouble: 1 +ldouble: 1 Test "Imaginary part of: clog10 (0 + inf i) == inf + pi/2*log10(e) i": +double: 1 float: 1 +idouble: 1 ifloat: 1 +ildouble: 1 +ldouble: 1 Test "Imaginary part of: clog10 (0 - inf i) == inf - pi/2*log10(e) i": +double: 1 float: 1 +idouble: 1 ifloat: 1 +ildouble: 1 +ldouble: 1 Test "Real part of: clog10 (0.75 + 1.25 i) == 0.163679467193165171449476605077428975 + 0.447486970040493067069984724340855636 i": float: 1 ifloat: 1 +ildouble: 3 +ldouble: 3 Test "Imaginary part of: clog10 (3 + inf i) == inf + pi/2*log10(e) i": +double: 1 float: 1 +idouble: 1 ifloat: 1 +ildouble: 1 +ldouble: 1 Test "Imaginary part of: clog10 (3 - inf i) == inf - pi/2*log10(e) i": +double: 1 float: 1 +idouble: 1 ifloat: 1 +ildouble: 1 +ldouble: 1 Test "Imaginary part of: clog10 (inf + inf i) == inf + pi/4*log10(e) i": +double: 1 float: 1 +idouble: 1 ifloat: 1 +ildouble: 1 +ldouble: 1 Test "Imaginary part of: clog10 (inf - inf i) == inf - pi/4*log10(e) i": +double: 1 float: 1 +idouble: 1 ifloat: 1 +ildouble: 1 +ldouble: 1 # cos Test "cos (M_PI_6l * 2.0) == 0.5": @@ -206,48 +311,71 @@ double: 1 float: 1 idouble: 1 ifloat: 1 +Test "cos (16.0) == -0.9576594803233846418996372326511034717803" +ildouble: 2 +ldouble: 2 # cpow Test "Real part of: cpow (0.75 + 1.25 i, 0.0 + 1.0 i) == 0.331825439177608832276067945276730566 + 0.131338600281188544930936345230903032 i": float: 1 ifloat: 1 +ildouble: 1 +ldouble: 1 Test "Imaginary part of: cpow (0.75 + 1.25 i, 0.0 + 1.0 i) == 0.331825439177608832276067945276730566 + 0.131338600281188544930936345230903032 i": float: 1 ifloat: 1 +ildouble: 1 +ldouble: 1 Test "Real part of: cpow (0.75 + 1.25 i, 0.75 + 1.25 i) == 0.117506293914473555420279832210420483 + 0.346552747708338676483025352060418001 i": double: 1 float: 4 idouble: 1 ifloat: 4 +Test "Real part of: cpow (0.75 + 1.25 i, 1.0 + 0.0 i) == 0.75 + 1.25 i": +ildouble: 2 +ldouble: 2 Test "Real part of: cpow (0.75 + 1.25 i, 1.0 + 1.0 i) == 0.0846958290317209430433805274189191353 + 0.513285749182902449043287190519090481 i": double: 2 float: 3 idouble: 2 ifloat: 3 +Test "Real part of: cpow (2 + 0 i, 10 + 0 i) == 1024.0 + 0.0 i": +ildouble: 1 +ldouble: 1 Test "Real part of: cpow (2 + 3 i, 4 + 0 i) == -119.0 - 120.0 i": double: 1 -float: 4 +float: 5 idouble: 1 -ifloat: 4 +ifloat: 5 Test "Imaginary part of: cpow (2 + 3 i, 4 + 0 i) == -119.0 - 120.0 i": float: 2 ifloat: 2 +ildouble: 2 +ldouble: 2 Test "Imaginary part of: cpow (e + 0 i, 0 + 2 * M_PIl i) == 1.0 + 0.0 i": double: 2 float: 2 idouble: 2 ifloat: 2 +ildouble: 2 +ldouble: 2 # csinh Test "Imaginary part of: csinh (-2 - 3 i) == 3.59056458998577995201256544779481679 - 0.530921086248519805267040090660676560 i": double: 1 idouble: 1 +ildouble: 1 +ldouble: 1 Test "Real part of: csinh (0.75 + 1.25 i) == 0.259294854551162779153349830618433028 + 1.22863452409509552219214606515777594 i": float: 1 ifloat: 1 +ildouble: 1 +ldouble: 1 Test "Imaginary part of: csinh (0.75 + 1.25 i) == 0.259294854551162779153349830618433028 + 1.22863452409509552219214606515777594 i": float: 1 ifloat: 1 +ildouble: 1 +ldouble: 1 # csqrt Test "Real part of: csqrt (-2 + 3 i) == 0.89597747612983812471573375529004348 + 1.6741492280355400404480393008490519 i": @@ -261,6 +389,9 @@ ifloat: 1 Test "Real part of: ctan (-2 - 3 i) == 0.376402564150424829275122113032269084e-2 - 1.00323862735360980144635859782192726 i": double: 1 idouble: 1 +Test "Imaginary part of: ctan (-2 - 3 i) == 0.376402564150424829275122113032269084e-2 - 1.00323862735360980144635859782192726 i": +ildouble: 1 +ldouble: 1 Test "Imaginary part of: ctan (0.75 + 1.25 i) == 0.160807785916206426725166058173438663 + 0.975363285031235646193581759755216379 i": double: 1 idouble: 1 @@ -277,6 +408,8 @@ ifloat: 1 Test "Real part of: ctanh (0.75 + 1.25 i) == 1.37260757053378320258048606571226857 + 0.385795952609750664177596760720790220 i": double: 1 idouble: 1 +ildouble: 1 +ldouble: 1 # erf Test "erf (1.25) == 0.922900128256458230136523481197281140": @@ -294,29 +427,50 @@ Test "erfc (4.125) == 0.542340079956506600531223408575531062e-8": double: 1 idouble: 1 +# exp +Test "exp (0.75) == 2.11700001661267466854536981983709561": +ildouble: 1 +ldouble: 1 +Test "exp (50.0) == 5184705528587072464087.45332293348538": +ildouble: 1 +ldouble: 1 + # exp10 Test "exp10 (-1) == 0.1": double: 2 float: 1 idouble: 2 ifloat: 1 +ildouble: 1 +ldouble: 1 Test "exp10 (0.75) == 5.62341325190349080394951039776481231": double: 1 float: 1 idouble: 1 ifloat: 1 +ildouble: 1 +ldouble: 1 Test "exp10 (3) == 1000": double: 6 float: 2 idouble: 6 ifloat: 2 +ildouble: 8 +ldouble: 8 + +# exp2 +Test "exp2 (10) == 1024": +ildouble: 2 +ldouble: 2 # expm1 Test "expm1 (0.75) == 1.11700001661267466854536981983709561": double: 1 idouble: 1 Test "expm1 (1) == M_El - 1.0": +double: 1 float: 1 +idouble: 1 ifloat: 1 # hypot @@ -338,6 +492,9 @@ ifloat: 1 Test "hypot (0.7, 12.4) == 12.419742348374220601176836866763271": float: 1 ifloat: 1 +Test "hypot (0.75, 1.25) == 1.45773797371132511771853821938639577": +ildouble: 1 +ldouble: 1 Test "hypot (12.4, -0.7) == 12.419742348374220601176836866763271": float: 1 ifloat: 1 @@ -348,78 +505,121 @@ ifloat: 1 # j0 Test "j0 (-4.0) == -3.9714980986384737228659076845169804197562E-1": double: 1 -float: 1 +float: 2 idouble: 1 -ifloat: 1 +ifloat: 2 +ildouble: 1 +ldouble: 1 Test "j0 (10.0) == -0.245935764451348335197760862485328754": -double: 2 +double: 3 float: 1 -idouble: 2 +idouble: 3 ifloat: 1 +ildouble: 1 +ldouble: 1 +Test "j0 (2.0) == 0.223890779141235668051827454649948626": +float: 2 +ifloat: 2 Test "j0 (4.0) == -3.9714980986384737228659076845169804197562E-1": double: 1 -float: 1 +float: 2 idouble: 1 -ifloat: 1 +ifloat: 2 +ildouble: 1 +ldouble: 1 Test "j0 (8.0) == 0.171650807137553906090869407851972001": float: 1 ifloat: 1 +ildouble: 1 +ldouble: 1 # j1 Test "j1 (10.0) == 0.0434727461688614366697487680258592883": float: 2 ifloat: 2 +ildouble: 1 +ldouble: 1 Test "j1 (2.0) == 0.576724807756873387202448242269137087": double: 1 idouble: 1 Test "j1 (8.0) == 0.234636346853914624381276651590454612": double: 1 idouble: 1 +ildouble: 1 +ldouble: 1 # jn Test "jn (0, -4.0) == -3.9714980986384737228659076845169804197562E-1": double: 1 -float: 1 +float: 2 idouble: 1 -ifloat: 1 +ifloat: 2 +ildouble: 1 +ldouble: 1 Test "jn (0, 10.0) == -0.245935764451348335197760862485328754": -double: 2 +double: 3 float: 1 -idouble: 2 +idouble: 3 ifloat: 1 +ildouble: 1 +ldouble: 1 +Test "jn (0, 2.0) == 0.223890779141235668051827454649948626": +float: 2 +ifloat: 2 Test "jn (0, 4.0) == -3.9714980986384737228659076845169804197562E-1": double: 1 -float: 1 +float: 2 idouble: 1 -ifloat: 1 +ifloat: 2 +ildouble: 1 +ldouble: 1 Test "jn (0, 8.0) == 0.171650807137553906090869407851972001": float: 1 ifloat: 1 +ildouble: 1 +ldouble: 1 Test "jn (1, 10.0) == 0.0434727461688614366697487680258592883": float: 2 ifloat: 2 +ildouble: 1 +ldouble: 1 Test "jn (1, 2.0) == 0.576724807756873387202448242269137087": double: 1 idouble: 1 Test "jn (1, 8.0) == 0.234636346853914624381276651590454612": double: 1 idouble: 1 +ildouble: 1 +ldouble: 1 +Test "jn (10, -1.0) == 0.263061512368745320699785368779050294e-9": +ildouble: 1 +ldouble: 1 Test "jn (10, 0.125) == 0.250543369809369890173993791865771547e-18": double: 1 float: 1 idouble: 1 ifloat: 1 +ildouble: 1 +ldouble: 1 Test "jn (10, 0.75) == 0.149621713117596814698712483621682835e-10": double: 1 float: 1 idouble: 1 ifloat: 1 +Test "jn (10, 1.0) == 0.263061512368745320699785368779050294e-9": +ildouble: 1 +ldouble: 1 Test "jn (10, 10.0) == 0.207486106633358857697278723518753428": float: 1 ifloat: 1 +ildouble: 4 +ldouble: 4 Test "jn (10, 2.0) == 0.251538628271673670963516093751820639e-6": -float: 3 -ifloat: 3 +float: 4 +ifloat: 4 +Test "jn (3, -1.0) == -0.0195633539826684059189053216217515083": +ildouble: 1 +ldouble: 1 Test "jn (3, 0.125) == 0.406503832554912875023029337653442868e-4": double: 1 float: 1 @@ -428,16 +628,23 @@ ifloat: 1 Test "jn (3, 0.75) == 0.848438342327410884392755236884386804e-2": double: 1 idouble: 1 +Test "jn (3, 1.0) == 0.0195633539826684059189053216217515083": +ildouble: 1 +ldouble: 1 Test "jn (3, 10.0) == 0.0583793793051868123429354784103409563": double: 3 -float: 1 +float: 2 idouble: 3 -ifloat: 1 +ifloat: 2 +ildouble: 2 +ldouble: 2 Test "jn (3, 2.0) == 0.128943249474402051098793332969239835": double: 1 -float: 1 +float: 2 idouble: 1 -ifloat: 1 +ifloat: 2 +ildouble: 2 +ldouble: 2 # lgamma Test "lgamma (0.7) == 0.260867246531666514385732417016759578": @@ -450,6 +657,8 @@ double: 1 float: 2 idouble: 1 ifloat: 2 +ildouble: 3 +ldouble: 3 # log10 Test "log10 (0.75) == -0.124938736608299953132449886193870744": @@ -466,6 +675,16 @@ Test "log1p (-0.25) == -0.287682072451780927439219005993827432": float: 1 ifloat: 1 +# log2 +Test "log2 (e) == M_LOG2El": +ildouble: 1 +ldouble: 1 + +# sin +Test "sin (16.0) == -0.2879033166650652947844562482186175296207" +ildouble: 2 +ldouble: 2 + # sincos Test "sincos (M_PI_6l*2.0, &sin_res, &cos_res) puts 0.5 in cos_res": double: 1 @@ -486,10 +705,25 @@ Test "sincos (pi/6, &sin_res, &cos_res) puts 0.866025403784438646763723170752936 float: 1 ifloat: 1 +# sinh +Test "sinh (0.75) == 0.822316731935829980703661634446913849": +ildouble: 1 +ldouble: 1 + # tan Test "tan (pi/4) == 1": double: 1 idouble: 1 +ildouble: 1 +ldouble: 1 + +# tanh +Test "tanh (-0.75) == -0.635148952387287319214434357312496495": +ildouble: 1 +ldouble: 1 +Test "tanh (0.75) == 0.635148952387287319214434357312496495": +ildouble: 1 +ldouble: 1 # tgamma Test "tgamma (-0.5) == -2 sqrt (pi)": @@ -507,11 +741,19 @@ idouble: 1 ifloat: 1 # y0 +Test "y0 (0.125) == -1.38968062514384052915582277745018693": +ildouble: 1 +ldouble: 1 +Test "y0 (0.75) == -0.137172769385772397522814379396581855": +ildouble: 1 +ldouble: 1 Test "y0 (1.0) == 0.0882569642156769579829267660235151628": double: 2 float: 1 idouble: 2 ifloat: 1 +ildouble: 1 +ldouble: 1 Test "y0 (1.5) == 0.382448923797758843955068554978089862": double: 2 float: 1 @@ -522,6 +764,8 @@ double: 1 float: 1 idouble: 1 ifloat: 1 +ildouble: 1 +ldouble: 1 Test "y0 (2.0) == 0.510375672649745119596606592727157873": double: 1 idouble: 1 @@ -530,30 +774,50 @@ double: 1 float: 1 idouble: 1 ifloat: 1 +ildouble: 1 +ldouble: 1 # y1 +Test "y1 (0.125) == -5.19993611253477499595928744876579921": +double: 1 +idouble: 1 +Test "y1 (1.5) == -0.412308626973911295952829820633445323": +float: 1 +ifloat: 1 Test "y1 (10.0) == 0.249015424206953883923283474663222803": double: 3 float: 1 idouble: 3 ifloat: 1 +ildouble: 2 +ldouble: 2 Test "y1 (2.0) == -0.107032431540937546888370772277476637": double: 1 float: 1 -idouble: 1 -ifloat: 1 +idouble: 2 +ifloat: 2 Test "y1 (8.0) == -0.158060461731247494255555266187483550": double: 1 float: 2 idouble: 1 ifloat: 2 +ildouble: 2 +ldouble: 2 # yn +Test "yn (0, 0.125) == -1.38968062514384052915582277745018693": +ildouble: 1 +ldouble: 1 +Test "yn (0, 0.75) == -0.137172769385772397522814379396581855": +ildouble: 1 +ldouble: 1 Test "yn (0, 1.0) == 0.0882569642156769579829267660235151628": double: 2 float: 1 idouble: 2 ifloat: 1 +ildouble: 2 +ldouble: 2 Test "yn (0, 1.5) == 0.382448923797758843955068554978089862": double: 2 float: 1 @@ -564,6 +828,8 @@ double: 1 float: 1 idouble: 1 ifloat: 1 +ildouble: 2 +ldouble: 2 Test "yn (0, 2.0) == 0.510375672649745119596606592727157873": double: 1 idouble: 1 @@ -572,11 +838,21 @@ double: 1 float: 1 idouble: 1 ifloat: 1 +ildouble: 2 +ldouble: 2 +Test "yn (1, 0.125) == -5.19993611253477499595928744876579921": +double: 1 +idouble: 1 +Test "yn (1, 1.5) == -0.412308626973911295952829820633445323": +float: 2 +ifloat: 2 Test "yn (1, 10.0) == 0.249015424206953883923283474663222803": double: 3 float: 1 idouble: 3 ifloat: 1 +ildouble: 2 +ldouble: 2 Test "yn (1, 2.0) == -0.107032431540937546888370772277476637": double: 1 float: 1 @@ -587,6 +863,14 @@ double: 1 float: 2 idouble: 1 ifloat: 2 +ildouble: 2 +ldouble: 2 +Test "yn (3, 0.125) == -2612.69757350066712600220955744091741": +double: 1 +idouble: 1 +Test "yn (10, 0.125) == -127057845771019398.252538486899753195": +double: 1 +idouble: 1 Test "yn (10, 0.75) == -2133501638.90573424452445412893839236": double: 1 float: 2 @@ -597,12 +881,21 @@ float: 2 ifloat: 2 Test "yn (10, 10.0) == -0.359814152183402722051986577343560609": double: 2 +float: 2 idouble: 2 +ifloat: 2 +ildouble: 2 +ldouble: 2 Test "yn (10, 2.0) == -129184.542208039282635913145923304214": double: 3 float: 1 idouble: 3 ifloat: 1 +ildouble: 2 +ldouble: 2 +Test "yn (3, 0.125) == -2612.69757350066712600220955744091741": +double: 1 +idouble: 1 Test "yn (3, 0.75) == -12.9877176234475433186319774484809207": float: 1 ifloat: 1 @@ -611,24 +904,58 @@ double: 1 float: 1 idouble: 1 ifloat: 1 +ildouble: 2 +ldouble: 2 Test "yn (3, 2.0) == -1.12778377684042778608158395773179238": double: 1 idouble: 1 # Maximal error of functions: +Function: "acos": +ildouble: 1 +ldouble: 1 + +Function: "acosh": +ildouble: 1 +ldouble: 1 + +Function: "asin": +ildouble: 2 +ldouble: 2 + +Function: "asinh": +ildouble: 1 +ldouble: 1 + Function: "atan2": -float: 6 -ifloat: 6 +float: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 Function: "atanh": float: 1 ifloat: 1 +Function: "cabs": +ildouble: 1 +ldouble: 1 + +Function: Real part of "cacos": +ildouble: 1 +ldouble: 1 + +Function: Imaginary part of "cacos": +ildouble: 1 +ldouble: 1 + Function: Real part of "cacosh": double: 1 float: 7 idouble: 1 ifloat: 7 +ildouble: 1 +ldouble: 1 Function: Imaginary part of "cacosh": double: 1 @@ -641,28 +968,42 @@ double: 1 float: 1 idouble: 1 ifloat: 1 +ildouble: 1 +ldouble: 1 + +Function: Imaginary part of "casin": +ildouble: 1 +ldouble: 1 Function: Real part of "casinh": double: 5 float: 1 idouble: 5 ifloat: 1 +ildouble: 4 +ldouble: 4 Function: Imaginary part of "casinh": double: 3 float: 6 idouble: 3 ifloat: 6 +ildouble: 1 +ldouble: 1 Function: Real part of "catan": float: 4 ifloat: 4 +ildouble: 1 +ldouble: 1 Function: Imaginary part of "catan": double: 1 float: 1 idouble: 1 ifloat: 1 +ildouble: 1 +ldouble: 1 Function: Real part of "catanh": double: 4 @@ -675,118 +1016,190 @@ ifloat: 6 Function: "cbrt": double: 1 idouble: 1 +ildouble: 1 +ldouble: 1 Function: Real part of "ccos": double: 1 float: 1 idouble: 1 ifloat: 1 +ildouble: 1 +ldouble: 1 Function: Imaginary part of "ccos": float: 1 ifloat: 1 +ildouble: 1 +ldouble: 1 Function: Real part of "ccosh": double: 1 float: 1 idouble: 1 ifloat: 1 +ildouble: 1 +ldouble: 1 Function: Imaginary part of "ccosh": float: 1 ifloat: 1 +ildouble: 2 +ldouble: 2 Function: Real part of "cexp": float: 1 ifloat: 1 +ildouble: 2 +ldouble: 2 Function: Imaginary part of "cexp": float: 1 ifloat: 1 +ildouble: 1 +ldouble: 1 Function: Real part of "clog": float: 1 ifloat: 1 +ildouble: 2 +ldouble: 2 Function: Imaginary part of "clog": float: 3 ifloat: 3 +ildouble: 1 +ldouble: 1 Function: Real part of "clog10": float: 1 ifloat: 1 +ildouble: 3 +ldouble: 3 Function: Imaginary part of "clog10": double: 1 float: 5 idouble: 1 ifloat: 5 +ildouble: 1 +ldouble: 1 Function: "cos": double: 2 float: 1 idouble: 2 ifloat: 1 +ildouble: 1 +ldouble: 1 + +Function: "cosh": +ildouble: 1 +ldouble: 1 Function: Real part of "cpow": double: 2 -float: 4 +float: 5 idouble: 2 -ifloat: 4 +ifloat: 5 +ildouble: 2 +ldouble: 2 Function: Imaginary part of "cpow": double: 2 float: 2 idouble: 2 ifloat: 2 +ildouble: 2 +ldouble: 2 + +Function: Imaginary part of "cproj": +ildouble: 1 +ldouble: 1 + +Function: Real part of "csin": +ildouble: 1 +ldouble: 1 Function: Real part of "csinh": float: 1 ifloat: 1 +ildouble: 1 +ldouble: 1 Function: Imaginary part of "csinh": double: 1 float: 1 idouble: 1 ifloat: 1 +ildouble: 1 +ldouble: 1 Function: Real part of "csqrt": float: 1 ifloat: 1 +ildouble: 1 +ldouble: 1 + +Function: Imaginary part of "csqrt": +ildouble: 1 +ldouble: 1 Function: Real part of "ctan": double: 1 idouble: 1 +ildouble: 1 +ldouble: 1 Function: Imaginary part of "ctan": double: 1 idouble: 1 +ildouble: 1 +ldouble: 1 Function: Real part of "ctanh": double: 1 float: 2 idouble: 1 ifloat: 2 +ildouble: 1 +ldouble: 1 Function: Imaginary part of "ctanh": float: 1 ifloat: 1 +ildouble: 1 +ldouble: 1 Function: "erf": double: 1 idouble: 1 +ildouble: 1 +ldouble: 1 Function: "erfc": double: 1 float: 1 idouble: 1 ifloat: 1 +ildouble: 1 +ldouble: 1 + +Function: "exp": +ildouble: 1 +ldouble: 1 Function: "exp10": double: 6 float: 2 idouble: 6 ifloat: 2 +ildouble: 8 +ldouble: 8 + +Function: "exp2": +ildouble: 2 +ldouble: 2 Function: "expm1": double: 1 @@ -794,76 +1207,130 @@ float: 1 idouble: 1 ifloat: 1 +Function: "gamma": +ildouble: 1 +ldouble: 1 + Function: "hypot": float: 1 ifloat: 1 +ildouble: 1 +ldouble: 1 Function: "j0": -double: 2 -float: 1 -idouble: 2 -ifloat: 1 +double: 3 +float: 2 +idouble: 3 +ifloat: 2 +ildouble: 1 +ldouble: 1 Function: "j1": double: 1 float: 2 idouble: 1 ifloat: 2 +ildouble: 1 +ldouble: 1 Function: "jn": double: 3 -float: 3 +float: 4 idouble: 3 -ifloat: 3 +ifloat: 4 +ildouble: 4 +ldouble: 4 Function: "lgamma": double: 1 float: 2 idouble: 1 ifloat: 2 +ildouble: 3 +ldouble: 3 + +Function: "log": +ildouble: 1 +ldouble: 1 Function: "log10": double: 1 float: 2 idouble: 1 ifloat: 2 +ildouble: 1 +ldouble: 1 Function: "log1p": float: 1 ifloat: 1 +ildouble: 1 +ldouble: 1 + +Function: "log2": +ildouble: 1 +ldouble: 1 + +Function: "pow": +ildouble: 1 +ldouble: 1 + +Function: "sin": +ildouble: 1 +ldouble: 1 Function: "sincos": double: 1 float: 1 idouble: 1 ifloat: 1 +ildouble: 1 +ldouble: 1 + +Function: "sinh": +ildouble: 1 +ldouble: 1 Function: "tan": double: 1 idouble: 1 +ildouble: 1 +ldouble: 1 + +Function: "tanh": +ildouble: 1 +ldouble: 1 Function: "tgamma": double: 1 float: 1 idouble: 1 ifloat: 1 +ildouble: 1 +ldouble: 1 Function: "y0": double: 2 float: 1 idouble: 2 ifloat: 1 +ildouble: 1 +ldouble: 1 Function: "y1": double: 3 float: 2 idouble: 3 ifloat: 2 +ildouble: 2 +ldouble: 2 Function: "yn": double: 3 float: 2 idouble: 3 ifloat: 2 +ildouble: 2 +ldouble: 2 # end of automatic generation diff --git a/sysdeps/powerpc/fpu/math_ldbl.h b/sysdeps/powerpc/fpu/math_ldbl.h new file mode 100644 index 0000000..6cd6d0b --- /dev/null +++ b/sysdeps/powerpc/fpu/math_ldbl.h @@ -0,0 +1,189 @@ +#ifndef _MATH_PRIVATE_H_ +#error "Never use <math_ldbl.h> directly; include <math_private.h> instead." +#endif + +#include <sysdeps/ieee754/ldbl-128/math_ldbl.h> +#include <ieee754.h> + +static inline void +ldbl_extract_mantissa (int64_t *hi64, u_int64_t *lo64, int *exp, long double x) +{ + /* We have 105 bits of mantissa plus one implicit digit. Since + 106 bits are representable we use the first implicit digit for + the number before the decimal point and the second implicit bit + as bit 53 of the mantissa. */ + unsigned long long hi, lo; + int ediff; + union ibm_extended_long_double eldbl; + eldbl.d = x; + *exp = eldbl.ieee.exponent - IBM_EXTENDED_LONG_DOUBLE_BIAS; + + lo = ((long long)eldbl.ieee.mantissa2 << 32) | eldbl.ieee.mantissa3; + hi = ((long long)eldbl.ieee.mantissa0 << 32) | eldbl.ieee.mantissa1; + /* If the lower double is not a denomal or zero then set the hidden + 53rd bit. */ + if (eldbl.ieee.exponent2 > 0x001) + { + lo |= (1ULL << 52); + lo = lo << 7; /* pre-shift lo to match ieee854. */ + /* The lower double is normalized separately from the upper. We + may need to adjust the lower manitissa to reflect this. */ + ediff = eldbl.ieee.exponent - eldbl.ieee.exponent2; + if (ediff > 53) + lo = lo >> (ediff-53); + } + hi |= (1ULL << 52); + + if ((eldbl.ieee.negative != eldbl.ieee.negative2) + && ((eldbl.ieee.exponent2 != 0) && (lo != 0LL))) + { + hi--; + lo = (1ULL << 60) - lo; + if (hi < (1ULL << 52)) + { + /* we have a borrow from the hidden bit, so shift left 1. */ + hi = (hi << 1) | (lo >> 59); + lo = 0xfffffffffffffffLL & (lo << 1); + *exp = *exp - 1; + } + } + *lo64 = (hi << 60) | lo; + *hi64 = hi >> 4; +} + +static inline long double +ldbl_insert_mantissa (int sign, int exp, int64_t hi64, u_int64_t lo64) +{ + union ibm_extended_long_double u; + unsigned long hidden2, lzcount; + unsigned long long hi, lo; + + u.ieee.negative = sign; + u.ieee.negative2 = sign; + u.ieee.exponent = exp + IBM_EXTENDED_LONG_DOUBLE_BIAS; + u.ieee.exponent2 = exp-53 + IBM_EXTENDED_LONG_DOUBLE_BIAS; + /* Expect 113 bits (112 bits + hidden) right justified in two longs. + The low order 53 bits (52 + hidden) go into the lower double */ + lo = (lo64 >> 7)& ((1ULL << 53) - 1); + hidden2 = (lo64 >> 59) & 1ULL; + /* The high order 53 bits (52 + hidden) go into the upper double */ + hi = (lo64 >> 60) & ((1ULL << 11) - 1); + hi |= (hi64 << 4); + + if (lo != 0LL) + { + /* hidden2 bit of low double controls rounding of the high double. + If hidden2 is '1' then round up hi and adjust lo (2nd mantissa) + plus change the sign of the low double to compensate. */ + if (hidden2) + { + hi++; + u.ieee.negative2 = !sign; + lo = (1ULL << 53) - lo; + } + /* The hidden bit of the lo mantissa is zero so we need to + normalize the it for the low double. Shift it left until the + hidden bit is '1' then adjust the 2nd exponent accordingly. */ + + if (sizeof (lo) == sizeof (long)) + lzcount = __builtin_clzl (lo); + else if ((lo >> 32) != 0) + lzcount = __builtin_clzl ((long) (lo >> 32)); + else + lzcount = __builtin_clzl ((long) lo) + 32; + lzcount = lzcount - 11; + if (lzcount > 0) + { + int expnt2 = u.ieee.exponent2 - lzcount; + if (expnt2 >= 1) + { + /* Not denormal. Normalize and set low exponent. */ + lo = lo << lzcount; + u.ieee.exponent2 = expnt2; + } + else + { + /* Is denormal. */ + lo = lo << (lzcount + expnt2); + u.ieee.exponent2 = 0; + } + } + } + else + { + u.ieee.negative2 = 0; + u.ieee.exponent2 = 0; + } + + u.ieee.mantissa3 = lo & ((1ULL << 32) - 1); + u.ieee.mantissa2 = (lo >> 32) & ((1ULL << 20) - 1); + u.ieee.mantissa1 = hi & ((1ULL << 32) - 1); + u.ieee.mantissa0 = (hi >> 32) & ((1ULL << 20) - 1); + return u.d; +} + +/* gcc generates disgusting code to pack and unpack long doubles. + This tells gcc that pack/unpack is really a nop. We use fr1/fr2 + because those are the regs used to pass/return a single + long double arg. */ +static inline long double +ldbl_pack (double a, double aa) +{ + register long double x __asm__ ("fr1"); + register double xh __asm__ ("fr1"); + register double xl __asm__ ("fr2"); + xh = a; + xl = aa; + __asm__ ("" : "=f" (x) : "f" (xh), "f" (xl)); + return x; +} + +static inline void +ldbl_unpack (long double l, double *a, double *aa) +{ + register long double x __asm__ ("fr1"); + register double xh __asm__ ("fr1"); + register double xl __asm__ ("fr2"); + x = l; + __asm__ ("" : "=f" (xh), "=f" (xl) : "f" (x)); + *a = xh; + *aa = xl; +} + + +/* Convert a finite long double to canonical form. + Does not handle +/-Inf properly. */ +static inline void +ldbl_canonicalize (double *a, double *aa) +{ + double xh, xl; + + xh = *a + *aa; + xl = (*a - xh) + *aa; + *a = xh; + *aa = xl; +} + +/* Simple inline nearbyint (double) function . + Only works in the default rounding mode + but is useful in long double rounding functions. */ +static inline double +ldbl_nearbyint (double a) +{ + double two52 = 0x10000000000000LL; + + if (__builtin_expect ((__builtin_fabs (a) < two52), 1)) + { + if (__builtin_expect ((a > 0.0), 1)) + { + a += two52; + a -= two52; + } + else if (__builtin_expect ((a < 0.0), 1)) + { + a = two52 - a; + a = -(a - two52); + } + } + return a; +} diff --git a/sysdeps/powerpc/fpu/s_fabs.S b/sysdeps/powerpc/fpu/s_fabs.S index 157ef09..ab9a3a9 100644 --- a/sysdeps/powerpc/fpu/s_fabs.S +++ b/sysdeps/powerpc/fpu/s_fabs.S @@ -25,13 +25,13 @@ ENTRY(__fabs) blr END(__fabs) -weak_alias(__fabs,fabs) +weak_alias (__fabs,fabs) /* It turns out that it's safe to use this code even for single-precision. */ strong_alias(__fabs,__fabsf) -weak_alias(__fabs,fabsf) +weak_alias (__fabs,fabsf) #ifdef NO_LONG_DOUBLE -weak_alias(__fabs,__fabsl) -weak_alias(__fabs,fabsl) +weak_alias (__fabs,__fabsl) +weak_alias (__fabs,fabsl) #endif diff --git a/sysdeps/powerpc/fpu/s_fmax.S b/sysdeps/powerpc/fpu/s_fmax.S index 5666cdd..8502c86 100644 --- a/sysdeps/powerpc/fpu/s_fmax.S +++ b/sysdeps/powerpc/fpu/s_fmax.S @@ -31,13 +31,13 @@ ENTRY(__fmax) blr END(__fmax) -weak_alias(__fmax,fmax) +weak_alias (__fmax,fmax) /* It turns out that it's safe to use this code even for single-precision. */ strong_alias(__fmax,__fmaxf) -weak_alias(__fmax,fmaxf) +weak_alias (__fmax,fmaxf) #ifdef NO_LONG_DOUBLE -weak_alias(__fmax,__fmaxl) -weak_alias(__fmax,fmaxl) +weak_alias (__fmax,__fmaxl) +weak_alias (__fmax,fmaxl) #endif diff --git a/sysdeps/powerpc/fpu/s_fmin.S b/sysdeps/powerpc/fpu/s_fmin.S index 96387d9..5f788d0 100644 --- a/sysdeps/powerpc/fpu/s_fmin.S +++ b/sysdeps/powerpc/fpu/s_fmin.S @@ -31,13 +31,13 @@ ENTRY(__fmin) blr END(__fmin) -weak_alias(__fmin,fmin) +weak_alias (__fmin,fmin) /* It turns out that it's safe to use this code even for single-precision. */ strong_alias(__fmin,__fminf) -weak_alias(__fmin,fminf) +weak_alias (__fmin,fminf) #ifdef NO_LONG_DOUBLE -weak_alias(__fmin,__fminl) -weak_alias(__fmin,fminl) +weak_alias (__fmin,__fminl) +weak_alias (__fmin,fminl) #endif diff --git a/sysdeps/powerpc/fpu/s_isnan.c b/sysdeps/powerpc/fpu/s_isnan.c index 38ec821..f3313c7 100644 --- a/sysdeps/powerpc/fpu/s_isnan.c +++ b/sysdeps/powerpc/fpu/s_isnan.c @@ -1,5 +1,5 @@ /* Return 1 if argument is a NaN, else 0. - Copyright (C) 1997, 2000, 2002 Free Software Foundation, Inc. + Copyright (C) 1997, 2000, 2002, 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 @@ -23,6 +23,7 @@ #define __GI___isnanf __GI___Xisnanf #include "math.h" +#include <math_ldbl_opt.h> #include <fenv_libc.h> #undef __isnanf diff --git a/sysdeps/powerpc/fpu/w_sqrtf.c b/sysdeps/powerpc/fpu/w_sqrtf.c index e3f3c99..54b4f3b 100644 --- a/sysdeps/powerpc/fpu/w_sqrtf.c +++ b/sysdeps/powerpc/fpu/w_sqrtf.c @@ -23,7 +23,6 @@ #include <sysdep.h> #include <ldsodefs.h> -#include <dl-procinfo.h> #ifdef __STDC__ float diff --git a/sysdeps/powerpc/jmpbuf-offsets.h b/sysdeps/powerpc/jmpbuf-offsets.h new file mode 100644 index 0000000..5f74a85 --- /dev/null +++ b/sysdeps/powerpc/jmpbuf-offsets.h @@ -0,0 +1,39 @@ +/* Private macros for accessing __jmp_buf contents. PowerPC 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. */ + +#define JB_GPR1 0 /* Also known as the stack pointer */ +#define JB_GPR2 1 +#define JB_LR 2 /* The address we will return to */ +#if __WORDSIZE == 64 +# define JB_GPRS 3 /* GPRs 14 through 31 are saved, 18*2 words total. */ +# define JB_CR 21 /* Condition code registers with the VRSAVE at */ + /* offset 172 (low half of the double word. */ +# define JB_FPRS 22 /* FPRs 14 through 31 are saved, 18*2 words total. */ +# define JB_SIZE (64 * 8) /* As per PPC64-VMX ABI. */ +# define JB_VRSAVE 21 /* VRSAVE shares a double word with the CR at offset */ + /* 168 (high half of the double word). */ +# define JB_VRS 40 /* VRs 20 through 31 are saved, 12*4 words total. */ +#else +# define JB_GPRS 3 /* GPRs 14 through 31 are saved, 18 in total. */ +# define JB_CR 21 /* Condition code registers. */ +# define JB_FPRS 22 /* FPRs 14 through 31 are saved, 18*2 words total. */ +# define JB_SIZE ((64 + (12 * 4)) * 4) +# define JB_VRSAVE 62 +# define JB_VRS 64 +#endif diff --git a/sysdeps/powerpc/jmpbuf-unwind.h b/sysdeps/powerpc/jmpbuf-unwind.h new file mode 100644 index 0000000..20bab75 --- /dev/null +++ b/sysdeps/powerpc/jmpbuf-unwind.h @@ -0,0 +1,48 @@ +/* Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Jakub Jelinek <jakub@redhat.com>, 2003. + + 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 <setjmp.h> +#include <jmpbuf-offsets.h> +#include <stdint.h> +#include <unwind.h> +#include <sysdep.h> + +/* Test if longjmp to JMPBUF would unwind the frame + containing a local variable at ADDRESS. */ +#define _JMPBUF_UNWINDS(jmpbuf, address, demangle) \ + ((void *) (address) < (void *) demangle ((jmpbuf)[JB_GPR1])) + +#define _JMPBUF_CFA_UNWINDS_ADJ(_jmpbuf, _context, _adj) \ + _JMPBUF_UNWINDS_ADJ (_jmpbuf, (void *) _Unwind_GetCFA (_context), _adj) + +static inline uintptr_t __attribute__ ((unused)) +_jmpbuf_sp (__jmp_buf regs) +{ + uintptr_t sp = regs[JB_GPR1]; +#ifdef PTR_DEMANGLE + PTR_DEMANGLE (sp); +#endif + return sp; +} + +#define _JMPBUF_UNWINDS_ADJ(_jmpbuf, _address, _adj) \ + ((uintptr_t) (_address) - (_adj) < _jmpbuf_sp (_jmpbuf) - (_adj)) + +/* We use the normal longjmp for unwinding. */ +#define __libc_unwind_longjmp(buf, val) __libc_longjmp (buf, val) diff --git a/sysdeps/powerpc/nofpu/Dist b/sysdeps/powerpc/nofpu/Dist deleted file mode 100644 index 35a33ab..0000000 --- a/sysdeps/powerpc/nofpu/Dist +++ /dev/null @@ -1,3 +0,0 @@ -sim-full.c -fenv_const.c -soft-supp.h diff --git a/sysdeps/powerpc/nofpu/Makefile b/sysdeps/powerpc/nofpu/Makefile deleted file mode 100644 index f85cb0b..0000000 --- a/sysdeps/powerpc/nofpu/Makefile +++ /dev/null @@ -1,9 +0,0 @@ -# Makefile fragment for PowerPC with no FPU. - -ifeq ($(subdir),soft-fp) -sysdep_routines += $(gcc-single-routines) $(gcc-double-routines) sim-full -endif - -ifeq ($(subdir),math) -libm-support += fenv_const fe_nomask -endif diff --git a/sysdeps/powerpc/nofpu/Versions b/sysdeps/powerpc/nofpu/Versions deleted file mode 100644 index 4103db5..0000000 --- a/sysdeps/powerpc/nofpu/Versions +++ /dev/null @@ -1,13 +0,0 @@ -libc { - GLIBC_2.3.2 { - __sim_exceptions; __sim_disabled_exceptions; __sim_round_mode; - __adddf3; __addsf3; __divdf3; __divsf3; __eqdf2; __eqsf2; - __extendsfdf2; __fixdfdi; __fixdfsi; __fixsfdi; __fixsfsi; - __fixtfdi; __fixtfsi; - __fixunsdfdi; __fixunsdfsi; __fixunssfdi; __fixunssfsi; - __floatdidf; __floatdisf; __floatsidf; __floatsisf; - __gedf2; __gesf2; __ledf2; __lesf2; __muldf3; __mulsf3; - __negdf2; __negsf2; __sqrtdf2; __sqrtsf2; __subdf3; - __subsf3; __truncdfsf2; __trunctfsf2; - } -} diff --git a/sysdeps/powerpc/nofpu/feenablxcpt.c b/sysdeps/powerpc/nofpu/feenablxcpt.c deleted file mode 100644 index 060e450..0000000 --- a/sysdeps/powerpc/nofpu/feenablxcpt.c +++ /dev/null @@ -1,33 +0,0 @@ -/* Enable exceptions (soft-float edition). - Copyright (C) 2002 Free Software Foundation, Inc. - Contributed by Aldy Hernandez <aldyh@redhat.com>, 2002. - 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 <fenv.h> - -extern int __sim_disabled_exceptions; - -int -feenableexcept (int exceptions) -{ - int old_exceptions = ~__sim_disabled_exceptions & FE_ALL_EXCEPT; - - __sim_disabled_exceptions &= ~exceptions; - - return old_exceptions; -} diff --git a/sysdeps/powerpc/nofpu/fegetenv.c b/sysdeps/powerpc/nofpu/fegetenv.c deleted file mode 100644 index 3cc8b13..0000000 --- a/sysdeps/powerpc/nofpu/fegetenv.c +++ /dev/null @@ -1,49 +0,0 @@ -/* Store current floating-point environment (soft-float edition). - Copyright (C) 2002 Free Software Foundation, Inc. - Contributed by Aldy Hernandez <aldyh@redhat.com>, 2002. - 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 "soft-fp.h" -#include "soft-supp.h" -#include <bp-sym.h> - -extern int __sim_exceptions; -extern int __sim_disabled_exceptions; -extern int __sim_round_mode; - -int -__fegetenv (fenv_t *envp) -{ - fenv_union_t u; - - u.l[0] = __sim_exceptions; - u.l[0] |= __sim_round_mode; - u.l[1] = __sim_disabled_exceptions; - - *envp = u.fenv; - - return 0; -} - -#include <shlib-compat.h> -#if SHLIB_COMPAT (libm, GLIBC_2_1, GLIBC_2_2) -strong_alias (__fegetenv, __old_fegetenv) -compat_symbol (libm, BP_SYM (__old_fegetenv), BP_SYM (fegetenv), GLIBC_2_1); -#endif - -versioned_symbol (libm, BP_SYM (__fegetenv), BP_SYM (fegetenv), GLIBC_2_2); diff --git a/sysdeps/powerpc/nofpu/fegetexcept.c b/sysdeps/powerpc/nofpu/fegetexcept.c deleted file mode 100644 index 0a47a09..0000000 --- a/sysdeps/powerpc/nofpu/fegetexcept.c +++ /dev/null @@ -1,28 +0,0 @@ -/* Get floating-point exceptions (soft-float edition). - Copyright (C) 2002 Free Software Foundation, Inc. - Contributed by Aldy Hernandez <aldyh@redhat.com>, 2002. - 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 "soft-fp.h" -#include "soft-supp.h" - -int -fegetexcept (void) -{ - return (__sim_disabled_exceptions ^ FE_ALL_EXCEPT) & FE_ALL_EXCEPT; -} diff --git a/sysdeps/powerpc/nofpu/feholdexcpt.c b/sysdeps/powerpc/nofpu/feholdexcpt.c deleted file mode 100644 index 786c691..0000000 --- a/sysdeps/powerpc/nofpu/feholdexcpt.c +++ /dev/null @@ -1,43 +0,0 @@ -/* Store current floating-point environment and clear exceptions - (soft-float edition). - Copyright (C) 2002 Free Software Foundation, Inc. - Contributed by Aldy Hernandez <aldyh@redhat.com>, 2002. - 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 "soft-fp.h" -#include "soft-supp.h" - -int -feholdexcept (fenv_t *envp) -{ - fenv_union_t u; - - /* Get the current state. */ - fegetenv (envp); - - u.fenv = *envp; - /* Clear everything except the rounding mode. */ - u.l[0] &= 0x3; - - /* ?? Should we clear the disabled exceptions as well ?? */ - - /* Put the new state in effect. */ - fesetenv (envp); - - return 0; -} diff --git a/sysdeps/powerpc/nofpu/fenv_const.c b/sysdeps/powerpc/nofpu/fenv_const.c deleted file mode 100644 index 7dc2e81..0000000 --- a/sysdeps/powerpc/nofpu/fenv_const.c +++ /dev/null @@ -1,35 +0,0 @@ -/* Constants for fenv_bits.h (soft float edition). - Copyright (C) 2002 Free Software Foundation, Inc. - Contributed by Aldy Hernandez <aldyh@redhat.com>, 2002. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ - -/* We want to specify the bit pattern of the __fe_*_env constants, so - pretend they're really `long long' instead of `double'. */ - -/* If the default argument is used we use this value. Disable all - signalling exceptions as default. */ -const unsigned long long __fe_dfl_env __attribute__ ((aligned (8))) = -0x000000003e000000ULL; - -/* Floating-point environment where none of the exceptions are masked. */ -const unsigned long long __fe_enabled_env __attribute__ ((aligned (8))) = -0xfff80000000000f8ULL; - -/* Floating-point environment with the NI bit set. */ -const unsigned long long __fe_nonieee_env __attribute__ ((aligned (8))) = -0xfff8000000000004ULL; diff --git a/sysdeps/powerpc/nofpu/fesetenv.c b/sysdeps/powerpc/nofpu/fesetenv.c deleted file mode 100644 index 43d03a4..0000000 --- a/sysdeps/powerpc/nofpu/fesetenv.c +++ /dev/null @@ -1,48 +0,0 @@ -/* Set floating point environment (soft-float edition). - Copyright (C) 2002 Free Software Foundation, Inc. - Contributed by Aldy Hernandez <aldyh@redhat.com>, 2002. - 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 "soft-fp.h" -#include "soft-supp.h" -#include <bp-sym.h> - -extern int __sim_exceptions attribute_hidden; -extern int __sim_disabled_exceptions attribute_hidden; -extern int __sim_round_mode attribute_hidden; - -int -__fesetenv (const fenv_t *envp) -{ - fenv_union_t u; - - u.fenv = *envp; - __sim_exceptions = u.l[0] & FE_ALL_EXCEPT; - __sim_round_mode = u.l[0] & 0x3; - __sim_disabled_exceptions = u.l[1]; - return 0; -} - -#include <shlib-compat.h> -#if SHLIB_COMPAT (libm, GLIBC_2_1, GLIBC_2_2) -strong_alias (__fesetenv, __old_fesetenv) -compat_symbol (libm, BP_SYM (__old_fesetenv), BP_SYM (fesetenv), GLIBC_2_1); -#endif - -libm_hidden_ver (__fesetenv, fesetenv) -versioned_symbol (libm, BP_SYM (__fesetenv), BP_SYM (fesetenv), GLIBC_2_2); diff --git a/sysdeps/powerpc/nofpu/feupdateenv.c b/sysdeps/powerpc/nofpu/feupdateenv.c deleted file mode 100644 index 5073776..0000000 --- a/sysdeps/powerpc/nofpu/feupdateenv.c +++ /dev/null @@ -1,50 +0,0 @@ -/* Install given floating-point environment and raise exceptions - (soft-float edition). - Copyright (C) 2002 Free Software Foundation, Inc. - Contributed by Aldy Hernandez <aldyh@redhat.com>, 2002. - 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 "soft-fp.h" -#include "soft-supp.h" -#include <bp-sym.h> - -int -__feupdateenv (const fenv_t *envp) -{ - fenv_union_t u; - int saved_exceptions; - - /* Save currently set exceptions. */ - saved_exceptions = __sim_exceptions; - - /* Set environment. */ - fesetenv (envp); - - /* Raise old exceptions. */ - __sim_exceptions |= saved_exceptions; - - return 0; -} - -#include <shlib-compat.h> -#if SHLIB_COMPAT (libm, GLIBC_2_1, GLIBC_2_2) -strong_alias (__feupdateenv, __old_feupdateenv) -compat_symbol (libm, BP_SYM (__old_feupdateenv), BP_SYM (feupdateenv), GLIBC_2_1); -#endif - -versioned_symbol (libm, BP_SYM (__feupdateenv), BP_SYM (feupdateenv), GLIBC_2_2); diff --git a/sysdeps/powerpc/nofpu/fraiseexcpt.c b/sysdeps/powerpc/nofpu/fraiseexcpt.c deleted file mode 100644 index cd91502..0000000 --- a/sysdeps/powerpc/nofpu/fraiseexcpt.c +++ /dev/null @@ -1,46 +0,0 @@ -/* Raise given exceptions (soft-float edition). - Copyright (C) 2002 Free Software Foundation, Inc. - Contributed by Aldy Hernandez <aldyh@redhat.com>, 2002. - 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 "soft-fp.h" -#include "soft-supp.h" -#include <signal.h> -#include <bp-sym.h> - -#undef feraiseexcept -int -__feraiseexcept (int x) -{ - __sim_exceptions |= x; - if (x == 0 || __sim_disabled_exceptions & x) - /* Ignore exception. */ - ; - else - raise (SIGFPE); - return 0; -} - -#include <shlib-compat.h> -#if SHLIB_COMPAT (libm, GLIBC_2_1, GLIBC_2_2) -strong_alias (__feraiseexcept, __old_feraiseexcept) -compat_symbol (libm, BP_SYM (__old_feraiseexcept), BP_SYM (feraiseexcept), GLIBC_2_1); -#endif - -libm_hidden_ver (__feraiseexcept, feraiseexcept) -versioned_symbol (libm, BP_SYM (__feraiseexcept), BP_SYM (feraiseexcept), GLIBC_2_2); diff --git a/sysdeps/powerpc/nofpu/fsetexcptflg.c b/sysdeps/powerpc/nofpu/fsetexcptflg.c deleted file mode 100644 index 85fd88f..0000000 --- a/sysdeps/powerpc/nofpu/fsetexcptflg.c +++ /dev/null @@ -1,40 +0,0 @@ -/* Set floating-point environment exception handling (soft-float edition). - Copyright (C) 2002 Free Software Foundation, Inc. - Contributed by Aldy Hernandez <aldyh@redhat.com>, 2002. - 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 "soft-fp.h" -#include "soft-supp.h" -#include <bp-sym.h> - -int -__fesetexceptflag(const fexcept_t *flagp, int excepts) -{ - /* Ignore exceptions not listed in 'excepts'. */ - __sim_exceptions = *flagp & excepts; - - return 0; -} - -#include <shlib-compat.h> -#if SHLIB_COMPAT (libm, GLIBC_2_1, GLIBC_2_2) -strong_alias (__fesetexceptflag, __old_fesetexceptflag) -compat_symbol (libm, BP_SYM (__old_fesetexceptflag), BP_SYM (fesetexceptflag), GLIBC_2_1); -#endif - -versioned_symbol (libm, BP_SYM (__fesetexceptflag), BP_SYM (fesetexceptflag), GLIBC_2_2); diff --git a/sysdeps/powerpc/nofpu/libm-test-ulps b/sysdeps/powerpc/nofpu/libm-test-ulps deleted file mode 100644 index 73172b4..0000000 --- a/sysdeps/powerpc/nofpu/libm-test-ulps +++ /dev/null @@ -1,890 +0,0 @@ -# Begin of automatic generation - -# atan2 -Test "atan2 (-0.75, -1.0) == -2.49809154479650885165983415456218025": -float: 3 -ifloat: 3 -Test "atan2 (0.75, -1.0) == 2.49809154479650885165983415456218025": -float: 3 -ifloat: 3 -Test "atan2 (1.390625, 0.9296875) == 0.981498387184244311516296577615519772": -float: 1 -ifloat: 1 - -# atanh -Test "atanh (0.75) == 0.972955074527656652552676371721589865": -float: 1 -ifloat: 1 - -# cacosh -Test "Real part of: cacosh (-2 - 3 i) == -1.9833870299165354323470769028940395 + 2.1414491111159960199416055713254211 i": -double: 1 -float: 7 -idouble: 1 -ifloat: 7 -Test "Imaginary part of: cacosh (-2 - 3 i) == -1.9833870299165354323470769028940395 + 2.1414491111159960199416055713254211 i": -double: 1 -float: 3 -idouble: 1 -ifloat: 3 - -# casin -Test "Real part of: casin (0.75 + 1.25 i) == 0.453276177638793913448921196101971749 + 1.13239363160530819522266333696834467 i": -double: 1 -float: 1 -idouble: 1 -ifloat: 1 - -# casinh -Test "Real part of: casinh (-2 - 3 i) == -1.9686379257930962917886650952454982 - 0.96465850440760279204541105949953237 i": -double: 5 -float: 1 -idouble: 5 -ifloat: 1 -Test "Imaginary part of: casinh (-2 - 3 i) == -1.9686379257930962917886650952454982 - 0.96465850440760279204541105949953237 i": -double: 3 -float: 6 -idouble: 3 -ifloat: 6 -Test "Real part of: casinh (0.75 + 1.25 i) == 1.03171853444778027336364058631006594 + 0.911738290968487636358489564316731207 i": -float: 1 -ifloat: 1 -Test "Imaginary part of: casinh (0.75 + 1.25 i) == 1.03171853444778027336364058631006594 + 0.911738290968487636358489564316731207 i": -double: 1 -float: 1 -idouble: 1 -ifloat: 1 - -# catan -Test "Real part of: catan (-2 - 3 i) == -1.4099210495965755225306193844604208 - 0.22907268296853876629588180294200276 i": -float: 3 -ifloat: 3 -Test "Imaginary part of: catan (-2 - 3 i) == -1.4099210495965755225306193844604208 - 0.22907268296853876629588180294200276 i": -double: 1 -float: 1 -idouble: 1 -ifloat: 1 -Test "Real part of: catan (0.75 + 1.25 i) == 1.10714871779409050301706546017853704 + 0.549306144334054845697622618461262852 i": -float: 4 -ifloat: 4 - -# catanh -Test "Real part of: catanh (-2 - 3 i) == -0.14694666622552975204743278515471595 - 1.3389725222944935611241935759091443 i": -double: 4 -idouble: 4 -Test "Imaginary part of: catanh (-2 - 3 i) == -0.14694666622552975204743278515471595 - 1.3389725222944935611241935759091443 i": -float: 4 -ifloat: 4 -Test "Real part of: catanh (0.75 + 1.25 i) == 0.261492138795671927078652057366532140 + 0.996825126463918666098902241310446708 i": -double: 1 -idouble: 1 -Test "Imaginary part of: catanh (0.75 + 1.25 i) == 0.261492138795671927078652057366532140 + 0.996825126463918666098902241310446708 i": -float: 6 -ifloat: 6 - -# cbrt -Test "cbrt (-27.0) == -3.0": -double: 1 -idouble: 1 -Test "cbrt (0.75) == 0.908560296416069829445605878163630251": -double: 1 -idouble: 1 -Test "cbrt (0.9921875) == 0.997389022060725270579075195353955217": -double: 1 -idouble: 1 - -# ccos -Test "Imaginary part of: ccos (-2 - 3 i) == -4.18962569096880723013255501961597373 - 9.10922789375533659797919726277886212 i": -float: 1 -ifloat: 1 -Test "Real part of: ccos (0.75 + 1.25 i) == 1.38173873063425888530729933139078645 - 1.09193013555397466170919531722024128 i": -double: 1 -float: 1 -idouble: 1 -ifloat: 1 -Test "Imaginary part of: ccos (0.75 + 1.25 i) == 1.38173873063425888530729933139078645 - 1.09193013555397466170919531722024128 i": -float: 1 -ifloat: 1 - -# ccosh -Test "Real part of: ccosh (-2 - 3 i) == -3.72454550491532256547397070325597253 + 0.511822569987384608834463849801875634 i": -float: 1 -ifloat: 1 -Test "Imaginary part of: ccosh (-2 - 3 i) == -3.72454550491532256547397070325597253 + 0.511822569987384608834463849801875634 i": -float: 1 -ifloat: 1 -Test "Real part of: ccosh (0.75 + 1.25 i) == 0.408242591877968807788852146397499084 + 0.780365930845853240391326216300863152 i": -double: 1 -float: 1 -idouble: 1 -ifloat: 1 -Test "Imaginary part of: ccosh (0.75 + 1.25 i) == 0.408242591877968807788852146397499084 + 0.780365930845853240391326216300863152 i": -float: 1 -ifloat: 1 - -# cexp -Test "Imaginary part of: cexp (-2.0 - 3.0 i) == -0.13398091492954261346140525546115575 - 0.019098516261135196432576240858800925 i": -float: 1 -ifloat: 1 -Test "Real part of: cexp (0.75 + 1.25 i) == 0.667537446429131586942201977015932112 + 2.00900045494094876258347228145863909 i": -float: 1 -ifloat: 1 - -# clog -Test "Imaginary part of: clog (-2 - 3 i) == 1.2824746787307683680267437207826593 - 2.1587989303424641704769327722648368 i": -float: 3 -ifloat: 3 -Test "Real part of: clog (0.75 + 1.25 i) == 0.376885901188190075998919126749298416 + 1.03037682652431246378774332703115153 i": -float: 1 -ifloat: 1 - -# clog10 -Test "Imaginary part of: clog10 (-0 + inf i) == inf + pi/2*log10(e) i": -float: 1 -ifloat: 1 -Test "Imaginary part of: clog10 (-0 - inf i) == inf - pi/2*log10(e) i": -float: 1 -ifloat: 1 -Test "Imaginary part of: clog10 (-2 - 3 i) == 0.556971676153418384603252578971164214 - 0.937554462986374708541507952140189646 i": -double: 1 -float: 5 -idouble: 1 -ifloat: 5 -Test "Imaginary part of: clog10 (-3 + inf i) == inf + pi/2*log10(e) i": -float: 1 -ifloat: 1 -Test "Imaginary part of: clog10 (-3 - inf i) == inf - pi/2*log10(e) i": -float: 1 -ifloat: 1 -Test "Imaginary part of: clog10 (-inf + 0 i) == inf + pi*log10(e) i": -float: 1 -ifloat: 1 -Test "Imaginary part of: clog10 (-inf + 1 i) == inf + pi*log10(e) i": -float: 1 -ifloat: 1 -Test "Imaginary part of: clog10 (-inf - 0 i) == inf - pi*log10(e) i": -float: 1 -ifloat: 1 -Test "Imaginary part of: clog10 (-inf - 1 i) == inf - pi*log10(e) i": -float: 1 -ifloat: 1 -Test "Imaginary part of: clog10 (0 + inf i) == inf + pi/2*log10(e) i": -float: 1 -ifloat: 1 -Test "Imaginary part of: clog10 (0 - inf i) == inf - pi/2*log10(e) i": -float: 1 -ifloat: 1 -Test "Real part of: clog10 (0.75 + 1.25 i) == 0.163679467193165171449476605077428975 + 0.447486970040493067069984724340855636 i": -float: 1 -ifloat: 1 -Test "Imaginary part of: clog10 (3 + inf i) == inf + pi/2*log10(e) i": -float: 1 -ifloat: 1 -Test "Imaginary part of: clog10 (3 - inf i) == inf - pi/2*log10(e) i": -float: 1 -ifloat: 1 -Test "Imaginary part of: clog10 (inf + inf i) == inf + pi/4*log10(e) i": -float: 1 -ifloat: 1 -Test "Imaginary part of: clog10 (inf - inf i) == inf - pi/4*log10(e) i": -float: 1 -ifloat: 1 - -# cos -Test "cos (M_PI_6l * 2.0) == 0.5": -double: 1 -float: 1 -idouble: 1 -ifloat: 1 -Test "cos (M_PI_6l * 4.0) == -0.5": -double: 2 -float: 1 -idouble: 2 -ifloat: 1 -Test "cos (pi/2) == 0": -double: 1 -float: 1 -idouble: 1 -ifloat: 1 - -# cpow -Test "Real part of: cpow (0.75 + 1.25 i, 0.0 + 1.0 i) == 0.331825439177608832276067945276730566 + 0.131338600281188544930936345230903032 i": -float: 1 -ifloat: 1 -Test "Imaginary part of: cpow (0.75 + 1.25 i, 0.0 + 1.0 i) == 0.331825439177608832276067945276730566 + 0.131338600281188544930936345230903032 i": -float: 1 -ifloat: 1 -Test "Real part of: cpow (0.75 + 1.25 i, 0.75 + 1.25 i) == 0.117506293914473555420279832210420483 + 0.346552747708338676483025352060418001 i": -double: 1 -float: 4 -idouble: 1 -ifloat: 4 -Test "Real part of: cpow (0.75 + 1.25 i, 1.0 + 1.0 i) == 0.0846958290317209430433805274189191353 + 0.513285749182902449043287190519090481 i": -double: 2 -float: 3 -idouble: 2 -ifloat: 3 -Test "Real part of: cpow (2 + 3 i, 4 + 0 i) == -119.0 - 120.0 i": -double: 1 -float: 4 -idouble: 1 -ifloat: 4 -Test "Imaginary part of: cpow (2 + 3 i, 4 + 0 i) == -119.0 - 120.0 i": -float: 2 -ifloat: 2 -Test "Imaginary part of: cpow (e + 0 i, 0 + 2 * M_PIl i) == 1.0 + 0.0 i": -double: 2 -float: 2 -idouble: 2 -ifloat: 2 - -# csinh -Test "Imaginary part of: csinh (-2 - 3 i) == 3.59056458998577995201256544779481679 - 0.530921086248519805267040090660676560 i": -double: 1 -idouble: 1 -Test "Real part of: csinh (0.75 + 1.25 i) == 0.259294854551162779153349830618433028 + 1.22863452409509552219214606515777594 i": -float: 1 -ifloat: 1 -Test "Imaginary part of: csinh (0.75 + 1.25 i) == 0.259294854551162779153349830618433028 + 1.22863452409509552219214606515777594 i": -float: 1 -ifloat: 1 - -# csqrt -Test "Real part of: csqrt (-2 + 3 i) == 0.89597747612983812471573375529004348 + 1.6741492280355400404480393008490519 i": -float: 1 -ifloat: 1 -Test "Real part of: csqrt (-2 - 3 i) == 0.89597747612983812471573375529004348 - 1.6741492280355400404480393008490519 i": -float: 1 -ifloat: 1 - -# ctan -Test "Real part of: ctan (-2 - 3 i) == 0.376402564150424829275122113032269084e-2 - 1.00323862735360980144635859782192726 i": -double: 1 -idouble: 1 -Test "Imaginary part of: ctan (0.75 + 1.25 i) == 0.160807785916206426725166058173438663 + 0.975363285031235646193581759755216379 i": -double: 1 -idouble: 1 - -# ctanh -Test "Real part of: ctanh (-2 - 3 i) == -0.965385879022133124278480269394560686 + 0.988437503832249372031403430350121098e-2 i": -double: 1 -float: 2 -idouble: 1 -ifloat: 2 -Test "Imaginary part of: ctanh (0 + pi/4 i) == 0.0 + 1.0 i": -float: 1 -ifloat: 1 -Test "Real part of: ctanh (0.75 + 1.25 i) == 1.37260757053378320258048606571226857 + 0.385795952609750664177596760720790220 i": -double: 1 -idouble: 1 - -# erf -Test "erf (1.25) == 0.922900128256458230136523481197281140": -double: 1 -idouble: 1 - -# erfc -Test "erfc (2.0) == 0.00467773498104726583793074363274707139": -double: 1 -idouble: 1 -Test "erfc (4.125) == 0.542340079956506600531223408575531062e-8": -double: 1 -idouble: 1 - -# exp10 -Test "exp10 (-1) == 0.1": -double: 2 -float: 1 -idouble: 2 -ifloat: 1 -Test "exp10 (0.75) == 5.62341325190349080394951039776481231": -double: 1 -float: 1 -idouble: 1 -ifloat: 1 -Test "exp10 (3) == 1000": -double: 6 -float: 2 -idouble: 6 -ifloat: 2 - -# expm1 -Test "expm1 (0.75) == 1.11700001661267466854536981983709561": -double: 1 -idouble: 1 -Test "expm1 (1) == M_El - 1.0": -float: 1 -ifloat: 1 - -# hypot -Test "hypot (-0.7, -12.4) == 12.419742348374220601176836866763271": -float: 1 -ifloat: 1 -Test "hypot (-0.7, 12.4) == 12.419742348374220601176836866763271": -float: 1 -ifloat: 1 -Test "hypot (-12.4, -0.7) == 12.419742348374220601176836866763271": -float: 1 -ifloat: 1 -Test "hypot (-12.4, 0.7) == 12.419742348374220601176836866763271": -float: 1 -ifloat: 1 -Test "hypot (0.7, -12.4) == 12.419742348374220601176836866763271": -float: 1 -ifloat: 1 -Test "hypot (0.7, 12.4) == 12.419742348374220601176836866763271": -float: 1 -ifloat: 1 -Test "hypot (12.4, -0.7) == 12.419742348374220601176836866763271": -float: 1 -ifloat: 1 -Test "hypot (12.4, 0.7) == 12.419742348374220601176836866763271": -float: 1 -ifloat: 1 - -# j0 -Test "j0 (-4.0) == -3.9714980986384737228659076845169804197562E-1": -double: 1 -float: 1 -idouble: 1 -ifloat: 1 -Test "j0 (0.75) == 0.864242275166648623555731103820923211": -float: 1 -ifloat: 1 -Test "j0 (10.0) == -0.245935764451348335197760862485328754": -double: 2 -float: 1 -idouble: 2 -ifloat: 1 -Test "j0 (2.0) == 0.223890779141235668051827454649948626": -float: 2 -ifloat: 2 -Test "j0 (4.0) == -3.9714980986384737228659076845169804197562E-1": -double: 1 -float: 1 -idouble: 1 -ifloat: 1 -Test "j0 (8.0) == 0.171650807137553906090869407851972001": -float: 1 -ifloat: 1 - -# j1 -Test "j1 (10.0) == 0.0434727461688614366697487680258592883": -float: 2 -ifloat: 2 -Test "j1 (2.0) == 0.576724807756873387202448242269137087": -double: 1 -idouble: 1 -Test "j1 (8.0) == 0.234636346853914624381276651590454612": -double: 1 -idouble: 1 - -# jn -Test "jn (0, -4.0) == -3.9714980986384737228659076845169804197562E-1": -double: 1 -float: 1 -idouble: 1 -ifloat: 1 -Test "jn (0, 0.75) == 0.864242275166648623555731103820923211": -float: 1 -ifloat: 1 -Test "jn (0, 10.0) == -0.245935764451348335197760862485328754": -double: 2 -float: 1 -idouble: 2 -ifloat: 1 -Test "jn (0, 2.0) == 0.223890779141235668051827454649948626": -float: 2 -ifloat: 2 -Test "jn (0, 4.0) == -3.9714980986384737228659076845169804197562E-1": -double: 1 -float: 1 -idouble: 1 -ifloat: 1 -Test "jn (0, 8.0) == 0.171650807137553906090869407851972001": -float: 1 -ifloat: 1 -Test "jn (1, 10.0) == 0.0434727461688614366697487680258592883": -float: 2 -ifloat: 2 -Test "jn (1, 2.0) == 0.576724807756873387202448242269137087": -double: 1 -idouble: 1 -Test "jn (1, 8.0) == 0.234636346853914624381276651590454612": -double: 1 -idouble: 1 -Test "jn (10, 0.125) == 0.250543369809369890173993791865771547e-18": -double: 1 -float: 1 -idouble: 1 -ifloat: 1 -Test "jn (10, 0.75) == 0.149621713117596814698712483621682835e-10": -double: 1 -float: 1 -idouble: 1 -ifloat: 1 -Test "jn (10, 10.0) == 0.207486106633358857697278723518753428": -double: 4 -float: 3 -idouble: 4 -ifloat: 3 -Test "jn (10, 2.0) == 0.251538628271673670963516093751820639e-6": -float: 4 -ifloat: 4 -Test "jn (3, 0.125) == 0.406503832554912875023029337653442868e-4": -double: 1 -float: 1 -idouble: 1 -ifloat: 1 -Test "jn (3, 0.75) == 0.848438342327410884392755236884386804e-2": -double: 1 -float: 1 -idouble: 1 -ifloat: 1 -Test "jn (3, 10.0) == 0.0583793793051868123429354784103409563": -double: 3 -float: 1 -idouble: 3 -ifloat: 1 -Test "jn (3, 2.0) == 0.128943249474402051098793332969239835": -double: 1 -float: 2 -idouble: 1 -ifloat: 2 - -# lgamma -Test "lgamma (0.7) == 0.260867246531666514385732417016759578": -double: 1 -float: 1 -idouble: 1 -ifloat: 1 -Test "lgamma (1.2) == -0.853740900033158497197028392998854470e-1": -double: 1 -float: 2 -idouble: 1 -ifloat: 2 - -# log10 -Test "log10 (0.75) == -0.124938736608299953132449886193870744": -double: 1 -float: 2 -idouble: 1 -ifloat: 2 -Test "log10 (e) == log10(e)": -float: 1 -ifloat: 1 - -# log1p -Test "log1p (-0.25) == -0.287682072451780927439219005993827432": -float: 1 -ifloat: 1 - -# sincos -Test "sincos (M_PI_6l*2.0, &sin_res, &cos_res) puts 0.5 in cos_res": -double: 1 -float: 1 -idouble: 1 -ifloat: 1 -Test "sincos (M_PI_6l*2.0, &sin_res, &cos_res) puts 0.86602540378443864676372317075293616 in sin_res": -double: 1 -float: 1 -idouble: 1 -ifloat: 1 -Test "sincos (pi/2, &sin_res, &cos_res) puts 0 in cos_res": -double: 1 -float: 1 -idouble: 1 -ifloat: 1 -Test "sincos (pi/6, &sin_res, &cos_res) puts 0.86602540378443864676372317075293616 in cos_res": -float: 1 -ifloat: 1 - -# tan -Test "tan (pi/4) == 1": -double: 1 -idouble: 1 - -# tgamma -Test "tgamma (-0.5) == -2 sqrt (pi)": -double: 1 -float: 1 -idouble: 1 -ifloat: 1 -Test "tgamma (0.5) == sqrt (pi)": -float: 1 -ifloat: 1 -Test "tgamma (0.7) == 1.29805533264755778568117117915281162": -double: 1 -float: 1 -idouble: 1 -ifloat: 1 - -# y0 -Test "y0 (1.0) == 0.0882569642156769579829267660235151628": -double: 2 -float: 1 -idouble: 2 -ifloat: 1 -Test "y0 (1.5) == 0.382448923797758843955068554978089862": -double: 2 -float: 1 -idouble: 2 -ifloat: 1 -Test "y0 (10.0) == 0.0556711672835993914244598774101900481": -float: 1 -ifloat: 1 -Test "y0 (8.0) == 0.223521489387566220527323400498620359": -double: 1 -float: 1 -idouble: 1 -ifloat: 1 - -# y1 -Test "y1 (0.125) == -5.19993611253477499595928744876579921": -double: 1 -idouble: 1 -Test "y1 (1.5) == -0.412308626973911295952829820633445323": -float: 1 -ifloat: 1 -Test "y1 (10.0) == 0.249015424206953883923283474663222803": -double: 3 -float: 1 -idouble: 3 -ifloat: 1 -Test "y1 (2.0) == -0.107032431540937546888370772277476637": -double: 1 -float: 1 -idouble: 1 -ifloat: 1 -Test "y1 (8.0) == -0.158060461731247494255555266187483550": -double: 1 -float: 2 -idouble: 1 -ifloat: 2 - -# yn -Test "yn (0, 1.0) == 0.0882569642156769579829267660235151628": -double: 2 -float: 1 -idouble: 2 -ifloat: 1 -Test "yn (0, 1.5) == 0.382448923797758843955068554978089862": -double: 2 -float: 1 -idouble: 2 -ifloat: 1 -Test "yn (0, 10.0) == 0.0556711672835993914244598774101900481": -float: 1 -ifloat: 1 -Test "yn (0, 8.0) == 0.223521489387566220527323400498620359": -double: 1 -float: 1 -idouble: 1 -ifloat: 1 -Test "yn (1, 0.125) == -5.19993611253477499595928744876579921": -double: 1 -idouble: 1 -Test "yn (1, 1.5) == -0.412308626973911295952829820633445323": -float: 1 -ifloat: 1 -Test "yn (1, 10.0) == 0.249015424206953883923283474663222803": -double: 3 -float: 1 -idouble: 3 -ifloat: 1 -Test "yn (1, 2.0) == -0.107032431540937546888370772277476637": -double: 1 -float: 1 -idouble: 1 -ifloat: 1 -Test "yn (1, 8.0) == -0.158060461731247494255555266187483550": -double: 1 -float: 2 -idouble: 1 -ifloat: 2 -Test "yn (10, 0.125) == -127057845771019398.252538486899753195": -double: 1 -idouble: 1 -Test "yn (10, 0.75) == -2133501638.90573424452445412893839236": -double: 1 -float: 1 -idouble: 1 -ifloat: 1 -Test "yn (10, 1.0) == -121618014.278689189288130426667971145": -double: 1 -idouble: 1 -Test "yn (10, 10.0) == -0.359814152183402722051986577343560609": -double: 1 -float: 1 -idouble: 1 -ifloat: 1 -Test "yn (10, 2.0) == -129184.542208039282635913145923304214": -double: 2 -idouble: 2 -Test "yn (3, 0.125) == -2612.69757350066712600220955744091741": -double: 1 -idouble: 1 -Test "yn (3, 0.75) == -12.9877176234475433186319774484809207": -double: 1 -float: 1 -idouble: 1 -ifloat: 1 -Test "yn (3, 10.0) == -0.251362657183837329779204747654240998": -double: 1 -float: 1 -idouble: 1 -ifloat: 1 -Test "yn (3, 2.0) == -1.12778377684042778608158395773179238": -double: 1 -idouble: 1 - -# Maximal error of functions: -Function: "atan2": -float: 3 -ifloat: 3 - -Function: "atanh": -float: 1 -ifloat: 1 - -Function: Real part of "cacosh": -double: 1 -float: 7 -idouble: 1 -ifloat: 7 - -Function: Imaginary part of "cacosh": -double: 1 -float: 3 -idouble: 1 -ifloat: 3 - -Function: Real part of "casin": -double: 1 -float: 1 -idouble: 1 -ifloat: 1 - -Function: Real part of "casinh": -double: 5 -float: 1 -idouble: 5 -ifloat: 1 - -Function: Imaginary part of "casinh": -double: 3 -float: 6 -idouble: 3 -ifloat: 6 - -Function: Real part of "catan": -float: 4 -ifloat: 4 - -Function: Imaginary part of "catan": -double: 1 -float: 1 -idouble: 1 -ifloat: 1 - -Function: Real part of "catanh": -double: 4 -idouble: 4 - -Function: Imaginary part of "catanh": -float: 6 -ifloat: 6 - -Function: "cbrt": -double: 1 -idouble: 1 - -Function: Real part of "ccos": -double: 1 -float: 1 -idouble: 1 -ifloat: 1 - -Function: Imaginary part of "ccos": -float: 1 -ifloat: 1 - -Function: Real part of "ccosh": -double: 1 -float: 1 -idouble: 1 -ifloat: 1 - -Function: Imaginary part of "ccosh": -float: 1 -ifloat: 1 - -Function: Real part of "cexp": -float: 1 -ifloat: 1 - -Function: Imaginary part of "cexp": -float: 1 -ifloat: 1 - -Function: Real part of "clog": -float: 1 -ifloat: 1 - -Function: Imaginary part of "clog": -float: 3 -ifloat: 3 - -Function: Real part of "clog10": -float: 1 -ifloat: 1 - -Function: Imaginary part of "clog10": -double: 1 -float: 5 -idouble: 1 -ifloat: 5 - -Function: "cos": -double: 2 -float: 1 -idouble: 2 -ifloat: 1 - -Function: Real part of "cpow": -double: 2 -float: 4 -idouble: 2 -ifloat: 4 - -Function: Imaginary part of "cpow": -double: 2 -float: 2 -idouble: 2 -ifloat: 2 - -Function: Real part of "csinh": -float: 1 -ifloat: 1 - -Function: Imaginary part of "csinh": -double: 1 -float: 1 -idouble: 1 -ifloat: 1 - -Function: Real part of "csqrt": -float: 1 -ifloat: 1 - -Function: Real part of "ctan": -double: 1 -idouble: 1 - -Function: Imaginary part of "ctan": -double: 1 -idouble: 1 - -Function: Real part of "ctanh": -double: 1 -float: 2 -idouble: 1 -ifloat: 2 - -Function: Imaginary part of "ctanh": -float: 1 -ifloat: 1 - -Function: "erf": -double: 1 -idouble: 1 - -Function: "erfc": -double: 1 -idouble: 1 - -Function: "exp10": -double: 6 -float: 2 -idouble: 6 -ifloat: 2 - -Function: "expm1": -double: 1 -float: 1 -idouble: 1 -ifloat: 1 - -Function: "hypot": -float: 1 -ifloat: 1 - -Function: "j0": -double: 2 -float: 2 -idouble: 2 -ifloat: 2 - -Function: "j1": -double: 1 -float: 2 -idouble: 1 -ifloat: 2 - -Function: "jn": -double: 4 -float: 4 -idouble: 4 -ifloat: 4 - -Function: "lgamma": -double: 1 -float: 2 -idouble: 1 -ifloat: 2 - -Function: "log10": -double: 1 -float: 2 -idouble: 1 -ifloat: 2 - -Function: "log1p": -float: 1 -ifloat: 1 - -Function: "sincos": -double: 1 -float: 1 -idouble: 1 -ifloat: 1 - -Function: "tan": -double: 1 -idouble: 1 - -Function: "tgamma": -double: 1 -float: 1 -idouble: 1 -ifloat: 1 - -Function: "y0": -double: 2 -float: 1 -idouble: 2 -ifloat: 1 - -Function: "y1": -double: 3 -float: 2 -idouble: 3 -ifloat: 2 - -Function: "yn": -double: 3 -float: 2 -idouble: 3 -ifloat: 2 - -# end of automatic generation diff --git a/sysdeps/powerpc/nofpu/sim-full.c b/sysdeps/powerpc/nofpu/sim-full.c deleted file mode 100644 index d018240..0000000 --- a/sysdeps/powerpc/nofpu/sim-full.c +++ /dev/null @@ -1,45 +0,0 @@ -/* Software floating-point exception handling emulation. - Copyright (C) 2002, 2004 Free Software Foundation, Inc. - Contributed by Aldy Hernandez <aldyh@redhat.com>, 2002. - 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 <signal.h> -#include "soft-fp.h" -#include "soft-supp.h" - -/* Global to store sticky exceptions. */ -int __sim_exceptions __attribute__ ((nocommon)); -libc_hidden_data_def (__sim_exceptions); - -/* By default, no exceptions should trap. */ -int __sim_disabled_exceptions = 0xffffffff; -libc_hidden_data_def (__sim_disabled_exceptions); - -int __sim_round_mode __attribute__ ((nocommon)); -libc_hidden_data_def (__sim_round_mode); - -void -__simulate_exceptions (int x) -{ - __sim_exceptions |= x; - if (x == 0 || __sim_disabled_exceptions & x) - /* Ignore exception. */ - ; - else - raise (SIGFPE); -} diff --git a/sysdeps/powerpc/nofpu/soft-supp.h b/sysdeps/powerpc/nofpu/soft-supp.h deleted file mode 100644 index 3922426..0000000 --- a/sysdeps/powerpc/nofpu/soft-supp.h +++ /dev/null @@ -1,37 +0,0 @@ -/* Internal support stuff for complete soft float. - Copyright (C) 2002, 2004 Free Software Foundation, Inc. - Contributed by Aldy Hernandez <aldyh@redhat.com>, 2002. - 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 <fenv.h> - -typedef union -{ - fenv_t fenv; - unsigned int l[2]; -} fenv_union_t; - - -extern int __sim_exceptions; -libc_hidden_proto (__sim_exceptions); -extern int __sim_disabled_exceptions; -libc_hidden_proto (__sim_disabled_exceptions); -extern int __sim_round_mode; -libc_hidden_proto (__sim_round_mode); - -extern void __simulate_exceptions (int x) attribute_hidden; diff --git a/sysdeps/powerpc/powerpc32/Dist b/sysdeps/powerpc/powerpc32/Dist deleted file mode 100644 index ada834f..0000000 --- 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 9ef3ac1..39a34c5 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 82b4fc9..1d58a06 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 82531ad..2093b7e 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 118f0d6..e7e1254 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 0f1a723..6fcc669 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 50deda8..4c28c2e 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 159b122..01b195d 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 0000000..0ff56c9 --- /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 0000000..7219ad9 --- /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 0000000..7fe2be7 --- /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 0696071..4120a02 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 a8c1e3e..496fa71 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 d72202d..c77c4de 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 0000000..6a158c3 --- /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 7827357..bafd2ae 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 375e571..0000000 --- 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 a2415b9..404f403 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 4231780..2f6c6de 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 d7bc1ab..c051787 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 d211314..bc74d30 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 4439dc2..47a75ec 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 933435d..dd68b08 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/nofpu/fgetexcptflg.c b/sysdeps/powerpc/powerpc32/fpu/s_copysignl.S index 713bd92..64b6a45 100644 --- a/sysdeps/powerpc/nofpu/fgetexcptflg.c +++ b/sysdeps/powerpc/powerpc32/fpu/s_copysignl.S @@ -1,6 +1,6 @@ -/* Store current representation for exceptions (soft-float edition). - Copyright (C) 2002 Free Software Foundation, Inc. - Contributed by Aldy Hernandez <aldyh@redhat.com>, 2002. +/* 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 @@ -18,21 +18,33 @@ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -#include "soft-fp.h" -#include "soft-supp.h" -#include <bp-sym.h> - -__fegetexceptflag (fexcept_t *flagp, int excepts) -{ - *flagp = (fexcept_t) __sim_exceptions & excepts & FE_ALL_EXCEPT; - - return 0; -} - -#include <shlib-compat.h> -#if SHLIB_COMPAT (libm, GLIBC_2_1, GLIBC_2_2) -strong_alias (__fegetexceptflag, __old_fegetexceptflag) -compat_symbol (libm, BP_SYM (__old_fegetexceptflag), BP_SYM (fegetexceptflag), GLIBC_2_1); +#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 - -versioned_symbol (libm, BP_SYM (__fegetexceptflag), BP_SYM (fegetexceptflag), GLIBC_2_2); diff --git a/sysdeps/powerpc/powerpc32/fpu/s_fabs.S b/sysdeps/powerpc/powerpc32/fpu/s_fabs.S new file mode 100644 index 0000000..53d2130 --- /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/nofpu/fesetround.c b/sysdeps/powerpc/powerpc32/fpu/s_fabsl.S index 842614a..3655e5b 100644 --- a/sysdeps/powerpc/nofpu/fesetround.c +++ b/sysdeps/powerpc/powerpc32/fpu/s_fabsl.S @@ -1,6 +1,6 @@ -/* Set rounding mode (soft-float edition). - Copyright (C) 2002 Free Software Foundation, Inc. - Contributed by Aldy Hernandez <aldyh@redhat.com>, 2002. +/* 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 @@ -18,16 +18,19 @@ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -#include "soft-fp.h" -#include "soft-supp.h" +#include <sysdep.h> +#include <math_ldbl_opt.h> -int -fesetround (int round) -{ - if ((unsigned int) round > FE_DOWNWARD) - return 1; +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) - __sim_round_mode = round; - - return 0; -} +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 0000000..e34b51e --- /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 143f907..a29e479 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 154bc30..99fbdc5 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 0000000..6973576 --- /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 0000000..6d4a0a9 --- /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 0000000..397717b --- /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 7fdc296..cb96be7 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 57d56c4..da0a1e5 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 dcb97e3..9c534ec 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 dee25f2..c8dca31 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 cebf642..7771cb2 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 13fc74f..590c87a 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 ea8aaf3..7e99bca 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 a4be651..5bc0856 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 9a8dae9..e2e3bd6 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 77ee05f..851480d 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 cf493f0..90eb4a0 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 5ac1860..ca00b8f 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 a09f1e5..c74272b 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 06ee4a6..6c17901 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 0000000..b62b0f2 --- /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 9f5870d..65054f2 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 53f1143..f09c294 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 a72d676..7e39acb 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 d341eea..7071632 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 40f6264..12ee14d 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 3b33bb9..3e0fff5 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 59761f7..8fc624e 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 diff --git a/sysdeps/powerpc/powerpc64/Dist b/sysdeps/powerpc/powerpc64/Dist deleted file mode 100644 index bbadfef..0000000 --- a/sysdeps/powerpc/powerpc64/Dist +++ /dev/null @@ -1,4 +0,0 @@ -dl-machine.c -ppc-mcount.S -elf/entry.h -bp-asm.h diff --git a/sysdeps/powerpc/powerpc64/Makefile b/sysdeps/powerpc/powerpc64/Makefile index 3ced656..78d4f07 100644 --- a/sysdeps/powerpc/powerpc64/Makefile +++ b/sysdeps/powerpc/powerpc64/Makefile @@ -10,11 +10,25 @@ ifeq (yes,$(build-shared)) pic-ccflag = -fpic endif +# These flags prevent FPU or Altivec registers from being used, +# for code called in contexts that is not allowed to touch those registers. +# Stupid GCC requires us to pass all these ridiculous switches. +no-special-regs := $(sort $(foreach n,40 41 50 51 60 61 62 63 \ + $(foreach m,2 3 4 5 6 7 8 9, \ + 3$m 4$m 5$m),\ + -ffixed-$n)) \ + $(sort $(foreach n,$(foreach m,0 1 2 3 4 5 6 7 8 9,\ + $m 1$m 2$m) 30 31,\ + -ffixed-v$n)) \ + -ffixed-vrsave -ffixed-vscr + ifeq ($(subdir),csu) +sysdep_routines += hp-timing +elide-routines.os += hp-timing ifneq ($(elf),no) -# The initfini generation code doesn't work in the presence of -g1 or -# higher, so we use -g0. -CFLAGS-initfini.s = -g0 -fpic -O1 +# The initfini generation code doesn't work in the presence of -fPIC, so +# we use -fpic instead which is much better. +CFLAGS-initfini.s += -fpic -O1 endif endif @@ -27,5 +41,5 @@ ifeq ($(subdir),gmon) # The assembly functions assume that fp arg regs are not trashed. # Compiling with -msoft-float ensures that fp regs are not used # for moving memory around. -CFLAGS-mcount.c += -msoft-float +CFLAGS-mcount.c += $(no-special-regs) endif diff --git a/sysdeps/powerpc/powerpc64/__longjmp-common.S b/sysdeps/powerpc/powerpc64/__longjmp-common.S index 30087d7..700a2a5 100644 --- a/sysdeps/powerpc/powerpc64/__longjmp-common.S +++ b/sysdeps/powerpc/powerpc64/__longjmp-common.S @@ -1,6 +1,6 @@ /* longjmp for PowerPC64. - Copyright (C) 1995, 1996, 1997, 1999, 2000, 2001, 2002, 2003, 2004 - Free Software Foundation, Inc. + Copyright (C) 1995, 1996,1997,1999,2000,2001,2002,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 @@ -24,7 +24,7 @@ #ifdef __NO_VMX__ # include <novmxsetjmp.h> #else -# include <bits/setjmp.h> +# include <jmpbuf-offsets.h> #endif #include <bp-sym.h> #include <bp-asm.h> @@ -108,7 +108,12 @@ aligned_restore_vmx: lvx v31,0,r6 L(no_vmx): #endif +#ifdef PTR_DEMANGLE + ld r22,(JB_GPR1*8)(r3) + PTR_DEMANGLE3 (r1, r22, r25) +#else ld r1,(JB_GPR1*8)(r3) +#endif ld r2,(JB_GPR2*8)(r3) ld r0,(JB_LR*8)(r3) ld r14,((JB_GPRS+0)*8)(r3) @@ -128,6 +133,9 @@ L(no_vmx): lfd fp19,((JB_FPRS+5)*8)(r3) ld r20,((JB_GPRS+6)*8)(r3) lfd fp20,((JB_FPRS+6)*8)(r3) +#ifdef PTR_DEMANGLE + PTR_DEMANGLE2 (r0, r25) +#endif mtlr r0 /* std r2,40(r1) Restore the TOC save area. */ ld r21,((JB_GPRS+7)*8)(r3) diff --git a/sysdeps/powerpc/powerpc64/backtrace.c b/sysdeps/powerpc/powerpc64/backtrace.c index 8669b6a..9c8ebbb 100644 --- a/sysdeps/powerpc/powerpc64/backtrace.c +++ b/sysdeps/powerpc/powerpc64/backtrace.c @@ -1,5 +1,5 @@ /* Return backtrace of current program state. - Copyright (C) 1998, 2000, 2002 Free Software Foundation, Inc. + Copyright (C) 1998, 2000, 2002, 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 @@ -67,3 +67,4 @@ __backtrace (void **array, int size) return count; } weak_alias (__backtrace, backtrace) +libc_hidden_def (__backtrace) diff --git a/sysdeps/powerpc/powerpc64/dl-machine.h b/sysdeps/powerpc/powerpc64/dl-machine.h index 3fcf77d..cec271b 100644 --- a/sysdeps/powerpc/powerpc64/dl-machine.h +++ b/sysdeps/powerpc/powerpc64/dl-machine.h @@ -1,6 +1,6 @@ /* Machine-dependent ELF dynamic relocation inline functions. PowerPC64 version. - Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 + Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. This file is part of the GNU C Library. @@ -107,92 +107,6 @@ elf_machine_dynamic (void) /* The PLT uses Elf64_Rela relocs. */ #define elf_machine_relplt elf_machine_rela -/* This code gets called via a .glink stub which loads PLT0. It is - used in dl-runtime.c to call the `fixup' function and then redirect - to the address `fixup' returns. - - Enter with r0 = plt reloc index, - r2 = ld.so tocbase, - r11 = ld.so link map. */ - -#define TRAMPOLINE_TEMPLATE(tramp_name, fixup_name) \ - asm (".section \".text\"\n" \ -" .align 2\n" \ -" .type " BODY_PREFIX #tramp_name ",@function\n" \ -" .section \".opd\",\"aw\"\n" \ -" .align 3\n" \ -" .globl " #tramp_name "\n" \ -" " ENTRY_2(tramp_name) "\n" \ -#tramp_name ":\n" \ -" " OPD_ENT(tramp_name) "\n" \ -" .previous\n" \ -BODY_PREFIX #tramp_name ":\n" \ -/* We need to save the registers used to pass parameters, ie. r3 thru \ - r10; the registers are saved in a stack frame. */ \ -" stdu 1,-128(1)\n" \ -" std 3,48(1)\n" \ -" mr 3,11\n" \ -" std 4,56(1)\n" \ -" sldi 4,0,1\n" \ -" std 5,64(1)\n" \ -" add 4,4,0\n" \ -" std 6,72(1)\n" \ -" sldi 4,4,3\n" \ -" std 7,80(1)\n" \ -" mflr 0\n" \ -" std 8,88(1)\n" \ -/* Store the LR in the LR Save area of the previous frame. */ \ -" std 0,128+16(1)\n" \ -" mfcr 0\n" \ -" std 9,96(1)\n" \ -" std 10,104(1)\n" \ -/* I'm almost certain we don't have to save cr... be safe. */ \ -" std 0,8(1)\n" \ -" bl " DOT_PREFIX #fixup_name "\n" \ -/* Put the registers back. */ \ -" ld 0,128+16(1)\n" \ -" ld 10,104(1)\n" \ -" ld 9,96(1)\n" \ -" ld 8,88(1)\n" \ -" ld 7,80(1)\n" \ -" mtlr 0\n" \ -" ld 0,8(1)\n" \ -" ld 6,72(1)\n" \ -" ld 5,64(1)\n" \ -" ld 4,56(1)\n" \ -" mtcrf 0xFF,0\n" \ -/* Load the target address, toc and static chain reg from the function \ - descriptor returned by fixup. */ \ -" ld 0,0(3)\n" \ -" ld 2,8(3)\n" \ -" mtctr 0\n" \ -" ld 11,16(3)\n" \ -" ld 3,48(1)\n" \ -/* Unwind the stack frame, and jump. */ \ -" addi 1,1,128\n" \ -" bctr\n" \ -".LT_" #tramp_name ":\n" \ -" .long 0\n" \ -" .byte 0x00,0x0c,0x24,0x40,0x00,0x00,0x00,0x00\n" \ -" .long .LT_" #tramp_name "-" BODY_PREFIX #tramp_name "\n" \ -" .short .LT_" #tramp_name "_name_end-.LT_" #tramp_name "_name_start\n" \ -".LT_" #tramp_name "_name_start:\n" \ -" .ascii \"" #tramp_name "\"\n" \ -".LT_" #tramp_name "_name_end:\n" \ -" .align 2\n" \ -" " END_2(tramp_name) "\n" \ -" .previous"); - -#ifndef PROF -#define ELF_MACHINE_RUNTIME_TRAMPOLINE \ - TRAMPOLINE_TEMPLATE (_dl_runtime_resolve, fixup); \ - TRAMPOLINE_TEMPLATE (_dl_profile_resolve, profile_fixup); -#else -#define ELF_MACHINE_RUNTIME_TRAMPOLINE \ - TRAMPOLINE_TEMPLATE (_dl_runtime_resolve, fixup); \ - void _dl_runtime_resolve (void); \ - strong_alias (_dl_runtime_resolve, _dl_profile_resolve); -#endif #ifdef HAVE_INLINED_SYSCALLS /* We do not need _dl_starting_up. */ @@ -208,16 +122,16 @@ BODY_PREFIX #tramp_name ":\n" \ `_dl_start' is the real entry point; its return value is the user program's entry point. */ #define RTLD_START \ - asm (".section \".text\"\n" \ + asm (".pushsection \".text\"\n" \ " .align 2\n" \ " .type " BODY_PREFIX "_start,@function\n" \ -" .section \".opd\",\"aw\"\n" \ +" .pushsection \".opd\",\"aw\"\n" \ " .align 3\n" \ " .globl _start\n" \ " " ENTRY_2(_start) "\n" \ "_start:\n" \ " " OPD_ENT(_start) "\n" \ -" .previous\n" \ +" .popsection\n" \ BODY_PREFIX "_start:\n" \ /* We start with the following on the stack, from top: \ argc (4 bytes); \ @@ -243,11 +157,11 @@ BODY_PREFIX "_start:\n" \ " .align 2\n" \ " " END_2(_start) "\n" \ " .globl _dl_start_user\n" \ -" .section \".opd\",\"aw\"\n" \ +" .pushsection \".opd\",\"aw\"\n" \ "_dl_start_user:\n" \ " " OPD_ENT(_dl_start_user) "\n" \ -" .previous\n" \ -" .section \".toc\",\"aw\"\n" \ +" .popsection\n" \ +" .pushsection \".toc\",\"aw\"\n" \ DL_STARTING_UP_DEF \ ".LC__rtld_global:\n" \ " .tc _rtld_global[TC],_rtld_global\n" \ @@ -257,7 +171,7 @@ DL_STARTING_UP_DEF \ " .tc _dl_argv_internal[TC],_dl_argv_internal\n" \ ".LC__dl_fini:\n" \ " .tc _dl_fini[TC],_dl_fini\n" \ -" .previous\n" \ +" .popsection\n" \ " .type " BODY_PREFIX "_dl_start_user,@function\n" \ " " ENTRY_2(_dl_start_user) "\n" \ /* Now, we do our main work of calling initialisation procedures. \ @@ -331,7 +245,7 @@ BODY_PREFIX "_dl_start_user:\n" \ ".LT__dl_start_user_name_end:\n" \ " .align 2\n" \ " " END_2(_dl_start_user) "\n" \ -" .previous"); +" .popsection"); /* Nonzero iff TYPE should not be allowed to resolve to one of the main executable's symbols, as for a COPY reloc. */ @@ -420,7 +334,8 @@ elf_machine_runtime_setup (struct link_map *map, int lazy, int profile) resolve_fd = (Elf64_FuncDesc *) (profile ? _dl_profile_resolve : _dl_runtime_resolve); - 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; @@ -545,6 +460,11 @@ elf_machine_plt_value (struct link_map *map, const Elf64_Rela *reloc, return value + reloc->r_addend; } + +/* Names of the architecture-specific auditing callback functions. */ +#define ARCH_LA_PLTENTER ppc64_gnu_pltenter +#define ARCH_LA_PLTEXIT ppc64_gnu_pltexit + #endif /* dl_machine_h */ #ifdef RESOLVE_MAP @@ -567,7 +487,7 @@ extern void _dl_reloc_overflow (struct link_map *map, const Elf64_Sym *refsym) attribute_hidden; -static inline void +auto inline void __attribute__ ((always_inline)) elf_machine_rela_relative (Elf64_Addr l_addr, const Elf64_Rela *reloc, void *const reloc_addr_arg) { @@ -577,7 +497,7 @@ elf_machine_rela_relative (Elf64_Addr l_addr, const Elf64_Rela *reloc, #if defined USE_TLS && (!defined RTLD_BOOTSTRAP || USE___THREAD) /* This computes the value used by TPREL* relocs. */ -static Elf64_Addr __attribute__ ((const)) +auto inline Elf64_Addr __attribute__ ((always_inline, const)) elf_machine_tprel (struct link_map *map, struct link_map *sym_map, const Elf64_Sym *sym, @@ -598,7 +518,7 @@ elf_machine_tprel (struct link_map *map, /* Perform the relocation specified by RELOC and SYM (which is fully resolved). MAP is the object containing the reloc. */ -static inline void +auto inline void __attribute__ ((always_inline)) elf_machine_rela (struct link_map *map, const Elf64_Rela *reloc, const Elf64_Sym *sym, @@ -883,11 +803,12 @@ elf_machine_rela (struct link_map *map, MODIFIED_CODE_NOQUEUE (reloc_addr); } -static inline void +auto inline void __attribute__ ((always_inline)) elf_machine_lazy_rel (struct link_map *map, Elf64_Addr l_addr, const Elf64_Rela *reloc) { /* elf_machine_runtime_setup handles this. */ } + #endif /* RESOLVE */ diff --git a/sysdeps/powerpc/powerpc64/dl-trampoline.S b/sysdeps/powerpc/powerpc64/dl-trampoline.S new file mode 100644 index 0000000..9ca394d --- /dev/null +++ b/sysdeps/powerpc/powerpc64/dl-trampoline.S @@ -0,0 +1,442 @@ +/* PLT trampolines. PPC64 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> +#include <rtld-global-offsets.h> + + + .section ".text" +/* On entry r0 contains the index of the PLT entry we need to fixup + and r11 contains the link_map (from PLT0+16). The link_map becomes + parm1 (r3) and the index (r0) need to be converted to an offset + (index * 24) in parm2 (r4). */ + +EALIGN(_dl_runtime_resolve, 4, 0) +/* We need to save the registers used to pass parameters, ie. r3 thru + r10; the registers are saved in a stack frame. */ + stdu r1,-128(r1) + cfi_adjust_cfa_offset (128) + std r3,48(r1) + mr r3,r11 + std r4,56(r1) + sldi r4,r0,1 + std r5,64(r1) + add r4,r4,r0 + std r6,72(r1) + sldi r4,r4,3 + std r7,80(r1) + mflr r0 + std r8,88(r1) +/* Store the LR in the LR Save area of the previous frame. */ + std r0,128+16(r1) + cfi_offset (lr, 16) + mfcr r0 + std r9,96(r1) + std r10,104(r1) +/* I'm almost certain we don't have to save cr... be safe. */ + std r0,8(r1) + bl JUMPTARGET(_dl_fixup) +/* Put the registers back. */ + ld r0,128+16(r1) + ld r10,104(r1) + ld r9,96(r1) + ld r8,88(r1) + ld r7,80(r1) + mtlr r0 + ld r0,8(r1) + ld r6,72(r1) + ld r5,64(r1) + ld r4,56(r1) + mtcrf 0xFF,r0 +/* Load the target address, toc and static chain reg from the function + descriptor returned by fixup. */ + ld r0,0(r3) + ld r2,8(r3) + mtctr r0 + ld r11,16(r3) + ld r3,48(r1) +/* Unwind the stack frame, and jump. */ + addi r1,r1,128 + bctr +END(_dl_runtime_resolve) + + /* Stack layout: + +592 previous backchain + +584 spill_r31 + +576 spill_r30 + +560 v1 + +552 fp4 + +544 fp3 + +536 fp2 + +528 fp1 + +520 r4 + +512 r3 + return values + +504 free + +496 stackframe + +488 lr + +480 r1 + +464 v13 + +448 v12 + +432 v11 + +416 v10 + +400 v9 + +384 v8 + +368 v7 + +352 v6 + +336 v5 + +320 v4 + +304 v3 + +288 v2 + * VMX Parms in V2-V13, V0-V1 are scratch + +284 vrsave + +280 free + +272 fp13 + +264 fp12 + +256 fp11 + +248 fp10 + +240 fp9 + +232 fp8 + +224 fp7 + +216 fp6 + +208 fp5 + +200 fp4 + +192 fp3 + +184 fp2 + +176 fp1 + * FP Parms in FP1-FP13, FP0 is a scratch register + +168 r10 + +160 r9 + +152 r8 + +144 r7 + +136 r6 + +128 r5 + +120 r4 + +112 r3 + * Integer parms in R3-R10, R0 is scratch, R1 SP, R2 is TOC + +104 parm8 + +96 parm7 + +88 parm6 + +80 parm5 + +72 parm4 + +64 parm3 + +56 parm2 + +48 parm1 + * Parameter save area, Allocated by the call, at least 8 double words + +40 TOC save area + +32 Reserved for linker + +24 Reserved for compiler + +16 LR save area + +8 CR save area + r1+0 stack back chain + */ +#define FRAME_SIZE 592 +#define INT_RTN 512 +#define FPR_RTN 528 +#define VR_RTN 560 +#define STACK_FRAME 496 +#define CALLING_LR 488 +#define CALLING_SP 480 +#define INT_PARMS 112 +#define FPR_PARMS 176 +#define VR_PARMS 288 +#define VR_VRSAVE 284 + .section ".toc","aw" +.LC__dl_hwcap: +# ifdef SHARED + .tc _rtld_global_ro[TC],_rtld_global_ro +# else + .tc _dl_hwcap[TC],_dl_hwcap +# endif + .section ".text" + + .machine "altivec" +/* On entry r0 contains the index of the PLT entry we need to fixup + and r11 contains the link_map (from PLT0+16). The link_map becomes + parm1 (r3) and the index (r0) needs to be converted to an offset + (index * 24) in parm2 (r4). */ +#ifndef PROF +EALIGN(_dl_profile_resolve, 4, 0) +/* Spill r30, r31 to preserve the link_map* and reloc_addr, in case we + need to call _dl_call_pltexit. */ + std r31,-8(r1) + cfi_offset(r31,-8) + std r30,-16(r1) + cfi_offset(r30,-16) +/* We need to save the registers used to pass parameters, ie. r3 thru + r10; the registers are saved in a stack frame. */ + stdu r1,-FRAME_SIZE(r1) + cfi_adjust_cfa_offset (FRAME_SIZE) + std r3,INT_PARMS+0(r1) + mr r3,r11 + std r4,INT_PARMS+8(r1) + sldi r4,r0,1 /* index * 2 */ + std r5,INT_PARMS+16(r1) + add r4,r4,r0 /* index * 3 */ + std r6,INT_PARMS+24(r1) + sldi r4,r4,3 /* index * 24 == PLT offset */ + mflr r5 + std r7,INT_PARMS+32(r1) + std r8,INT_PARMS+40(r1) +/* Store the LR in the LR Save area of the previous frame. */ +/* XXX Do we have to do this? */ + la r8,FRAME_SIZE(r1) + std r5,FRAME_SIZE+16(r1) + cfi_offset (lr, 16) + std r5,CALLING_LR(r1) + mfcr r0 + std r9,INT_PARMS+48(r1) + std r10,INT_PARMS+56(r1) + std r8,CALLING_SP(r1) +/* I'm almost certain we don't have to save cr... be safe. */ + std r0,8(r1) + ld r12,.LC__dl_hwcap@toc(r2) +#ifdef SHARED + /* Load _rtld-global._dl_hwcap. */ + ld r12,RTLD_GLOBAL_RO_DL_HWCAP_OFFSET(r12) +#else + ld r12,0(r12) /* Load extern _dl_hwcap. */ +#endif + andis. r0,r12,(PPC_FEATURE_HAS_ALTIVEC >> 16) + beq L(saveFP) + la r10,(VR_PARMS+0)(r1) + la r9,(VR_PARMS+16)(r1) + li r11,32 + li r12,64 + stvx v2,0,r10 + stvx v3,0,r9 + + stvx v4,r11,r10 + stvx v5,r11,r9 + addi r11,r11,64 + + stvx v6,r12,r10 + stvx v7,r12,r9 + addi r12,r12,64 + + stvx v8,r11,r10 + stvx v9,r11,r9 + addi r11,r11,64 + + stvx v10,r12,r10 + stvx v11,r12,r9 + mfspr r0,VRSAVE + + stvx v12,r11,r10 + stvx v13,r11,r9 +L(saveFP): + stw r0,VR_VRSAVE(r1) +/* Save floating registers. */ + stfd fp1,FPR_PARMS+0(r1) + stfd fp2,FPR_PARMS+8(r1) + stfd fp3,FPR_PARMS+16(r1) + stfd fp4,FPR_PARMS+24(r1) + stfd fp5,FPR_PARMS+32(r1) + stfd fp6,FPR_PARMS+40(r1) + stfd fp7,FPR_PARMS+48(r1) + stfd fp8,FPR_PARMS+56(r1) + stfd fp9,FPR_PARMS+64(r1) + stfd fp10,FPR_PARMS+72(r1) + stfd fp11,FPR_PARMS+80(r1) + li r0,-1 + stfd fp12,FPR_PARMS+88(r1) + stfd fp13,FPR_PARMS+96(r1) +/* Load the extra parameters. */ + addi r6,r1,INT_PARMS + addi r7,r1,STACK_FRAME +/* Save link_map* and reloc_addr parms for later. */ + mr r31,r3 + mr r30,r4 + std r0,0(r7) + bl JUMPTARGET(_dl_profile_fixup) + nop +/* Test *framesizep > 0 to see if need to do pltexit processing. */ + ld r0,STACK_FRAME(r1) +/* Put the registers back. */ + lwz r12,VR_VRSAVE(r1) + cmpdi cr1,r0,0 + cmpdi cr0,r12,0 + bgt cr1,L(do_pltexit) + la r10,(VR_PARMS+0)(r1) + la r9,(VR_PARMS+16)(r1) +/* VRSAVE must be non-zero if VMX is present and VRs are in use. */ + beq L(restoreFXR) + li r11,32 + li r12,64 + lvx v2,0,r10 + lvx v3,0,r9 + + lvx v4,r11,r10 + lvx v5,r11,r9 + addi r11,r11,64 + + lvx v6,r12,r10 + lvx v7,r12,r9 + addi r12,r12,64 + + lvx v8,r11,r10 + lvx v9,r11,r9 + addi r11,r11,64 + + lvx v10,r12,r10 + lvx v11,r12,r9 + + lvx v12,r11,r10 + lvx v13,r11,r9 +L(restoreFXR): + ld r0,FRAME_SIZE+16(r1) + ld r10,INT_PARMS+56(r1) + ld r9,INT_PARMS+48(r1) + ld r8,INT_PARMS+40(r1) + ld r7,INT_PARMS+32(r1) + mtlr r0 + ld r0,8(r1) + ld r6,INT_PARMS+24(r1) + ld r5,INT_PARMS+16(r1) + ld r4,INT_PARMS+8(r1) + mtcrf 0xFF,r0 +/* Load the target address, toc and static chain reg from the function + descriptor returned by fixup. */ + ld r0,0(r3) + ld r2,8(r3) + ld r11,16(r3) + ld r3,INT_PARMS+0(r1) + mtctr r0 +/* Load the floating point registers. */ + lfd fp1,FPR_PARMS+0(r1) + lfd fp2,FPR_PARMS+8(r1) + lfd fp3,FPR_PARMS+16(r1) + lfd fp4,FPR_PARMS+24(r1) + lfd fp5,FPR_PARMS+32(r1) + lfd fp6,FPR_PARMS+40(r1) + lfd fp7,FPR_PARMS+48(r1) + lfd fp8,FPR_PARMS+56(r1) + lfd fp9,FPR_PARMS+64(r1) + lfd fp10,FPR_PARMS+72(r1) + lfd fp11,FPR_PARMS+80(r1) + lfd fp12,FPR_PARMS+88(r1) + lfd fp13,FPR_PARMS+96(r1) +/* Unwind the stack frame, and jump. */ + ld r31,584(r1) + ld r30,576(r1) + addi r1,r1,FRAME_SIZE + bctr +L(do_pltexit): + la r10,(VR_PARMS+0)(r1) + la r9,(VR_PARMS+16)(r1) + beq L(restoreFXR2) + li r11,32 + li r12,64 + lvx v2,0,r10 + lvx v3,0,r9 + + lvx v4,r11,r10 + lvx v5,r11,r9 + addi r11,r11,64 + + lvx v6,r12,r10 + lvx v7,r12,r9 + addi r12,r12,64 + + lvx v8,r11,r10 + lvx v9,r11,r9 + addi r11,r11,64 + + lvx v10,r12,r10 + lvx v11,r12,r9 + + lvx v12,r11,r10 + lvx v13,r11,r9 +L(restoreFXR2): + ld r0,FRAME_SIZE+16(r1) + ld r10,INT_PARMS+56(r1) + ld r9,INT_PARMS+48(r1) + ld r8,INT_PARMS+40(r1) + ld r7,INT_PARMS+32(r1) + mtlr r0 + ld r0,8(r1) + ld r6,INT_PARMS+24(r1) + ld r5,INT_PARMS+16(r1) + ld r4,INT_PARMS+8(r1) + mtcrf 0xFF,r0 +/* Load the target address, toc and static chain reg from the function + descriptor returned by fixup. */ + ld r0,0(r3) + std r2,40(r1) + ld r2,8(r3) + ld r11,16(r3) + ld r3,INT_PARMS+0(r1) + mtctr r0 +/* Load the floating point registers. */ + lfd fp1,FPR_PARMS+0(r1) + lfd fp2,FPR_PARMS+8(r1) + lfd fp3,FPR_PARMS+16(r1) + lfd fp4,FPR_PARMS+24(r1) + lfd fp5,FPR_PARMS+32(r1) + lfd fp6,FPR_PARMS+40(r1) + lfd fp7,FPR_PARMS+48(r1) + lfd fp8,FPR_PARMS+56(r1) + lfd fp9,FPR_PARMS+64(r1) + lfd fp10,FPR_PARMS+72(r1) + lfd fp11,FPR_PARMS+80(r1) + lfd fp12,FPR_PARMS+88(r1) + lfd fp13,FPR_PARMS+96(r1) +/* Call the target function. */ + bctrl + ld r2,40(r1) + lwz r12,VR_VRSAVE(r1) +/* But return here and store the return values. */ + std r3,INT_RTN(r1) + std r4,INT_RTN+8(r1) + stfd fp1,FPR_PARMS+0(r1) + stfd fp2,FPR_PARMS+8(r1) + cmpdi cr0,r12,0 + la r10,VR_RTN(r1) + stfd fp3,FPR_PARMS+16(r1) + stfd fp4,FPR_PARMS+24(r1) + mr r3,r31 + mr r4,r30 + beq L(callpltexit) + stvx v2,0,r10 +L(callpltexit): + addi r5,r1,INT_PARMS + addi r6,r1,INT_RTN + bl JUMPTARGET(_dl_call_pltexit) + nop +/* Restore the return values from target function. */ + lwz r12,VR_VRSAVE(r1) + ld r3,INT_RTN(r1) + ld r4,INT_RTN+8(r1) + lfd fp1,FPR_PARMS+0(r1) + lfd fp2,FPR_PARMS+8(r1) + cmpdi cr0,r12,0 + la r10,VR_RTN(r1) + lfd fp3,FPR_PARMS+16(r1) + lfd fp4,FPR_PARMS+24(r1) + beq L(pltexitreturn) + lvx v2,0,r10 +L(pltexitreturn): + ld r0,FRAME_SIZE+16(r1) + ld r31,584(r1) + ld r30,576(r1) + mtlr r0 + ld r1,0(r1) + blr +END(_dl_profile_resolve) +#endif diff --git a/sysdeps/powerpc/powerpc64/elf/Makefile b/sysdeps/powerpc/powerpc64/elf/Makefile index bd0580e..6a77e11 100644 --- a/sysdeps/powerpc/powerpc64/elf/Makefile +++ b/sysdeps/powerpc/powerpc64/elf/Makefile @@ -2,10 +2,10 @@ # Need to prevent gcc from using fprs in code used during dynamic linking. -CFLAGS-dl-runtime.os := -msoft-float -CFLAGS-dl-lookup.os := -msoft-float -CFLAGS-dl-misc.os := -msoft-float -CFLAGS-rtld-mempcpy.os := -msoft-float -CFLAGS-rtld-memmove.os := -msoft-float -CFLAGS-rtld-memchr.os := -msoft-float -CFLAGS-rtld-strnlen.os := -msoft-float +CFLAGS-dl-runtime.os = $(no-special-regs) +CFLAGS-dl-lookup.os = $(no-special-regs) +CFLAGS-dl-misc.os = $(no-special-regs) +CFLAGS-rtld-mempcpy.os = $(no-special-regs) +CFLAGS-rtld-memmove.os = $(no-special-regs) +CFLAGS-rtld-memchr.os = $(no-special-regs) +CFLAGS-rtld-strnlen.os = $(no-special-regs) diff --git a/sysdeps/powerpc/nofpu/fegetround.c b/sysdeps/powerpc/powerpc64/fpu/e_sqrt.c index 0d01e44..0a229cb 100644 --- a/sysdeps/powerpc/nofpu/fegetround.c +++ b/sysdeps/powerpc/powerpc64/fpu/e_sqrt.c @@ -1,6 +1,5 @@ -/* Return current rounding mode (soft-float edition). - Copyright (C) 2002 Free Software Foundation, Inc. - Contributed by Aldy Hernandez <aldyh@redhat.com>, 2002. +/* Double-precision floating point square root. + Copyright (C) 1997, 2002, 2003, 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,12 +17,13 @@ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -#include "soft-fp.h" -#include "soft-supp.h" +#include <math.h> +#include <math_private.h> -#undef fegetround -int -fegetround (void) +double +__ieee754_sqrt (double x) { - return __sim_round_mode; + double z; + __asm __volatile ("fsqrt %0,%1" : "=f" (z) : "f" (x)); + return z; } diff --git a/sysdeps/powerpc/nofpu/ftestexcept.c b/sysdeps/powerpc/powerpc64/fpu/e_sqrtf.c index ce8044f..0f17a64 100644 --- a/sysdeps/powerpc/nofpu/ftestexcept.c +++ b/sysdeps/powerpc/powerpc64/fpu/e_sqrtf.c @@ -1,6 +1,5 @@ -/* Test floating-point exceptions (soft-float edition). - Copyright (C) 2002 Free Software Foundation, Inc. - Contributed by Aldy Hernandez <aldyh@redhat.com>, 2002. +/* Single-precision floating point square root. + Copyright (C) 1997, 2003, 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,11 +17,13 @@ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -#include "soft-fp.h" -#include "soft-supp.h" +#include <math.h> +#include <math_private.h> -int -fetestexcept (int x) +float +__ieee754_sqrtf (float x) { - return __sim_exceptions & x; + double z; + __asm ("fsqrts %0,%1" : "=f" (z) : "f" (x)); + return z; } diff --git a/sysdeps/powerpc/powerpc64/fpu/s_ceil.S b/sysdeps/powerpc/powerpc64/fpu/s_ceil.S index a1bfaa7..02b7094 100644 --- a/sysdeps/powerpc/powerpc64/fpu/s_ceil.S +++ b/sysdeps/powerpc/powerpc64/fpu/s_ceil.S @@ -1,5 +1,5 @@ /* ceil function. PowerPC64 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,14 @@ 02111-1307 USA. */ #include <sysdep.h> +#include <math_ldbl_opt.h> .section ".toc","aw" .LC0: /* 2**52 */ .tc FD_43300000_0[TC],0x4330000000000000 -.LC1: /* -0.0 */ - .tc FD_80000000_0[TC],0x8000000000000000 .section ".text" -ENTRY (__ceil) +EALIGN (__ceil, 4, 0) CALL_MCOUNT 0 mffs fp11 /* Save current FPU rounding mode. */ lfd fp13,.LC0@toc(2) @@ -39,17 +38,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 - lfd fp1,.LC1@toc(2) /* x must be -0.0 for the 0.0 case. */ blr END (__ceil) @@ -59,3 +59,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/powerpc64/fpu/s_ceilf.S b/sysdeps/powerpc/powerpc64/fpu/s_ceilf.S index 42eb274..1ccd133 100644 --- a/sysdeps/powerpc/powerpc64/fpu/s_ceilf.S +++ b/sysdeps/powerpc/powerpc64/fpu/s_ceilf.S @@ -21,15 +21,13 @@ .section ".toc","aw" .LC0: /* 2**23 */ - .tc FD_41600000_0[TC],0x4160000000000000 -.LC1: /* -0.0 */ - .tc FD_80000000_0[TC],0x8000000000000000 + .tc FD_4b000000_0[TC],0x4b00000000000000 .section ".text" -ENTRY (__ceilf) +EALIGN (__ceilf, 4, 0) CALL_MCOUNT 0 mffs fp11 /* Save current FPU rounding mode. */ - lfd fp13,.LC0@toc(2) + lfs fp13,.LC0@toc(2) fabs fp0,fp1 fsubs fp12,fp13,fp13 /* generate 0.0 */ fcmpu cr7,fp0,fp13 /* if (fabs(x) > TWO23) */ @@ -39,17 +37,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 - lfd fp1,.LC1@toc(2) /* x must be -0.0 for the 0.0 case. */ blr END (__ceilf) diff --git a/sysdeps/powerpc/powerpc64/fpu/s_ceill.S b/sysdeps/powerpc/powerpc64/fpu/s_ceill.S new file mode 100644 index 0000000..a8f8a0a --- /dev/null +++ b/sysdeps/powerpc/powerpc64/fpu/s_ceill.S @@ -0,0 +1,133 @@ +/* s_ceill.S 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> + + .section ".toc","aw" +.LC0: /* 2**52 */ + .tc FD_43300000_0[TC],0x4330000000000000 + + .section ".text" + +/* long double [fp1,fp2] ceill (long double x [fp1,fp2]) + IEEE 1003.1 ceil function. + + PowerPC64 long double uses the IBM extended format which is + represented two 64-floating point double values. The values are + non-overlapping giving an effective precision of 106 bits. The first + double contains the high order bits of mantisa and is always ceiled + to represent a normal ceiling of long double to double. Since the + long double value is sum of the high and low values, the low double + normally has the opposite sign to compensate for the this ceiling. + + For long double there are two cases: + 1) |x| < 2**52, all the integer bits are in the high double. + ceil the high double and set the low double to -0.0. + 2) |x| >= 2**52, ceiling involves both doubles. + See the comment before lable .L2 for details. + */ + +ENTRY (__ceill) + mffs fp11 /* Save current FPU rounding mode. */ + lfd fp13,.LC0@toc(2) + fabs fp0,fp1 + fabs fp9,fp2 + fsub fp12,fp13,fp13 /* generate 0.0 */ + fcmpu cr7,fp0,fp13 /* if (fabs(x) > TWO52) */ + fcmpu cr6,fp1,fp12 /* if (x > 0.0) */ + bnl- cr7,.L2 + mtfsfi 7,2 /* Set rounding mode toward +inf. */ + fneg fp2,fp12 + ble- cr6,.L1 + fadd fp1,fp1,fp13 /* x+= TWO52; */ + fsub fp1,fp1,fp13 /* x-= TWO52; */ + fabs fp1,fp1 /* if (x == 0.0) */ +.L0: + mtfsf 0x01,fp11 /* restore previous rounding mode. */ + blr /* x = 0.0; */ +.L1: + bge- cr6,.L0 /* if (x < 0.0) */ + fsub fp1,fp1,fp13 /* x-= TWO52; */ + fadd fp1,fp1,fp13 /* x+= TWO52; */ + fcmpu cr5,fp1,fp12 /* if (x > 0.0) */ + mtfsf 0x01,fp11 /* restore previous rounding mode. */ + fnabs fp1,fp1 /* if (x == 0.0) */ + blr /* x = -0.0; */ + +/* The high double is > TWO52 so we need to round the low double and + perhaps the high double. In this case we have to round the low + double and handle any adjustment to the high double that may be + caused by rounding (up). This is complicated by the fact that the + high double may already be rounded and the low double may have the + opposite sign to compensate.This gets a bit tricky so we use the + following algorithm: + + tau = floor(x_high/TWO52); + x0 = x_high - tau; + x1 = x_low + tau; + r1 = rint(x1); + y_high = x0 + r1; + y_low = x0 - y_high + r1; + return y; */ +.L2: + fcmpu cr7,fp9,fp13 /* if (|x_low| > TWO52) */ + fcmpu cr0,fp9,fp12 /* || (|x_low| == 0.0) */ + fcmpu cr5,fp2,fp12 /* if (x_low > 0.0) */ + bgelr- cr7 /* return x; */ + beqlr- cr0 + mtfsfi 7,2 /* Set rounding mode toward +inf. */ + fdiv fp8,fp1,fp13 /* x_high/TWO52 */ + + bng- cr6,.L6 /* if (x > 0.0) */ + fctidz fp0,fp8 + fcfid fp8,fp0 /* tau = floor(x_high/TWO52); */ + bng cr5,.L4 /* if (x_low > 0.0) */ + fmr fp3,fp1 + fmr fp4,fp2 + b .L5 +.L4: /* if (x_low < 0.0) */ + fsub fp3,fp1,fp8 /* x0 = x_high - tau; */ + fadd fp4,fp2,fp8 /* x1 = x_low + tau; */ +.L5: + fadd fp5,fp4,fp13 /* r1 = r1 + TWO52; */ + fsub fp5,fp5,fp13 /* r1 = r1 - TWO52; */ + b .L9 +.L6: /* if (x < 0.0) */ + fctidz fp0,fp8 + fcfid fp8,fp0 /* tau = floor(x_high/TWO52); */ + bnl cr5,.L7 /* if (x_low < 0.0) */ + fmr fp3,fp1 + fmr fp4,fp2 + b .L8 +.L7: /* if (x_low > 0.0) */ + fsub fp3,fp1,fp8 /* x0 = x_high - tau; */ + fadd fp4,fp2,fp8 /* x1 = x_low + tau; */ +.L8: + fsub fp5,fp4,fp13 /* r1-= TWO52; */ + fadd fp5,fp5,fp13 /* r1+= TWO52; */ +.L9: + mtfsf 0x01,fp11 /* restore previous rounding mode. */ + fadd fp1,fp3,fp5 /* y_high = x0 + r1; */ + fsub fp2,fp3,fp1 /* y_low = x0 - y_high + r1; */ + fadd fp2,fp2,fp5 + blr +END (__ceill) + +long_double_symbol (libm, __ceill, ceill) diff --git a/sysdeps/powerpc/powerpc64/fpu/s_copysign.S b/sysdeps/powerpc/powerpc64/fpu/s_copysign.S index a43ed12..38171e3 100644 --- a/sysdeps/powerpc/powerpc64/fpu/s_copysign.S +++ b/sysdeps/powerpc/powerpc64/fpu/s_copysign.S @@ -1,5 +1,5 @@ /* Copy a sign bit between floating-point values. PowerPC64 version. - Copyright (C) 1997, 1999, 2000, 2002 Free Software Foundation, Inc. + Copyright (C) 1997, 1999, 2000, 2002, 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 @@ -21,6 +21,7 @@ when it's coded in C. */ #include <sysdep.h> +#include <math_ldbl_opt.h> ENTRY(__copysign) CALL_MCOUNT 0 @@ -28,7 +29,11 @@ ENTRY(__copysign) copysign(x,y) returns a value with the magnitude of x and with the sign bit of y. */ stdu r1,-48(r1) + cfi_adjust_cfa_offset (48) stfd fp2,24(r1) + nop + nop + nop ld r3,24(r1) cmpdi r3,0 addi r1,r1,48 @@ -39,13 +44,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/nofpu/fclrexcpt.c b/sysdeps/powerpc/powerpc64/fpu/s_copysignl.S index 16e96ba..b2c62ea 100644 --- a/sysdeps/powerpc/nofpu/fclrexcpt.c +++ b/sysdeps/powerpc/powerpc64/fpu/s_copysignl.S @@ -1,6 +1,6 @@ -/* Clear floating-point exceptions (soft-float edition). - Copyright (C) 2002 Free Software Foundation, Inc. - Contributed by Aldy Hernandez <aldyh@redhat.com>, 2002. +/* 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 @@ -18,20 +18,34 @@ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -#include "soft-fp.h" -#include "soft-supp.h" +#include <sysdep.h> +#include <math_ldbl_opt.h> -int -__feclearexcept (int x) -{ - __sim_exceptions &= ~x; - return 0; -} +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. */ + stfd fp3,-16(r1) + ld r3,-16(r1) + cmpdi r3,0 + blt L(0) + fmr fp0,fp1 + fabs fp1,fp1 + fcmpu cr1,fp0,fp1 + beqlr cr1 + fneg fp2,fp2 + blr +L(0): + fmr fp0,fp1 + fnabs fp1,fp1 + fcmpu cr1,fp0,fp1 + beqlr cr1 + fneg fp2,fp2 + blr +END (__copysignl) -#include <shlib-compat.h> -#if SHLIB_COMPAT (libm, GLIBC_2_1, GLIBC_2_2) -strong_alias (__feclearexcept, __old_feclearexcept) -compat_symbol (libm, __old_feclearexcept, feclearexcept, GLIBC_2_1); +#ifdef IS_IN_libm +long_double_symbol (libm, __copysignl, copysignl) +#else +long_double_symbol (libc, __copysignl, copysignl) #endif - -versioned_symbol (libm, __feclearexcept, feclearexcept, GLIBC_2_2); diff --git a/sysdeps/powerpc/powerpc64/fpu/s_fabs.S b/sysdeps/powerpc/powerpc64/fpu/s_fabs.S new file mode 100644 index 0000000..53d2130 --- /dev/null +++ b/sysdeps/powerpc/powerpc64/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/nofpu/fedisblxcpt.c b/sysdeps/powerpc/powerpc64/fpu/s_fabsl.S index 3d8dd44..3655e5b 100644 --- a/sysdeps/powerpc/nofpu/fedisblxcpt.c +++ b/sysdeps/powerpc/powerpc64/fpu/s_fabsl.S @@ -1,6 +1,6 @@ -/* Disable exceptions (soft-float edition). - Copyright (C) 2002 Free Software Foundation, Inc. - Contributed by Aldy Hernandez <aldyh@redhat.com>, 2002. +/* 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 @@ -18,16 +18,19 @@ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -#include "soft-fp.h" -#include "soft-supp.h" -#include <fenv.h> +#include <sysdep.h> +#include <math_ldbl_opt.h> -int -fedisableexcept (int x) -{ - int old_exceptions = ~__sim_disabled_exceptions & FE_ALL_EXCEPT; +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) - __sim_disabled_exceptions |= x; - - return old_exceptions; -} +long_double_symbol (libm, __fabsl, fabsl) diff --git a/sysdeps/powerpc/powerpc64/fpu/s_fdim.c b/sysdeps/powerpc/powerpc64/fpu/s_fdim.c new file mode 100644 index 0000000..e34b51e --- /dev/null +++ b/sysdeps/powerpc/powerpc64/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/powerpc64/fpu/s_floor.S b/sysdeps/powerpc/powerpc64/fpu/s_floor.S index 80cbdc5..65a2848 100644 --- a/sysdeps/powerpc/powerpc64/fpu/s_floor.S +++ b/sysdeps/powerpc/powerpc64/fpu/s_floor.S @@ -1,5 +1,5 @@ /* Floor function. PowerPC64 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,13 +18,14 @@ 02111-1307 USA. */ #include <sysdep.h> +#include <math_ldbl_opt.h> .section ".toc","aw" .LC0: /* 2**52 */ .tc FD_43300000_0[TC],0x4330000000000000 .section ".text" -ENTRY (__floor) +EALIGN (__floor, 4, 0) CALL_MCOUNT 0 mffs fp11 /* Save current FPU rounding mode. */ lfd fp13,.LC0@toc(2) @@ -37,15 +38,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 @@ -57,3 +59,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/powerpc64/fpu/s_floorf.S b/sysdeps/powerpc/powerpc64/fpu/s_floorf.S index 20cbb15..bcdbf78 100644 --- a/sysdeps/powerpc/powerpc64/fpu/s_floorf.S +++ b/sysdeps/powerpc/powerpc64/fpu/s_floorf.S @@ -21,13 +21,13 @@ .section ".toc","aw" .LC0: /* 2**23 */ - .tc FD_41600000_0[TC],0x4160000000000000 + .tc FD_4b000000_0[TC],0x4b00000000000000 .section ".text" -ENTRY (__floorf) +EALIGN (__floorf, 4, 0) CALL_MCOUNT 0 mffs fp11 /* Save current FPU rounding mode. */ - lfd fp13,.LC0@toc(2) + lfs fp13,.LC0@toc(2) fabs fp0,fp1 fsubs fp12,fp13,fp13 /* generate 0.0 */ fcmpu cr7,fp0,fp13 /* if (fabs(x) > TWO23) */ @@ -37,15 +37,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/powerpc64/fpu/s_floorl.S b/sysdeps/powerpc/powerpc64/fpu/s_floorl.S new file mode 100644 index 0000000..01b3c21 --- /dev/null +++ b/sysdeps/powerpc/powerpc64/fpu/s_floorl.S @@ -0,0 +1,134 @@ +/* long double floor function. + 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> + + .section ".toc","aw" +.LC0: /* 2**52 */ + .tc FD_43300000_0[TC],0x4330000000000000 + + .section ".text" +/* long double [fp1,fp2] floorl (long double x [fp1,fp2]) + IEEE 1003.1 floor function. + + PowerPC64 long double uses the IBM extended format which is + represented two 64-floating point double values. The values are + non-overlapping giving an effective precision of 106 bits. The first + double contains the high order bits of mantisa and is always rounded + to represent a normal rounding of long double to double. Since the + long double value is sum of the high and low values, the low double + normally has the opposite sign to compensate for the this rounding. + + For long double there are two cases: + 1) |x| < 2**52, all the integer bits are in the high double. + floor the high double and set the low double to -0.0. + 2) |x| >= 2**52, Rounding involves both doubles. + See the comment before lable .L2 for details. + */ + +ENTRY (__floorl) + mffs fp11 /* Save current FPU rounding mode. */ + lfd fp13,.LC0@toc(2) + fabs fp0,fp1 + fabs fp9,fp2 + fsub fp12,fp13,fp13 /* generate 0.0 */ + fcmpu cr7,fp0,fp13 /* if (fabs(x) > TWO52) */ + fcmpu cr6,fp1,fp12 /* if (x > 0.0) */ + bnl- cr7,.L2 + mtfsfi 7,3 /* Set rounding mode toward -inf. */ + fneg fp2,fp12 /* set low double to -0.0. */ + ble- cr6,.L0 + fadd fp1,fp1,fp13 /* x+= TWO52; */ + fsub fp1,fp1,fp13 /* x-= TWO52; */ + fcmpu cr5,fp1,fp12 /* if (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 +.L0: + bge- cr6,.L1 /* if (x < 0.0) */ + fsub fp1,fp1,fp13 /* x-= TWO52; */ + fadd fp1,fp1,fp13 /* x+= TWO52; */ +.L1: + mtfsf 0x01,fp11 /* restore previous rounding mode. */ + blr + + +/* The high double is > TWO52 so we need to round the low double and + perhaps the high double. In this case we have to round the low + double and handle any adjustment to the high double that may be + caused by rounding (up). This is complicated by the fact that the + high double may already be rounded and the low double may have the + opposite sign to compensate.This gets a bit tricky so we use the + following algorithm: + + tau = floor(x_high/TWO52); + x0 = x_high - tau; + x1 = x_low + tau; + r1 = rint(x1); + y_high = x0 + r1; + y_low = x0 - y_high + r1; + return y; */ +.L2: + fcmpu cr7,fp9,fp13 /* if (|x_low| > TWO52) */ + fcmpu cr0,fp9,fp12 /* || (|x_low| == 0.0) */ + fcmpu cr5,fp2,fp12 /* if (x_low > 0.0) */ + bgelr- cr7 /* return x; */ + beqlr- cr0 + mtfsfi 7,3 /* Set rounding mode toward -inf. */ + fdiv fp8,fp1,fp13 /* x_high/TWO52 */ + + bng- cr6,.L6 /* if (x > 0.0) */ + fctidz fp0,fp8 + fcfid fp8,fp0 /* tau = floor(x_high/TWO52); */ + bng cr5,.L4 /* if (x_low > 0.0) */ + fmr fp3,fp1 + fmr fp4,fp2 + b .L5 +.L4: /* if (x_low < 0.0) */ + fsub fp3,fp1,fp8 /* x0 = x_high - tau; */ + fadd fp4,fp2,fp8 /* x1 = x_low + tau; */ +.L5: + fadd fp5,fp4,fp13 /* r1 = r1 + TWO52; */ + fsub fp5,fp5,fp13 /* r1 = r1 - TWO52; */ + b .L9 +.L6: /* if (x < 0.0) */ + fctidz fp0,fp8 + fcfid fp8,fp0 /* tau = floor(x_high/TWO52); */ + bnl cr5,.L7 /* if (x_low < 0.0) */ + fmr fp3,fp1 + fmr fp4,fp2 + b .L8 +.L7: /* if (x_low > 0.0) */ + fsub fp3,fp1,fp8 /* x0 = x_high - tau; */ + fadd fp4,fp2,fp8 /* x1 = x_low + tau; */ +.L8: + fsub fp5,fp4,fp13 /* r1-= TWO52; */ + fadd fp5,fp5,fp13 /* r1+= TWO52; */ +.L9: + mtfsf 0x01,fp11 /* restore previous rounding mode. */ + fadd fp1,fp3,fp5 /* y_high = x0 + r1; */ + fsub fp2,fp3,fp1 /* y_low = x0 - y_high + r1; */ + fadd fp2,fp2,fp5 + blr +END (__floorl) + +long_double_symbol (libm, __floorl, floorl) diff --git a/sysdeps/powerpc/powerpc64/fpu/s_fmax.S b/sysdeps/powerpc/powerpc64/fpu/s_fmax.S new file mode 100644 index 0000000..6973576 --- /dev/null +++ b/sysdeps/powerpc/powerpc64/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/powerpc64/fpu/s_fmin.S b/sysdeps/powerpc/powerpc64/fpu/s_fmin.S new file mode 100644 index 0000000..6d4a0a9 --- /dev/null +++ b/sysdeps/powerpc/powerpc64/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/powerpc64/fpu/s_isnan.c b/sysdeps/powerpc/powerpc64/fpu/s_isnan.c new file mode 100644 index 0000000..397717b --- /dev/null +++ b/sysdeps/powerpc/powerpc64/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/powerpc64/fpu/s_llrint.S b/sysdeps/powerpc/powerpc64/fpu/s_llrint.S index 610b561..ff0ba94 100644 --- a/sysdeps/powerpc/powerpc64/fpu/s_llrint.S +++ b/sysdeps/powerpc/powerpc64/fpu/s_llrint.S @@ -1,5 +1,5 @@ /* Round double to long int. PowerPC64 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,6 +18,7 @@ 02111-1307 USA. */ #include <sysdep.h> +#include <math_ldbl_opt.h> /* long long int[r3] __llrint (double x[fp1]) */ ENTRY (__llrint) @@ -41,3 +42,7 @@ weak_alias (__llrint, llrintl) strong_alias (__lrint, __lrintl) weak_alias (__lrint, lrintl) #endif +#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_1) +compat_symbol (libm, __llrint, llrintl, GLIBC_2_1) +compat_symbol (libm, __lrint, lrintl, GLIBC_2_1) +#endif diff --git a/sysdeps/powerpc/powerpc64/fpu/s_llround.S b/sysdeps/powerpc/powerpc64/fpu/s_llround.S index a3dcd4c..d023b8f 100644 --- a/sysdeps/powerpc/powerpc64/fpu/s_llround.S +++ b/sysdeps/powerpc/powerpc64/fpu/s_llround.S @@ -1,5 +1,5 @@ /* llround function. PowerPC64 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,6 +18,7 @@ 02111-1307 USA. */ #include <sysdep.h> +#include <math_ldbl_opt.h> .section ".toc","aw" .LC0: /* -0.0 */ @@ -66,3 +67,7 @@ strong_alias (__llround, __llroundl) weak_alias (__lround, lroundl) strong_alias (__lround, __lroundl) #endif +#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_1) +compat_symbol (libm, __llround, llroundl, GLIBC_2_1) +compat_symbol (libm, __lround, lroundl, GLIBC_2_1) +#endif diff --git a/sysdeps/powerpc/powerpc64/fpu/s_llroundf.S b/sysdeps/powerpc/powerpc64/fpu/s_llroundf.S index b5ca43b..bbbd054 100644 --- a/sysdeps/powerpc/powerpc64/fpu/s_llroundf.S +++ b/sysdeps/powerpc/powerpc64/fpu/s_llroundf.S @@ -1,5 +1,5 @@ /* llroundf function. PowerPC64 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 @@ -28,8 +28,8 @@ /* long long [r3] llroundf (float x [fp1]) IEEE 1003.1 llroundf function. IEEE specifies "roundf to the nearest - integer value, roundfing halfway cases away from zero, regardless of - the current roundfing mode." However PowerPC Architecture defines + integer value, rounding halfway cases away from zero, regardless of + the current rounding mode." However PowerPC Architecture defines "roundf to Nearest" as "Choose the best approximation. In case of a tie, choose the one that is even (least significant bit o).". So we can't use the PowerPC "round to Nearest" mode. Instead we set diff --git a/sysdeps/powerpc/powerpc64/fpu/s_nearbyintl.S b/sysdeps/powerpc/powerpc64/fpu/s_nearbyintl.S new file mode 100644 index 0000000..0d0eb36 --- /dev/null +++ b/sysdeps/powerpc/powerpc64/fpu/s_nearbyintl.S @@ -0,0 +1,114 @@ +/* nearbyint long double. + 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> + + .section ".toc","aw" +.LC0: /* 2**52 */ + .tc FD_43300000_0[TC],0x4330000000000000 + .section ".text" + +/* long double [fp1,fp2] nearbyintl (long double x [fp1,fp2]) + IEEE 1003.1 nearbyintl function. nearbyintl is simular to the rintl + but does raise the "inexact" exception. This implementation is + based on rintl but explicitly maskes the inexact exception on entry + and clears any pending inexact before restoring the exception mask + on exit. + + PowerPC64 long double uses the IBM extended format which is + represented two 64-floating point double values. The values are + non-overlapping giving an effective precision of 106 bits. The first + double contains the high order bits of mantisa and is always rounded + to represent a normal rounding of long double to double. Since the + long double value is sum of the high and low values, the low double + normally has the opposite sign to compensate for the this rounding. + + For long double there are two cases: + 1) |x| < 2**52, all the integer bits are in the high double. + floor the high double and set the low double to -0.0. + 2) |x| >= 2**52, Rounding involves both doubles. + See the comment before lable .L2 for details. + */ +ENTRY (__nearbyintl) + mffs fp11 /* Save current FPSCR. */ + lfd fp13,.LC0@toc(2) + fabs fp0,fp1 + mtfsb0 28 /* Disable "inexact" exceptions. */ + fsub fp12,fp13,fp13 /* generate 0.0 */ + fabs fp9,fp2 + fcmpu cr7,fp0,fp13 /* if (fabs(x) > TWO52) */ + fcmpu cr6,fp1,fp12 /* if (x > 0.0) */ + bnl- cr7,.L2 + fmr fp2,fp12 + bng- cr6,.L4 + fadd fp1,fp1,fp13 /* x+= TWO52; */ + fsub fp1,fp1,fp13 /* x-= TWO52; */ + b .L9 +.L4: + bnl- cr6,.L9 /* if (x < 0.0) */ + fsub fp1,fp13,fp1 /* x = TWO52 - x; */ + fsub fp0,fp1,fp13 /* x = - (x - TWO52); */ + fneg fp1,fp0 +.L9: + mtfsb0 6 /* Clear any pending "inexact" exceptions. */ + mtfsf 0x01,fp11 /* restore exception mask. */ + blr + +/* The high double is > TWO52 so we need to round the low double and + perhaps the high double. This gets a bit tricky so we use the + following algorithm: + + tau = floor(x_high/TWO52); + x0 = x_high - tau; + x1 = x_low + tau; + r1 = nearbyint(x1); + y_high = x0 + r1; + y_low = r1 - tau; + return y; */ +.L2: + fcmpu cr7,fp9,fp13 /* if (|x_low| > TWO52) */ + fcmpu cr0,fp9,fp12 /* || (|x_low| == 0.0) */ + bge- cr7,.L9 /* return x; */ + beq- cr0,.L9 + fdiv fp8,fp1,fp13 /* x_high/TWO52 */ + fctidz fp0,fp8 + fcfid fp8,fp0 /* tau = floor(x_high/TWO52); */ + fsub fp3,fp1,fp8 /* x0 = x_high - tau; */ + fadd fp4,fp2,fp8 /* x1 = x_low + tau; */ + + fcmpu cr6,fp4,fp12 /* if (x1 > 0.0) */ + bng- cr6,.L8 + fadd fp5,fp4,fp13 /* r1 = x1 + TWO52; */ + fsub fp5,fp5,fp13 /* r1 = r1 - TWO52; */ + b .L6 +.L8: + fmr fp5,fp4 + bge- cr6,.L6 /* if (x1 < 0.0) */ + fsub fp5,fp13,fp4 /* r1 = TWO52 - x1; */ + fsub fp0,fp5,fp13 /* r1 = - (r1 - TWO52); */ + fneg fp5,fp0 +.L6: + fadd fp1,fp3,fp5 /* y_high = x0 + r1; */ + fsub fp2,fp5,fp8 /* y_low = r1 - tau; */ + b .L9 +END (__nearbyintl) + +long_double_symbol (libm, __nearbyintl, nearbyintl) diff --git a/sysdeps/powerpc/powerpc64/fpu/s_rint.S b/sysdeps/powerpc/powerpc64/fpu/s_rint.S index 79e8072..b4fbc0b 100644 --- a/sysdeps/powerpc/powerpc64/fpu/s_rint.S +++ b/sysdeps/powerpc/powerpc64/fpu/s_rint.S @@ -1,5 +1,5 @@ /* Round to int floating-point values. PowerPC64 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 @@ -21,13 +21,14 @@ when it's coded in C. */ #include <sysdep.h> +#include <math_ldbl_opt.h> .section ".toc","aw" .LC0: /* 2**52 */ .tc FD_43300000_0[TC],0x4330000000000000 .section ".text" -ENTRY (__rint) +EALIGN (__rint, 4, 0) CALL_MCOUNT 0 lfd fp13,.LC0@toc(2) fabs fp0,fp1 @@ -38,13 +39,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) @@ -53,3 +55,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/powerpc64/fpu/s_rintf.S b/sysdeps/powerpc/powerpc64/fpu/s_rintf.S index eb34dd5..e4fa9ba 100644 --- a/sysdeps/powerpc/powerpc64/fpu/s_rintf.S +++ b/sysdeps/powerpc/powerpc64/fpu/s_rintf.S @@ -21,12 +21,12 @@ .section ".toc","aw" .LC0: /* 2**23 */ - .tc FD_41600000_0[TC],0x4160000000000000 + .tc FD_4b000000_0[TC],0x4b00000000000000 .section ".text" -ENTRY (__rintf) +EALIGN (__rintf, 4, 0) CALL_MCOUNT 0 - lfd fp13,.LC0@toc(2) + lfs fp13,.LC0@toc(2) fabs fp0,fp1 fsubs fp12,fp13,fp13 /* generate 0.0 */ fcmpu cr7,fp0,fp13 /* if (fabs(x) > TWO23) */ @@ -35,13 +35,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/powerpc64/fpu/s_round.S b/sysdeps/powerpc/powerpc64/fpu/s_round.S index c0b6d46..15afca1 100644 --- a/sysdeps/powerpc/powerpc64/fpu/s_round.S +++ b/sysdeps/powerpc/powerpc64/fpu/s_round.S @@ -1,5 +1,5 @@ /* round function. PowerPC64 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,14 +18,13 @@ 02111-1307 USA. */ #include <sysdep.h> +#include <math_ldbl_opt.h> .section ".toc","aw" .LC0: /* 2**52 */ .tc FD_43300000_0[TC],0x4330000000000000 .LC1: /* 0.5 */ .tc FD_3fe00000_0[TC],0x3fe0000000000000 -.LC2: /* -0.0 */ - .tc FD_80000000_0[TC],0x8000000000000000 .section ".text" /* double [fp1] round (double x [fp1]) @@ -38,7 +37,7 @@ "Round toward Zero" mode and round by adding +-0.5 before rounding to the integer value. */ -ENTRY (__round) +EALIGN (__round, 4, 0) CALL_MCOUNT 0 mffs fp11 /* Save current FPU rounding mode. */ lfd fp13,.LC0@toc(2) @@ -53,7 +52,8 @@ ENTRY (__round) 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: @@ -61,10 +61,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) */ - mtfsf 0x01,fp11 /* restore previous rounding mode. */ - bnelr+ cr5 - lfd fp1,.LC2@toc(2) /* x must be -0.0 for the 0.0 case. */ + fnabs fp1,fp1 /* if (x == 0.0) */ + /* x = -0.0; */ +.L9: + mtfsf 0x01,fp11 /* restore previous rounding mode. */ blr END (__round) @@ -74,3 +74,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/powerpc64/fpu/s_roundf.S b/sysdeps/powerpc/powerpc64/fpu/s_roundf.S index 23ee4c0..d2e29fd 100644 --- a/sysdeps/powerpc/powerpc64/fpu/s_roundf.S +++ b/sysdeps/powerpc/powerpc64/fpu/s_roundf.S @@ -21,11 +21,9 @@ .section ".toc","aw" .LC0: /* 2**23 */ - .tc FD_41600000_0[TC],0x4160000000000000 + .tc FD_4b000000_0[TC],0x4b00000000000000 .LC1: /* 0.5 */ - .tc FD_3fe00000_0[TC],0x3fe0000000000000 -.LC2: /* -0.0 */ - .tc FD_80000000_0[TC],0x8000000000000000 + .tc FD_3f000000_0[TC],0x3f00000000000000 .section ".text" /* float [fp1] roundf (float x [fp1]) @@ -38,22 +36,23 @@ "Round toward Zero" mode and round by adding +-0.5 before rounding to the integer value. */ -ENTRY (__roundf ) +EALIGN (__roundf, 4, 0) CALL_MCOUNT 0 mffs fp11 /* Save current FPU rounding mode. */ - lfd fp13,.LC0@toc(2) + lfs fp13,.LC0@toc(2) fabs fp0,fp1 fsubs fp12,fp13,fp13 /* generate 0.0 */ fcmpu cr7,fp0,fp13 /* if (fabs(x) > TWO23) */ fcmpu cr6,fp1,fp12 /* if (x > 0.0) */ bnllr- cr7 mtfsfi 7,1 /* Set rounding mode toward 0. */ - lfd fp10,.LC1@toc(2) + lfs fp10,.LC1@toc(2) 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: @@ -61,10 +60,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) */ - mtfsf 0x01,fp11 /* restore previous rounding mode. */ - bnelr+ cr5 - lfd fp1,.LC2@toc(2) /* x must be -0.0 for the 0.0 case. */ + fnabs fp1,fp1 /* if (x == 0.0) */ + /* x = -0.0; */ +.L9: + mtfsf 0x01,fp11 /* restore previous rounding mode. */ blr END (__roundf) diff --git a/sysdeps/powerpc/powerpc64/fpu/s_roundl.S b/sysdeps/powerpc/powerpc64/fpu/s_roundl.S new file mode 100644 index 0000000..20da828 --- /dev/null +++ b/sysdeps/powerpc/powerpc64/fpu/s_roundl.S @@ -0,0 +1,133 @@ +/* long double round function. + 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> + + .section ".toc","aw" +.LC0: /* 2**52 */ + .tc FD_43300000_0[TC],0x4330000000000000 +.LC1: /* 0.5 */ + .tc FD_3fe00000_0[TC],0x3fe0000000000000 + .section ".text" + +/* long double [fp1,fp2] roundl (long double x [fp1,fp2]) + IEEE 1003.1 round function. IEEE specifies "round to the nearest + integer value, rounding halfway cases away from zero, regardless of + the current rounding mode." However PowerPC Architecture defines + "Round to Nearest" as "Choose the best approximation. In case of a + tie, choose the one that is even (least significant bit o).". + So we can't use the PowerPC "Round to Nearest" mode. Instead we set + "Round toward Zero" mode and round by adding +-0.5 before rounding + to the integer value. */ + +ENTRY (__roundl) + mffs fp11 /* Save current FPU rounding mode. */ + lfd fp13,.LC0@toc(2) + fabs fp0,fp1 + fabs fp9,fp2 + fsub fp12,fp13,fp13 /* generate 0.0 */ + fcmpu cr7,fp0,fp13 /* if (fabs(x) > TWO52) */ + fcmpu cr6,fp1,fp12 /* if (x > 0.0) */ + bnl- cr7,.L2 + mtfsfi 7,1 /* Set rounding mode toward 0. */ + lfd fp10,.LC1@toc(2) + ble- cr6,.L1 + fneg fp2,fp12 + fadd fp1,fp1,fp10 /* x+= 0.5; */ + fadd fp1,fp1,fp13 /* x+= TWO52; */ + fsub fp1,fp1,fp13 /* x-= TWO52; */ + fabs fp1,fp1 /* if (x == 0.0) x = 0.0; */ +.L0: + mtfsf 0x01,fp11 /* restore previous rounding mode. */ + blr +.L1: + fsub fp9,fp1,fp10 /* x-= 0.5; */ + fneg fp2,fp12 + bge- cr6,.L0 /* if (x < 0.0) */ + fsub fp1,fp9,fp13 /* x-= TWO52; */ + fadd fp1,fp1,fp13 /* x+= TWO52; */ + fnabs fp1,fp1 /* if (x == 0.0) x = -0.0; */ + mtfsf 0x01,fp11 /* restore previous rounding mode. */ + blr + +/* The high double is > TWO52 so we need to round the low double and + perhaps the high double. In this case we have to round the low + double and handle any adjustment to the high double that may be + caused by rounding (up). This is complicated by the fact that the + high double may already be rounded and the low double may have the + opposite sign to compensate.This gets a bit tricky so we use the + following algorithm: + + tau = floor(x_high/TWO52); + x0 = x_high - tau; + x1 = x_low + tau; + r1 = rint(x1); + y_high = x0 + r1; + y_low = x0 - y_high + r1; + return y; */ +.L2: + fcmpu cr7,fp9,fp13 /* if (|x_low| > TWO52) */ + fcmpu cr0,fp9,fp12 /* || (|x_low| == 0.0) */ + fcmpu cr5,fp2,fp12 /* if (x_low > 0.0) */ + lfd fp10,.LC1@toc(2) + bgelr- cr7 /* return x; */ + beqlr- cr0 + mtfsfi 7,1 /* Set rounding mode toward 0. */ + fdiv fp8,fp1,fp13 /* x_high/TWO52 */ + + bng- cr6,.L6 /* if (x > 0.0) */ + fctidz fp0,fp8 + fcfid fp8,fp0 /* tau = floor(x_high/TWO52); */ + bng cr5,.L4 /* if (x_low > 0.0) */ + fmr fp3,fp1 + fmr fp4,fp2 + b .L5 +.L4: /* if (x_low < 0.0) */ + fsub fp3,fp1,fp8 /* x0 = x_high - tau; */ + fadd fp4,fp2,fp8 /* x1 = x_low + tau; */ +.L5: + fadd fp5,fp4,fp10 /* r1 = x1 + 0.5; */ + fadd fp5,fp5,fp13 /* r1 = r1 + TWO52; */ + fsub fp5,fp5,fp13 /* r1 = r1 - TWO52; */ + b .L9 +.L6: /* if (x < 0.0) */ + fctidz fp0,fp8 + fcfid fp8,fp0 /* tau = floor(x_high/TWO52); */ + bnl cr5,.L7 /* if (x_low < 0.0) */ + fmr fp3,fp1 + fmr fp4,fp2 + b .L8 +.L7: /* if (x_low > 0.0) */ + fsub fp3,fp1,fp8 /* x0 = x_high - tau; */ + fadd fp4,fp2,fp8 /* x1 = x_low + tau; */ +.L8: + fsub fp5,fp4,fp10 /* r1 = x1 - 0.5; */ + fsub fp5,fp5,fp13 /* r1-= TWO52; */ + fadd fp5,fp5,fp13 /* r1+= TWO52; */ +.L9: + mtfsf 0x01,fp11 /* restore previous rounding mode. */ + fadd fp1,fp3,fp5 /* y_high = x0 + r1; */ + fsub fp2,fp3,fp1 /* y_low = x0 - y_high + r1; */ + fadd fp2,fp2,fp5 + blr +END (__roundl) + +long_double_symbol (libm, __roundl, roundl) diff --git a/sysdeps/powerpc/powerpc64/fpu/s_trunc.S b/sysdeps/powerpc/powerpc64/fpu/s_trunc.S index 3ddd298..086ed00 100644 --- a/sysdeps/powerpc/powerpc64/fpu/s_trunc.S +++ b/sysdeps/powerpc/powerpc64/fpu/s_trunc.S @@ -1,5 +1,5 @@ /* trunc function. PowerPC64 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,12 +18,11 @@ 02111-1307 USA. */ #include <sysdep.h> +#include <math_ldbl_opt.h> .section ".toc","aw" .LC0: /* 2**52 */ .tc FD_43300000_0[TC],0x4330000000000000 -.LC2: /* -0.0 */ - .tc FD_80000000_0[TC],0x8000000000000000 .section ".text" /* double [fp1] trunc (double x [fp1]) @@ -33,7 +32,7 @@ We set "round toward Zero" mode and trunc by adding +-2**52 then subtracting +-2**52. */ -ENTRY (__trunc) +EALIGN (__trunc, 4, 0) CALL_MCOUNT 0 mffs fp11 /* Save current FPU rounding mode. */ lfd fp13,.LC0@toc(2) @@ -46,17 +45,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 - lfd fp1,.LC2@toc(2) /* x must be -0.0 for the 0.0 case. */ blr END (__trunc) @@ -66,3 +66,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/powerpc64/fpu/s_truncf.S b/sysdeps/powerpc/powerpc64/fpu/s_truncf.S index b38b722..1456e7f 100644 --- a/sysdeps/powerpc/powerpc64/fpu/s_truncf.S +++ b/sysdeps/powerpc/powerpc64/fpu/s_truncf.S @@ -1,5 +1,5 @@ /* truncf function. PowerPC64 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 @@ -21,9 +21,7 @@ .section ".toc","aw" .LC0: /* 2**23 */ - .tc FD_41600000_0[TC],0x4160000000000000 -.LC2: /* -0.0 */ - .tc FD_80000000_0[TC],0x8000000000000000 + .tc FD_4b000000_0[TC],0x4b00000000000000 .section ".text" /* float [fp1] truncf (float x [fp1]) @@ -33,10 +31,10 @@ We set "round toward Zero" mode and trunc by adding +-2**23 then subtracting +-2**23. */ -ENTRY (__truncf) +EALIGN (__truncf, 4, 0) CALL_MCOUNT 0 mffs fp11 /* Save current FPU rounding mode. */ - lfd fp13,.LC0@toc(2) + lfs fp13,.LC0@toc(2) fabs fp0,fp1 fsubs fp12,fp13,fp13 /* generate 0.0 */ fcmpu cr7,fp0,fp13 /* if (fabs(x) > TWO23) */ @@ -46,17 +44,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 - lfd fp1,.LC2@toc(2) /* x must be -0.0 for the 0.0 case. */ blr END (__truncf) diff --git a/sysdeps/powerpc/powerpc64/fpu/s_truncl.S b/sysdeps/powerpc/powerpc64/fpu/s_truncl.S new file mode 100644 index 0000000..1864fc1 --- /dev/null +++ b/sysdeps/powerpc/powerpc64/fpu/s_truncl.S @@ -0,0 +1,121 @@ +/* long double trunc function. + 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> + + .section ".toc","aw" +.LC0: /* 2**52 */ + .tc FD_43300000_0[TC],0x4330000000000000 +.LC1: /* 0.5 */ + .tc FD_3fe00000_0[TC],0x3fe0000000000000 + .section ".text" + +/* long double [fp1,fp2] truncl (long double x [fp1,fp2]) */ + +ENTRY (__truncl) + mffs fp11 /* Save current FPU rounding mode. */ + lfd fp13,.LC0@toc(2) + fabs fp0,fp1 + fabs fp9,fp2 + fsub fp12,fp13,fp13 /* generate 0.0 */ + fcmpu cr7,fp0,fp13 /* if (fabs(x) > TWO52) */ + fcmpu cr6,fp1,fp12 /* if (x > 0.0) */ + bnl- cr7,.L2 + mtfsfi 7,1 /* Set rounding mode toward 0. */ + ble- cr6,.L1 + fneg fp2,fp12 + fadd fp1,fp1,fp13 /* x+= TWO52; */ + fsub fp1,fp1,fp13 /* x-= TWO52; */ + fabs fp1,fp1 /* if (x == 0.0) x = 0.0; */ +.L0: + mtfsf 0x01,fp11 /* restore previous rounding mode. */ + blr +.L1: + fneg fp2,fp12 + bge- cr6,.L0 /* 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; */ + mtfsf 0x01,fp11 /* restore previous rounding mode. */ + blr + +/* The high double is > TWO52 so we need to round the low double and + perhaps the high double. In this case we have to round the low + double and handle any adjustment to the high double that may be + caused by rounding (up). This is complicated by the fact that the + high double may already be rounded and the low double may have the + opposite sign to compensate.This gets a bit tricky so we use the + following algorithm: + + tau = floor(x_high/TWO52); + x0 = x_high - tau; + x1 = x_low + tau; + r1 = rint(x1); + y_high = x0 + r1; + y_low = x0 - y_high + r1; + return y; */ +.L2: + fcmpu cr7,fp9,fp13 /* if (|x_low| > TWO52) */ + fcmpu cr0,fp9,fp12 /* || (|x_low| == 0.0) */ + fcmpu cr5,fp2,fp12 /* if (x_low > 0.0) */ + bgelr- cr7 /* return x; */ + beqlr- cr0 + mtfsfi 7,1 /* Set rounding mode toward 0. */ + fdiv fp8,fp1,fp13 /* x_high/TWO52 */ + + bng- cr6,.L6 /* if (x > 0.0) */ + fctidz fp0,fp8 + fcfid fp8,fp0 /* tau = floor(x_high/TWO52); */ + fadd fp8,fp8,fp8 /* tau++; Make tau even */ + bng cr5,.L4 /* if (x_low > 0.0) */ + fmr fp3,fp1 + fmr fp4,fp2 + b .L5 +.L4: /* if (x_low < 0.0) */ + fsub fp3,fp1,fp8 /* x0 = x_high - tau; */ + fadd fp4,fp2,fp8 /* x1 = x_low + tau; */ +.L5: + fadd fp5,fp4,fp13 /* r1 = r1 + TWO52; */ + fsub fp5,fp5,fp13 /* r1 = r1 - TWO52; */ + b .L9 +.L6: /* if (x < 0.0) */ + fctidz fp0,fp8 + fcfid fp8,fp0 /* tau = floor(x_high/TWO52); */ + fadd fp8,fp8,fp8 /* tau++; Make tau even */ + bnl cr5,.L7 /* if (x_low < 0.0) */ + fmr fp3,fp1 + fmr fp4,fp2 + b .L8 +.L7: /* if (x_low > 0.0) */ + fsub fp3,fp1,fp8 /* x0 = x_high - tau; */ + fadd fp4,fp2,fp8 /* x1 = x_low + tau; */ +.L8: + fsub fp5,fp4,fp13 /* r1-= TWO52; */ + fadd fp5,fp5,fp13 /* r1+= TWO52; */ +.L9: + mtfsf 0x01,fp11 /* restore previous rounding mode. */ + fadd fp1,fp3,fp5 /* y_high = x0 + r1; */ + fsub fp2,fp3,fp1 /* y_low = x0 - y_high + r1; */ + fadd fp2,fp2,fp5 + blr +END (__truncl) + +long_double_symbol (libm, __truncl, truncl) diff --git a/sysdeps/powerpc/powerpc64/dl-lookupcfg.h b/sysdeps/powerpc/powerpc64/hp-timing.c index e502941..4e54e66 100644 --- a/sysdeps/powerpc/powerpc64/dl-lookupcfg.h +++ b/sysdeps/powerpc/powerpc64/hp-timing.c @@ -1,6 +1,8 @@ -/* Configuration of lookup functions. PowerPC64 version. - Copyright (C) 2002 Free Software Foundation, Inc. +/* Support for high precision, low overhead timing functions. + powerpc64 version. + Copyright (C) 2005 Free Software Foundation, Inc. This file is part of the GNU C Library. + Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -17,6 +19,7 @@ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -/* Return the symbol map from the symbol lookup function. */ +#include <hp-timing.h> -#define DL_LOOKUP_RETURNS_MAP 1 +/* We have to define the variable for the overhead. */ +hp_timing_t _dl_hp_timing_overhead; diff --git a/sysdeps/powerpc/powerpc64/hp-timing.h b/sysdeps/powerpc/powerpc64/hp-timing.h new file mode 100644 index 0000000..b58cca9 --- /dev/null +++ b/sysdeps/powerpc/powerpc64/hp-timing.h @@ -0,0 +1,136 @@ +/* High precision, low overhead timing functions. powerpc64 version. + Copyright (C) 2005 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998. + + 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 + +#include <string.h> +#include <sys/param.h> +#include <stdio-common/_itoa.h> +#include <atomic.h> + +/* The macros defined here use the powerpc 64-bit time base register. + The time base is nominally clocked at 1/8th the CPU clock, but this + can vary. + + The list of macros we need includes the following: + + - 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. + +*/ + +/* We always assume having the timestamp register. */ +#define HP_TIMING_AVAIL (1) + +/* We indeed have inlined functions. */ +#define HP_TIMING_INLINE (1) + +/* We use 64bit values for the times. */ +typedef unsigned long long int hp_timing_t; + +/* Set timestamp value to zero. */ +#define HP_TIMING_ZERO(Var) (Var) = (0) + +/* That's quite simple. Use the `mftb' instruction. Note that the value + might not be 100% accurate since there might be some more instructions + running in this moment. This could be changed by using a barrier like + 'lwsync' right before the `mftb' instruciton. But we are not interested + in accurate clock cycles here so we don't do this. */ +#define HP_TIMING_NOW(Var) __asm__ __volatile__ ("mftb %0" : "=r" (Var)) + +/* Use two 'mftb' instructions in a row to find out how long it takes. + On current POWER4, POWER5, and 970 processors mftb take ~10 cycles. */ +#define HP_TIMING_DIFF_INIT() \ + do { \ + if (GLRO(dl_hp_timing_overhead) == 0) \ + { \ + int __cnt = 5; \ + GLRO(dl_hp_timing_overhead) = ~0ull; \ + do \ + { \ + hp_timing_t __t1, __t2; \ + HP_TIMING_NOW (__t1); \ + HP_TIMING_NOW (__t2); \ + if (__t2 - __t1 < GLRO(dl_hp_timing_overhead)) \ + GLRO(dl_hp_timing_overhead) = __t2 - __t1; \ + } \ + while (--__cnt > 0); \ + } \ + } while (0) + +/* It's simple arithmetic in 64-bit. */ +#define HP_TIMING_DIFF(Diff, Start, End) (Diff) = ((End) - (Start)) + +/* We need to insure that this add is atomic in threaded environments. We use + __arch_atomic_exchange_and_add_64 from atomic.h to get thread safety. */ +#define HP_TIMING_ACCUM(Sum, Diff) \ + do { \ + hp_timing_t __diff = (Diff) - GLRO(dl_hp_timing_overhead); \ + __arch_atomic_exchange_and_add_64 (&(Sum), __diff); \ + } while (0) + +/* No threads, no extra work. */ +#define HP_TIMING_ACCUM_NT(Sum, Diff) (Sum) += (Diff) + +/* Print the time value. */ +#define HP_TIMING_PRINT(Buf, Len, Val) \ + do { \ + char __buf[20]; \ + char *__cp = _itoa (Val, __buf + sizeof (__buf), 10, 0); \ + size_t __len = (Len); \ + char *__dest = (Buf); \ + while (__len-- > 0 && __cp < __buf + sizeof (__buf)) \ + *__dest++ = *__cp++; \ + memcpy (__dest, " ticks", MIN (__len, sizeof (" ticks"))); \ + } while (0) + +#endif /* hp-timing.h */ diff --git a/sysdeps/powerpc/powerpc64/memcpy.S b/sysdeps/powerpc/powerpc64/memcpy.S index 9df5bb4..f395de9 100644 --- a/sysdeps/powerpc/powerpc64/memcpy.S +++ b/sysdeps/powerpc/powerpc64/memcpy.S @@ -1,5 +1,5 @@ /* Optimized memcpy implementation for PowerPC64. - Copyright (C) 2003 Free Software Foundation, Inc. + Copyright (C) 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 @@ -43,6 +43,7 @@ EALIGN (BP_SYM (memcpy), 5, 0) neg 0,3 std 3,-16(1) std 31,-8(1) + cfi_offset(31,-8) andi. 11,3,7 /* check alignement of dst. */ clrldi 0,0,61 /* Number of bytes until the 1st doubleword of dst. */ clrldi 10,4,61 /* check alignement of src. */ diff --git a/sysdeps/powerpc/powerpc64/memset.S b/sysdeps/powerpc/powerpc64/memset.S index 1abc59b..09c79fc 100644 --- a/sysdeps/powerpc/powerpc64/memset.S +++ b/sysdeps/powerpc/powerpc64/memset.S @@ -62,8 +62,7 @@ EALIGN (BP_SYM (memset), 5, 0) #define rNEG64 r8 /* Constant -64 for clearing with dcbz. */ #define rCLS r8 /* Cache line size obtained from static. */ #define rCLM r9 /* Cache line size mask to check for cache alignment. */ - -___memset: +L(_memset): #if __BOUNDED_POINTERS__ cmpldi cr1, rRTN, 0 CHECK_BOUNDS_BOTH_WIDE (rMEMP0, rTMP, rTMP2, rLEN) @@ -282,11 +281,11 @@ ENTRY (BP_SYM (__bzero)) mr r4,r3 /* Tell memset that we don't want a return value. */ li r3,0 - b ___memset + b L(_memset) #else mr r5,r4 li r4,0 - b ___memset + b L(_memset) #endif END_GEN_TB (BP_SYM (__bzero),TB_TOCLESS) diff --git a/sysdeps/powerpc/powerpc64/ppc-mcount.S b/sysdeps/powerpc/powerpc64/ppc-mcount.S index 46cb9fd..5df9650 100644 --- a/sysdeps/powerpc/powerpc64/ppc-mcount.S +++ b/sysdeps/powerpc/powerpc64/ppc-mcount.S @@ -1,5 +1,5 @@ /* PowerPC64-specific implementation of profiling support. - Copyright (C) 1997, 1999, 2002 Free Software Foundation, Inc. + Copyright (C) 1997, 1999, 2002, 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> /* We don't need to save the parameter-passing registers as gcc takes @@ -26,7 +26,9 @@ ENTRY(_mcount) mflr r4 ld r11, 0(r1) stdu r1,-112(r1) + cfi_adjust_cfa_offset (112) std r4, 128(r1) + cfi_offset (lr, 16) ld r3, 16(r11) bl JUMPTARGET(__mcount_internal) nop diff --git a/sysdeps/powerpc/powerpc64/register-dump.h b/sysdeps/powerpc/powerpc64/register-dump.h index dd69af3..fc27dca 100644 --- a/sysdeps/powerpc/powerpc64/register-dump.h +++ b/sysdeps/powerpc/powerpc64/register-dump.h @@ -1,5 +1,5 @@ /* Dump registers. - Copyright (C) 1998, 2002 Free Software Foundation, Inc. + Copyright (C) 1998, 2002, 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 @@ -34,7 +34,7 @@ gr16-19: 000000000000010% 000000000000011% 000000000000012% 000000000000013%\n\ gr20-23: 000000000000014% 000000000000015% 000000000000016% 000000000000017%\n\ gr24-27: 000000000000018% 000000000000019% 00000000000001a% 00000000000001b%\n\ gr28-31: 00000000000001c% 00000000000001d% 00000000000001e% 00000000000001f%\n\ -fscr=0000071%\n\ +fscr=000000000000050%\n\ fp0-3: 000000000000030% 000000000000031% 000000000000032% 000000000000033%\n\ fp4-7: 000000000000034% 000000000000035% 000000000000036% 000000000000037%\n\ fp8-11: 000000000000038% 000000000000038% 00000000000003a% 00000000000003b%\n\ @@ -104,7 +104,7 @@ register_dump (int fd, struct sigcontext *ctx) char buffer[sizeof(dumpform)]; char *bufferpos; unsigned regno; - unsigned *regs = (unsigned *)(ctx->regs); + unsigned long *regs = (unsigned long *)(ctx->regs); memcpy(buffer, dumpform, sizeof(dumpform)); @@ -117,7 +117,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/powerpc64/setjmp-common.S b/sysdeps/powerpc/powerpc64/setjmp-common.S index 0de07a8..606eef5 100644 --- a/sysdeps/powerpc/powerpc64/setjmp-common.S +++ b/sysdeps/powerpc/powerpc64/setjmp-common.S @@ -1,5 +1,5 @@ /* setjmp for PowerPC64. - Copyright (C) 1995-2003, 2004 Free Software Foundation, Inc. + Copyright (C) 1995-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 +19,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> @@ -46,7 +45,13 @@ ENTRY (BP_SYM (__sigsetjmp)) .hidden JUMPTARGET(GLUE(__sigsetjmp,_ent)) JUMPTARGET(GLUE(__sigsetjmp,_ent)): CHECK_BOUNDS_BOTH_WIDE_LIT (r3, r8, r9, JB_SIZE) +#ifdef PTR_MANGLE + mr r5, r1 + PTR_MANGLE (r5, r6) + std r5,(JB_GPR1*8)(3) +#else std r1,(JB_GPR1*8)(3) +#endif mflr r0 #if defined SHARED && !defined IS_IN_rtld ld r5,40(r1) /* Retrieve the callers TOC. */ @@ -56,6 +61,9 @@ JUMPTARGET(GLUE(__sigsetjmp,_ent)): #endif std r14,((JB_GPRS+0)*8)(3) stfd fp14,((JB_FPRS+0)*8)(3) +#ifdef PTR_MANGLE + PTR_MANGLE2 (r0, r6) +#endif std r0,(JB_LR*8)(3) std r15,((JB_GPRS+1)*8)(3) stfd fp15,((JB_FPRS+1)*8)(3) @@ -94,14 +102,14 @@ JUMPTARGET(GLUE(__sigsetjmp,_ent)): std r31,((JB_GPRS+17)*8)(3) stfd fp31,((JB_FPRS+17)*8)(3) #ifndef __NO_VMX__ - ld r5,.LC__dl_hwcap@toc(r2) + ld r6,.LC__dl_hwcap@toc(r2) # ifdef SHARED /* Load _rtld-global._dl_hwcap. */ - ld r5,RTLD_GLOBAL_RO_DL_HWCAP_OFFSET(r5) + ld r6,RTLD_GLOBAL_RO_DL_HWCAP_OFFSET(r6) # else - ld r5,0(r5) /* Load extern _dl_hwcap. */ + ld r6,0(r6) /* Load extern _dl_hwcap. */ # endif - andis. r5,r5,(PPC_FEATURE_HAS_ALTIVEC >> 16) + andis. r6,r6,(PPC_FEATURE_HAS_ALTIVEC >> 16) beq L(no_vmx) la r5,((JB_VRS)*8)(3) andi. r6,r5,0xf @@ -176,6 +184,13 @@ L(aligned_save_vmx): stvx 30,0,r5 stvx 31,0,r6 L(no_vmx): +#else + li r6,0 #endif +#if defined NOT_IN_libc && defined IS_IN_rtld + li r3,0 + blr +#else b JUMPTARGET (BP_SYM (__sigjmp_save)) +#endif END (BP_SYM (__sigsetjmp)) diff --git a/sysdeps/powerpc/powerpc64/strncmp.S b/sysdeps/powerpc/powerpc64/strncmp.S index 04bdc2f..34479e2 100644 --- a/sysdeps/powerpc/powerpc64/strncmp.S +++ b/sysdeps/powerpc/powerpc64/strncmp.S @@ -48,6 +48,7 @@ EALIGN (BP_SYM(strncmp), 4, 0) lis r7F7F, 0x7f7f dcbt 0,rSTR2 clrldi. rTMP, rTMP, 61 + cmpldi cr1, rN, 0 lis rFEFE, -0x101 bne L(unaligned) /* We are doubleword alligned so set up for two loops. first a double word @@ -55,7 +56,8 @@ EALIGN (BP_SYM(strncmp), 4, 0) srdi. rTMP, rN, 3 clrldi rN, rN, 61 addi rFEFE, rFEFE, -0x101 - addi r7F7F, r7F7F, 0x7f7f + addi r7F7F, r7F7F, 0x7f7f + cmpldi cr1, rN, 0 beq L(unaligned) mtctr rTMP /* Power4 wants mtctr 1st in dispatch group. */ @@ -126,16 +128,19 @@ L(tail): addi rSTR1, rSTR1, 8 bne- cr1, L(different) addi rSTR2, rSTR2, 8 + cmpldi cr1, rN, 0 L(unaligned): mtctr rN /* Power4 wants mtctr 1st in dispatch group */ - cmpdi 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/powerpc64/sysdep.h b/sysdeps/powerpc/powerpc64/sysdep.h index fead0b5..2745d7e 100644 --- a/sysdeps/powerpc/powerpc64/sysdep.h +++ b/sysdeps/powerpc/powerpc64/sysdep.h @@ -1,5 +1,5 @@ /* Assembly macros for 64-bit PowerPC. - Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc. + Copyright (C) 2002, 2003, 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,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> @@ -92,7 +92,8 @@ name##: OPD_ENT (name); \ #define ENTRY(name) \ ENTRY_2(name) \ .align ALIGNARG(2); \ -BODY_LABEL(name): +BODY_LABEL(name): \ + cfi_startproc; #define EALIGN_W_0 /* No words to insert. */ #define EALIGN_W_1 nop @@ -109,7 +110,8 @@ BODY_LABEL(name): ENTRY_2(name) \ .align ALIGNARG(alignt); \ EALIGN_W_##words; \ -BODY_LABEL(name): +BODY_LABEL(name): \ + cfi_startproc; /* Local labels stripped out by the linker. */ #undef L @@ -173,11 +175,13 @@ LT_LABELSUFFIX(name,_name_end): ; \ /* END generates Traceback tables */ #undef END #define END(name) \ + cfi_endproc; \ TRACEBACK(name) \ END_2(name) /* This form supports more informative traceback tables */ #define END_GEN_TB(name,mask) \ + cfi_endproc; \ TRACEBACK_MASK(name,mask) \ END_2(name) diff --git a/sysdeps/powerpc/soft-fp/Dist b/sysdeps/powerpc/soft-fp/Dist deleted file mode 100644 index a917524..0000000 --- a/sysdeps/powerpc/soft-fp/Dist +++ /dev/null @@ -1,28 +0,0 @@ -q_add.c -q_cmp.c -q_cmpe.c -q_div.c -q_dtoq.c -q_feq.c -q_fge.c -q_fgt.c -q_fle.c -q_flt.c -q_fne.c -q_itoq.c -q_lltoq.c -q_mul.c -q_neg.c -q_qtod.c -q_qtoi.c -q_qtoll.c -q_qtos.c -q_qtou.c -q_qtoull.c -q_sqrt.c -q_stoq.c -q_sub.c -q_ulltoq.c -q_util.c -q_utoq.c -sfp-machine.h diff --git a/sysdeps/powerpc/soft-fp/q_add.c b/sysdeps/powerpc/soft-fp/q_add.c index 4338803..80a0b3f 100644 --- a/sysdeps/powerpc/soft-fp/q_add.c +++ b/sysdeps/powerpc/soft-fp/q_add.c @@ -1,6 +1,6 @@ /* Software floating-point emulation. Return a + b - 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. Contributed by Richard Henderson (rth@cygnus.com) and Jakub Jelinek (jj@ultra.linux.cz). @@ -30,10 +30,10 @@ long double _q_add(const long double a, const long double b) long double c; FP_INIT_ROUNDMODE; - FP_UNPACK_Q(A, a); - FP_UNPACK_Q(B, b); + FP_UNPACK_SEMIRAW_Q(A, a); + FP_UNPACK_SEMIRAW_Q(B, b); FP_ADD_Q(C, A, B); - FP_PACK_Q(c, C); + FP_PACK_SEMIRAW_Q(c, C); FP_HANDLE_EXCEPTIONS; return c; } diff --git a/sysdeps/powerpc/soft-fp/q_dtoq.c b/sysdeps/powerpc/soft-fp/q_dtoq.c index 6c4c740..baebea5 100644 --- a/sysdeps/powerpc/soft-fp/q_dtoq.c +++ b/sysdeps/powerpc/soft-fp/q_dtoq.c @@ -1,6 +1,6 @@ /* Software floating-point emulation. Return (long double)(a) - 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. Contributed by Richard Henderson (rth@cygnus.com) and Jakub Jelinek (jj@ultra.linux.cz). @@ -32,13 +32,13 @@ long double _q_dtoq(const double a) long double c; FP_INIT_ROUNDMODE; - FP_UNPACK_D(A, a); + FP_UNPACK_RAW_D(A, a); #if (2 * _FP_W_TYPE_SIZE) < _FP_FRACBITS_Q - FP_CONV(Q,D,4,2,C,A); + FP_EXTEND(Q,D,4,2,C,A); #else - FP_CONV(Q,D,2,1,C,A); + FP_EXTEND(Q,D,2,1,C,A); #endif - FP_PACK_Q(c, C); + FP_PACK_RAW_Q(c, C); FP_HANDLE_EXCEPTIONS; return c; } diff --git a/sysdeps/powerpc/soft-fp/q_itoq.c b/sysdeps/powerpc/soft-fp/q_itoq.c index 166138c..e288400 100644 --- a/sysdeps/powerpc/soft-fp/q_itoq.c +++ b/sysdeps/powerpc/soft-fp/q_itoq.c @@ -1,6 +1,6 @@ /* Software floating-point emulation. Return (long double)(a) - 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. Contributed by Richard Henderson (rth@cygnus.com) and Jakub Jelinek (jj@ultra.linux.cz). @@ -30,8 +30,8 @@ long double _q_itoq(const int a) int b = a; long double c; - FP_FROM_INT_Q(C, b, 32, int); - FP_PACK_Q(c, C); + FP_FROM_INT_Q(C, b, 32, unsigned int); + FP_PACK_RAW_Q(c, C); FP_CLEAR_EXCEPTIONS; FP_HANDLE_EXCEPTIONS; return c; diff --git a/sysdeps/powerpc/soft-fp/q_lltoq.c b/sysdeps/powerpc/soft-fp/q_lltoq.c index 6412ecc..22d2e55 100644 --- a/sysdeps/powerpc/soft-fp/q_lltoq.c +++ b/sysdeps/powerpc/soft-fp/q_lltoq.c @@ -1,6 +1,6 @@ /* Software floating-point emulation. Return (long double)a - 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. Contributed by Richard Henderson (rth@cygnus.com) and Jakub Jelinek (jj@ultra.linux.cz). @@ -30,8 +30,8 @@ long double _q_lltoq(const long long a) long double c; long long b = a; - FP_FROM_INT_Q(C, b, 64, long long); - FP_PACK_Q(c, C); + FP_FROM_INT_Q(C, b, 64, unsigned long long); + FP_PACK_RAW_Q(c, C); FP_CLEAR_EXCEPTIONS; FP_HANDLE_EXCEPTIONS; return c; diff --git a/sysdeps/powerpc/soft-fp/q_qtod.c b/sysdeps/powerpc/soft-fp/q_qtod.c index d107f38..685aa68 100644 --- a/sysdeps/powerpc/soft-fp/q_qtod.c +++ b/sysdeps/powerpc/soft-fp/q_qtod.c @@ -1,6 +1,6 @@ /* Software floating-point emulation. Return (double)a - 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. Contributed by Richard Henderson (rth@cygnus.com) and Jakub Jelinek (jj@ultra.linux.cz). @@ -32,13 +32,13 @@ double _q_qtod(const long double a) double r; FP_INIT_ROUNDMODE; - FP_UNPACK_Q(A, a); + FP_UNPACK_SEMIRAW_Q(A, a); #if (2 * _FP_W_TYPE_SIZE) < _FP_FRACBITS_Q - FP_CONV(D,Q,2,4,R,A); + FP_TRUNC(D,Q,2,4,R,A); #else - FP_CONV(D,Q,1,2,R,A); + FP_TRUNC(D,Q,1,2,R,A); #endif - FP_PACK_D(r, R); + FP_PACK_SEMIRAW_D(r, R); FP_HANDLE_EXCEPTIONS; return r; diff --git a/sysdeps/powerpc/soft-fp/q_qtoi.c b/sysdeps/powerpc/soft-fp/q_qtoi.c index 90c01e6..89410d1 100644 --- a/sysdeps/powerpc/soft-fp/q_qtoi.c +++ b/sysdeps/powerpc/soft-fp/q_qtoi.c @@ -1,6 +1,6 @@ /* Software floating-point emulation. Return (int)a - 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. Contributed by Richard Henderson (rth@cygnus.com) and Jakub Jelinek (jj@ultra.linux.cz). @@ -28,9 +28,9 @@ int _q_qtoi(const long double a) { FP_DECL_EX; FP_DECL_Q(A); - int r; + unsigned int r; - FP_UNPACK_Q(A, a); + FP_UNPACK_RAW_Q(A, a); FP_TO_INT_Q(r, A, 32, 1); FP_HANDLE_EXCEPTIONS; diff --git a/sysdeps/powerpc/soft-fp/q_qtoll.c b/sysdeps/powerpc/soft-fp/q_qtoll.c index 72bde2e..3b0251f 100644 --- a/sysdeps/powerpc/soft-fp/q_qtoll.c +++ b/sysdeps/powerpc/soft-fp/q_qtoll.c @@ -1,6 +1,6 @@ /* Software floating-point emulation. Return (long)a - 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. Contributed by Richard Henderson (rth@cygnus.com) and Jakub Jelinek (jj@ultra.linux.cz). @@ -28,9 +28,9 @@ long long _q_qtoll(const long double a) { FP_DECL_EX; FP_DECL_Q(A); - long long r; + unsigned long long r; - FP_UNPACK_Q(A, a); + FP_UNPACK_RAW_Q(A, a); FP_TO_INT_Q(r, A, 64, 1); FP_HANDLE_EXCEPTIONS; diff --git a/sysdeps/powerpc/soft-fp/q_qtos.c b/sysdeps/powerpc/soft-fp/q_qtos.c index ebd6bae..0d71271 100644 --- a/sysdeps/powerpc/soft-fp/q_qtos.c +++ b/sysdeps/powerpc/soft-fp/q_qtos.c @@ -1,6 +1,6 @@ /* Software floating-point emulation. Return (float)a - 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. Contributed by Richard Henderson (rth@cygnus.com) and Jakub Jelinek (jj@ultra.linux.cz). @@ -32,13 +32,13 @@ float _q_qtos(const long double a) float r; FP_INIT_ROUNDMODE; - FP_UNPACK_Q(A, a); + FP_UNPACK_SEMIRAW_Q(A, a); #if (2 * _FP_W_TYPE_SIZE) < _FP_FRACBITS_Q - FP_CONV(S,Q,1,4,R,A); + FP_TRUNC(S,Q,1,4,R,A); #else - FP_CONV(S,Q,1,2,R,A); + FP_TRUNC(S,Q,1,2,R,A); #endif - FP_PACK_S(r, R); + FP_PACK_SEMIRAW_S(r, R); FP_HANDLE_EXCEPTIONS; return r; diff --git a/sysdeps/powerpc/soft-fp/q_qtou.c b/sysdeps/powerpc/soft-fp/q_qtou.c index b9119d0..e5d21f1 100644 --- a/sysdeps/powerpc/soft-fp/q_qtou.c +++ b/sysdeps/powerpc/soft-fp/q_qtou.c @@ -1,6 +1,6 @@ /* Software floating-point emulation. Return (unsigned int)a - 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. Contributed by Richard Henderson (rth@cygnus.com) and Jakub Jelinek (jj@ultra.linux.cz). @@ -30,7 +30,7 @@ unsigned int _q_qtou(const long double a) FP_DECL_Q(A); unsigned int r; - FP_UNPACK_Q(A, a); + FP_UNPACK_RAW_Q(A, a); FP_TO_INT_Q(r, A, 32, -1); FP_HANDLE_EXCEPTIONS; diff --git a/sysdeps/powerpc/soft-fp/q_qtoull.c b/sysdeps/powerpc/soft-fp/q_qtoull.c index 9fcefd6..a01100c 100644 --- a/sysdeps/powerpc/soft-fp/q_qtoull.c +++ b/sysdeps/powerpc/soft-fp/q_qtoull.c @@ -1,6 +1,6 @@ /* Software floating-point emulation. Return (long)a - 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. Contributed by Richard Henderson (rth@cygnus.com) and Jakub Jelinek (jj@ultra.linux.cz). @@ -30,7 +30,7 @@ unsigned long long _q_qtoull(const long double a) FP_DECL_Q(A); unsigned long long r; - FP_UNPACK_Q(A, a); + FP_UNPACK_RAW_Q(A, a); FP_TO_INT_Q(r, A, 64, -1); FP_HANDLE_EXCEPTIONS; diff --git a/sysdeps/powerpc/soft-fp/q_stoq.c b/sysdeps/powerpc/soft-fp/q_stoq.c index 3fc4a59..f43a93c 100644 --- a/sysdeps/powerpc/soft-fp/q_stoq.c +++ b/sysdeps/powerpc/soft-fp/q_stoq.c @@ -1,6 +1,6 @@ /* Software floating-point emulation. c = (long double)(a) - 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. Contributed by Richard Henderson (rth@cygnus.com) and Jakub Jelinek (jj@ultra.linux.cz). @@ -31,13 +31,13 @@ long double _q_stoq(const float a) FP_DECL_Q(C); long double c; - FP_UNPACK_S(A, a); + FP_UNPACK_RAW_S(A, a); #if (2 * _FP_W_TYPE_SIZE) < _FP_FRACBITS_Q - FP_CONV(Q,S,4,1,C,A); + FP_EXTEND(Q,S,4,1,C,A); #else - FP_CONV(Q,S,2,1,C,A); + FP_EXTEND(Q,S,2,1,C,A); #endif - FP_PACK_Q(c, C); + FP_PACK_RAW_Q(c, C); FP_HANDLE_EXCEPTIONS; return c; } diff --git a/sysdeps/powerpc/soft-fp/q_sub.c b/sysdeps/powerpc/soft-fp/q_sub.c index 50c56b2..399be02 100644 --- a/sysdeps/powerpc/soft-fp/q_sub.c +++ b/sysdeps/powerpc/soft-fp/q_sub.c @@ -1,6 +1,6 @@ /* Software floating-point emulation. c = a - b - 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. Contributed by Richard Henderson (rth@cygnus.com) and Jakub Jelinek (jj@ultra.linux.cz). @@ -30,10 +30,10 @@ long double _q_sub(const long double a, const long double b) long double c; FP_INIT_ROUNDMODE; - FP_UNPACK_Q(A, a); - FP_UNPACK_Q(B, b); + FP_UNPACK_SEMIRAW_Q(A, a); + FP_UNPACK_SEMIRAW_Q(B, b); FP_SUB_Q(C, A, B); - FP_PACK_Q(c, C); + FP_PACK_SEMIRAW_Q(c, C); FP_HANDLE_EXCEPTIONS; return c; } diff --git a/sysdeps/powerpc/soft-fp/q_ulltoq.c b/sysdeps/powerpc/soft-fp/q_ulltoq.c index 428f201..30f5fc9 100644 --- a/sysdeps/powerpc/soft-fp/q_ulltoq.c +++ b/sysdeps/powerpc/soft-fp/q_ulltoq.c @@ -1,6 +1,6 @@ /* Software floating-point emulation. Return (long double)a - 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. Contributed by Richard Henderson (rth@cygnus.com) and Jakub Jelinek (jj@ultra.linux.cz). @@ -30,8 +30,8 @@ long double _q_ulltoq(const unsigned long long a) long double c; unsigned long long b = a; - FP_FROM_INT_Q(C, b, 64, long long); - FP_PACK_Q(c, C); + FP_FROM_INT_Q(C, b, 64, unsigned long long); + FP_PACK_RAW_Q(c, C); FP_CLEAR_EXCEPTIONS; FP_HANDLE_EXCEPTIONS; return c; diff --git a/sysdeps/powerpc/soft-fp/q_utoq.c b/sysdeps/powerpc/soft-fp/q_utoq.c index 87607e3..232bcfe 100644 --- a/sysdeps/powerpc/soft-fp/q_utoq.c +++ b/sysdeps/powerpc/soft-fp/q_utoq.c @@ -1,6 +1,6 @@ /* Software floating-point emulation. c = (long double)(a) - 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. Contributed by Richard Henderson (rth@cygnus.com) and Jakub Jelinek (jj@ultra.linux.cz). @@ -30,8 +30,8 @@ long double _q_uitoq(const unsigned int a) long double c; unsigned int b = a; - FP_FROM_INT_Q(C, b, 32, int); - FP_PACK_Q(c, C); + FP_FROM_INT_Q(C, b, 32, unsigned int); + FP_PACK_RAW_Q(c, C); FP_CLEAR_EXCEPTIONS; FP_HANDLE_EXCEPTIONS; return c; diff --git a/sysdeps/powerpc/sysdep.h b/sysdeps/powerpc/sysdep.h index fb668ad..2ae52b7 100644 --- a/sysdeps/powerpc/sysdep.h +++ b/sysdeps/powerpc/sysdep.h @@ -1,4 +1,4 @@ -/* Copyright (C) 1999, 2001, 2002 Free Software Foundation, Inc. +/* Copyright (C) 1999, 2001, 2002, 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 @@ -29,6 +29,22 @@ #define PPC_FEATURE_HAS_MMU 0x04000000 /* Memory Management Unit. */ #define PPC_FEATURE_HAS_4xxMAC 0x02000000 /* 4xx Multiply Accumulator. */ #define PPC_FEATURE_UNIFIED_CACHE 0x01000000 /* Unified I/D cache. */ +#define PPC_FEATURE_HAS_SPE 0x00800000 /* Signal Processing ext. */ +#define PPC_FEATURE_HAS_EFP_SINGLE 0x00400000 /* SPE Float. */ +#define PPC_FEATURE_HAS_EFP_DOUBLE 0x00200000 /* SPE Double. */ +#define PPC_FEATURE_NO_TB 0x00100000 /* 601/403gx have no timebase */ +#define PPC_FEATURE_POWER4 0x00080000 /* POWER4 ISA 2.00 */ +#define PPC_FEATURE_POWER5 0x00040000 /* POWER5 ISA 2.02 */ +#define PPC_FEATURE_POWER5_PLUS 0x00020000 /* POWER5+ ISA 2.03 */ +#define PPC_FEATURE_CELL_BE 0x00010000 /* CELL Broadband Engine */ +#define PPC_FEATURE_BOOKE 0x00008000 +#define PPC_FEATURE_SMT 0x00004000 /* Simultaneous Multi-Threading */ +#define PPC_FEATURE_ICACHE_SNOOP 0x00002000 +#define PPC_FEATURE_ARCH_2_05 0x00001000 /* ISA 2.05 */ +#define PPC_FEATURE_PA6T 0x00000800 /* PA Semi 6T Core */ +#define PPC_FEATURE_HAS_DFP 0x00000400 /* Decimal FP Unit */ +#define PPC_FEATURE_POWER6_EXT 0x00000200 /* P6 + mffgpr/mftgpr */ +#define PPC_FEATURE_970 (PPC_FEATURE_POWER4 + PPC_FEATURE_HAS_ALTIVEC) #ifdef __ASSEMBLER__ diff --git a/sysdeps/powerpc/tst-stack-align.h b/sysdeps/powerpc/tst-stack-align.h new file mode 100644 index 0000000..99a0ffc --- /dev/null +++ b/sysdeps/powerpc/tst-stack-align.h @@ -0,0 +1,47 @@ +/* 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. */ + +#include <stdio.h> +#include <stdint.h> + +#define TEST_STACK_ALIGN() \ + ({ \ + /* Altivec __vector int etc. needs 16byte aligned stack. \ + Instead of using altivec.h here, use aligned attribute instead. */ \ + struct _S \ + { \ + int _i __attribute__((aligned (16))); \ + int _j[3]; \ + } _s = { ._i = 18, ._j[0] = 19, ._j[1] = 20, ._j[2] = 21 }; \ + double _d = 12.0; \ + long double _ld = 15.0; \ + int _ret = 0; \ + printf ("__vector int: { %d, %d, %d, %d } %p %zu\n", _s._i, _s._j[0], \ + _s._j[1], _s._j[2], &_s, __alignof (_s)); \ + if ((((uintptr_t) &_s) & (__alignof (_s) - 1)) != 0) \ + _ret = 1; \ + \ + printf ("double: %g %p %zu\n", _d, &_d, __alignof (double)); \ + if ((((uintptr_t) &_d) & (__alignof (double) - 1)) != 0) \ + _ret = 1; \ + \ + printf ("ldouble: %Lg %p %zu\n", _ld, &_ld, __alignof (long double)); \ + if ((((uintptr_t) &_ld) & (__alignof (long double) - 1)) != 0) \ + _ret = 1; \ + _ret; \ + }) |