[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Commits] r22584 - in /fsf/trunk/libc: ./ ports/ ports/sysdeps/arm/armv6/ ports/sysdeps/arm/armv6t2/ ports/sysdeps/unix/sysv/linux/aar...



Author: eglibc
Date: Fri Mar  8 00:03:58 2013
New Revision: 22584

Log:
Import glibc-mainline for 2013-03-08

Added:
    fsf/trunk/libc/ports/sysdeps/arm/armv6/
    fsf/trunk/libc/ports/sysdeps/arm/armv6/rawmemchr.S
    fsf/trunk/libc/ports/sysdeps/arm/armv6/stpcpy.S
    fsf/trunk/libc/ports/sysdeps/arm/armv6/strchr.S
    fsf/trunk/libc/ports/sysdeps/arm/armv6/strcpy.S
    fsf/trunk/libc/ports/sysdeps/arm/armv6/strlen.S
    fsf/trunk/libc/ports/sysdeps/arm/armv6/strrchr.S
    fsf/trunk/libc/ports/sysdeps/arm/armv6t2/Implies
    fsf/trunk/libc/posix/tst-pathconf.c
Removed:
    fsf/trunk/libc/sysdeps/powerpc/powerpc32/power4/fpu/slowexp.c
    fsf/trunk/libc/sysdeps/powerpc/powerpc32/power4/fpu/slowpow.c
    fsf/trunk/libc/sysdeps/powerpc/powerpc64/power4/fpu/slowexp.c
    fsf/trunk/libc/sysdeps/powerpc/powerpc64/power4/fpu/slowpow.c
Modified:
    fsf/trunk/libc/ChangeLog
    fsf/trunk/libc/NEWS
    fsf/trunk/libc/ports/ChangeLog.aarch64
    fsf/trunk/libc/ports/ChangeLog.arm
    fsf/trunk/libc/ports/sysdeps/unix/sysv/linux/aarch64/bits/mman.h
    fsf/trunk/libc/posix/Makefile
    fsf/trunk/libc/sysdeps/ieee754/dbl-64/mpa.c
    fsf/trunk/libc/sysdeps/ieee754/dbl-64/slowexp.c
    fsf/trunk/libc/sysdeps/ieee754/dbl-64/slowpow.c
    fsf/trunk/libc/sysdeps/powerpc/powerpc32/power4/fpu/Makefile
    fsf/trunk/libc/sysdeps/powerpc/powerpc32/power4/fpu/mpa.c
    fsf/trunk/libc/sysdeps/powerpc/powerpc64/power4/fpu/Makefile
    fsf/trunk/libc/sysdeps/powerpc/powerpc64/power4/fpu/mpa.c
    fsf/trunk/libc/sysdeps/unix/sysv/linux/Makefile
    fsf/trunk/libc/sysdeps/unix/sysv/linux/fpathconf.c
    fsf/trunk/libc/sysdeps/unix/sysv/linux/pathconf.c

Modified: fsf/trunk/libc/ChangeLog
==============================================================================
--- fsf/trunk/libc/ChangeLog (original)
+++ fsf/trunk/libc/ChangeLog Fri Mar  8 00:03:58 2013
@@ -1,3 +1,51 @@
+2013-03-07  Andreas Jaeger  <aj@xxxxxxx>
+
+	* sysdeps/unix/sysv/linux/Makefile (sysdep_headers): Add
+	bits/mman-linux.h.
+
+2013-03-07  Siddhesh Poyarekar  <siddhesh@xxxxxxxxxx>
+
+	* sysdeps/ieee754/dbl-64/slowexp.c [!USE_LONG_DOUBLE_FOR_MP]:
+	Include mpa.h and declare __MPEXP.
+	[USE_LONG_DOUBLE_FOR_MP] (__slowexp): Call __IEEE754_EXPL.
+	* sysdeps/powerpc/powerpc32/power4/fpu/Makefile
+	(CPPFLAGS-slowexp.c): Define USE_LONG_DOUBLE_FOR_MP.
+	* sysdeps/powerpc/powerpc32/power4/fpu/slowexp.c: Remove.
+	* sysdeps/powerpc/powerpc64/power4/fpu/Makefile
+	(CPPFLAGS-slowexp.c): Define USE_LONG_DOUBLE_FOR_MP.
+	* sysdeps/powerpc/powerpc64/power4/fpu/slowexp.c: Remove.
+
+	* sysdeps/ieee754/dbl-64/slowpow.c [USE_LONG_DOUBLE_FOR_MP]
+	(__slowpow): Use long double EXPL and LOGL functions to
+	compute POW.
+	* sysdeps/powerpc/powerpc32/power4/fpu/Makefile
+	(CPPFLAGS-slowpow.c): Define USE_LONG_DOUBLE_FOR_MP.
+	* sysdeps/powerpc/powerpc32/power4/fpu/slowpow.c: Remove.
+	* sysdeps/powerpc/powerpc64/power4/fpu/Makefile
+	(CPPFLAGS-slowpow.c): Define USE_LONG_DOUBLE_FOR_MP.
+	* sysdeps/powerpc/powerpc64/power4/fpu/slowpow.c: Remove.
+
+	* sysdeps/powerpc/powerpc32/power4/fpu/mpa.c (__mul): Use
+	intermediate variable to calculate exponent.
+	(__sqr): Likewise.
+	* sysdeps/powerpc/powerpc64/power4/fpu/mpa.c (__mul):
+	Likewise.
+	(__sqr): Likewise.
+
+	* sysdeps/ieee754/dbl-64/mpa.c [!NO__MUL]: Define __mul.
+	[!NO__SQR]: Define __sqr.
+	* sysdeps/powerpc/powerpc32/power4/fpu/mpa.c: define NO__MUL
+	and NO__SQR.  Remove all code except __mul and __sqr.  Include
+	sysdeps/ieee754/dbl-64/mpa.c.
+	* sysdeps/powerpc/powerpc64/power4/fpu/mpa.c: Likewise.
+
+	[BZ #12723]
+	* posix/Makefile (tests): Add tst-pathconf.
+	* posix/tst-pathconf.c: New test case.
+	* sysdeps/unix/sysv/linux/fpathconf.c (__fpathconf): Remove
+	_PC_PIPE_BUF.
+	* sysdeps/unix/sysv/linux/pathconf.c (__pathconf): Likewise.
+
 2013-03-06  Patsy Franklin  <pfrankli@xxxxxxxxxx>
 
 	* io/fcntl.h: Added a comment about AT_EACCESS and AT_REMOVEDIR.

Modified: fsf/trunk/libc/NEWS
==============================================================================
--- fsf/trunk/libc/NEWS (original)
+++ fsf/trunk/libc/NEWS Fri Mar  8 00:03:58 2013
@@ -9,9 +9,9 @@
 
 * The following bugs are resolved with this release:
 
-  11561, 13550, 13951, 14142, 14200, 14317, 14327, 14496, 14920, 14964,
-  14981, 14982, 14985, 14994, 14996, 15003, 15006, 15020, 15023, 15036,
-  15054, 15055, 15062, 15078, 15160, 15232.
+  11561, 12723, 13550, 13951, 14142, 14200, 14317, 14327, 14496, 14920,
+  14964, 14981, 14982, 14985, 14994, 14996, 15003, 15006, 15020, 15023,
+  15036, 15054, 15055, 15062, 15078, 15160, 15232.
 
 * Add support for calling C++11 thread_local object destructors on thread
   and program exit.  This needs compiler support for offloading C++11

Modified: fsf/trunk/libc/ports/ChangeLog.aarch64
==============================================================================
--- fsf/trunk/libc/ports/ChangeLog.aarch64 (original)
+++ fsf/trunk/libc/ports/ChangeLog.aarch64 Fri Mar  8 00:03:58 2013
@@ -1,3 +1,8 @@
+2013-03-07  Andreas Jaeger  <aj@xxxxxxx>
+
+	* sysdeps/unix/sysv/linux/aarch64/bits/mman.h: Remove all defines
+	provided by bits/mman-linux.h and include <bits/mman-linux.h>.
+
 2013-02-18  Siddhesh Poyarekar  <siddhesh@xxxxxxxxxx>
 
 	* sysdeps/unix/sysv/linux/aarch64/nptl/libc.abilist: Add

Modified: fsf/trunk/libc/ports/ChangeLog.arm
==============================================================================
--- fsf/trunk/libc/ports/ChangeLog.arm (original)
+++ fsf/trunk/libc/ports/ChangeLog.arm Fri Mar  8 00:03:58 2013
@@ -1,3 +1,13 @@
+2013-03-06  Richard Henderson <rth@xxxxxxxxxx>
+
+	* sysdeps/arm/armv6/rawmemchr.S: New file.
+	* sysdeps/arm/armv6/stpcpy.S: New file.
+	* sysdeps/arm/armv6/strchr.S: New file.
+	* sysdeps/arm/armv6/strcpy.S: New file.
+	* sysdeps/arm/armv6/strlen.S: New file.
+	* sysdeps/arm/armv6/strrchr.S: New file.
+	* sysdeps/arm/armv6t2/Implies: New file.
+
 2013-03-06  Richard Henderson <rth@xxxxxxxxxx>
 
 	* sysdeps/arm/add_n.S: New file.

Added: fsf/trunk/libc/ports/sysdeps/arm/armv6/rawmemchr.S
==============================================================================
--- fsf/trunk/libc/ports/sysdeps/arm/armv6/rawmemchr.S (added)
+++ fsf/trunk/libc/ports/sysdeps/arm/armv6/rawmemchr.S Fri Mar  8 00:03:58 2013
@@ -1,0 +1,105 @@
+/* rawmemchr -- find a byte within an unsized memory block.
+   Copyright (C) 2013 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, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <sysdep.h>
+
+	.syntax unified
+	.text
+
+ENTRY (__rawmemchr)
+	@ r0 = start of string
+	@ r1 = character to match
+	@ returns a pointer to the match, which must be present.
+	ldrb	r2, [r0]		@ load first byte asap
+
+	@ To cater to long strings, we want to search through a few
+	@ characters until we reach an aligned pointer.  To cater to
+	@ small strings, we don't want to start doing word operations
+	@ immediately.  The compromise is a maximum of 16 bytes less
+	@ whatever is required to end with an aligned pointer.
+	@ r3 = number of characters to search in alignment loop
+	and	r3, r0, #7
+	uxtb	r1, r1
+	rsb	r3, r3, #15		@ 16 - 1 peeled loop iteration
+	cmp	r2, r1
+	it	eq
+	bxeq	lr
+
+	@ Loop until we find ...
+1:	ldrb	r2, [r0, #1]!
+	subs	r3, r3, #1		@ ... the alignment point
+	it	ne
+	cmpne	r2, r1			@ ... or C
+	bne	1b
+
+	@ Disambiguate the exit possibilites above
+	cmp	r2, r1			@ Found C
+	it	eq
+	bxeq	lr
+	add	r0, r0, #1
+
+	@ So now we're aligned.
+	ldrd	r2, r3, [r0], #8
+	orr	r1, r1, r1, lsl #8	@ Replicate C to all bytes
+#ifdef ARCH_HAS_T2
+	movw	ip, #0x0101
+	pld	[r0, #64]
+	movt	ip, #0x0101
+#else
+	ldr	ip, =0x01010101
+	pld	[r0, #64]
+#endif
+	orr	r1, r1, r1, lsl #16
+
+	@ Loop searching for C, 8 bytes at a time.
+	@ Subtracting (unsigned saturating) from 1 means result of 1 for
+	@ any byte that was originally zero and 0 otherwise.  Therefore
+	@ we consider the lsb of each byte the "found" bit.
+2:	eor	r2, r2, r1		@ Convert C bytes to 0
+	eor	r3, r3, r1
+	uqsub8	r2, ip, r2		@ Find C
+	uqsub8	r3, ip, r3
+	pld	[r0, #128]
+	orrs	r3, r3, r2		@ Test both words for found
+	it	eq
+	ldrdeq	r2, r3, [r0], #8
+	beq	2b
+
+	@ Found something.  Disambiguate between first and second words.
+	@ Adjust r0 to point to the word containing the match.
+	@ Adjust r2 to the found bits for the word containing the match.
+	cmp	r2, #0
+	sub	r0, r0, #4
+	ite	eq
+	moveq	r2, r3
+	subne	r0, r0, #4
+
+	@ Find the bit-offset of the match within the word.  Note that the
+	@ bit result from clz will be 7 higher than "true", but we'll
+	@ immediately discard those bits converting to a byte offset.
+#ifdef __ARMEL__
+	rev	r2, r2			@ For LE, count from the little end
+#endif
+	clz	r2, r2
+	add	r0, r0, r2, lsr #3	@ Adjust the pointer to the found byte
+	bx	lr
+
+END (__rawmemchr)
+
+weak_alias (__rawmemchr, rawmemchr)
+libc_hidden_def (__rawmemchr)

Added: fsf/trunk/libc/ports/sysdeps/arm/armv6/stpcpy.S
==============================================================================
--- fsf/trunk/libc/ports/sysdeps/arm/armv6/stpcpy.S (added)
+++ fsf/trunk/libc/ports/sysdeps/arm/armv6/stpcpy.S Fri Mar  8 00:03:58 2013
@@ -1,0 +1,1 @@
+/* Defined in strcpy.S.  */

Added: fsf/trunk/libc/ports/sysdeps/arm/armv6/strchr.S
==============================================================================
--- fsf/trunk/libc/ports/sysdeps/arm/armv6/strchr.S (added)
+++ fsf/trunk/libc/ports/sysdeps/arm/armv6/strchr.S Fri Mar  8 00:03:58 2013
@@ -1,0 +1,143 @@
+/* strchr -- find the first instance of C in a nul-terminated string.
+   Copyright (C) 2013 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, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <sysdep.h>
+
+	.syntax unified
+	.text
+
+ENTRY (strchr)
+	@ r0 = start of string
+	@ r1 = character to match
+	@ returns NULL for no match, or a pointer to the match
+	ldrb	r2, [r0]		@ load the first byte asap
+	uxtb	r1, r1
+
+	@ To cater to long strings, we want to search through a few
+	@ characters until we reach an aligned pointer.  To cater to
+	@ small strings, we don't want to start doing word operations
+	@ immediately.  The compromise is a maximum of 16 bytes less
+	@ whatever is required to end with an aligned pointer.
+	@ r3 = number of characters to search in alignment loop
+	and	r3, r0, #7
+	rsb	r3, r3, #15		@ 16 - 1 peeled loop iteration
+	cmp	r2, r1			@ Found C?
+	it	ne
+	cmpne	r2, #0			@ Found EOS?
+	beq	99f
+
+	@ Loop until we find ...
+1:	ldrb	r2, [r0, #1]!
+	subs	r3, r3, #1		@ ... the aligment point
+	it	ne
+	cmpne	r2, r1			@ ... or the character
+	it	ne
+	cmpne	r2, #0			@ ... or EOS
+	bne	1b
+
+	@ Disambiguate the exit possibilites above
+	cmp	r2, r1			@ Found the character
+	it	ne
+	cmpne	r2, #0			@ Found EOS
+	beq	99f
+	add	r0, r0, #1
+
+	@ So now we're aligned.  Now we actually need a stack frame.
+	push	{ r4, r5, r6, r7 }
+	cfi_adjust_cfa_offset (16)
+	cfi_rel_offset (r4, 0)
+	cfi_rel_offset (r5, 4)
+	cfi_rel_offset (r6, 8)
+	cfi_rel_offset (r7, 12)
+
+	ldrd	r2, r3, [r0], #8
+	orr	r1, r1, r1, lsl #8	@ Replicate C to all bytes
+#ifdef ARCH_HAS_T2
+	movw	ip, #0x0101
+	pld	[r0, #64]
+	movt	ip, #0x0101
+#else
+	ldr	ip, =0x01010101
+	pld	[r0, #64]
+#endif
+	orr	r1, r1, r1, lsl #16
+
+	@ Loop searching for EOS or C, 8 bytes at a time.
+2:
+	@ Subtracting (unsigned saturating) from 1 means result of 1 for
+	@ any byte that was originally zero and 0 otherwise.  Therefore
+	@ we consider the lsb of each byte the "found" bit.
+	uqsub8	r4, ip, r2		@ Find EOS
+	eor	r6, r2, r1		@ Convert C bytes to 0
+	uqsub8	r5, ip, r3
+	eor	r7, r3, r1
+	uqsub8	r6, ip, r6		@ Find C
+	pld	[r0, #128]		@ Prefetch 2 lines ahead
+	uqsub8	r7, ip, r7
+	orr	r4, r4, r6		@ Combine found for EOS and C
+	orr	r5, r5, r7
+	orrs	r6, r4, r5		@ Combine the two words
+	it	eq
+	ldrdeq	r2, r3, [r0], #8
+	beq	2b
+
+	@ Found something.  Disambiguate between first and second words.
+	@ Adjust r0 to point to the word containing the match.
+	@ Adjust r2 to the contents of the word containing the match.
+	@ Adjust r4 to the found bits for the word containing the match.
+	cmp	r4, #0
+	sub	r0, r0, #4
+	itte	eq
+	moveq	r4, r5
+	moveq	r2, r3
+	subne	r0, r0, #4
+
+	@ Find the bit-offset of the match within the word.
+#if defined(__ARMEL__)
+	@ For LE, swap the found word so clz searches from the little end.
+	rev	r4, r4
+#else
+	@ For BE, byte swap the word to make it easier to extract the byte.
+	rev	r2, r2
+#endif
+	@ We're counting 0x01 (not 0x80), so the bit offset is 7 too high.
+	clz	r3, r4
+	sub	r3, r3, #7
+	lsr	r2, r2, r3		@ Shift down found byte
+	uxtb	r1, r1			@ Undo replication of C
+	uxtb	r2, r2			@ Extract found byte
+	add	r0, r0, r3, lsr #3	@ Adjust the pointer to the found byte
+
+	pop	{ r4, r5, r6, r7 }
+	cfi_adjust_cfa_offset (-16)
+	cfi_restore (r4)
+	cfi_restore (r5)
+	cfi_restore (r6)
+	cfi_restore (r7)
+
+	@ Disambiguate between EOS and C.
+99:
+	cmp	r2, r1
+	it	ne
+	movne	r0, #0			@ Found EOS, return NULL
+	bx	lr
+
+END (strchr)
+
+weak_alias (strchr, index)
+libc_hidden_builtin_def (strchr)

Added: fsf/trunk/libc/ports/sysdeps/arm/armv6/strcpy.S
==============================================================================
--- fsf/trunk/libc/ports/sysdeps/arm/armv6/strcpy.S (added)
+++ fsf/trunk/libc/ports/sysdeps/arm/armv6/strcpy.S Fri Mar  8 00:03:58 2013
@@ -1,0 +1,218 @@
+/* strcpy -- copy a nul-terminated string.
+   Copyright (C) 2013 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, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <sysdep.h>
+
+/* Endian independent macros for shifting bytes within registers.  */
+#ifdef __ARMEB__
+#define lsh_gt		lsr
+#define lsh_ls		lsl
+#else
+#define lsh_gt		lsl
+#define lsh_ls		lsr
+#endif
+
+	.syntax unified
+	.text
+
+ENTRY (__stpcpy)
+	@ Signal stpcpy with NULL in IP.
+	mov	ip, #0
+	b	0f
+END (__stpcpy)
+
+weak_alias (__stpcpy, stpcpy)
+libc_hidden_def (__stpcpy)
+libc_hidden_builtin_def (stpcpy)
+
+ENTRY (strcpy)
+	@ Signal strcpy with DEST in IP.
+	mov	ip, r0
+0:
+	pld	[r0]
+	pld	[r1]
+
+	@ To cater to long strings, we want 8 byte alignment in the source.
+	@ To cater to small strings, we don't want to start that right away.
+	@ Loop up to 16 times, less whatever it takes to reach alignment.
+	and	r3, r1, #7
+	rsb	r3, r3, #16
+
+	@ Loop until we find ...
+1:	ldrb	r2, [r1], #1
+	subs	r3, r3, #1		@ ... the alignment point
+	strb	r2, [r0], #1
+	it	ne
+	cmpne	r2, #0			@ ... or EOS
+	bne	1b
+
+	@ Disambiguate the exit possibilites above
+	cmp	r2, #0			@ Found EOS
+	beq	.Lreturn
+
+	@ Load the next two words asap
+	ldrd	r2, r3, [r1], #8
+	pld	[r0, #64]
+	pld	[r1, #64]
+
+	@ For longer strings, we actaully need a stack frame.
+	push	{ r4, r5, r6, r7 }
+	cfi_adjust_cfa_offset (16)
+	cfi_rel_offset (r4, 0)
+	cfi_rel_offset (r5, 4)
+	cfi_rel_offset (r6, 8)
+	cfi_rel_offset (r7, 12)
+
+	@ Subtracting (unsigned saturating) from 1 for any byte means result
+	@ of 1 for any byte that was originally zero and 0 otherwise.
+	@ Therefore we consider the lsb of each byte the "found" bit.
+#ifdef ARCH_HAS_T2
+	movw	r7, #0x0101
+	tst	r0, #3			@ Test alignment of DEST
+	movt	r7, #0x0101
+#else
+	ldr	ip, =0x01010101
+	tst	r0, #3
+#endif
+	bne	.Lunaligned
+
+	@ So now source (r1) is aligned to 8, and dest (r0) is aligned to 4.
+	@ Loop, reading 8 bytes at a time, searching for EOS.
+	.balign	16
+2:	uqsub8	r4, r7, r2		@ Find EOS
+	uqsub8	r5, r7, r3
+	pld	[r1, #128]
+	cmp	r4, #0			@ EOS in first word?
+	pld	[r0, #128]
+	bne	3f
+	str	r2, [r0], #4
+	cmp	r5, #0			@ EOS in second word?
+	bne	4f
+	str	r3, [r0], #4
+	ldrd	r2, r3, [r1], #8
+	b	2b
+
+3:	sub	r1, r1, #4		@ backup to first word
+4:	sub	r1, r1, #4		@ backup to second word
+
+	@ ... then finish up any tail a byte at a time.
+	@ Note that we generally back up and re-read source bytes,
+	@ but we'll not re-write dest bytes.
+.Lbyte_loop:
+	ldrb	r2, [r1], #1
+	cmp	r2, #0
+	strb	r2, [r0], #1
+	bne	.Lbyte_loop
+
+	pop	{ r4, r5, r6, r7 }
+	cfi_remember_state
+	cfi_adjust_cfa_offset (-16)
+	cfi_restore (r4)
+	cfi_restore (r5)
+	cfi_restore (r6)
+	cfi_restore (r7)
+
+.Lreturn:
+	cmp	ip, #0			@ Was this strcpy or stpcpy?
+	ite	eq
+	subeq	r0, r0, #1		@ stpcpy: undo post-inc from store
+	movne	r0, ip			@ strcpy: return original dest
+	bx	lr
+
+.Lunaligned:
+	cfi_restore_state
+	@ Here, source is aligned to 8, but the destination is not word
+	@ aligned.  Therefore we have to shift the data in order to be
+	@ able to perform aligned word stores.
+
+	@ Find out which misalignment we're dealing with.
+	tst	r0, #1
+	beq	.Lunaligned2
+	tst	r0, #2
+	bne	.Lunaligned3
+	@ Fallthru to .Lunaligned1.
+
+.macro unaligned_copy	unalign
+	@ Prologue to unaligned loop.  Seed shifted non-zero bytes.
+	uqsub8	r4, r7, r2		@ Find EOS
+	uqsub8	r5, r7, r3
+	mvns	r4, r4			@ EOS in first word?
+	it	ne
+	subne	r1, r1, #8
+	bne	.Lbyte_loop
+#ifdef __ARMEB__
+	rev	r2, r2			@ Byte stores below need LE data
+#endif
+	@ Store a few bytes from the first word.
+	@ At the same time we align r0 and shift out bytes from r2.
+.rept	4-\unalign
+	strb	r2, [r0], #1
+	lsr	r2, r2, #8
+.endr
+#ifdef __ARMEB__
+	rev	r2, r2			@ Undo previous rev
+#endif
+	@ Rotated unaligned copy loop.  The tail of the prologue is
+	@ shared with the loop itself.
+	.balign 8
+1:	mvns	r5, r5			@ EOS in second word?
+	bne	4f
+	@ Combine first and second words
+	orr	r2, r2, r3, lsh_gt #(\unalign*8)
+	@ Save leftover bytes from the two words
+	lsh_ls	r6, r3, #((4-\unalign)*8)
+	str	r2, [r0], #4
+	@ The "real" start of the unaligned copy loop.
+	ldrd	r2, r3, [r1], #8	@ Load 8 more bytes
+	uqsub8	r4, r7, r2		@ Find EOS
+	pld	[r1, #128]
+	uqsub8	r5, r7, r3
+	pld	[r0, #128]
+	mvns	r4, r4			@ EOS in first word?
+	bne	3f
+	@ Combine the leftover and the first word
+	orr	r6, r6, r2, lsh_gt #(\unalign*8)
+	@ Discard used bytes from the first word.
+	lsh_ls	r2, r2, #((4-\unalign)*8)
+	str	r6, [r0], #4
+	b	1b
+	@ Found EOS in one of the words; adjust backward
+3:	sub	r1, r1, #4
+	mov	r2, r6
+4:	sub	r1, r1, #4
+	@ And store the remaining bytes from the leftover
+#ifdef __ARMEB__
+	rev	r2, r2
+#endif
+.rept	\unalign
+	strb	r2, [r0], #1
+	lsr	r2, r2, #8
+.endr
+	b	.Lbyte_loop
+.endm
+
+.Lunaligned1:
+	unaligned_copy	1
+.Lunaligned2:
+	unaligned_copy	2
+.Lunaligned3:
+	unaligned_copy	3
+
+END (strcpy)
+
+libc_hidden_builtin_def (strcpy)

Added: fsf/trunk/libc/ports/sysdeps/arm/armv6/strlen.S
==============================================================================
--- fsf/trunk/libc/ports/sysdeps/arm/armv6/strlen.S (added)
+++ fsf/trunk/libc/ports/sysdeps/arm/armv6/strlen.S Fri Mar  8 00:03:58 2013
@@ -1,0 +1,99 @@
+/* strlen -- find the length of a nul-terminated string.
+   Copyright (C) 2013 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, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <sysdep.h>
+
+	.syntax unified
+	.text
+
+ENTRY (strlen)
+	@ r0 = start of string
+	ldrb	r2, [r0]		@ load the first byte asap
+
+	@ To cater to long strings, we want to search through a few
+	@ characters until we reach an aligned pointer.  To cater to
+	@ small strings, we don't want to start doing word operations
+	@ immediately.  The compromise is a maximum of 16 bytes less
+	@ whatever is required to end with an aligned pointer.
+	@ r3 = number of characters to search in alignment loop
+	and	r3, r0, #7
+	mov	r1, r0			@ Save the input pointer
+	rsb	r3, r3, #15		@ 16 - 1 peeled loop iteration
+	cmp	r2, #0
+	beq	99f
+
+	@ Loop until we find ...
+1:	ldrb	r2, [r0, #1]!
+	subs	r3, r3, #1		@ ... the aligment point
+	it	ne
+	cmpne	r2, #0			@ ... or EOS
+	bne	1b
+
+	@ Disambiguate the exit possibilites above
+	cmp	r2, #0			@ Found EOS
+	beq	99f
+	add	r0, r0, #1
+
+	@ So now we're aligned.
+	ldrd	r2, r3, [r0], #8
+#ifdef ARCH_HAS_T2
+	movw	ip, #0x0101
+	pld	[r0, #64]
+	movt	ip, #0x0101
+#else
+	ldr	ip, =0x01010101
+	pld	[r0, #64]
+#endif
+
+	@ Loop searching for EOS, 8 bytes at a time.
+	@ Subtracting (unsigned saturating) from 1 for any byte means that
+	@ we get 1 for any byte that was originally zero and 0 otherwise.
+	@ Therefore we consider the lsb of each byte the "found" bit.
+	.balign	16
+2:	uqsub8	r2, ip, r2		@ Find EOS
+	uqsub8	r3, ip, r3
+	pld	[r0, #128]		@ Prefetch 2 lines ahead
+	orrs	r3, r3, r2		@ Combine the two words
+	it	eq
+	ldrdeq	r2, r3, [r0], #8
+	beq	2b
+
+	@ Found something.  Disambiguate between first and second words.
+	@ Adjust r0 to point to the word containing the match.
+	@ Adjust r2 to the found bits for the word containing the match.
+	cmp	r2, #0
+	sub	r0, r0, #4
+	ite	eq
+	moveq	r2, r3
+	subne	r0, r0, #4
+
+	@ Find the bit-offset of the match within the word.  Note that the
+	@ bit result from clz will be 7 higher than "true", but we'll
+	@ immediately discard those bits converting to a byte offset.
+#ifdef __ARMEL__
+	rev	r2, r2			@ For LE, count from the little end
+#endif
+	clz	r2, r2
+	add	r0, r0, r2, lsr #3	@ Adjust the pointer to the found byte
+99:
+	sub	r0, r0, r1		@ Subtract input to compute length
+	bx	lr
+
+END (strlen)
+
+libc_hidden_builtin_def (strlen)

Added: fsf/trunk/libc/ports/sysdeps/arm/armv6/strrchr.S
==============================================================================
--- fsf/trunk/libc/ports/sysdeps/arm/armv6/strrchr.S (added)
+++ fsf/trunk/libc/ports/sysdeps/arm/armv6/strrchr.S Fri Mar  8 00:03:58 2013
@@ -1,0 +1,129 @@
+/* strrchr -- find the last occurence of C in a nul-terminated string
+   Copyright (C) 2013 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, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <sysdep.h>
+
+	.syntax unified
+	.text
+
+ENTRY (strrchr)
+	@ r0 = start of string
+	@ r1 = character to match
+	@ returns NULL for no match, or a pointer to the match
+
+	mov	r3, r0
+	mov	r0, #0
+	uxtb	r1, r1
+
+	@ Loop a few times until we're aligned.
+	tst	r3, #7
+	beq	2f
+1:	ldrb	r2, [r3], #1
+	cmp	r2, r1			@ Find the character
+	it	eq
+	subeq	r0, r3, #1
+	cmp	r2, #0			@ Find EOS
+	it	eq
+	bxeq	lr
+	tst	r3, #7			@ Find the aligment point
+	bne	1b
+
+	@ So now we're aligned.  Now we actually need a stack frame.
+2:	push	{ r4, r5, r6, r7 }
+	cfi_adjust_cfa_offset (16)
+	cfi_rel_offset (r4, 0)
+	cfi_rel_offset (r5, 4)
+	cfi_rel_offset (r6, 8)
+	cfi_rel_offset (r7, 12)
+
+	orr	r1, r1, r1, lsl #8	@ Replicate C to all bytes
+#ifdef ARCH_HAS_T2
+	movw	ip, #0x0101
+	movt	ip, #0x0101
+#else
+	ldr	ip, =0x01010101
+#endif
+	orr	r1, r1, r1, lsl #16
+	mov	r2, #0			@ No found bits yet
+
+	@ Loop searching for EOS and C, 8 bytes at a time.
+	@ Any time we find a match in a word, we copy the address of
+	@ the word to r0, and the found bits to r2.
+3:	ldrd	r4, r5, [r3], #8
+	@ Subtracting (unsigned saturating) from 1 means result of 1 for
+	@ any byte that was originally zero and 0 otherwise.  Therefore
+	@ we consider the lsb of each byte the "found" bit.
+	uqsub8	r6, ip, r4		@ Find EOS
+	uqsub8	r7, ip, r5
+	eor	r4, r4, r1		@ Convert C bytes to 0
+	eor	r5, r5, r1
+	uqsub8	r4, ip, r4		@ Find C
+	uqsub8	r5, ip, r5
+	cmp	r6, #0			@ Found EOS, first word
+	bne	4f
+	cmp	r4, #0			@ Handle C, first word
+	itt	ne
+	subne	r0, r3, #8
+	movne	r2, r4
+	cmp	r7, #0			@ Found EOS, second word
+	bne	5f
+	cmp	r5, #0			@ Handle C, second word
+	itt	ne
+	subne	r0, r3, #4
+	movne	r2, r5
+	b	3b
+
+	@ Found EOS in second word; fold to first word.
+5:	add	r3, r3, #4		@ Dec pointer to 2nd word, with below
+	mov	r4, r5			@ Overwrite first word C found
+	mov	r6, r7			@ Overwrite first word EOS found
+
+	@ Found EOS.  Zap found C after EOS.
+4:	sub	r3, r3, #8		@ Decrement pointer to first word
+#ifdef __ARMEB__
+	@ Byte swap to be congruent with LE, which is easier from here on.
+	rev	r6, r6			@ Byte swap found EOS,
+	rev	r4, r4			@ ... this found C
+	rev	r2, r2			@ ... prev found C
+#endif
+	sub	r7, r6, #1		@ Toggle EOS lsb and below
+	eor	r6, r6, r7		@ All bits below and including lsb
+	ands	r4, r4, r6		@ Zap C above EOS
+	itt	ne
+	movne	r2, r4			@ Copy to result, if still non-zero
+	movne	r0, r3
+
+	pop	{ r4, r5, r6, r7 }
+	cfi_adjust_cfa_offset (-16)
+	cfi_restore (r4)
+	cfi_restore (r5)
+	cfi_restore (r6)
+	cfi_restore (r7)
+
+	@ Adjust the result pointer if we found a word containing C.
+	cmp	r2, #0
+	clz	r2, r2			@ Find the bit offset of the last C
+	itt	ne
+	rsbne	r2, r2, #32		@ Convert to a count from the right
+	addne	r0, r0, r2, lsr #3	@ Convert to byte offset and add.
+	bx	lr
+
+END (strrchr)
+
+weak_alias (strrchr, rindex)
+libc_hidden_builtin_def (strrchr)

Added: fsf/trunk/libc/ports/sysdeps/arm/armv6t2/Implies
==============================================================================
--- fsf/trunk/libc/ports/sysdeps/arm/armv6t2/Implies (added)
+++ fsf/trunk/libc/ports/sysdeps/arm/armv6t2/Implies Fri Mar  8 00:03:58 2013
@@ -1,0 +1,2 @@
+# We can do everything that 6 can
+arm/armv6

Modified: fsf/trunk/libc/ports/sysdeps/unix/sysv/linux/aarch64/bits/mman.h
==============================================================================
--- fsf/trunk/libc/ports/sysdeps/unix/sysv/linux/aarch64/bits/mman.h (original)
+++ fsf/trunk/libc/ports/sysdeps/unix/sysv/linux/aarch64/bits/mman.h Fri Mar  8 00:03:58 2013
@@ -25,38 +25,8 @@
 /* The following definitions basically come from the kernel headers.
    But the kernel header is not namespace clean.  */
 
-
-/* Protections are chosen from these bits, OR'd together.  The
-   implementation does not necessarily support PROT_EXEC or PROT_WRITE
-   without PROT_READ.  The only guarantees are that no writing will be
-   allowed without PROT_WRITE and no access will be allowed for PROT_NONE. */
-
-#define PROT_READ	0x1		/* Page can be read.  */
-#define PROT_WRITE	0x2		/* Page can be written.  */
-#define PROT_EXEC	0x4		/* Page can be executed.  */
-#define PROT_NONE	0x0		/* Page can not be accessed.  */
-#define PROT_GROWSDOWN	0x01000000	/* Extend change to start of
-					   growsdown vma (mprotect only).  */
-#define PROT_GROWSUP	0x02000000	/* Extend change to start of
-					   growsup vma (mprotect only).  */
-
-/* Sharing types (must choose one and only one of these).  */
-#define MAP_SHARED	0x01		/* Share changes.  */
-#define MAP_PRIVATE	0x02		/* Changes are private.  */
+/* These are Linux-specific.  */
 #ifdef __USE_MISC
-# define MAP_TYPE	0x0f		/* Mask for type of mapping.  */
-#endif
-
-/* Other flags.  */
-#define MAP_FIXED	0x10		/* Interpret addr exactly.  */
-#ifdef __USE_MISC
-# define MAP_FILE	0
-# define MAP_ANONYMOUS	0x20		/* Don't use a file.  */
-# define MAP_ANON	MAP_ANONYMOUS
-#endif
-
-#ifdef __USE_MISC
-/* These are Linux-specific.  */
 # define MAP_GROWSDOWN	0x00100		/* Stack-like segment.  */
 # define MAP_DENYWRITE	0x00800		/* ETXTBSY */
 # define MAP_EXECUTABLE	0x01000		/* Mark it as an executable.  */
@@ -68,47 +38,7 @@
 # define MAP_HUGETLB	0x40000		/* Create huge page mapping.  */
 #endif
 
-/* Flags to `msync'.  */
-#define MS_ASYNC	1		/* Sync memory asynchronously.  */
-#define MS_SYNC		4		/* Synchronous memory sync.  */
-#define MS_INVALIDATE	2		/* Invalidate the caches.  */
 
-/* Flags for `mlockall'.  */
-#define MCL_CURRENT	1		/* Lock all currently mapped pages.  */
-#define MCL_FUTURE	2		/* Lock all additions to address
-					   space.  */
 
-/* Flags for `mremap'.  */
-#ifdef __USE_GNU
-# define MREMAP_MAYMOVE	1
-# define MREMAP_FIXED	2
-#endif
-
-/* Advice to `madvise'.  */
-#ifdef __USE_BSD
-# define MADV_NORMAL	  0	/* No further special treatment.  */
-# define MADV_RANDOM	  1	/* Expect random page references.  */
-# define MADV_SEQUENTIAL  2	/* Expect sequential page references.  */
-# define MADV_WILLNEED	  3	/* Will need these pages.  */
-# define MADV_DONTNEED	  4	/* Don't need these pages.  */
-# define MADV_REMOVE	  9	/* Remove these pages and resources.  */
-# define MADV_DONTFORK	  10	/* Do not inherit across fork.  */
-# define MADV_DOFORK	  11	/* Do inherit across fork.  */
-# define MADV_MERGEABLE	  12	/* KSM may merge identical pages.  */
-# define MADV_UNMERGEABLE 13	/* KSM may not merge identical pages.  */
-# define MADV_HUGEPAGE	  14	/* Worth backing with hugepages.  */
-# define MADV_NOHUGEPAGE  15	/* Not worth backing with hugepages.  */
-# define MADV_DONTDUMP	  16	/* Explicity exclude from the core dump,
-				   overrides the coredump filter bits.  */
-# define MADV_DODUMP	  17	/* Clear the MADV_DONTDUMP flag.  */
-# define MADV_HWPOISON	  100	/* Poison a page for testing.  */
-#endif
-
-/* The POSIX people had to invent similar names for the same things.  */
-#ifdef __USE_XOPEN2K
-# define POSIX_MADV_NORMAL	0 /* No further special treatment.  */
-# define POSIX_MADV_RANDOM	1 /* Expect random page references.  */
-# define POSIX_MADV_SEQUENTIAL	2 /* Expect sequential page references.  */
-# define POSIX_MADV_WILLNEED	3 /* Will need these pages.  */
-# define POSIX_MADV_DONTNEED	4 /* Don't need these pages.  */
-#endif
+/* Include generic Linux declarations.  */
+#include <bits/mman-linux.h>

Modified: fsf/trunk/libc/posix/Makefile
==============================================================================
--- fsf/trunk/libc/posix/Makefile (original)
+++ fsf/trunk/libc/posix/Makefile Fri Mar  8 00:03:58 2013
@@ -86,7 +86,8 @@
 		   tst-rfc3484-3 \
 		   tst-getaddrinfo3 tst-fnmatch2 tst-cpucount tst-cpuset \
 		   bug-getopt1 bug-getopt2 bug-getopt3 bug-getopt4 \
-		   bug-getopt5 tst-getopt_long1 bug-regex34 bug-regex35
+		   bug-getopt5 tst-getopt_long1 bug-regex34 bug-regex35 \
+		   tst-pathconf
 xtests		:= bug-ga2
 ifeq (yes,$(build-shared))
 test-srcs	:= globtest

Added: fsf/trunk/libc/posix/tst-pathconf.c
==============================================================================
--- fsf/trunk/libc/posix/tst-pathconf.c (added)
+++ fsf/trunk/libc/posix/tst-pathconf.c Fri Mar  8 00:03:58 2013
@@ -1,0 +1,176 @@
+/* Test that values of pathconf and fpathconf are consistent for a file.
+   Copyright (C) 2013 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, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+
+static void prepare (void);
+#define PREPARE(argc, argv) prepare ()
+
+static int do_test (void);
+#define TEST_FUNCTION do_test ()
+
+#include "../test-skeleton.c"
+
+static int dir_fd;
+static char *dirbuf;
+
+static void
+prepare (void)
+{
+  size_t test_dir_len = strlen (test_dir);
+  static const char dir_name[] = "/tst-pathconf.XXXXXX";
+
+  size_t dirbuflen = test_dir_len + sizeof (dir_name);
+  dirbuf = malloc (dirbuflen);
+  if (dirbuf == NULL)
+    {
+      puts ("Out of memory");
+      exit (1);
+    }
+
+  snprintf (dirbuf, dirbuflen, "%s%s", test_dir, dir_name);
+  if (mkdtemp (dirbuf) == NULL)
+    {
+      printf ("Cannot create temporary directory: %s\n", strerror (errno));
+      exit (1);
+    }
+
+  add_temp_file (dirbuf);
+
+  dir_fd = open (dirbuf, O_RDONLY);
+  if (dir_fd == -1)
+    {
+      printf ("Cannot open directory: %s\n", strerror (errno));
+      exit (1);
+    }
+}
+
+
+static int
+do_test (void)
+{
+  int ret = 0;
+  static const char *fifo_name = "some-fifo";
+
+  size_t filenamelen = strlen (dirbuf) + strlen (fifo_name) + 2;
+  char *filename = malloc (filenamelen);
+
+  snprintf (filename, filenamelen, "%s/%s", dirbuf, fifo_name);
+
+  /* Create a fifo in the directory.  */
+  int e = mkfifo (filename, 0777);
+  if (e == -1)
+    {
+      printf ("fifo creation failed (%s)\n", strerror (errno));
+      ret = 1;
+      goto out_nofifo;
+    }
+
+  long dir_pathconf = pathconf (dirbuf, _PC_PIPE_BUF);
+
+  if (dir_pathconf < 0)
+    {
+      printf ("pathconf on directory failed: %s\n", strerror (errno));
+      ret = 1;
+      goto out_nofifo;
+    }
+
+  long fifo_pathconf = pathconf (filename, _PC_PIPE_BUF);
+
+  if (fifo_pathconf < 0)
+    {
+      printf ("pathconf on file failed: %s\n", strerror (errno));
+      ret = 1;
+      goto out_nofifo;
+    }
+
+  int fifo = open (filename, O_RDONLY | O_NONBLOCK);
+
+  if (fifo < 0)
+    {
+      printf ("fifo open failed (%s)\n", strerror (errno));
+      ret = 1;
+      goto out_nofifo;
+    }
+
+  long dir_fpathconf = fpathconf (dir_fd, _PC_PIPE_BUF);
+
+  if (dir_fpathconf < 0)
+    {
+      printf ("fpathconf on directory failed: %s\n", strerror (errno));
+      ret = 1;
+      goto out;
+    }
+
+  long fifo_fpathconf = fpathconf (fifo, _PC_PIPE_BUF);
+
+  if (fifo_fpathconf < 0)
+    {
+      printf ("fpathconf on file failed: %s\n", strerror (errno));
+      ret = 1;
+      goto out;
+    }
+
+  if (fifo_pathconf != fifo_fpathconf)
+    {
+      printf ("fifo pathconf (%ld) != fifo fpathconf (%ld)\n", fifo_pathconf,
+	      fifo_fpathconf);
+      ret = 1;
+      goto out;
+    }
+
+  if (dir_pathconf != fifo_pathconf)
+    {
+      printf ("directory pathconf (%ld) != fifo pathconf (%ld)\n",
+	      dir_pathconf, fifo_pathconf);
+      ret = 1;
+      goto out;
+    }
+
+  if (dir_fpathconf != fifo_fpathconf)
+    {
+      printf ("directory fpathconf (%ld) != fifo fpathconf (%ld)\n",
+	      dir_fpathconf, fifo_fpathconf);
+      ret = 1;
+      goto out;
+    }
+
+out:
+  close (fifo);
+out_nofifo:
+  close (dir_fd);
+
+  if (unlink (filename) != 0)
+    {
+      printf ("Could not remove fifo (%s)\n", strerror (errno));
+      ret = 1;
+    }
+
+  if (rmdir (dirbuf) != 0)
+    {
+      printf ("Could not remove directory (%s)\n", strerror (errno));
+      ret = 1;
+    }
+
+  return ret;
+}

Modified: fsf/trunk/libc/sysdeps/ieee754/dbl-64/mpa.c
==============================================================================
--- fsf/trunk/libc/sysdeps/ieee754/dbl-64/mpa.c (original)
+++ fsf/trunk/libc/sysdeps/ieee754/dbl-64/mpa.c Fri Mar  8 00:03:58 2013
@@ -611,6 +611,7 @@
     }
 }
 
+#ifndef NO__MUL
 /* Multiply *X and *Y and store result in *Z.  X and Y may overlap but not X
    and Z or Y and Z.  For P in [1, 2, 3], the exact result is truncated to P
    digits.  In case P > 3 the error is bounded by 1.001 ULP.  */
@@ -761,7 +762,9 @@
   EZ = e;
   Z[0] = X[0] * Y[0];
 }
-
+#endif
+
+#ifndef NO__SQR
 /* Square *X and store result in *Y.  X and Y may not overlap.  For P in
    [1, 2, 3], the exact result is truncated to P digits.  In case P > 3 the
    error is bounded by 1.001 ULP.  This is a faster special case of
@@ -862,6 +865,7 @@
 
   EY = e;
 }
+#endif
 
 /* Invert *X and store in *Y.  Relative error bound:
    - For P = 2: 1.001 * R ^ (1 - P)

Modified: fsf/trunk/libc/sysdeps/ieee754/dbl-64/slowexp.c
==============================================================================
--- fsf/trunk/libc/sysdeps/ieee754/dbl-64/slowexp.c (original)
+++ fsf/trunk/libc/sysdeps/ieee754/dbl-64/slowexp.c Fri Mar  8 00:03:58 2013
@@ -27,20 +27,23 @@
 /*Converting from double precision to Multi-precision and calculating     */
 /* e^x                                                                    */
 /**************************************************************************/
-#include "mpa.h"
 #include <math_private.h>
+
+#ifndef USE_LONG_DOUBLE_FOR_MP
+# include "mpa.h"
+void __mpexp (mp_no *x, mp_no *y, int p);
+#endif
 
 #ifndef SECTION
 # define SECTION
 #endif
-
-void __mpexp (mp_no *x, mp_no *y, int p);
 
 /*Converting from double precision to Multi-precision and calculating  e^x */
 double
 SECTION
 __slowexp (double x)
 {
+#ifndef USE_LONG_DOUBLE_FOR_MP
   double w, z, res, eps = 3.0e-26;
   int p;
   mp_no mpx, mpy, mpz, mpw, mpeps, mpcor;
@@ -66,4 +69,7 @@
       __mp_dbl (&mpy, &res, p);
       return res;
     }
+#else
+  return (double) __ieee754_expl((long double)x);
+#endif
 }

Modified: fsf/trunk/libc/sysdeps/ieee754/dbl-64/slowpow.c
==============================================================================
--- fsf/trunk/libc/sysdeps/ieee754/dbl-64/slowpow.c (original)
+++ fsf/trunk/libc/sysdeps/ieee754/dbl-64/slowpow.c Fri Mar  8 00:03:58 2013
@@ -59,6 +59,23 @@
   if (res >= 0)
     return res;
 
+  /* Compute pow as long double.  This is currently only used by powerpc, where
+     one may get 106 bits of accuracy.  */
+#ifdef USE_LONG_DOUBLE_FOR_MP
+  long double ldw, ldz, ldpp;
+  static const long double ldeps = 0x4.0p-96;
+
+  ldz = __ieee754_logl ((long double) x);
+  ldw = (long double) y *ldz;
+  ldpp = __ieee754_expl (ldw);
+  res = (double) (ldpp + ldeps);
+  res1 = (double) (ldpp - ldeps);
+
+  /* Return the result if it is accurate enough.  */
+  if (res == res1)
+    return res;
+#endif
+
   /* Or else, calculate using multiple precision.  P = 10 implies accuracy of
      240 bits accuracy, since MP_NO has a radix of 2^24.  */
   p = 10;

Modified: fsf/trunk/libc/sysdeps/powerpc/powerpc32/power4/fpu/Makefile
==============================================================================
--- fsf/trunk/libc/sysdeps/powerpc/powerpc32/power4/fpu/Makefile (original)
+++ fsf/trunk/libc/sysdeps/powerpc/powerpc32/power4/fpu/Makefile Fri Mar  8 00:03:58 2013
@@ -2,4 +2,6 @@
 
 ifeq ($(subdir),math)
 CFLAGS-mpa.c += --param max-unroll-times=4 -funroll-loops -fpeel-loops
+CPPFLAGS-slowpow.c += -DUSE_LONG_DOUBLE_FOR_MP=1
+CPPFLAGS-slowexp.c += -DUSE_LONG_DOUBLE_FOR_MP=1
 endif

Modified: fsf/trunk/libc/sysdeps/powerpc/powerpc32/power4/fpu/mpa.c
==============================================================================
--- fsf/trunk/libc/sysdeps/powerpc/powerpc32/power4/fpu/mpa.c (original)
+++ fsf/trunk/libc/sysdeps/powerpc/powerpc32/power4/fpu/mpa.c Fri Mar  8 00:03:58 2013
@@ -17,582 +17,12 @@
  * You should have received a copy of the GNU Lesser General Public License
  * along with this program; if not, see <http://www.gnu.org/licenses/>.
  */
-/************************************************************************/
-/*  MODULE_NAME: mpa.c                                                  */
-/*                                                                      */
-/*  FUNCTIONS:                                                          */
-/*               mcr                                                    */
-/*               acr                                                    */
-/*               cpy                                                    */
-/*               norm                                                   */
-/*               denorm                                                 */
-/*               mp_dbl                                                 */
-/*               dbl_mp                                                 */
-/*               add_magnitudes                                         */
-/*               sub_magnitudes                                         */
-/*               add                                                    */
-/*               sub                                                    */
-/*               mul                                                    */
-/*               inv                                                    */
-/*               dvd                                                    */
-/*                                                                      */
-/* Arithmetic functions for multiple precision numbers.                 */
-/* Relative errors are bounded                                          */
-/************************************************************************/
-
-
-#include "endian.h"
-#include "mpa.h"
-#include <sys/param.h>
-
-const mp_no mpone = {1, {1.0, 1.0}};
-const mp_no mptwo = {1, {1.0, 2.0}};
-
-/* Compare mantissa of two multiple precision numbers regardless of the sign
-   and exponent of the numbers.  */
-static int
-mcr (const mp_no *x, const mp_no *y, int p)
-{
-  long i;
-  long p2 = p;
-  for (i = 1; i <= p2; i++)
-    {
-      if (X[i] == Y[i])
-	continue;
-      else if (X[i] > Y[i])
-	return 1;
-      else
-	return -1;
-    }
-  return 0;
-}
-
-/* Compare the absolute values of two multiple precision numbers.  */
-int
-__acr (const mp_no *x, const mp_no *y, int p)
-{
-  long i;
-
-  if (X[0] == ZERO)
-    {
-      if (Y[0] == ZERO)
-	i = 0;
-      else
-	i = -1;
-    }
-  else if (Y[0] == ZERO)
-    i = 1;
-  else
-    {
-      if (EX > EY)
-	i = 1;
-      else if (EX < EY)
-	i = -1;
-      else
-	i = mcr (x, y, p);
-    }
-
-  return i;
-}
-
-/* Copy multiple precision number X into Y.  They could be the same
-   number.  */
-void
-__cpy (const mp_no *x, mp_no *y, int p)
-{
-  long i;
-
-  EY = EX;
-  for (i = 0; i <= p; i++)
-    Y[i] = X[i];
-}
-
-/* Convert a multiple precision number *X into a double precision
-   number *Y, normalized case  (|x| >= 2**(-1022))).  */
-static void
-norm (const mp_no *x, double *y, int p)
-{
-#define R RADIXI
-  long i;
-  double a, c, u, v, z[5];
-  if (p < 5)
-    {
-      if (p == 1)
-	c = X[1];
-      else if (p == 2)
-	c = X[1] + R * X[2];
-      else if (p == 3)
-	c = X[1] + R * (X[2] + R * X[3]);
-      else if (p == 4)
-	c = (X[1] + R * X[2]) + R * R * (X[3] + R * X[4]);
-    }
-  else
-    {
-      for (a = ONE, z[1] = X[1]; z[1] < TWO23;)
-	{
-	  a *= TWO;
-	  z[1] *= TWO;
-	}
-
-      for (i = 2; i < 5; i++)
-	{
-	  z[i] = X[i] * a;
-	  u = (z[i] + CUTTER) - CUTTER;
-	  if (u > z[i])
-	    u -= RADIX;
-	  z[i] -= u;
-	  z[i - 1] += u * RADIXI;
-	}
-
-      u = (z[3] + TWO71) - TWO71;
-      if (u > z[3])
-	u -= TWO19;
-      v = z[3] - u;
-
-      if (v == TWO18)
-	{
-	  if (z[4] == ZERO)
-	    {
-	      for (i = 5; i <= p; i++)
-		{
-		  if (X[i] == ZERO)
-		    continue;
-		  else
-		    {
-		      z[3] += ONE;
-		      break;
-		    }
-		}
-	    }
-	  else
-	    z[3] += ONE;
-	}
-
-      c = (z[1] + R * (z[2] + R * z[3])) / a;
-    }
-
-  c *= X[0];
-
-  for (i = 1; i < EX; i++)
-    c *= RADIX;
-  for (i = 1; i > EX; i--)
-    c *= RADIXI;
-
-  *y = c;
-#undef R
-}
-
-/* Convert a multiple precision number *X into a double precision
-   number *Y, Denormal case  (|x| < 2**(-1022))).  */
-static void
-denorm (const mp_no *x, double *y, int p)
-{
-  long i, k;
-  long p2 = p;
-  double c, u, z[5];
-
-#define R RADIXI
-  if (EX < -44 || (EX == -44 && X[1] < TWO5))
-    {
-      *y = ZERO;
-      return;
-    }
-
-  if (p2 == 1)
-    {
-      if (EX == -42)
-	{
-	  z[1] = X[1] + TWO10;
-	  z[2] = ZERO;
-	  z[3] = ZERO;
-	  k = 3;
-	}
-      else if (EX == -43)
-	{
-	  z[1] = TWO10;
-	  z[2] = X[1];
-	  z[3] = ZERO;
-	  k = 2;
-	}
-      else
-	{
-	  z[1] = TWO10;
-	  z[2] = ZERO;
-	  z[3] = X[1];
-	  k = 1;
-	}
-    }
-  else if (p2 == 2)
-    {
-      if (EX == -42)
-	{
-	  z[1] = X[1] + TWO10;
-	  z[2] = X[2];
-	  z[3] = ZERO;
-	  k = 3;
-	}
-      else if (EX == -43)
-	{
-	  z[1] = TWO10;
-	  z[2] = X[1];
-	  z[3] = X[2];
-	  k = 2;
-	}
-      else
-	{
-	  z[1] = TWO10;
-	  z[2] = ZERO;
-	  z[3] = X[1];
-	  k = 1;
-	}
-    }
-  else
-    {
-      if (EX == -42)
-	{
-	  z[1] = X[1] + TWO10;
-	  z[2] = X[2];
-	  k = 3;
-	}
-      else if (EX == -43)
-	{
-	  z[1] = TWO10;
-	  z[2] = X[1];
-	  k = 2;
-	}
-      else
-	{
-	  z[1] = TWO10;
-	  z[2] = ZERO;
-	  k = 1;
-	}
-      z[3] = X[k];
-    }
-
-  u = (z[3] + TWO57) - TWO57;
-  if (u > z[3])
-    u -= TWO5;
-
-  if (u == z[3])
-    {
-      for (i = k + 1; i <= p2; i++)
-	{
-	  if (X[i] == ZERO)
-	    continue;
-	  else
-	    {
-	      z[3] += ONE;
-	      break;
-	    }
-	}
-    }
-
-  c = X[0] * ((z[1] + R * (z[2] + R * z[3])) - TWO10);
-
-  *y = c * TWOM1032;
-#undef R
-}
-
-/* Convert multiple precision number *X into double precision number *Y.  The
-   result is correctly rounded to the nearest/even.  */
-void
-__mp_dbl (const mp_no *x, double *y, int p)
-{
-  if (X[0] == ZERO)
-    {
-      *y = ZERO;
-      return;
-    }
-
-  if (__glibc_likely (EX > -42 || (EX == -42 && X[1] >= TWO10)))
-    norm (x, y, p);
-  else
-    denorm (x, y, p);
-}
-
-/* Get the multiple precision equivalent of X into *Y.  If the precision is too
-   small, the result is truncated.  */
-void
-__dbl_mp (double x, mp_no *y, int p)
-{
-  long i, n;
-  long p2 = p;
-  double u;
-
-  /* Sign.  */
-  if (x == ZERO)
-    {
-      Y[0] = ZERO;
-      return;
-    }
-  else if (x > ZERO)
-    Y[0] = ONE;
-  else
-    {
-      Y[0] = MONE;
-      x = -x;
-    }
-
-  /* Exponent.  */
-  for (EY = ONE; x >= RADIX; EY += ONE)
-    x *= RADIXI;
-  for (; x < ONE; EY -= ONE)
-    x *= RADIX;
-
-  /* Digits.  */
-  n = MIN (p2, 4);
-  for (i = 1; i <= n; i++)
-    {
-      u = (x + TWO52) - TWO52;
-      if (u > x)
-	u -= ONE;
-      Y[i] = u;
-      x -= u;
-      x *= RADIX;
-    }
-  for (; i <= p2; i++)
-    Y[i] = ZERO;
-}
-
-/* Add magnitudes of *X and *Y assuming that abs (*X) >= abs (*Y) > 0.  The
-   sign of the sum *Z is not changed.  X and Y may overlap but not X and Z or
-   Y and Z.  No guard digit is used.  The result equals the exact sum,
-   truncated.  */
-static void
-add_magnitudes (const mp_no *x, const mp_no *y, mp_no *z, int p)
-{
-  long i, j, k;
-  long p2 = p;
-  double zk;
-
-  EZ = EX;
-
-  i = p2;
-  j = p2 + EY - EX;
-  k = p2 + 1;
-
-  if (__glibc_unlikely (j < 1))
-    {
-      __cpy (x, z, p);
-      return;
-    }
-
-  zk = ZERO;
-
-  for (; j > 0; i--, j--)
-    {
-      zk += X[i] + Y[j];
-      if (zk >= RADIX)
-	{
-	  Z[k--] = zk - RADIX;
-	  zk = ONE;
-	}
-      else
-        {
-	  Z[k--] = zk;
-	  zk = ZERO;
-	}
-    }
-
-  for (; i > 0; i--)
-    {
-      zk += X[i];
-      if (zk >= RADIX)
-	{
-	  Z[k--] = zk - RADIX;
-	  zk = ONE;
-	}
-      else
-        {
-	  Z[k--] = zk;
-	  zk = ZERO;
-	}
-    }
-
-  if (zk == ZERO)
-    {
-      for (i = 1; i <= p2; i++)
-	Z[i] = Z[i + 1];
-    }
-  else
-    {
-      Z[1] = zk;
-      EZ += ONE;
-    }
-}
-
-/* Subtract the magnitudes of *X and *Y assuming that abs (*x) > abs (*y) > 0.
-   The sign of the difference *Z is not changed.  X and Y may overlap but not X
-   and Z or Y and Z.  One guard digit is used.  The error is less than one
-   ULP.  */
-static void
-sub_magnitudes (const mp_no *x, const mp_no *y, mp_no *z, int p)
-{
-  long i, j, k;
-  long p2 = p;
-  double zk;
-
-  EZ = EX;
-  i = p2;
-  j = p2 + EY - EX;
-  k = p2;
-
-  /* Y is too small compared to X, copy X over to the result.  */
-  if (__glibc_unlikely (j < 1))
-    {
-      __cpy (x, z, p);
-      return;
-    }
-
-  /* The relevant least significant digit in Y is non-zero, so we factor it in
-     to enhance accuracy.  */
-  if (j < p2 && Y[j + 1] > ZERO)
-    {
-      Z[k + 1] = RADIX - Y[j + 1];
-      zk = MONE;
-    }
-  else
-    zk = Z[k + 1] = ZERO;
-
-  /* Subtract and borrow.  */
-  for (; j > 0; i--, j--)
-    {
-      zk += (X[i] - Y[j]);
-      if (zk < ZERO)
-	{
-	  Z[k--] = zk + RADIX;
-	  zk = MONE;
-	}
-      else
-        {
-	  Z[k--] = zk;
-	  zk = ZERO;
-	}
-    }
-
-  /* We're done with digits from Y, so it's just digits in X.  */
-  for (; i > 0; i--)
-    {
-      zk += X[i];
-      if (zk < ZERO)
-	{
-	  Z[k--] = zk + RADIX;
-	  zk = MONE;
-	}
-      else
-        {
-	  Z[k--] = zk;
-	  zk = ZERO;
-	}
-    }
-
-  /* Normalize.  */
-  for (i = 1; Z[i] == ZERO; i++);
-  EZ = EZ - i + 1;
-  for (k = 1; i <= p2 + 1;)
-    Z[k++] = Z[i++];
-  for (; k <= p2;)
-    Z[k++] = ZERO;
-}
-
-/* Add *X and *Y and store the result in *Z.  X and Y may overlap, but not X
-   and Z or Y and Z.  One guard digit is used.  The error is less than one
-   ULP.  */
-void
-__add (const mp_no *x, const mp_no *y, mp_no *z, int p)
-{
-  int n;
-
-  if (X[0] == ZERO)
-    {
-      __cpy (y, z, p);
-      return;
-    }
-  else if (Y[0] == ZERO)
-    {
-      __cpy (x, z, p);
-      return;
-    }
-
-  if (X[0] == Y[0])
-    {
-      if (__acr (x, y, p) > 0)
-	{
-	  add_magnitudes (x, y, z, p);
-	  Z[0] = X[0];
-	}
-      else
-	{
-	  add_magnitudes (y, x, z, p);
-	  Z[0] = Y[0];
-	}
-    }
-  else
-    {
-      if ((n = __acr (x, y, p)) == 1)
-	{
-	  sub_magnitudes (x, y, z, p);
-	  Z[0] = X[0];
-	}
-      else if (n == -1)
-	{
-	  sub_magnitudes (y, x, z, p);
-	  Z[0] = Y[0];
-	}
-      else
-	Z[0] = ZERO;
-    }
-}
-
-/* Subtract *Y from *X and return the result in *Z.  X and Y may overlap but
-   not X and Z or Y and Z.  One guard digit is used.  The error is less than
-   one ULP.  */
-void
-__sub (const mp_no *x, const mp_no *y, mp_no *z, int p)
-{
-  int n;
-
-  if (X[0] == ZERO)
-    {
-      __cpy (y, z, p);
-      Z[0] = -Z[0];
-      return;
-    }
-  else if (Y[0] == ZERO)
-    {
-      __cpy (x, z, p);
-      return;
-    }
-
-  if (X[0] != Y[0])
-    {
-      if (__acr (x, y, p) > 0)
-	{
-	  add_magnitudes (x, y, z, p);
-	  Z[0] = X[0];
-	}
-      else
-	{
-	  add_magnitudes (y, x, z, p);
-	  Z[0] = -Y[0];
-	}
-    }
-  else
-    {
-      if ((n = __acr (x, y, p)) == 1)
-	{
-	  sub_magnitudes (x, y, z, p);
-	  Z[0] = X[0];
-	}
-      else if (n == -1)
-	{
-	  sub_magnitudes (y, x, z, p);
-	  Z[0] = -Y[0];
-	}
-      else
-	Z[0] = ZERO;
-    }
-}
+
+/* Define __mul and __sqr and use the rest from generic code.  */
+#define NO__MUL
+#define NO__SQR
+
+#include <sysdeps/ieee754/dbl-64/mpa.c>
 
 /* Multiply *X and *Y and store result in *Z.  X and Y may overlap but not X
    and Z or Y and Z.  For P in [1, 2, 3], the exact result is truncated to P
@@ -669,16 +99,16 @@
     }
   Z[k] = zk;
 
+  int e = EX + EY;
   /* Is there a carry beyond the most significant digit?  */
   if (Z[1] == ZERO)
     {
       for (i = 1; i <= p2; i++)
 	Z[i] = Z[i + 1];
-      EZ = EX + EY - 1;
-    }
-  else
-    EZ = EX + EY;
-
+      e--;
+    }
+
+  EZ = e;
   Z[0] = X[0] * Y[0];
 }
 
@@ -772,66 +202,13 @@
   /* Squares are always positive.  */
   Y[0] = 1.0;
 
-  EY = 2 * EX;
+  int e = EX * 2;
   /* Is there a carry beyond the most significant digit?  */
   if (__glibc_unlikely (Y[1] == ZERO))
     {
       for (i = 1; i <= p; i++)
 	Y[i] = Y[i + 1];
-      EY--;
-    }
+      e--;
+    }
+  EY = e;
 }
-
-/* Invert *X and store in *Y.  Relative error bound:
-   - For P = 2: 1.001 * R ^ (1 - P)
-   - For P = 3: 1.063 * R ^ (1 - P)
-   - For P > 3: 2.001 * R ^ (1 - P)
-
-   *X = 0 is not permissible.  */
-static void
-__inv (const mp_no *x, mp_no *y, int p)
-{
-  long i;
-  double t;
-  mp_no z, w;
-  static const int np1[] =
-    { 0, 0, 0, 0, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3,
-    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4
-  };
-
-  __cpy (x, &z, p);
-  z.e = 0;
-  __mp_dbl (&z, &t, p);
-  t = ONE / t;
-  __dbl_mp (t, y, p);
-  EY -= EX;
-
-  for (i = 0; i < np1[p]; i++)
-    {
-      __cpy (y, &w, p);
-      __mul (x, &w, y, p);
-      __sub (&mptwo, y, &z, p);
-      __mul (&w, &z, y, p);
-    }
-}
-
-/* Divide *X by *Y and store result in *Z.  X and Y may overlap but not X and Z
-   or Y and Z.  Relative error bound:
-   - For P = 2: 2.001 * R ^ (1 - P)
-   - For P = 3: 2.063 * R ^ (1 - P)
-   - For P > 3: 3.001 * R ^ (1 - P)
-
-   *X = 0 is not permissible.  */
-void
-__dvd (const mp_no *x, const mp_no *y, mp_no *z, int p)
-{
-  mp_no w;
-
-  if (X[0] == ZERO)
-    Z[0] = ZERO;
-  else
-    {
-      __inv (y, &w, p);
-      __mul (x, &w, z, p);
-    }
-}

Removed: fsf/trunk/libc/sysdeps/powerpc/powerpc32/power4/fpu/slowexp.c
==============================================================================
--- fsf/trunk/libc/sysdeps/powerpc/powerpc32/power4/fpu/slowexp.c (original)
+++ fsf/trunk/libc/sysdeps/powerpc/powerpc32/power4/fpu/slowexp.c (removed)
@@ -1,65 +1,0 @@
-/*
- * IBM Accurate Mathematical Library
- * written by International Business Machines Corp.
- * Copyright (C) 2001-2013 Free Software Foundation, Inc.
- *
- * This program 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.
- *
- * This program 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 this program; if not, see <http://www.gnu.org/licenses/>.
- */
-/**************************************************************************/
-/*  MODULE_NAME:slowexp.c                                                 */
-/*                                                                        */
-/*  FUNCTION:slowexp                                                      */
-/*                                                                        */
-/*  FILES NEEDED:mpa.h                                                    */
-/*               mpa.c mpexp.c                                            */
-/*                                                                        */
-/*Converting from double precision to Multi-precision and calculating     */
-/* e^x                                                                    */
-/**************************************************************************/
-#include <math_private.h>
-
-#ifdef NO_LONG_DOUBLE
-#include "mpa.h"
-void __mpexp(mp_no *x, mp_no *y, int p);
-#endif
-
-/*Converting from double precision to Multi-precision and calculating  e^x */
-double __slowexp(double x) {
-#ifdef NO_LONG_DOUBLE
-  double w,z,res,eps=3.0e-26;
-  int p;
-  mp_no mpx, mpy, mpz,mpw,mpeps,mpcor;
-
-  p=6;
-  __dbl_mp(x,&mpx,p); /* Convert a double precision number  x               */
-                    /* into a multiple precision number mpx with prec. p. */
-  __mpexp(&mpx, &mpy, p); /* Multi-Precision exponential function */
-  __dbl_mp(eps,&mpeps,p);
-  __mul(&mpeps,&mpy,&mpcor,p);
-  __add(&mpy,&mpcor,&mpw,p);
-  __sub(&mpy,&mpcor,&mpz,p);
-  __mp_dbl(&mpw, &w, p);
-  __mp_dbl(&mpz, &z, p);
-  if (w == z) return w;
-  else  {                   /* if calculating is not exactly   */
-    p = 32;
-    __dbl_mp(x,&mpx,p);
-    __mpexp(&mpx, &mpy, p);
-    __mp_dbl(&mpy, &res, p);
-    return res;
-  }
-#else
-  return (double) __ieee754_expl((long double)x);
-#endif
-}

Removed: fsf/trunk/libc/sysdeps/powerpc/powerpc32/power4/fpu/slowpow.c
==============================================================================
--- fsf/trunk/libc/sysdeps/powerpc/powerpc32/power4/fpu/slowpow.c (original)
+++ fsf/trunk/libc/sysdeps/powerpc/powerpc32/power4/fpu/slowpow.c (removed)
@@ -1,93 +1,0 @@
-/*
- * IBM Accurate Mathematical Library
- * written by International Business Machines Corp.
- * Copyright (C) 2001-2013 Free Software Foundation, Inc.
- *
- * This program 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.
- *
- * This program 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 this program; if not, see <http://www.gnu.org/licenses/>.
- */
-/*************************************************************************/
-/* MODULE_NAME:slowpow.c                                                 */
-/*                                                                       */
-/* FUNCTION:slowpow                                                      */
-/*                                                                       */
-/*FILES NEEDED:mpa.h                                                     */
-/*             mpa.c mpexp.c mplog.c halfulp.c                           */
-/*                                                                       */
-/* Given two IEEE double machine numbers y,x , routine  computes the     */
-/* correctly  rounded (to nearest) value of x^y. Result calculated  by   */
-/* multiplication (in halfulp.c) or if result isn't accurate enough      */
-/* then routine converts x and y into multi-precision doubles and        */
-/* recompute.                                                            */
-/*************************************************************************/
-
-#include "mpa.h"
-#include <math_private.h>
-
-void __mpexp (mp_no * x, mp_no * y, int p);
-void __mplog (mp_no * x, mp_no * y, int p);
-double ulog (double);
-double __halfulp (double x, double y);
-
-double
-__slowpow (double x, double y, double z)
-{
-  double res, res1;
-  long double ldw, ldz, ldpp;
-  static const long double ldeps = 0x4.0p-96;
-
-  res = __halfulp (x, y);	/* halfulp() returns -10 or x^y             */
-  if (res >= 0)
-    return res;			/* if result was really computed by halfulp */
-  /*  else, if result was not really computed by halfulp */
-
-  /* Compute pow as long double, 106 bits */
-  ldz = __ieee754_logl ((long double) x);
-  ldw = (long double) y *ldz;
-  ldpp = __ieee754_expl (ldw);
-  res = (double) (ldpp + ldeps);
-  res1 = (double) (ldpp - ldeps);
-
-  if (res != res1)		/* if result still not accurate enough */
-    {				/* use mpa for higher precision.  */
-      mp_no mpx, mpy, mpz, mpw, mpp, mpr, mpr1;
-      static const mp_no eps = { -3, {1.0, 4.0} };
-      int p;
-
-      p = 10;			/*  p=precision 240 bits  */
-      __dbl_mp (x, &mpx, p);
-      __dbl_mp (y, &mpy, p);
-      __dbl_mp (z, &mpz, p);
-      __mplog (&mpx, &mpz, p);		/* log(x) = z   */
-      __mul (&mpy, &mpz, &mpw, p);	/*  y * z =w    */
-      __mpexp (&mpw, &mpp, p);		/*  e^w =pp     */
-      __add (&mpp, &eps, &mpr, p);	/*  pp+eps =r   */
-      __mp_dbl (&mpr, &res, p);
-      __sub (&mpp, &eps, &mpr1, p);	/*  pp -eps =r1 */
-      __mp_dbl (&mpr1, &res1, p);	/*  converting into double precision */
-      if (res == res1)
-	return res;
-
-      /* if we get here result wasn't calculated exactly, continue for
-         more exact calculation using 768 bits.  */
-      p = 32;
-      __dbl_mp (x, &mpx, p);
-      __dbl_mp (y, &mpy, p);
-      __dbl_mp (z, &mpz, p);
-      __mplog (&mpx, &mpz, p);		/* log(c)=z  */
-      __mul (&mpy, &mpz, &mpw, p);	/* y*z =w    */
-      __mpexp (&mpw, &mpp, p);		/* e^w=pp    */
-      __mp_dbl (&mpp, &res, p);		/* converting into double precision */
-    }
-  return res;
-}

Modified: fsf/trunk/libc/sysdeps/powerpc/powerpc64/power4/fpu/Makefile
==============================================================================
--- fsf/trunk/libc/sysdeps/powerpc/powerpc64/power4/fpu/Makefile (original)
+++ fsf/trunk/libc/sysdeps/powerpc/powerpc64/power4/fpu/Makefile Fri Mar  8 00:03:58 2013
@@ -2,4 +2,6 @@
 
 ifeq ($(subdir),math)
 CFLAGS-mpa.c += --param max-unroll-times=4 -funroll-loops -fpeel-loops
+CPPFLAGS-slowpow.c += -DUSE_LONG_DOUBLE_FOR_MP=1
+CPPFLAGS-slowexp.c += -DUSE_LONG_DOUBLE_FOR_MP=1
 endif

Modified: fsf/trunk/libc/sysdeps/powerpc/powerpc64/power4/fpu/mpa.c
==============================================================================
--- fsf/trunk/libc/sysdeps/powerpc/powerpc64/power4/fpu/mpa.c (original)
+++ fsf/trunk/libc/sysdeps/powerpc/powerpc64/power4/fpu/mpa.c Fri Mar  8 00:03:58 2013
@@ -17,582 +17,12 @@
  * You should have received a copy of the GNU Lesser General Public License
  * along with this program; if not, see <http://www.gnu.org/licenses/>.
  */
-/************************************************************************/
-/*  MODULE_NAME: mpa.c                                                  */
-/*                                                                      */
-/*  FUNCTIONS:                                                          */
-/*               mcr                                                    */
-/*               acr                                                    */
-/*               cpy                                                    */
-/*               norm                                                   */
-/*               denorm                                                 */
-/*               mp_dbl                                                 */
-/*               dbl_mp                                                 */
-/*               add_magnitudes                                         */
-/*               sub_magnitudes                                         */
-/*               add                                                    */
-/*               sub                                                    */
-/*               mul                                                    */
-/*               inv                                                    */
-/*               dvd                                                    */
-/*                                                                      */
-/* Arithmetic functions for multiple precision numbers.                 */
-/* Relative errors are bounded                                          */
-/************************************************************************/
-
-
-#include "endian.h"
-#include "mpa.h"
-#include <sys/param.h>
-
-const mp_no mpone = {1, {1.0, 1.0}};
-const mp_no mptwo = {1, {1.0, 2.0}};
-
-/* Compare mantissa of two multiple precision numbers regardless of the sign
-   and exponent of the numbers.  */
-static int
-mcr (const mp_no *x, const mp_no *y, int p)
-{
-  long i;
-  long p2 = p;
-  for (i = 1; i <= p2; i++)
-    {
-      if (X[i] == Y[i])
-	continue;
-      else if (X[i] > Y[i])
-	return 1;
-      else
-	return -1;
-    }
-  return 0;
-}
-
-/* Compare the absolute values of two multiple precision numbers.  */
-int
-__acr (const mp_no *x, const mp_no *y, int p)
-{
-  long i;
-
-  if (X[0] == ZERO)
-    {
-      if (Y[0] == ZERO)
-	i = 0;
-      else
-	i = -1;
-    }
-  else if (Y[0] == ZERO)
-    i = 1;
-  else
-    {
-      if (EX > EY)
-	i = 1;
-      else if (EX < EY)
-	i = -1;
-      else
-	i = mcr (x, y, p);
-    }
-
-  return i;
-}
-
-/* Copy multiple precision number X into Y.  They could be the same
-   number.  */
-void
-__cpy (const mp_no *x, mp_no *y, int p)
-{
-  long i;
-
-  EY = EX;
-  for (i = 0; i <= p; i++)
-    Y[i] = X[i];
-}
-
-/* Convert a multiple precision number *X into a double precision
-   number *Y, normalized case  (|x| >= 2**(-1022))).  */
-static void
-norm (const mp_no *x, double *y, int p)
-{
-#define R RADIXI
-  long i;
-  double a, c, u, v, z[5];
-  if (p < 5)
-    {
-      if (p == 1)
-	c = X[1];
-      else if (p == 2)
-	c = X[1] + R * X[2];
-      else if (p == 3)
-	c = X[1] + R * (X[2] + R * X[3]);
-      else if (p == 4)
-	c = (X[1] + R * X[2]) + R * R * (X[3] + R * X[4]);
-    }
-  else
-    {
-      for (a = ONE, z[1] = X[1]; z[1] < TWO23;)
-	{
-	  a *= TWO;
-	  z[1] *= TWO;
-	}
-
-      for (i = 2; i < 5; i++)
-	{
-	  z[i] = X[i] * a;
-	  u = (z[i] + CUTTER) - CUTTER;
-	  if (u > z[i])
-	    u -= RADIX;
-	  z[i] -= u;
-	  z[i - 1] += u * RADIXI;
-	}
-
-      u = (z[3] + TWO71) - TWO71;
-      if (u > z[3])
-	u -= TWO19;
-      v = z[3] - u;
-
-      if (v == TWO18)
-	{
-	  if (z[4] == ZERO)
-	    {
-	      for (i = 5; i <= p; i++)
-		{
-		  if (X[i] == ZERO)
-		    continue;
-		  else
-		    {
-		      z[3] += ONE;
-		      break;
-		    }
-		}
-	    }
-	  else
-	    z[3] += ONE;
-	}
-
-      c = (z[1] + R * (z[2] + R * z[3])) / a;
-    }
-
-  c *= X[0];
-
-  for (i = 1; i < EX; i++)
-    c *= RADIX;
-  for (i = 1; i > EX; i--)
-    c *= RADIXI;
-
-  *y = c;
-#undef R
-}
-
-/* Convert a multiple precision number *X into a double precision
-   number *Y, Denormal case  (|x| < 2**(-1022))).  */
-static void
-denorm (const mp_no *x, double *y, int p)
-{
-  long i, k;
-  long p2 = p;
-  double c, u, z[5];
-
-#define R RADIXI
-  if (EX < -44 || (EX == -44 && X[1] < TWO5))
-    {
-      *y = ZERO;
-      return;
-    }
-
-  if (p2 == 1)
-    {
-      if (EX == -42)
-	{
-	  z[1] = X[1] + TWO10;
-	  z[2] = ZERO;
-	  z[3] = ZERO;
-	  k = 3;
-	}
-      else if (EX == -43)
-	{
-	  z[1] = TWO10;
-	  z[2] = X[1];
-	  z[3] = ZERO;
-	  k = 2;
-	}
-      else
-	{
-	  z[1] = TWO10;
-	  z[2] = ZERO;
-	  z[3] = X[1];
-	  k = 1;
-	}
-    }
-  else if (p2 == 2)
-    {
-      if (EX == -42)
-	{
-	  z[1] = X[1] + TWO10;
-	  z[2] = X[2];
-	  z[3] = ZERO;
-	  k = 3;
-	}
-      else if (EX == -43)
-	{
-	  z[1] = TWO10;
-	  z[2] = X[1];
-	  z[3] = X[2];
-	  k = 2;
-	}
-      else
-	{
-	  z[1] = TWO10;
-	  z[2] = ZERO;
-	  z[3] = X[1];
-	  k = 1;
-	}
-    }
-  else
-    {
-      if (EX == -42)
-	{
-	  z[1] = X[1] + TWO10;
-	  z[2] = X[2];
-	  k = 3;
-	}
-      else if (EX == -43)
-	{
-	  z[1] = TWO10;
-	  z[2] = X[1];
-	  k = 2;
-	}
-      else
-	{
-	  z[1] = TWO10;
-	  z[2] = ZERO;
-	  k = 1;
-	}
-      z[3] = X[k];
-    }
-
-  u = (z[3] + TWO57) - TWO57;
-  if (u > z[3])
-    u -= TWO5;
-
-  if (u == z[3])
-    {
-      for (i = k + 1; i <= p2; i++)
-	{
-	  if (X[i] == ZERO)
-	    continue;
-	  else
-	    {
-	      z[3] += ONE;
-	      break;
-	    }
-	}
-    }
-
-  c = X[0] * ((z[1] + R * (z[2] + R * z[3])) - TWO10);
-
-  *y = c * TWOM1032;
-#undef R
-}
-
-/* Convert multiple precision number *X into double precision number *Y.  The
-   result is correctly rounded to the nearest/even.  */
-void
-__mp_dbl (const mp_no *x, double *y, int p)
-{
-  if (X[0] == ZERO)
-    {
-      *y = ZERO;
-      return;
-    }
-
-  if (__glibc_likely (EX > -42 || (EX == -42 && X[1] >= TWO10)))
-    norm (x, y, p);
-  else
-    denorm (x, y, p);
-}
-
-/* Get the multiple precision equivalent of X into *Y.  If the precision is too
-   small, the result is truncated.  */
-void
-__dbl_mp (double x, mp_no *y, int p)
-{
-  long i, n;
-  long p2 = p;
-  double u;
-
-  /* Sign.  */
-  if (x == ZERO)
-    {
-      Y[0] = ZERO;
-      return;
-    }
-  else if (x > ZERO)
-    Y[0] = ONE;
-  else
-    {
-      Y[0] = MONE;
-      x = -x;
-    }
-
-  /* Exponent.  */
-  for (EY = ONE; x >= RADIX; EY += ONE)
-    x *= RADIXI;
-  for (; x < ONE; EY -= ONE)
-    x *= RADIX;
-
-  /* Digits.  */
-  n = MIN (p2, 4);
-  for (i = 1; i <= n; i++)
-    {
-      u = (x + TWO52) - TWO52;
-      if (u > x)
-	u -= ONE;
-      Y[i] = u;
-      x -= u;
-      x *= RADIX;
-    }
-  for (; i <= p2; i++)
-    Y[i] = ZERO;
-}
-
-/* Add magnitudes of *X and *Y assuming that abs (*X) >= abs (*Y) > 0.  The
-   sign of the sum *Z is not changed.  X and Y may overlap but not X and Z or
-   Y and Z.  No guard digit is used.  The result equals the exact sum,
-   truncated.  */
-static void
-add_magnitudes (const mp_no *x, const mp_no *y, mp_no *z, int p)
-{
-  long i, j, k;
-  long p2 = p;
-  double zk;
-
-  EZ = EX;
-
-  i = p2;
-  j = p2 + EY - EX;
-  k = p2 + 1;
-
-  if (__glibc_unlikely (j < 1))
-    {
-      __cpy (x, z, p);
-      return;
-    }
-
-  zk = ZERO;
-
-  for (; j > 0; i--, j--)
-    {
-      zk += X[i] + Y[j];
-      if (zk >= RADIX)
-	{
-	  Z[k--] = zk - RADIX;
-	  zk = ONE;
-	}
-      else
-        {
-	  Z[k--] = zk;
-	  zk = ZERO;
-	}
-    }
-
-  for (; i > 0; i--)
-    {
-      zk += X[i];
-      if (zk >= RADIX)
-	{
-	  Z[k--] = zk - RADIX;
-	  zk = ONE;
-	}
-      else
-        {
-	  Z[k--] = zk;
-	  zk = ZERO;
-	}
-    }
-
-  if (zk == ZERO)
-    {
-      for (i = 1; i <= p2; i++)
-	Z[i] = Z[i + 1];
-    }
-  else
-    {
-      Z[1] = zk;
-      EZ += ONE;
-    }
-}
-
-/* Subtract the magnitudes of *X and *Y assuming that abs (*x) > abs (*y) > 0.
-   The sign of the difference *Z is not changed.  X and Y may overlap but not X
-   and Z or Y and Z.  One guard digit is used.  The error is less than one
-   ULP.  */
-static void
-sub_magnitudes (const mp_no *x, const mp_no *y, mp_no *z, int p)
-{
-  long i, j, k;
-  long p2 = p;
-  double zk;
-
-  EZ = EX;
-  i = p2;
-  j = p2 + EY - EX;
-  k = p2;
-
-  /* Y is too small compared to X, copy X over to the result.  */
-  if (__glibc_unlikely (j < 1))
-    {
-      __cpy (x, z, p);
-      return;
-    }
-
-  /* The relevant least significant digit in Y is non-zero, so we factor it in
-     to enhance accuracy.  */
-  if (j < p2 && Y[j + 1] > ZERO)
-    {
-      Z[k + 1] = RADIX - Y[j + 1];
-      zk = MONE;
-    }
-  else
-    zk = Z[k + 1] = ZERO;
-
-  /* Subtract and borrow.  */
-  for (; j > 0; i--, j--)
-    {
-      zk += (X[i] - Y[j]);
-      if (zk < ZERO)
-	{
-	  Z[k--] = zk + RADIX;
-	  zk = MONE;
-	}
-      else
-        {
-	  Z[k--] = zk;
-	  zk = ZERO;
-	}
-    }
-
-  /* We're done with digits from Y, so it's just digits in X.  */
-  for (; i > 0; i--)
-    {
-      zk += X[i];
-      if (zk < ZERO)
-	{
-	  Z[k--] = zk + RADIX;
-	  zk = MONE;
-	}
-      else
-        {
-	  Z[k--] = zk;
-	  zk = ZERO;
-	}
-    }
-
-  /* Normalize.  */
-  for (i = 1; Z[i] == ZERO; i++);
-  EZ = EZ - i + 1;
-  for (k = 1; i <= p2 + 1;)
-    Z[k++] = Z[i++];
-  for (; k <= p2;)
-    Z[k++] = ZERO;
-}
-
-/* Add *X and *Y and store the result in *Z.  X and Y may overlap, but not X
-   and Z or Y and Z.  One guard digit is used.  The error is less than one
-   ULP.  */
-void
-__add (const mp_no *x, const mp_no *y, mp_no *z, int p)
-{
-  int n;
-
-  if (X[0] == ZERO)
-    {
-      __cpy (y, z, p);
-      return;
-    }
-  else if (Y[0] == ZERO)
-    {
-      __cpy (x, z, p);
-      return;
-    }
-
-  if (X[0] == Y[0])
-    {
-      if (__acr (x, y, p) > 0)
-	{
-	  add_magnitudes (x, y, z, p);
-	  Z[0] = X[0];
-	}
-      else
-	{
-	  add_magnitudes (y, x, z, p);
-	  Z[0] = Y[0];
-	}
-    }
-  else
-    {
-      if ((n = __acr (x, y, p)) == 1)
-	{
-	  sub_magnitudes (x, y, z, p);
-	  Z[0] = X[0];
-	}
-      else if (n == -1)
-	{
-	  sub_magnitudes (y, x, z, p);
-	  Z[0] = Y[0];
-	}
-      else
-	Z[0] = ZERO;
-    }
-}
-
-/* Subtract *Y from *X and return the result in *Z.  X and Y may overlap but
-   not X and Z or Y and Z.  One guard digit is used.  The error is less than
-   one ULP.  */
-void
-__sub (const mp_no *x, const mp_no *y, mp_no *z, int p)
-{
-  int n;
-
-  if (X[0] == ZERO)
-    {
-      __cpy (y, z, p);
-      Z[0] = -Z[0];
-      return;
-    }
-  else if (Y[0] == ZERO)
-    {
-      __cpy (x, z, p);
-      return;
-    }
-
-  if (X[0] != Y[0])
-    {
-      if (__acr (x, y, p) > 0)
-	{
-	  add_magnitudes (x, y, z, p);
-	  Z[0] = X[0];
-	}
-      else
-	{
-	  add_magnitudes (y, x, z, p);
-	  Z[0] = -Y[0];
-	}
-    }
-  else
-    {
-      if ((n = __acr (x, y, p)) == 1)
-	{
-	  sub_magnitudes (x, y, z, p);
-	  Z[0] = X[0];
-	}
-      else if (n == -1)
-	{
-	  sub_magnitudes (y, x, z, p);
-	  Z[0] = -Y[0];
-	}
-      else
-	Z[0] = ZERO;
-    }
-}
+
+/* Define __mul and __sqr and use the rest from generic code.  */
+#define NO__MUL
+#define NO__SQR
+
+#include <sysdeps/ieee754/dbl-64/mpa.c>
 
 /* Multiply *X and *Y and store result in *Z.  X and Y may overlap but not X
    and Z or Y and Z.  For P in [1, 2, 3], the exact result is truncated to P
@@ -669,16 +99,16 @@
     }
   Z[k] = zk;
 
+  int e = EX + EY;
   /* Is there a carry beyond the most significant digit?  */
   if (Z[1] == ZERO)
     {
       for (i = 1; i <= p2; i++)
 	Z[i] = Z[i + 1];
-      EZ = EX + EY - 1;
-    }
-  else
-    EZ = EX + EY;
-
+      e--;
+    }
+
+  EZ = e;
   Z[0] = X[0] * Y[0];
 }
 
@@ -772,66 +202,13 @@
   /* Squares are always positive.  */
   Y[0] = 1.0;
 
-  EY = 2 * EX;
+  int e = EX * 2;
   /* Is there a carry beyond the most significant digit?  */
   if (__glibc_unlikely (Y[1] == ZERO))
     {
       for (i = 1; i <= p; i++)
 	Y[i] = Y[i + 1];
-      EY--;
-    }
+      e--;
+    }
+  EY = e;
 }
-
-/* Invert *X and store in *Y.  Relative error bound:
-   - For P = 2: 1.001 * R ^ (1 - P)
-   - For P = 3: 1.063 * R ^ (1 - P)
-   - For P > 3: 2.001 * R ^ (1 - P)
-
-   *X = 0 is not permissible.  */
-static void
-__inv (const mp_no *x, mp_no *y, int p)
-{
-  long i;
-  double t;
-  mp_no z, w;
-  static const int np1[] =
-    { 0, 0, 0, 0, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3,
-    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4
-  };
-
-  __cpy (x, &z, p);
-  z.e = 0;
-  __mp_dbl (&z, &t, p);
-  t = ONE / t;
-  __dbl_mp (t, y, p);
-  EY -= EX;
-
-  for (i = 0; i < np1[p]; i++)
-    {
-      __cpy (y, &w, p);
-      __mul (x, &w, y, p);
-      __sub (&mptwo, y, &z, p);
-      __mul (&w, &z, y, p);
-    }
-}
-
-/* Divide *X by *Y and store result in *Z.  X and Y may overlap but not X and Z
-   or Y and Z.  Relative error bound:
-   - For P = 2: 2.001 * R ^ (1 - P)
-   - For P = 3: 2.063 * R ^ (1 - P)
-   - For P > 3: 3.001 * R ^ (1 - P)
-
-   *X = 0 is not permissible.  */
-void
-__dvd (const mp_no *x, const mp_no *y, mp_no *z, int p)
-{
-  mp_no w;
-
-  if (X[0] == ZERO)
-    Z[0] = ZERO;
-  else
-    {
-      __inv (y, &w, p);
-      __mul (x, &w, z, p);
-    }
-}

Removed: fsf/trunk/libc/sysdeps/powerpc/powerpc64/power4/fpu/slowexp.c
==============================================================================
--- fsf/trunk/libc/sysdeps/powerpc/powerpc64/power4/fpu/slowexp.c (original)
+++ fsf/trunk/libc/sysdeps/powerpc/powerpc64/power4/fpu/slowexp.c (removed)
@@ -1,65 +1,0 @@
-/*
- * IBM Accurate Mathematical Library
- * written by International Business Machines Corp.
- * Copyright (C) 2001-2013 Free Software Foundation, Inc.
- *
- * This program 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.
- *
- * This program 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 this program; if not, see <http://www.gnu.org/licenses/>.
- */
-/**************************************************************************/
-/*  MODULE_NAME:slowexp.c                                                 */
-/*                                                                        */
-/*  FUNCTION:slowexp                                                      */
-/*                                                                        */
-/*  FILES NEEDED:mpa.h                                                    */
-/*               mpa.c mpexp.c                                            */
-/*                                                                        */
-/*Converting from double precision to Multi-precision and calculating     */
-/* e^x                                                                    */
-/**************************************************************************/
-#include <math_private.h>
-
-#ifdef NO_LONG_DOUBLE
-#include "mpa.h"
-void __mpexp(mp_no *x, mp_no *y, int p);
-#endif
-
-/*Converting from double precision to Multi-precision and calculating  e^x */
-double __slowexp(double x) {
-#ifdef NO_LONG_DOUBLE
-  double w,z,res,eps=3.0e-26;
-  int p;
-  mp_no mpx, mpy, mpz,mpw,mpeps,mpcor;
-
-  p=6;
-  __dbl_mp(x,&mpx,p); /* Convert a double precision number  x               */
-                    /* into a multiple precision number mpx with prec. p. */
-  __mpexp(&mpx, &mpy, p); /* Multi-Precision exponential function */
-  __dbl_mp(eps,&mpeps,p);
-  __mul(&mpeps,&mpy,&mpcor,p);
-  __add(&mpy,&mpcor,&mpw,p);
-  __sub(&mpy,&mpcor,&mpz,p);
-  __mp_dbl(&mpw, &w, p);
-  __mp_dbl(&mpz, &z, p);
-  if (w == z) return w;
-  else  {                   /* if calculating is not exactly   */
-    p = 32;
-    __dbl_mp(x,&mpx,p);
-    __mpexp(&mpx, &mpy, p);
-    __mp_dbl(&mpy, &res, p);
-    return res;
-  }
-#else
-  return (double) __ieee754_expl((long double)x);
-#endif
-}

Removed: fsf/trunk/libc/sysdeps/powerpc/powerpc64/power4/fpu/slowpow.c
==============================================================================
--- fsf/trunk/libc/sysdeps/powerpc/powerpc64/power4/fpu/slowpow.c (original)
+++ fsf/trunk/libc/sysdeps/powerpc/powerpc64/power4/fpu/slowpow.c (removed)
@@ -1,93 +1,0 @@
-/*
- * IBM Accurate Mathematical Library
- * written by International Business Machines Corp.
- * Copyright (C) 2001-2013 Free Software Foundation, Inc.
- *
- * This program 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.
- *
- * This program 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 this program; if not, see <http://www.gnu.org/licenses/>.
- */
-/*************************************************************************/
-/* MODULE_NAME:slowpow.c                                                 */
-/*                                                                       */
-/* FUNCTION:slowpow                                                      */
-/*                                                                       */
-/*FILES NEEDED:mpa.h                                                     */
-/*             mpa.c mpexp.c mplog.c halfulp.c                           */
-/*                                                                       */
-/* Given two IEEE double machine numbers y,x , routine  computes the     */
-/* correctly  rounded (to nearest) value of x^y. Result calculated  by   */
-/* multiplication (in halfulp.c) or if result isn't accurate enough      */
-/* then routine converts x and y into multi-precision doubles and        */
-/* recompute.                                                            */
-/*************************************************************************/
-
-#include "mpa.h"
-#include <math_private.h>
-
-void __mpexp (mp_no * x, mp_no * y, int p);
-void __mplog (mp_no * x, mp_no * y, int p);
-double ulog (double);
-double __halfulp (double x, double y);
-
-double
-__slowpow (double x, double y, double z)
-{
-  double res, res1;
-  long double ldw, ldz, ldpp;
-  static const long double ldeps = 0x4.0p-96;
-
-  res = __halfulp (x, y);	/* halfulp() returns -10 or x^y             */
-  if (res >= 0)
-    return res;			/* if result was really computed by halfulp */
-  /*  else, if result was not really computed by halfulp */
-
-  /* Compute pow as long double, 106 bits */
-  ldz = __ieee754_logl ((long double) x);
-  ldw = (long double) y *ldz;
-  ldpp = __ieee754_expl (ldw);
-  res = (double) (ldpp + ldeps);
-  res1 = (double) (ldpp - ldeps);
-
-  if (res != res1)		/* if result still not accurate enough */
-    {				/* use mpa for higher precision.  */
-      mp_no mpx, mpy, mpz, mpw, mpp, mpr, mpr1;
-      static const mp_no eps = { -3, {1.0, 4.0} };
-      int p;
-
-      p = 10;			/*  p=precision 240 bits  */
-      __dbl_mp (x, &mpx, p);
-      __dbl_mp (y, &mpy, p);
-      __dbl_mp (z, &mpz, p);
-      __mplog (&mpx, &mpz, p);		/* log(x) = z   */
-      __mul (&mpy, &mpz, &mpw, p);	/*  y * z =w    */
-      __mpexp (&mpw, &mpp, p);		/*  e^w =pp     */
-      __add (&mpp, &eps, &mpr, p);	/*  pp+eps =r   */
-      __mp_dbl (&mpr, &res, p);
-      __sub (&mpp, &eps, &mpr1, p);	/*  pp -eps =r1 */
-      __mp_dbl (&mpr1, &res1, p);	/*  converting into double precision */
-      if (res == res1)
-	return res;
-
-      /* if we get here result wasn't calculated exactly, continue for
-         more exact calculation using 768 bits.  */
-      p = 32;
-      __dbl_mp (x, &mpx, p);
-      __dbl_mp (y, &mpy, p);
-      __dbl_mp (z, &mpz, p);
-      __mplog (&mpx, &mpz, p);		/* log(c)=z  */
-      __mul (&mpy, &mpz, &mpw, p);	/* y*z =w    */
-      __mpexp (&mpw, &mpp, p);		/* e^w=pp    */
-      __mp_dbl (&mpp, &res, p);		/* converting into double precision */
-    }
-  return res;
-}

Modified: fsf/trunk/libc/sysdeps/unix/sysv/linux/Makefile
==============================================================================
--- fsf/trunk/libc/sysdeps/unix/sysv/linux/Makefile (original)
+++ fsf/trunk/libc/sysdeps/unix/sysv/linux/Makefile Fri Mar  8 00:03:58 2013
@@ -35,7 +35,8 @@
 		  bits/a.out.h sys/inotify.h sys/signalfd.h sys/eventfd.h \
 		  sys/timerfd.h sys/fanotify.h bits/eventfd.h bits/inotify.h \
 		  bits/signalfd.h bits/timerfd.h bits/epoll.h \
-		  bits/socket_type.h bits/syscall.h bits/sysctl.h
+		  bits/socket_type.h bits/syscall.h bits/sysctl.h \
+		  bits/mman-linux.h
 
 tests += tst-clone
 

Modified: fsf/trunk/libc/sysdeps/unix/sysv/linux/fpathconf.c
==============================================================================
--- fsf/trunk/libc/sysdeps/unix/sysv/linux/fpathconf.c (original)
+++ fsf/trunk/libc/sysdeps/unix/sysv/linux/fpathconf.c Fri Mar  8 00:03:58 2013
@@ -33,7 +33,6 @@
      int name;
 {
   struct statfs fsbuf;
-  int r;
 
   switch (name)
     {
@@ -49,12 +48,6 @@
     case _PC_CHOWN_RESTRICTED:
       return __statfs_chown_restricted (__fstatfs (fd, &fsbuf), &fsbuf);
 
-    case _PC_PIPE_BUF:
-      r = __fcntl (fd, F_GETPIPE_SZ);
-      if (r > 0)
-	return r;
-      /* FALLTHROUGH */
-
     default:
       return posix_fpathconf (fd, name);
     }

Modified: fsf/trunk/libc/sysdeps/unix/sysv/linux/pathconf.c
==============================================================================
--- fsf/trunk/libc/sysdeps/unix/sysv/linux/pathconf.c (original)
+++ fsf/trunk/libc/sysdeps/unix/sysv/linux/pathconf.c Fri Mar  8 00:03:58 2013
@@ -39,8 +39,6 @@
 __pathconf (const char *file, int name)
 {
   struct statfs fsbuf;
-  int fd;
-  int flags;
 
   switch (name)
     {
@@ -55,21 +53,6 @@
 
     case _PC_CHOWN_RESTRICTED:
       return __statfs_chown_restricted (__statfs (file, &fsbuf), &fsbuf);
-
-    case _PC_PIPE_BUF:
-      flags = O_RDONLY|O_NONBLOCK|O_NOCTTY;
-#ifdef O_CLOEXEC
-      flags |= O_CLOEXEC;
-#endif
-      fd = open_not_cancel_2 (file, flags);
-      if (fd >= 0)
-	{
-	  long int r = __fcntl (fd, F_GETPIPE_SZ);
-	  close_not_cancel_no_status (fd);
-	  if (r > 0)
-	    return r;
-	}
-      /* FALLTHROUGH */
 
     default:
       return posix_pathconf (file, name);

_______________________________________________
Commits mailing list
Commits@xxxxxxxxxx
http://eglibc.org/cgi-bin/mailman/listinfo/commits