about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2009-04-15 16:37:06 +0000
committerJakub Jelinek <jakub@redhat.com>2009-04-15 16:37:06 +0000
commitdc3be966c0050d3847ab528387801b9c93a2f831 (patch)
tree425ea50195684e38e91a72767d645d5fd1ee2e3a
parentded8b949ca91eae8bfcc9d3337913dda620416b3 (diff)
downloadglibc-dc3be966c0050d3847ab528387801b9c93a2f831.tar.gz
glibc-dc3be966c0050d3847ab528387801b9c93a2f831.tar.xz
glibc-dc3be966c0050d3847ab528387801b9c93a2f831.zip
Updated to fedora-glibc-20090415T1619 cvs/fedora-glibc-2_9_90-17
-rw-r--r--ChangeLog46
-rw-r--r--elf/elf.h64
-rw-r--r--fedora/branch.mk4
-rw-r--r--fedora/glibc.spec.in7
-rw-r--r--sysdeps/sh/bits/setjmp.h4
-rw-r--r--sysdeps/sh/libc-tls.c33
-rw-r--r--sysdeps/unix/sysv/linux/fallocate.c5
-rw-r--r--sysdeps/unix/sysv/linux/fallocate64.c5
-rw-r--r--sysdeps/unix/sysv/linux/getsysstats.c40
-rw-r--r--sysdeps/x86_64/add_n.S42
-rw-r--r--sysdeps/x86_64/addmul_1.S46
-rw-r--r--sysdeps/x86_64/lshift.S60
-rw-r--r--sysdeps/x86_64/mp_clz_tab.c1
-rw-r--r--sysdeps/x86_64/mul_1.S42
-rw-r--r--sysdeps/x86_64/rshift.S62
-rw-r--r--sysdeps/x86_64/sub_n.S42
-rw-r--r--sysdeps/x86_64/submul_1.S46
17 files changed, 518 insertions, 31 deletions
diff --git a/ChangeLog b/ChangeLog
index 645a157aae..609ae61280 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,49 @@
+2009-04-15  Ulrich Drepper  <drepper@redhat.com>
+
+	* sysdeps/unix/sysv/linux/getsysstats.c (next_line): Make sure there
+	are always at least 4 bytes in the returned line.
+
+2009-04-15  Jakub Jelinek  <jakub@redhat.com>
+
+	* sysdeps/unix/sysv/linux/getsysstats.c (__get_nprocs): Check
+	__libc_use_alloca (8192), if the stack is too small use 512 bytes
+	instead of 8K.  Stop searching in /proc/stat after hitting first
+	line not starting with cpu.
+	(next_line): Truncate too long
+	lines at buffer size * 3/4 instead of pretending there were line
+	breaks inside of large lines.
+
+2009-04-14  Ulrich Drepper  <drepper@redhat.com>
+
+	* sysdeps/x86_64/mp_clz_tab.c: New file.
+
+2009-03-17  Ryan S. Arnold  <rsa@us.ibm.com>
+            Ulrich Drepper  <drepper@redhat.com>
+
+	* sysdeps/unix/sysv/linux/fallocate.c: Handle old kernel headers.
+	* sysdeps/unix/sysv/linux/fallocate64.c: Likewise.
+
+2009-03-25  Andrew Stubbs  <ams@codesourcery.com>
+
+	* sysdeps/sh/libc-tls.c: New file.
+
+	* sysdeps/sh/bits/setjmp.h (__jmp_buf): Give name to structure type.
+
+2009-04-14  Roland McGrath  <roland@redhat.com>
+
+	* elf/elf.h: Add various missing ARM constants, to match binutils.
+
+2009-04-14  Ulrich Drepper  <drepper@redhat.com>
+
+	Optimizations from GMP.
+	* sysdeps/x86_64/add_n.S: New file.
+	* sysdeps/x86_64/addmul_1.S: New file.
+	* sysdeps/x86_64/lshift.S: New file.
+	* sysdeps/x86_64/mul_1.S: New file.
+	* sysdeps/x86_64/rshift.S: New file.
+	* sysdeps/x86_64/sub_n.S: New file.
+	* sysdeps/x86_64/submul_1.S: New file.
+
 2009-04-14  Jakub Jelinek  <jakub@redhat.com>
 
 	* sysdeps/powerpc/powerpc32/elf/start.S: Ensure .data is non-empty.
diff --git a/elf/elf.h b/elf/elf.h
index 6259350260..062ef00f57 100644
--- a/elf/elf.h
+++ b/elf/elf.h
@@ -2205,42 +2205,62 @@ typedef Elf32_Addr Elf32_Conflict;
 /* ARM specific declarations */
 
 /* Processor specific flags for the ELF header e_flags field.  */
-#define EF_ARM_RELEXEC     0x01
-#define EF_ARM_HASENTRY    0x02
-#define EF_ARM_INTERWORK   0x04
-#define EF_ARM_APCS_26     0x08
-#define EF_ARM_APCS_FLOAT  0x10
-#define EF_ARM_PIC         0x20
-#define EF_ARM_ALIGN8      0x40		/* 8-bit structure alignment is in use */
-#define EF_ARM_NEW_ABI     0x80
-#define EF_ARM_OLD_ABI     0x100
+#define EF_ARM_RELEXEC		0x01
+#define EF_ARM_HASENTRY		0x02
+#define EF_ARM_INTERWORK	0x04
+#define EF_ARM_APCS_26		0x08
+#define EF_ARM_APCS_FLOAT	0x10
+#define EF_ARM_PIC		0x20
+#define EF_ARM_ALIGN8		0x40 /* 8-bit structure alignment is in use */
+#define EF_ARM_NEW_ABI		0x80
+#define EF_ARM_OLD_ABI		0x100
+#define EF_ARM_SOFT_FLOAT	0x200
+#define EF_ARM_VFP_FLOAT	0x400
+#define EF_ARM_MAVERICK_FLOAT	0x800
+
 
 /* Other constants defined in the ARM ELF spec. version B-01.  */
 /* NB. These conflict with values defined above.  */
 #define EF_ARM_SYMSARESORTED	0x04
-#define EF_ARM_DYNSYMSUSESEGIDX 0x08
+#define EF_ARM_DYNSYMSUSESEGIDX	0x08
 #define EF_ARM_MAPSYMSFIRST	0x10
 #define EF_ARM_EABIMASK		0XFF000000
 
-#define EF_ARM_EABI_VERSION(flags) ((flags) & EF_ARM_EABIMASK)
-#define EF_ARM_EABI_UNKNOWN  0x00000000
-#define EF_ARM_EABI_VER1     0x01000000
-#define EF_ARM_EABI_VER2     0x02000000
+/* Constants defined in AAELF.  */
+#define EF_ARM_BE8	    0x00800000
+#define EF_ARM_LE8	    0x00400000
+
+#define EF_ARM_EABI_VERSION(flags)	((flags) & EF_ARM_EABIMASK)
+#define EF_ARM_EABI_UNKNOWN	0x00000000
+#define EF_ARM_EABI_VER1	0x01000000
+#define EF_ARM_EABI_VER2	0x02000000
+#define EF_ARM_EABI_VER3	0x03000000
+#define EF_ARM_EABI_VER4	0x04000000
+#define EF_ARM_EABI_VER5	0x05000000
 
-/* Additional symbol types for Thumb */
-#define STT_ARM_TFUNC      0xd
+/* Additional symbol types for Thumb.  */
+#define STT_ARM_TFUNC		STT_LOPROC /* A Thumb function.  */
+#define STT_ARM_16BIT		STT_HIPROC /* A Thumb label.  */
 
 /* ARM-specific values for sh_flags */
-#define SHF_ARM_ENTRYSECT  0x10000000   /* Section contains an entry point */
-#define SHF_ARM_COMDEF     0x80000000   /* Section may be multiply defined
-					   in the input to a link step */
+#define SHF_ARM_ENTRYSECT	0x10000000 /* Section contains an entry point */
+#define SHF_ARM_COMDEF		0x80000000 /* Section may be multiply defined
+					      in the input to a link step.  */
 
 /* ARM-specific program header flags */
-#define PF_ARM_SB          0x10000000   /* Segment contains the location
-					   addressed by the static base */
+#define PF_ARM_SB		0x10000000 /* Segment contains the location
+					      addressed by the static base. */
+#define PF_ARM_PI		0x20000000 /* Position-independent segment.  */
+#define PF_ARM_ABS		0x40000000 /* Absolute segment.  */
 
 /* Processor specific values for the Phdr p_type field.  */
-#define PT_ARM_EXIDX	0x70000001	/* .ARM.exidx segment */
+#define PT_ARM_EXIDX		(PT_LOPROC + 1)	/* ARM unwind segment.  */
+
+/* Processor specific values for the Shdr sh_type field.  */
+#define SHT_ARM_EXIDX		(SHT_LOPROC + 1) /* ARM unwind section.  */
+#define SHT_ARM_PREEMPTMAP	(SHT_LOPROC + 2) /* Preemption details.  */
+#define SHT_ARM_ATTRIBUTES	(SHT_LOPROC + 3) /* ARM attributes section.  */
+
 
 /* ARM relocs.  */
 
diff --git a/fedora/branch.mk b/fedora/branch.mk
index 3b62c91029..507bd62742 100644
--- a/fedora/branch.mk
+++ b/fedora/branch.mk
@@ -3,5 +3,5 @@ glibc-branch := fedora
 glibc-base := HEAD
 DIST_BRANCH := devel
 COLLECTION := dist-f8
-fedora-sync-date := 2009-04-14 21:04 UTC
-fedora-sync-tag := fedora-glibc-20090414T2104
+fedora-sync-date := 2009-04-15 16:19 UTC
+fedora-sync-tag := fedora-glibc-20090415T1619
diff --git a/fedora/glibc.spec.in b/fedora/glibc.spec.in
index 8d22e2f00e..5c76e5a408 100644
--- a/fedora/glibc.spec.in
+++ b/fedora/glibc.spec.in
@@ -19,7 +19,7 @@
 Summary: The GNU libc libraries
 Name: glibc
 Version: @glibcversion@
-Release: 16
+Release: 17
 # GPLv2+ is used in a bunch of programs, LGPLv2+ is used for libraries.
 # Things that are linked directly into dynamically linked programs
 # and shared libraries (e.g. crt files, lib*_nonshared.a) have an additional
@@ -1009,6 +1009,11 @@ rm -f *.filelist*
 %endif
 
 %changelog
+* Wed Apr 15 2009 Jakub Jelinek <jakub@redhat.com> 2.9.90-17
+- update from trunk
+  - if threads have very small stack sizes, use much smaller buffer
+    in __get_nprocs when called from within malloc (#494631)
+
 * Tue Apr 14 2009 Jakub Jelinek <jakub@redhat.com> 2.9.90-16
 - update from trunk
 
diff --git a/sysdeps/sh/bits/setjmp.h b/sysdeps/sh/bits/setjmp.h
index 7e3fbd3394..6196abedd6 100644
--- a/sysdeps/sh/bits/setjmp.h
+++ b/sysdeps/sh/bits/setjmp.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1999,2000,2003,2005,2006 Free Software Foundation, Inc.
+/* Copyright (C) 1999,2000,2003,2005,2006,2009 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,7 +25,7 @@
 #endif
 
 #ifndef _ASM
-typedef struct
+typedef struct __jmp_buf_internal_tag
   {
     /* Callee-saved registers r8 through r15.  */
     int __regs[8];
diff --git a/sysdeps/sh/libc-tls.c b/sysdeps/sh/libc-tls.c
new file mode 100644
index 0000000000..1a7db55c50
--- /dev/null
+++ b/sysdeps/sh/libc-tls.c
@@ -0,0 +1,33 @@
+/* Thread-local storage handling in the ELF dynamic linker.  SH version.
+   Copyright (C) 2009 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 <csu/libc-tls.c>
+#include <dl-tls.h>
+
+/* On SH, linker optimizations are not required, so __tls_get_addr
+   can be called even in statically linked binaries.  In this case module
+   must be always 1 and PT_TLS segment exist in the binary, otherwise it
+   would not link.  */
+
+void *
+__tls_get_addr (tls_index *ti)
+{
+  dtv_t *dtv = THREAD_DTV ();
+  return (char *) dtv[1].pointer.val + ti->ti_offset;
+}
diff --git a/sysdeps/unix/sysv/linux/fallocate.c b/sysdeps/unix/sysv/linux/fallocate.c
index a45b0f831d..116f00046e 100644
--- a/sysdeps/unix/sysv/linux/fallocate.c
+++ b/sysdeps/unix/sysv/linux/fallocate.c
@@ -25,7 +25,12 @@
 int
 fallocate (int fd, int mode, __off_t offset, __off_t len)
 {
+#ifndef __NR_fallocate
   return INLINE_SYSCALL (fallocate, 6, fd, mode,
 			 __LONG_LONG_PAIR (offset >> 31, offset),
 			 __LONG_LONG_PAIR (len >> 31, len));
+#else
+  __set_errno (ENOSYS);
+  return -1;
+#endif
 }
diff --git a/sysdeps/unix/sysv/linux/fallocate64.c b/sysdeps/unix/sysv/linux/fallocate64.c
index 601a70ba1f..2fbe988910 100644
--- a/sysdeps/unix/sysv/linux/fallocate64.c
+++ b/sysdeps/unix/sysv/linux/fallocate64.c
@@ -25,9 +25,14 @@
 int
 __fallocate64_l64 (int fd, int mode, __off64_t offset, __off64_t len)
 {
+#ifndef __NR_fallocate
   return INLINE_SYSCALL (fallocate, 6, fd, mode,
 			 __LONG_LONG_PAIR ((long int) (offset >> 32),
 					   (long int) offset),
 			 __LONG_LONG_PAIR ((long int) (len >> 32),
 					   (long int) len));
+#else
+  __set_errno (ENOSYS);
+  return -1;
+#endif
 }
diff --git a/sysdeps/unix/sysv/linux/getsysstats.c b/sysdeps/unix/sysv/linux/getsysstats.c
index 28f52c0463..97e20d249b 100644
--- a/sysdeps/unix/sysv/linux/getsysstats.c
+++ b/sysdeps/unix/sysv/linux/getsysstats.c
@@ -93,15 +93,42 @@ next_line (int fd, char *const buffer, char **cp, char **re,
 		return NULL;
 
 	      *re += n;
+
+	      nl = memchr (*cp, '\n', *re - *cp);
+	      while (nl == NULL && *re == buffer_end)
+		{
+		  /* Truncate too long lines.  */
+		  *re = buffer + 3 * (buffer_end - buffer) / 4;
+		  n = read_not_cancel (fd, *re, buffer_end - *re);
+		  if (n < 0)
+		    return NULL;
+
+		  nl = memchr (*re, '\n', n);
+		  **re = '\n';
+		  *re += n;
+		}
 	    }
+	  else
+	    nl = memchr (*cp, '\n', *re - *cp);
 
 	  res = *cp;
-	  nl = memchr (*cp, '\n', *re - *cp);
 	}
 
       if (nl == NULL)
 	nl = *re - 1;
     }
+  else if (nl + 5 >= *re)
+    {
+      memmove (buffer, nl, *re - nl);
+      *re = buffer + (*re - nl);
+      nl = *cp = buffer;
+
+      ssize_t n = read_not_cancel (fd, *re, buffer_end - *re);
+      if (n < 0)
+	return NULL;
+
+      *re += n;
+    }
 
   *cp = nl + 1;
   assert (*cp <= *re);
@@ -115,8 +142,9 @@ __get_nprocs ()
 {
   /* XXX Here will come a test for the new system call.  */
 
-  char buffer[8192];
-  char *const buffer_end = buffer + sizeof (buffer);
+  const size_t buffer_size = __libc_use_alloca (8192) ? 8192 : 512;
+  char *buffer = alloca (buffer_size);
+  char *buffer_end = buffer + buffer_size;
   char *cp = buffer_end;
   char *re = buffer_end;
   int result = 1;
@@ -134,7 +162,11 @@ __get_nprocs ()
 
       char *l;
       while ((l = next_line (fd, buffer, &cp, &re, buffer_end)) != NULL)
-	if (strncmp (l, "cpu", 3) == 0 && isdigit (l[3]))
+	/* The current format of /proc/stat has all the cpu* entries
+	   at the front.  We assume here that stays this way.  */
+	if (strncmp (l, "cpu", 3) != 0)
+	  break;
+	else if (isdigit (l[3]))
 	  ++result;
 
       close_not_cancel_no_status (fd);
diff --git a/sysdeps/x86_64/add_n.S b/sysdeps/x86_64/add_n.S
new file mode 100644
index 0000000000..7883f6c840
--- /dev/null
+++ b/sysdeps/x86_64/add_n.S
@@ -0,0 +1,42 @@
+/* Add two limb vectors of the same length > 0 and store sum in a third
+   limb vector.
+   Copyright (C) 2004 Free Software Foundation, Inc.
+   This file is part of the GNU MP Library.
+
+   The GNU MP Library is free software; you can redistribute it and/or modify
+   it under the terms of the GNU Lesser General Public License as published by
+   the Free Software Foundation; either version 2.1 of the License, or (at your
+   option) any later version.
+
+   The GNU MP Library is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
+   License for more details.
+
+   You should have received a copy of the GNU Lesser General Public License
+   along with the GNU MP Library; see the file COPYING.LIB.  If not, write to
+   the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+   MA 02111-1307, USA. */
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+	.text
+ENTRY (__mpn_add_n)
+	leaq	(%rsi,%rcx,8), %rsi
+	leaq	(%rdi,%rcx,8), %rdi
+	leaq	(%rdx,%rcx,8), %rdx
+	negq	%rcx
+	xorl	%eax, %eax			# clear cy
+	.p2align 2
+L(loop):
+	movq	(%rsi,%rcx,8), %rax
+	movq	(%rdx,%rcx,8), %r10
+	adcq	%r10, %rax
+	movq	%rax, (%rdi,%rcx,8)
+	incq	%rcx
+	jne	L(loop)
+	movq	%rcx, %rax			# zero %rax
+	adcq	%rax, %rax
+	ret
+END (__mpn_add_n)
diff --git a/sysdeps/x86_64/addmul_1.S b/sysdeps/x86_64/addmul_1.S
new file mode 100644
index 0000000000..bdb5226a33
--- /dev/null
+++ b/sysdeps/x86_64/addmul_1.S
@@ -0,0 +1,46 @@
+/* AMD64 __mpn_addmul_1 -- Multiply a limb vector with a limb and add
+   the result to a second limb vector.
+   Copyright (C) 2004 Free Software Foundation, Inc.
+   This file is part of the GNU MP Library.
+
+   The GNU MP Library is free software; you can redistribute it and/or modify
+   it under the terms of the GNU Lesser General Public License as published by
+   the Free Software Foundation; either version 2.1 of the License, or (at your
+   option) any later version.
+
+   The GNU MP Library is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
+   License for more details.
+
+   You should have received a copy of the GNU Lesser General Public License
+   along with the GNU MP Library; see the file COPYING.LIB.  If not, write to
+   the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+   MA 02111-1307, USA. */
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+	.text
+ENTRY (__mpn_addmul_1)
+	movq	%rdx, %r11
+	leaq	(%rsi,%rdx,8), %rsi
+	leaq	(%rdi,%rdx,8), %rdi
+	negq	%r11
+	xorl	%r8d, %r8d
+	xorl	%r10d, %r10d
+	.p2align 2
+L(loop):
+	movq	(%rsi,%r11,8), %rax
+	mulq	%rcx
+	addq	(%rdi,%r11,8), %rax
+	adcq	%r10, %rdx
+	addq	%r8, %rax
+	movq	%r10, %r8
+	movq	%rax, (%rdi,%r11,8)
+	adcq	%rdx, %r8
+	incq	%r11
+	jne	L(loop)
+	movq	%r8, %rax
+	ret
+END (__mpn_addmul_1)
diff --git a/sysdeps/x86_64/lshift.S b/sysdeps/x86_64/lshift.S
new file mode 100644
index 0000000000..5ac66f0a36
--- /dev/null
+++ b/sysdeps/x86_64/lshift.S
@@ -0,0 +1,60 @@
+/* AMD64 __mpn_lshift --
+   Copyright 2004, 2006 Free Software Foundation, Inc.
+   This file is part of the GNU MP Library.
+
+   The GNU MP Library is free software; you can redistribute it and/or modify
+   it under the terms of the GNU Lesser General Public License as published by
+   the Free Software Foundation; either version 2.1 of the License, or (at your
+   option) any later version.
+
+   The GNU MP Library is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
+   License for more details.
+
+   You should have received a copy of the GNU Lesser General Public License
+   along with the GNU MP Library; see the file COPYING.LIB.  If not, write to
+   the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+   MA 02111-1307, USA. */
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+
+	.text
+ENTRY (__mpn_lshift)
+	movq	-8(%rsi,%rdx,8), %mm7
+	movd	%ecx, %mm1
+	movl	$64, %eax
+	subl	%ecx, %eax
+	movd	%eax, %mm0
+	movq	%mm7, %mm3
+	psrlq	%mm0, %mm7
+	movd	%mm7, %rax
+	subq	$2, %rdx
+	jl	L(endo)
+	.p2align 2
+L(loop):
+	movq	(%rsi,%rdx,8), %mm6
+	movq	%mm6, %mm2
+	psrlq	%mm0, %mm6
+	psllq	%mm1, %mm3
+	por	%mm6, %mm3
+	movq	%mm3, 8(%rdi,%rdx,8)
+	je	L(ende)
+	movq	-8(%rsi,%rdx,8), %mm7
+	movq	%mm7, %mm3
+	psrlq	%mm0, %mm7
+	psllq	%mm1, %mm2
+	por	%mm7, %mm2
+	movq	%mm2, (%rdi,%rdx,8)
+	subq	$2, %rdx
+	jge	L(loop)
+L(endo):
+	movq	%mm3, %mm2
+L(ende):
+	psllq	%mm1, %mm2
+	movq	%mm2, (%rdi)
+	emms
+	ret
+END (__mpn_lshift)
diff --git a/sysdeps/x86_64/mp_clz_tab.c b/sysdeps/x86_64/mp_clz_tab.c
new file mode 100644
index 0000000000..7b13a394da
--- /dev/null
+++ b/sysdeps/x86_64/mp_clz_tab.c
@@ -0,0 +1 @@
+/* __clz_tab not needed on x86-64.  */
diff --git a/sysdeps/x86_64/mul_1.S b/sysdeps/x86_64/mul_1.S
new file mode 100644
index 0000000000..978916b72c
--- /dev/null
+++ b/sysdeps/x86_64/mul_1.S
@@ -0,0 +1,42 @@
+/* AMD64 __mpn_mul_1 -- Multiply a limb vector with a limb and store
+   the result in a second limb vector.
+   Copyright (C) 2004 Free Software Foundation, Inc.
+   This file is part of the GNU MP Library.
+
+   The GNU MP Library is free software; you can redistribute it and/or modify
+   it under the terms of the GNU Lesser General Public License as published by
+   the Free Software Foundation; either version 2.1 of the License, or (at your
+   option) any later version.
+
+   The GNU MP Library is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
+   License for more details.
+
+   You should have received a copy of the GNU Lesser General Public License
+   along with the GNU MP Library; see the file COPYING.LIB.  If not, write to
+   the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+   MA 02111-1307, USA. */
+
+#include <sysdep.h>
+#include "asm-syntax.h"
+
+	.text
+ENTRY (__mpn_mul_1)
+	movq	%rdx, %r11
+	leaq	(%rsi,%rdx,8), %rsi
+	leaq	(%rdi,%rdx,8), %rdi
+	negq	%r11
+	xorl	%r8d, %r8d
+L(loop):
+	movq	(%rsi,%r11,8), %rax
+	mulq	%rcx
+	addq	%r8, %rax
+	movl	$0, %r8d
+	adcq	%rdx, %r8
+	movq	%rax, (%rdi,%r11,8)
+	incq	%r11
+	jne	L(loop)
+	movq	%r8, %rax
+	ret
+END (__mpn_mul_1)
diff --git a/sysdeps/x86_64/rshift.S b/sysdeps/x86_64/rshift.S
new file mode 100644
index 0000000000..ee0c8aa15c
--- /dev/null
+++ b/sysdeps/x86_64/rshift.S
@@ -0,0 +1,62 @@
+/* AMD64 __mpn_rshift --
+   Copyright (C) 2004, 2006 Free Software Foundation, Inc.
+   This file is part of the GNU MP Library.
+
+   The GNU MP Library is free software; you can redistribute it and/or modify
+   it under the terms of the GNU Lesser General Public License as published by
+   the Free Software Foundation; either version 2.1 of the License, or (at your
+   option) any later version.
+
+   The GNU MP Library is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
+   License for more details.
+
+   You should have received a copy of the GNU Lesser General Public License
+   along with the GNU MP Library; see the file COPYING.LIB.  If not, write to
+   the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+   MA 02111-1307, USA. */
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+	.text
+ENTRY (__mpn_rshift)
+	movq	(%rsi), %mm7
+	movd	%ecx, %mm1
+	movl	$64, %eax
+	subl	%ecx, %eax
+	movd	%eax, %mm0
+	movq	%mm7, %mm3
+	psllq	%mm0, %mm7
+	movd	%mm7, %rax
+	leaq	(%rsi,%rdx,8), %rsi
+	leaq	(%rdi,%rdx,8), %rdi
+	negq	%rdx
+	addq	$2, %rdx
+	jg	L(endo)
+	.p2align 2
+L(loop):
+	movq	-8(%rsi,%rdx,8), %mm6
+	movq	%mm6, %mm2
+	psllq	%mm0, %mm6
+	psrlq	%mm1, %mm3
+	por	%mm6, %mm3
+	movq	%mm3, -16(%rdi,%rdx,8)
+	je	L(ende)
+	movq	(%rsi,%rdx,8), %mm7
+	movq	%mm7, %mm3
+	psllq	%mm0, %mm7
+	psrlq	%mm1, %mm2
+	por	%mm7, %mm2
+	movq	%mm2, -8(%rdi,%rdx,8)
+	addq	$2, %rdx
+	jle	L(loop)
+L(endo):
+	movq	%mm3, %mm2
+L(ende):
+	psrlq	%mm1, %mm2
+	movq	%mm2, -8(%rdi)
+	emms
+	ret
+END (__mpn_rshift)
diff --git a/sysdeps/x86_64/sub_n.S b/sysdeps/x86_64/sub_n.S
new file mode 100644
index 0000000000..48e1a2e0f4
--- /dev/null
+++ b/sysdeps/x86_64/sub_n.S
@@ -0,0 +1,42 @@
+/* AMD64 __mpn_sub_n -- Add two limb vectors of the same length > 0 and store
+   sum in a third limb vector.
+   Copyright (C) 2004 Free Software Foundation, Inc.
+   This file is part of the GNU MP Library.
+
+   The GNU MP Library is free software; you can redistribute it and/or modify
+   it under the terms of the GNU Lesser General Public License as published by
+   the Free Software Foundation; either version 2.1 of the License, or (at your
+   option) any later version.
+
+   The GNU MP Library is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
+   License for more details.
+
+   You should have received a copy of the GNU Lesser General Public License
+   along with the GNU MP Library; see the file COPYING.LIB.  If not, write to
+   the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+   MA 02111-1307, USA. */
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+	.text
+ENTRY (__mpn_sub_n)
+	leaq	(%rsi,%rcx,8), %rsi
+	leaq	(%rdi,%rcx,8), %rdi
+	leaq	(%rdx,%rcx,8), %rdx
+	negq	%rcx
+	xorl	%eax, %eax		# clear cy
+	.p2align 2
+L(loop):
+	movq	(%rsi,%rcx,8), %rax
+	movq	(%rdx,%rcx,8), %r10
+	sbbq	%r10, %rax
+	movq	%rax, (%rdi,%rcx,8)
+	incq	%rcx
+	jne	L(loop)
+	movq	%rcx, %rax		# zero %rax
+	adcq	%rax, %rax
+	ret
+END (__mpn_sub_n)
diff --git a/sysdeps/x86_64/submul_1.S b/sysdeps/x86_64/submul_1.S
new file mode 100644
index 0000000000..e94c9a7bee
--- /dev/null
+++ b/sysdeps/x86_64/submul_1.S
@@ -0,0 +1,46 @@
+/* AMD64 __mpn_submul_1 -- Multiply a limb vector with a limb and subtract
+   the result from a second limb vector.
+   Copyright (C) 2004 Free Software Foundation, Inc.
+   This file is part of the GNU MP Library.
+
+   The GNU MP Library is free software; you can redistribute it and/or modify
+   it under the terms of the GNU Lesser General Public License as published by
+   the Free Software Foundation; either version 2.1 of the License, or (at your
+   option) any later version.
+
+   The GNU MP Library is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
+   License for more details.
+
+   You should have received a copy of the GNU Lesser General Public License
+   along with the GNU MP Library; see the file COPYING.LIB.  If not, write to
+   the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+   MA 02111-1307, USA. */
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+	.text
+ENTRY (__mpn_submul_1)
+	movq	%rdx, %r11
+	leaq	(%rsi,%r11,8), %rsi
+	leaq	(%rdi,%r11,8), %rdi
+	negq	%r11
+	xorl	%r8d, %r8d
+	.p2align 3
+L(loop):
+	movq	(%rsi,%r11,8), %rax
+	movq	(%rdi,%r11,8), %r10
+	mulq	%rcx
+	subq	%r8, %r10
+	movl	$0, %r8d
+	adcl	%r8d, %r8d
+	subq	%rax, %r10
+	adcq	%rdx, %r8
+	movq	%r10, (%rdi,%r11,8)
+	incq	%r11
+	jne	L(loop)
+	movq	%r8, %rax
+	ret
+END (__mpn_submul_1)