This is the mail archive of the libc-ports@sources.redhat.com mailing list for the libc-ports project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] am33: bring port up to date with NPTL support


This is a first cut at bringing the AM33 port up to date. The basis of
the NPTL support comes from an older working implementation based on
glibc 2.9. Additional changes have been made to deal with glibc changes
and a newer gcc. Currently, this is untested pending some gcc tls support
fixes.
---
 sysdeps/am33/Makefile                              |   20 +
 sysdeps/am33/Versions                              |    5 +
 sysdeps/am33/atomicity.h                           |   11 +-
 sysdeps/am33/bits/atomic.h                         |  219 +++++++
 sysdeps/am33/bits/link.h                           |   57 ++
 sysdeps/am33/bits/linkmap.h                        |    5 +
 sysdeps/am33/bits/setjmp.h                         |   40 +-
 sysdeps/am33/crti.S                                |   84 +++
 sysdeps/am33/crtn.S                                |   46 ++
 sysdeps/am33/dl-machine.h                          |  376 ++++++------
 sysdeps/am33/dl-tls.h                              |   31 +
 sysdeps/am33/dl-trampoline.S                       |  178 ++++++
 sysdeps/am33/elf/configure                         |   84 +++
 sysdeps/am33/elf/configure.in                      |   37 ++
 sysdeps/am33/elf/start.S                           |   34 +-
 sysdeps/am33/fpu/bits/fenv.h                       |    6 +
 sysdeps/am33/fpu/fclrexcpt.c                       |   12 +-
 sysdeps/am33/fpu/fedisblxcpt.c                     |    3 +-
 sysdeps/am33/fpu/feenablxcpt.c                     |    3 +-
 sysdeps/am33/fpu/feholdexcpt.c                     |    8 +-
 sysdeps/am33/fpu/fesetenv.c                        |   25 +-
 sysdeps/am33/fpu/fesetround.c                      |    2 +
 sysdeps/am33/fpu/fpu_control.h                     |   14 +-
 sysdeps/am33/fpu/fraiseexcpt.c                     |   36 +-
 sysdeps/am33/fpu/fsetexcptflg.c                    |   18 +-
 sysdeps/am33/fpu/libm-test-ulps                    |  605 ++++++++++++++++++++
 sysdeps/am33/init-misc.c                           |   48 ++
 sysdeps/am33/ldsodefs.h                            |   41 ++
 sysdeps/am33/linuxthreads/pspinlock.c              |   73 ---
 sysdeps/am33/linuxthreads/pt-machine.h             |   67 ---
 sysdeps/am33/machine-gmon.h                        |   28 +
 sysdeps/am33/memusage.h                            |    2 +-
 sysdeps/am33/nptl/Makefile                         |   21 +
 sysdeps/am33/nptl/jmpbuf-unwind.h                  |   31 +
 sysdeps/am33/nptl/pthread_spin_lock.c              |   29 +
 sysdeps/am33/nptl/pthread_spin_trylock.c           |   33 ++
 sysdeps/am33/nptl/pthread_spin_unlock.c            |   29 +
 sysdeps/am33/nptl/pthreaddef.h                     |   41 ++
 sysdeps/am33/nptl/tcb-offsets.sym                  |    6 +
 sysdeps/am33/nptl/tls.h                            |  172 ++++++
 sysdeps/am33/setjmp.S                              |    4 +
 sysdeps/am33/stackinfo.h                           |    6 +
 sysdeps/am33/sysdep.h                              |   17 +-
 sysdeps/am33/tls-macros.h                          |   91 +++
 sysdeps/am33/tst-audit.h                           |   26 +
 sysdeps/arm/dl-machine.h                           |    3 +-
 sysdeps/unix/am33/sysdep.S                         |   38 +-
 sysdeps/unix/sysv/linux/am33/____longjmp_chk.c     |   57 ++
 sysdeps/unix/sysv/linux/am33/bits/fcntl.h          |   34 +-
 sysdeps/unix/sysv/linux/am33/bits/mman.h           |   20 +-
 sysdeps/unix/sysv/linux/am33/brk.c                 |    2 +-
 sysdeps/unix/sysv/linux/am33/clone.S               |   58 +-
 sysdeps/unix/sysv/linux/am33/fxstatat.c            |    1 +
 .../sysv/linux/am33/linuxthreads/sysdep-cancel.h   |  158 -----
 sysdeps/unix/sysv/linux/am33/mmap.S                |   67 +++
 sysdeps/unix/sysv/linux/am33/mmap64.S              |   74 +++
 sysdeps/unix/sysv/linux/am33/nptl/Makefile         |    6 +
 sysdeps/unix/sysv/linux/am33/nptl/Versions         |    8 +
 .../unix/sysv/linux/am33/nptl/bits/pthreadtypes.h  |  173 ++++++
 sysdeps/unix/sysv/linux/am33/nptl/bits/semaphore.h |   37 ++
 sysdeps/unix/sysv/linux/am33/nptl/clone.S          |    3 +
 sysdeps/unix/sysv/linux/am33/nptl/fork.c           |   31 +
 .../unix/sysv/linux/am33/nptl/libc_pthread_init.c  |   92 +++
 sysdeps/unix/sysv/linux/am33/nptl/lowlevellock.h   |  293 ++++++++++
 sysdeps/unix/sysv/linux/am33/nptl/pt-vfork.S       |   36 ++
 sysdeps/unix/sysv/linux/am33/nptl/pthread_once.c   |   99 ++++
 sysdeps/unix/sysv/linux/am33/nptl/sysdep-cancel.h  |  116 ++++
 .../sysv/linux/am33/nptl/unwind-forcedunwind.c     |  140 +++++
 sysdeps/unix/sysv/linux/am33/nptl/unwind-resume.c  |   87 +++
 sysdeps/unix/sysv/linux/am33/nptl/unwind.h         |   52 ++
 sysdeps/unix/sysv/linux/am33/nptl/vfork.S          |   37 ++
 sysdeps/unix/sysv/linux/am33/profil-counter.h      |    6 +-
 sysdeps/unix/sysv/linux/am33/socket.S              |   41 +-
 sysdeps/unix/sysv/linux/am33/sys/procfs.h          |  124 ++++
 sysdeps/unix/sysv/linux/am33/sys/ucontext.h        |  127 ++++
 sysdeps/unix/sysv/linux/am33/sys/user.h            |   47 ++
 sysdeps/unix/sysv/linux/am33/sysdep.h              |  249 +++++---
 sysdeps/unix/sysv/linux/am33/vfork.S               |   62 ++
 78 files changed, 4390 insertions(+), 712 deletions(-)
 create mode 100644 sysdeps/am33/Makefile
 create mode 100644 sysdeps/am33/Versions
 create mode 100644 sysdeps/am33/bits/atomic.h
 create mode 100644 sysdeps/am33/bits/link.h
 create mode 100644 sysdeps/am33/bits/linkmap.h
 create mode 100644 sysdeps/am33/crti.S
 create mode 100644 sysdeps/am33/crtn.S
 create mode 100644 sysdeps/am33/dl-tls.h
 create mode 100644 sysdeps/am33/dl-trampoline.S
 create mode 100644 sysdeps/am33/elf/configure
 create mode 100644 sysdeps/am33/elf/configure.in
 create mode 100644 sysdeps/am33/fpu/libm-test-ulps
 create mode 100644 sysdeps/am33/init-misc.c
 create mode 100644 sysdeps/am33/ldsodefs.h
 delete mode 100644 sysdeps/am33/linuxthreads/pspinlock.c
 delete mode 100644 sysdeps/am33/linuxthreads/pt-machine.h
 create mode 100644 sysdeps/am33/machine-gmon.h
 create mode 100644 sysdeps/am33/nptl/Makefile
 create mode 100644 sysdeps/am33/nptl/jmpbuf-unwind.h
 create mode 100644 sysdeps/am33/nptl/pthread_spin_lock.c
 create mode 100644 sysdeps/am33/nptl/pthread_spin_trylock.c
 create mode 100644 sysdeps/am33/nptl/pthread_spin_unlock.c
 create mode 100644 sysdeps/am33/nptl/pthreaddef.h
 create mode 100644 sysdeps/am33/nptl/tcb-offsets.sym
 create mode 100644 sysdeps/am33/nptl/tls.h
 create mode 100644 sysdeps/am33/tls-macros.h
 create mode 100644 sysdeps/am33/tst-audit.h
 create mode 100644 sysdeps/unix/sysv/linux/am33/____longjmp_chk.c
 create mode 100644 sysdeps/unix/sysv/linux/am33/fxstatat.c
 delete mode 100644 sysdeps/unix/sysv/linux/am33/linuxthreads/sysdep-cancel.h
 create mode 100644 sysdeps/unix/sysv/linux/am33/mmap.S
 create mode 100644 sysdeps/unix/sysv/linux/am33/mmap64.S
 create mode 100644 sysdeps/unix/sysv/linux/am33/nptl/Makefile
 create mode 100644 sysdeps/unix/sysv/linux/am33/nptl/Versions
 create mode 100644 sysdeps/unix/sysv/linux/am33/nptl/bits/pthreadtypes.h
 create mode 100644 sysdeps/unix/sysv/linux/am33/nptl/bits/semaphore.h
 create mode 100644 sysdeps/unix/sysv/linux/am33/nptl/clone.S
 create mode 100644 sysdeps/unix/sysv/linux/am33/nptl/fork.c
 create mode 100644 sysdeps/unix/sysv/linux/am33/nptl/libc_pthread_init.c
 create mode 100644 sysdeps/unix/sysv/linux/am33/nptl/lowlevellock.h
 create mode 100644 sysdeps/unix/sysv/linux/am33/nptl/pt-vfork.S
 create mode 100644 sysdeps/unix/sysv/linux/am33/nptl/pthread_once.c
 create mode 100644 sysdeps/unix/sysv/linux/am33/nptl/sysdep-cancel.h
 create mode 100644 sysdeps/unix/sysv/linux/am33/nptl/unwind-forcedunwind.c
 create mode 100644 sysdeps/unix/sysv/linux/am33/nptl/unwind-resume.c
 create mode 100644 sysdeps/unix/sysv/linux/am33/nptl/unwind.h
 create mode 100644 sysdeps/unix/sysv/linux/am33/nptl/vfork.S
 create mode 100644 sysdeps/unix/sysv/linux/am33/sys/procfs.h
 create mode 100644 sysdeps/unix/sysv/linux/am33/sys/ucontext.h
 create mode 100644 sysdeps/unix/sysv/linux/am33/sys/user.h
 create mode 100644 sysdeps/unix/sysv/linux/am33/vfork.S

diff --git a/sysdeps/am33/Makefile b/sysdeps/am33/Makefile
new file mode 100644
index 0000000..0166649
--- /dev/null
+++ b/sysdeps/am33/Makefile
@@ -0,0 +1,20 @@
+# Copyright (C) 2009 Free Software Foundation, Inc.
+# This file is part of the GNU C Library.
+# Contributed by Mark Salter <msalter@redhat.com>.
+
+# 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.
+
+pic-ccflag = -fPIC
diff --git a/sysdeps/am33/Versions b/sysdeps/am33/Versions
new file mode 100644
index 0000000..b9fb633
--- /dev/null
+++ b/sysdeps/am33/Versions
@@ -0,0 +1,5 @@
+libc {
+  GLIBC_2.9 {
+    __mn10300_hwcap;
+  }
+}
diff --git a/sysdeps/am33/atomicity.h b/sysdeps/am33/atomicity.h
index b0ba43d..b3ba5a4 100644
--- a/sysdeps/am33/atomicity.h
+++ b/sysdeps/am33/atomicity.h
@@ -1,5 +1,5 @@
 /* Low-level functions for atomic operations.  AM33 version.
-   Copyright 1999, 2001 Free Software Foundation, Inc.
+   Copyright 1999, 2001, 2009 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Alexandre Oliva <aoliva@redhat.com>.
    Based on ../sparc/sparc32/atomicity.h
@@ -25,11 +25,14 @@
 
 #define __acquire_lock(lock) \
   __asm__ __volatile__("1:	bset	%1, (%0)\n\t"		\
-		       "	beq	1b"			\
+		       "	bne	1b"			\
 		       : : "a" (&(lock)), "d" (1)		\
-		       : "memory")
+		       : "memory", "cc" )
 
-#define __release_lock(lock) lock = 0
+#define __release_lock(lock) \
+  __asm__ __volatile__("	bclr	%1, (%0)\n\t"		\
+		       : : "a" (&(lock)), "d" (1)		\
+		       : "memory", "cc")
 
 static int
 __attribute__ ((unused))
diff --git a/sysdeps/am33/bits/atomic.h b/sysdeps/am33/bits/atomic.h
new file mode 100644
index 0000000..fd72cff
--- /dev/null
+++ b/sysdeps/am33/bits/atomic.h
@@ -0,0 +1,219 @@
+/* Atomic operations.  am33 version.
+   Copyright (C) 2009, 2010 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Mark Salter <msalter@redhat.com>
+   Based on sparc32.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#ifndef _BITS_ATOMIC_H
+#define _BITS_ATOMIC_H	1
+
+#include <stdint.h>
+
+#ifndef HWCAP_MN10300_ATOMIC_OP_UNIT
+#define HWCAP_MN10300_ATOMIC_OP_UNIT 1
+#endif
+
+#ifdef IS_IN_rtld
+#ifdef GLRO
+#define __HWCAP GLRO(dl_hwcap)
+#else
+extern unsigned long long _dl_mn10300_hwcap;
+#define __HWCAP _dl_mn10300_hwcap
+#endif
+#else  /* IS_IN_rtld */
+extern unsigned long long __mn10300_hwcap;
+#define __HWCAP __mn10300_hwcap
+#endif /* IS_IN_rtld */
+
+#ifndef __HAVE_ATOMIC_OP_UNIT
+#define __HAVE_ATOMIC_OP_UNIT (__HWCAP & HWCAP_MN10300_ATOMIC_OP_UNIT)
+#endif
+
+#if 0
+/* Force segfault if atomic op unit not used.
+ * Useful when debugging atomic ops on smp machines
+ */
+#define __HWCHECK() *((int *)5)=1
+#else
+#define __HWCHECK()
+#endif
+
+typedef int32_t atomic32_t;
+typedef uint32_t uatomic32_t;
+typedef int_fast32_t atomic_fast32_t;
+typedef uint_fast32_t uatomic_fast32_t;
+
+typedef intptr_t atomicptr_t;
+typedef uintptr_t uatomicptr_t;
+typedef intmax_t atomic_max_t;
+typedef uintmax_t uatomic_max_t;
+
+/* The only basic operation needed is compare and exchange.  */
+
+/* We may have no compare and swap, just test and set.
+   If there is no hw atomic compare and swap, the following implementation
+   contends on 64 global locks per library and assumes no variable will be
+   accessed using atomic.h macros from two different libraries.  */
+
+__make_section_unallocated
+  (".gnu.linkonce.b.__am33_atomic_locks, \"aw\", %nobits");
+
+volatile unsigned char __am33_atomic_locks[64]
+  __attribute__ ((nocommon, section (".gnu.linkonce.b.__am33_atomic_locks"
+				     __sec_comment),
+		  visibility ("hidden")));
+
+#define __sw_cmpxch_val_acq_32(mem, newval, oldval)			\
+({									\
+    unsigned long	__swcev_ret;					\
+    volatile unsigned char *__l;					\
+    __l = &__am33_atomic_locks[(((long)(mem) >> 2)			\
+				^ ((long)(mem) >> 12)) & 63];		\
+									\
+    __asm__ volatile (							\
+	    "0:\n\t"							\
+	    "bset %2, (%1)\n\t"						\
+	    "bne 0b\n\t"						\
+	    "mov (%3),%0\n\t"						\
+	    "cmp %0,%5\n\t"						\
+	    "bne 1f\n\t"						\
+	    "mov %4,(%3)\n\t"						\
+	    "1:\n\t"							\
+	    "bclr %2, (%1)\n\t"						\
+	    : "=&r" (__swcev_ret)					\
+	    : "a" (__l), "d" (1), "a" (mem), "r" (newval), "r" (oldval)	\
+	    : "memory", "cc");						\
+    ((__typeof (*(mem)))__swcev_ret);					\
+})
+
+#define __sw_cmpxch_bool_acq_32(mem, newval, oldval)			\
+({									\
+    unsigned long	__swceb_ret = 1;				\
+    unsigned long	__swceb_tmp;					\
+    volatile unsigned char *__l;					\
+    __l = &__am33_atomic_locks[(((long)(mem) >> 2)			\
+				^ ((long)(mem) >> 12)) & 63];		\
+									\
+    __asm__ volatile (							\
+	    "0:\n\t"							\
+	    "bset %3, (%2)\n\t"						\
+	    "bne 0b\n\t"						\
+	    "mov (%4),%0\n\t"						\
+	    "cmp %0,%6\n\t"						\
+	    "bne 1f\n\t"						\
+	    "mov %5,(%4)\n\t"						\
+	    "xor %1,%1\n\t"						\
+	    "1:\n\t"							\
+	    "bclr %3, (%2)\n\t"						\
+	    : "=&r" (__swceb_tmp), "=&r" (__swceb_ret)			\
+	    : "a" (__l), "d" (1), "a" (mem),				\
+	      "r" (newval), "r" (oldval), "1" (__swceb_ret)		\
+	    : "memory", "cc");						\
+    __swceb_ret;							\
+})
+
+#define MMAP_AARU_ADDR  	0x70000a00
+#define __ATOMIC_ADDR     	0x0
+#define __ATOMIC_DATA     	0x8
+#define __ATOMIC_STATUS     	0xC
+
+#define __hw_cmpxch_val_acq_32(mem, newval, oldval)			\
+({									\
+    unsigned long	__hwcev_ret;					\
+    unsigned long	__hwcev_status;					\
+									\
+    __asm__ volatile (							\
+	    "1:mov %3,(%2)\n"						\
+	    "  mov (%6,%2),%0\n"					\
+	    "  mov %0,%1\n"						\
+	    "  cmp  %4,%1\n"						\
+	    "  bne 2f\n"						\
+	    "  mov %5,(%6,%2)\n"					\
+	    "2:mov (%6,%2),%0\n"					\
+	    "  mov (%7,%2),%0\n"					\
+	    "  or %0,%0\n"						\
+	    "  bne 1b\n"						\
+	    :"=&r" (__hwcev_status), "=&r" (__hwcev_ret)		\
+	    :"a" (MMAP_AARU_ADDR), "r" (mem),				\
+	     "r" (oldval), "r" (newval),				\
+	     "i" (__ATOMIC_DATA), "i" (__ATOMIC_STATUS)			\
+	    :"memory", "cc");						\
+    ((__typeof (*(mem)))__hwcev_ret);					\
+})
+
+#define __hw_cmpxch_bool_acq_32(mem, newval, oldval)			\
+({									\
+    int __hwceb_ret = 1;						\
+    unsigned long __hwceb_status;					\
+									\
+    __asm__ volatile (							\
+	    "1:mov %4,(%3)\n"						\
+	    "  mov (%7,%3),%0\n"					\
+	    "  cmp %5,%0\n"						\
+	    "  bne 2f\n"						\
+	    "  mov %6,(%7,%3)\n"					\
+	    "  mov (%7,%3),%0\n"					\
+	    "  mov (%8,%3),%0\n"					\
+	    "  or %0,%0\n"						\
+	    "  bne 1b\n"						\
+	    "  mov 0,%1\n"						\
+	    "  bra 3f\n"						\
+	    "2:mov (%7,%3),%0\n"					\
+	    "  mov (%8,%3),%0\n"					\
+	    "  or %0,%0\n"						\
+	    "  bne 1b\n"						\
+	    "3:\n"							\
+	    :"=&r" (__hwceb_status), "=&r" (__hwceb_ret)		\
+	    :"1" (__hwceb_ret), "a" (MMAP_AARU_ADDR),			\
+	     "r" (mem), "r" (oldval), "r" (newval),			\
+	     "i" (__ATOMIC_DATA), "i" (__ATOMIC_STATUS)			\
+	    :"memory", "cc");						\
+    __hwceb_ret;							\
+})
+
+extern void __am33_link_error(void);
+
+#define atomic_compare_and_exchange_val_acq(mem, newval, oldval)	\
+({									\
+    __typeof (*mem) __ret;						\
+    if (sizeof(*(mem)) != 4)						\
+	__am33_link_error();						\
+    if (__HAVE_ATOMIC_OP_UNIT) {					\
+	__ret = __hw_cmpxch_val_acq_32(mem, newval, oldval);		\
+    } else {								\
+	__HWCHECK();							\
+	__ret = __sw_cmpxch_val_acq_32(mem, newval, oldval);		\
+    }									\
+    __ret;								\
+})
+
+#define atomic_compare_and_exchange_bool_acq(mem, newval, oldval)	\
+({									\
+    int __aceb_ret;							\
+    if (sizeof(*(mem)) != 4)						\
+	__am33_link_error();						\
+    if (__HAVE_ATOMIC_OP_UNIT) {					\
+	__aceb_ret = __hw_cmpxch_bool_acq_32(mem, newval, oldval);	\
+    } else {								\
+	__HWCHECK();							\
+	__aceb_ret = __sw_cmpxch_bool_acq_32(mem, newval, oldval);	\
+    }									\
+    __aceb_ret;								\
+})
+
+#endif	/* bits/atomic.h */
diff --git a/sysdeps/am33/bits/link.h b/sysdeps/am33/bits/link.h
new file mode 100644
index 0000000..7cf30ab
--- /dev/null
+++ b/sysdeps/am33/bits/link.h
@@ -0,0 +1,57 @@
+/* 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.  */
+
+#ifndef	_LINK_H
+# error "Never include <bits/link.h> directly; use <link.h> instead."
+#endif
+
+
+/* Registers for entry into PLT on AM33.  */
+typedef struct La_am33_regs
+{
+  uint32_t lr_d0;
+  uint32_t lr_d1;
+  uint32_t lr_sp;
+} La_am33_regs;
+
+/* Return values for calls from PLT on AM33.  */
+typedef struct La_am33_retval
+{
+  uint32_t lrv_d0;
+  uint32_t lrv_d1;
+  uint32_t lrv_a0;
+} La_am33_retval;
+
+
+__BEGIN_DECLS
+
+extern Elf32_Addr la_am33_gnu_pltenter (Elf32_Sym *__sym, unsigned int __ndx,
+				       uintptr_t *__refcook,
+				       uintptr_t *__defcook,
+				       La_am33_regs *__regs,
+				       unsigned int *__flags,
+				       const char *__symname,
+				       long int *__framesizep);
+extern unsigned int la_am33_gnu_pltexit (Elf32_Sym *__sym, unsigned int __ndx,
+					uintptr_t *__refcook,
+					uintptr_t *__defcook,
+					const La_am33_regs *__inregs,
+					La_am33_retval *__outregs,
+					const char *__symname);
+
+__END_DECLS
diff --git a/sysdeps/am33/bits/linkmap.h b/sysdeps/am33/bits/linkmap.h
new file mode 100644
index 0000000..e3734d6
--- /dev/null
+++ b/sysdeps/am33/bits/linkmap.h
@@ -0,0 +1,5 @@
+struct link_map_machine
+  {
+    Elf32_Addr plt;
+    Elf32_Addr gotplt;
+  };
diff --git a/sysdeps/am33/bits/setjmp.h b/sysdeps/am33/bits/setjmp.h
index 6dd87cb..8d0c11b 100644
--- a/sysdeps/am33/bits/setjmp.h
+++ b/sysdeps/am33/bits/setjmp.h
@@ -1,4 +1,4 @@
-/* Copyright 2001 Free Software Foundation, Inc.
+/* Copyright 2001, 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
@@ -16,11 +16,47 @@
    <http://www.gnu.org/licenses/>.  */
 
 /* Define the machine-dependent type `jmp_buf'.  AM33 version. */
+#ifndef _BITS_SETJMP_H
+#define _BITS_SETJMP_H  1
 
-#ifndef _SETJMP_H
+#if !defined _SETJMP_H && !defined _PTHREAD_H
 # error "Never include <bits/setjmp.h> directly; use <setjmp.h> instead."
 #endif
 
 #ifndef _ASM
 typedef int __jmp_buf[26];
 #endif
+
+#define __JMP_BUF_D2	        0
+#define __JMP_BUF_D3	        1
+#define __JMP_BUF_MDR	        2
+#define __JMP_BUF_A2	        3
+#define __JMP_BUF_A3	        4
+#define __JMP_BUF_SP		5
+#define __JMP_BUF_R4	        6
+#define __JMP_BUF_R5	        7
+#define __JMP_BUF_R6	        8
+#define __JMP_BUF_R7	        9
+#define __JMP_BUF_FS4	        10
+#define __JMP_BUF_FS5	        11
+#define __JMP_BUF_FS6	        12
+#define __JMP_BUF_FS7	        13
+#define __JMP_BUF_FS8	        14
+#define __JMP_BUF_FS9	        15
+#define __JMP_BUF_FS10	        16
+#define __JMP_BUF_FS11	        17
+#define __JMP_BUF_FS12	        18
+#define __JMP_BUF_FS13	        19
+#define __JMP_BUF_FS14	        20
+#define __JMP_BUF_FS15	        21
+#define __JMP_BUF_FS16	        22
+#define __JMP_BUF_FS17	        23
+#define __JMP_BUF_FS18	        24
+#define __JMP_BUF_FS19	        25
+
+/* Test if longjmp to JMPBUF would unwind the frame
+   containing a local variable at ADDRESS.  */
+#define _JMPBUF_UNWINDS(jmpbuf, address) \
+  ((void *) (address) < (void *) (jmpbuf[__JMP_BUF_SP]))
+
+#endif
diff --git a/sysdeps/am33/crti.S b/sysdeps/am33/crti.S
new file mode 100644
index 0000000..231e514
--- /dev/null
+++ b/sysdeps/am33/crti.S
@@ -0,0 +1,84 @@
+/* Special .init and .fini section support for AM33.
+   Copyright (C) 1995-2012 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   In addition to the permissions in the GNU Lesser General Public
+   License, the Free Software Foundation gives you unlimited
+   permission to link the compiled version of this file with other
+   programs, and to distribute those programs without any restriction
+   coming from the use of this file. (The GNU Lesser General Public
+   License restrictions do apply in other respects; for example, they
+   cover modification of the file, and distribution when not linked
+   into another program.)
+
+   Note that people who make modified versions of this file are not
+   obligated to grant this special exception for their modified
+   versions; it is their choice whether to do so. The GNU Lesser
+   General Public License gives permission to release a modified
+   version without this exception; this exception also makes it
+   possible to release a modified version which carries forward this
+   exception.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+/* crti.S puts a function prologue at the beginning of the .init and
+   .fini sections and defines global symbols for those addresses, so
+   they can be called as functions.  The symbols _init and _fini are
+   magic and cause the linker to emit DT_INIT and DT_FINI.  */
+
+#include <libc-symbols.h>
+#include <sysdep.h>
+
+#ifndef PREINIT_FUNCTION
+# define PREINIT_FUNCTION __gmon_start__
+#endif
+
+#ifndef PREINIT_FUNCTION_WEAK
+# define PREINIT_FUNCTION_WEAK 1
+#endif
+
+#if PREINIT_FUNCTION_WEAK
+	weak_extern (PREINIT_FUNCTION)
+#else
+	.hidden PREINIT_FUNCTION
+#endif
+
+#if PREINIT_FUNCTION_WEAK
+	.p2align 2
+	.type call_weak_fn, %function
+call_weak_fn:
+	bra PREINIT_FUNCTION
+	.p2align 2
+#endif
+
+	.section .init,"ax",%progbits
+	.p2align 2
+	.globl _init
+	.type _init, %function
+_init:
+	movm	[d2,d3,a2],(sp)
+
+#if PREINIT_FUNCTION_WEAK
+	call	call_weak_fn[],0
+#else
+	call	PREINIT_FUNCTION[],0
+#endif
+
+	.section .fini,"ax",%progbits
+	.p2align 2
+	.globl _fini
+	.type _fini, %function
+_fini:
+	movm	[d2,d3,a2],(sp)
diff --git a/sysdeps/am33/crtn.S b/sysdeps/am33/crtn.S
new file mode 100644
index 0000000..0195d33
--- /dev/null
+++ b/sysdeps/am33/crtn.S
@@ -0,0 +1,46 @@
+/* Special .init and .fini section support for AM33.
+   Copyright (C) 1995-2012 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   In addition to the permissions in the GNU Lesser General Public
+   License, the Free Software Foundation gives you unlimited
+   permission to link the compiled version of this file with other
+   programs, and to distribute those programs without any restriction
+   coming from the use of this file. (The GNU Lesser General Public
+   License restrictions do apply in other respects; for example, they
+   cover modification of the file, and distribution when not linked
+   into another program.)
+
+   Note that people who make modified versions of this file are not
+   obligated to grant this special exception for their modified
+   versions; it is their choice whether to do so. The GNU Lesser
+   General Public License gives permission to release a modified
+   version without this exception; this exception also makes it
+   possible to release a modified version which carries forward this
+   exception.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <sysdep.h>
+
+/* crtn.S puts function epilogues in the .init and .fini sections
+   corresponding to the prologues in crti.S. */
+
+	.section .init,"ax",%progbits
+	retf [],0
+
+	.section .fini,"ax",%progbits
+	retf [],0
+
diff --git a/sysdeps/am33/dl-machine.h b/sysdeps/am33/dl-machine.h
index 52278c0..d8275c9 100644
--- a/sysdeps/am33/dl-machine.h
+++ b/sysdeps/am33/dl-machine.h
@@ -23,6 +23,8 @@
 #define ELF_MACHINE_NAME "mn10300"
 
 #include <sys/param.h>
+#include <ldsodefs.h>
+#include <tls.h>
 
 /* Return nonzero iff ELF header is compatible with the running host.  */
 static inline int __attribute__ ((unused))
@@ -56,22 +58,6 @@ elf_machine_load_address (void)
   return off + gotaddr - gotval;
 }
 
-#if !defined PROF && !__BOUNDED_POINTERS__
-/* We add a declaration of this function here so that in dl-runtime.c
-   the ELF_MACHINE_RUNTIME_TRAMPOLINE macro really can pass the parameters
-   in registers.
-
-   We cannot use this scheme for profiling because the _mcount call
-   destroys the passed register information.  */
-/* GKM FIXME: Fix trampoline to pass bounds so we can do
-   without the `__unbounded' qualifier.  */
-static ElfW(Addr) fixup (struct link_map *__unbounded l, ElfW(Word) reloc_offset)
-     __attribute__ ((unused));
-static ElfW(Addr) profile_fixup (struct link_map *l, ElfW(Word) reloc_offset,
-				 ElfW(Addr) retaddr)
-     __attribute__ ((unused));
-#endif
-
 /* Set up the loaded object described by L so its unrelocated PLT
    entries will jump to the on-demand fixup code in dl-runtime.c.  */
 
@@ -89,6 +75,14 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
 	 offset into the .rel.plt section, push _GLOBAL_OFFSET_TABLE_[1],
 	 and then jump to _GLOBAL_OFFSET_TABLE[2].  */
       got = (Elf32_Addr *) D_PTR (l, l_info[DT_PLTGOT]);
+      /* If a library is prelinked but we have to relocate anyway,
+	 we have to be able to undo the prelinking of .got.plt.
+	 The prelinker saved us here address of .plt + offset.  */
+      if (got[1])
+	{
+	  l->l_mach.plt = got[1] + l->l_addr;
+	  l->l_mach.gotplt = (Elf32_Addr) &got[3];
+	}
       got[1] = (Elf32_Addr) l;	/* Identify this shared object.  */
 
       /* The got[2] entry contains the address of a function which gets
@@ -101,7 +95,8 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
 	{
 	  got[2] = (Elf32_Addr) &_dl_runtime_profile;
 
-	  if (_dl_name_match_p (GLRO(dl_profile), l))
+	  if (GLRO(dl_profile) != NULL
+	      && _dl_name_match_p (GLRO(dl_profile), l))
 	    /* This is the object we are looking for.  Say that we really
 	       want profiling and the timers are started.  */
 	    GL(dl_profile_map) = l;
@@ -115,84 +110,38 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
   return lazy;
 }
 
-/* This code is used in dl-runtime.c to call the `fixup' function
-   and then redirect to the address it returns.  */
-#if !defined PROF && !__BOUNDED_POINTERS__
-# define ELF_MACHINE_RUNTIME_TRAMPOLINE asm ("\
-	.text\n\
-	.globl _dl_runtime_resolve\n\
-	.type _dl_runtime_resolve, @function\n\
-_dl_runtime_resolve:\n\
-	add -12,sp		# Preserve registers otherwise clobbered.\n\
-	mov d1,(20,sp)\n\
-	mov d0,(16,sp)\n\
-	mov r1,d0\n\
-	mov r0,d1\n\
-	call fixup,[],0		# Call resolver.\n\
-	mov d0,a0\n\
-	mov (12,sp),d1		# Copy return address back to mdr,\n\
-	mov d1,mdr		# in case the callee returns with retf\n\
-	mov (16,sp),d0		# Get register content back.\n\
-	mov (20,sp),d1\n\
-	add 12,sp\n\
-	jmp (a0)\n\
-	.size _dl_runtime_resolve, .-_dl_runtime_resolve\n\
-\n\
-	.globl _dl_runtime_profile\n\
-	.type _dl_runtime_profile, @function\n\
-_dl_runtime_profile:\n\
-	add -12,sp		# Preserve registers otherwise clobbered.\n\
-	mov d1,(20,sp)\n\
-	mov d0,(16,sp)\n\
-	mov r1,d0\n\
-	mov r0,d1\n\
-	call profile_fixup,[],0		# Call resolver.\n\
-	mov d0,a0\n\
-	mov (12,sp),d1		# Copy return address back to mdr,\n\
-	mov d1,mdr		# in case the callee returns with retf\n\
-	mov (16,sp),d0		# Get register content back.\n\
-	mov (20,sp),d1\n\
-	add 12,sp\n\
-	jmp (a0)\n\
-	.size _dl_runtime_profile, .-_dl_runtime_profile\n\
-	.previous\n\
-");
-#else
-# define ELF_MACHINE_RUNTIME_TRAMPOLINE asm ("\n\
-	.text\n\
-	.globl _dl_runtime_resolve\n\
-	.globl _dl_runtime_profile\n\
-	.type _dl_runtime_resolve, @function\n\
-	.type _dl_runtime_profile, @function\n\
-_dl_runtime_resolve:\n\
-_dl_runtime_profile:\n\
-	add -12,sp		# Preserve registers otherwise clobbered.\n\
-	mov d1,(20,sp)\n\
-	mov d0,(16,sp)\n\
-	mov r1,d0\n\
-	mov r0,d1\n\
-	call profile_fixup,[],0		# Call resolver.\n\
-	mov d0,a0\n\
-	mov (12,sp),d1		# Copy return address back to mdr,\n\
-	mov d1,mdr		# in case the callee returns with retf\n\
-	mov (16,sp),d0		# Get register content back.\n\
-	mov (20,sp),d1\n\
-	add 12,sp\n\
-	jmp (a0)\n\
-	.size _dl_runtime_resolve, .-_dl_runtime_resolve\n\
-	.size _dl_runtime_profile, .-_dl_runtime_profile\n\
-	.previous\n\
-");
-#endif
-
 /* Mask identifying addresses reserved for the user program,
    where the dynamic linker should not map anything.  */
 #define ELF_MACHINE_USER_ADDRESS_MASK	0xf8000000UL
 
+/* The mn10300 never uses Elf32_Rel relocations.  */
+#define ELF_MACHINE_NO_REL 1
+
+/* We define an initialization functions.  This is called very early in
+   _dl_sysdep_start.  */
+#define DL_PLATFORM_INIT dl_platform_init ()
+
+static inline void __attribute__ ((unused))
+dl_platform_init (void)
+{
+#ifdef SHARED
+  extern unsigned long long _dl_mn10300_hwcap;
+  _dl_mn10300_hwcap = GLRO(dl_hwcap);
+#endif
+}
+
+/* Undo the add -20,sp below to get at the value we want
+   in __libc_stack_end.  */
+#define DL_STACK_END(cookie) \
+  ((void *) (((long) (cookie)) + 20))
+
 /* Initial entry point code for the dynamic linker.
    The C function `_dl_start' is the real entry point;
    its return value is the user program's entry point.  */
-#define RTLD_START asm ("\n\
+#define RTLD_START \
+unsigned long long _dl_mn10300_hwcap = 0; \
+INTVARDEF(_dl_mn10300_hwcap)\
+   asm ("\n\
 	.text\n\
 .globl _start\n\
 .globl _dl_start_user\n\
@@ -208,9 +157,6 @@ _dl_start_user:\n\
 	# Point a2 at the GOT.\n\
 0:	mov pc,a2\n\
 	add _GLOBAL_OFFSET_TABLE_ - (0b-.),a2\n\
-	# Store the highest stack address\n\
-	mov (__libc_stack_end@GOT,a2),a0\n\
-	mov a1,(a0)\n\
 	# See if we were run as a command with the executable file\n\
 	# name as an extra leading argument.\n\
 	mov (_dl_skip_args@GOT,a2),a0\n\
@@ -241,7 +187,7 @@ _dl_start_user:\n\
 	mov a0,(16,sp)\n\
 	mov (_rtld_local@GOTOFF,a2),d0\n\
 	# Call the function to run the initializers.\n\
-	call _dl_init@PLT,[],0\n\
+	call _dl_init_internal@PLT,[],0\n\
 	# Pass our finalizer function to the user in d0, as per ELF ABI.\n\
 	mov (_dl_fini@GOT,a2),d0\n\
 	add 20,sp\n\
@@ -259,9 +205,17 @@ _dl_start_user:\n\
    PLT entries should not be allowed to define the value.
    ELF_RTYPE_CLASS_NOCOPY iff TYPE should not be allowed to resolve to one
    of the main executable's symbols, as for a COPY reloc.  */
-#define elf_machine_type_class(type) \
+#if !defined RTLD_BOOTSTRAP || USE___THREAD
+# define elf_machine_type_class(type) \
+  ((((type) == R_MN10300_JMP_SLOT || (type) == R_MN10300_TLS_DTPMOD      \
+     || (type) == R_MN10300_TLS_DTPOFF || (type) == R_MN10300_TLS_TPOFF) \
+    * ELF_RTYPE_CLASS_PLT)	                                         \
+   | (((type) == R_MN10300_COPY) * ELF_RTYPE_CLASS_COPY))
+#else
+# define elf_machine_type_class(type) \
   ((((type) == R_MN10300_JMP_SLOT) * ELF_RTYPE_CLASS_PLT)	\
    | (((type) == R_MN10300_COPY) * ELF_RTYPE_CLASS_COPY))
+#endif
 
 /* A reloc type used for ld.so cmdline arg lookups to reject PLT entries.  */
 #define ELF_MACHINE_JMP_SLOT	R_MN10300_JMP_SLOT
@@ -284,21 +238,39 @@ elf_machine_plt_value (struct link_map *map, const Elf32_Rela *reloc,
 
 #endif /* !dl_machine_h */
 
-#ifdef RESOLVE
+/* Names of the architecture-specific auditing callback functions.  */
+#define ARCH_LA_PLTENTER am33_gnu_pltenter
+#define ARCH_LA_PLTEXIT am33_gnu_pltexit
 
-/* The mn10300 never uses Elf32_Rel relocations.  */
-#define ELF_MACHINE_NO_REL 1
+#ifdef RESOLVE_MAP
 
 /* Perform the relocation specified by RELOC and SYM (which is fully resolved).
    MAP is the object containing the reloc.  */
 
-static inline void
+auto inline void __attribute__((always_inline))
 elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
 		  const Elf32_Sym *sym, const struct r_found_version *version,
 		  void *const reloc_addr_arg, int skip_ifunc)
 {
   const unsigned int r_type = ELF32_R_TYPE (reloc->r_info);
   Elf32_Addr value, *reloc_addr;
+#ifndef RESOLVE_CONFLICT_FIND_MAP
+  const Elf32_Sym *const refsym = sym;
+  struct link_map *sym_map = NULL;
+#endif
+
+#if !defined RTLD_BOOTSTRAP && !defined HAVE_Z_COMBRELOC
+      /* This is defined in rtld.c, but nowhere in the static libc.a;
+	 make the reference weak so static programs can still link.
+	 This declaration cannot be done when compiling rtld.c (i.e.
+	 #ifdef RTLD_BOOTSTRAP) because rtld.c contains the common
+	 defn for _dl_rtld_map, which is incompatible with a weak decl
+	 in the same file.  */
+  weak_extern (_dl_rtld_map);
+#endif
+
+  if (__builtin_expect (r_type == R_MN10300_NONE, 0))
+    return;
 
   /* Make sure we drop any previous alignment assumptions.  */
   asm ("" : "=r" (reloc_addr) : "0" (reloc_addr_arg));
@@ -346,13 +318,6 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
   if (__builtin_expect (r_type == R_MN10300_RELATIVE, 0))
     {
 # if !defined RTLD_BOOTSTRAP && !defined HAVE_Z_COMBRELOC
-      /* This is defined in rtld.c, but nowhere in the static libc.a;
-	 make the reference weak so static programs can still link.
-	 This declaration cannot be done when compiling rtld.c (i.e.
-	 #ifdef RTLD_BOOTSTRAP) because rtld.c contains the common
-	 defn for _dl_rtld_map, which is incompatible with a weak decl
-	 in the same file.  */
-      weak_extern (_dl_rtld_map);
       if (map != &_dl_rtld_map) /* Already done in rtld itself. */
 # endif
 	{
@@ -360,88 +325,142 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
 	  value += map->l_addr;
 	  COPY_UNALIGNED_WORD (value, *reloc_addr, (int) reloc_addr & 3);
 	}
+      return;
     }
-# ifndef RTLD_BOOTSTRAP
-  else if (__builtin_expect (r_type == R_MN10300_NONE, 0))
-    return;
-# endif
-  else
 #endif
+
+#ifndef RESOLVE_CONFLICT_FIND_MAP
+  if (sym->st_shndx != SHN_UNDEF &&
+      ELF32_ST_BIND (sym->st_info) == STB_LOCAL)
     {
-#ifndef RTLD_BOOTSTRAP
-      const Elf32_Sym *const refsym = sym;
+      value = map->l_addr;
+    }
+  else
+    {
+      sym_map = RESOLVE_MAP (&sym, version, r_type);
+      value = sym == NULL ? 0 : sym_map->l_addr + sym->st_value;
+    }
+#else
+  value = 0;
 #endif
 
-      value = RESOLVE (&sym, version, ELF32_R_TYPE (reloc->r_info));
-      if (sym)
-	value += sym->st_value;
-      value += reloc->r_addend;	/* Assume copy relocs have zero addend.  */
+  value += reloc->r_addend;	/* Assume copy relocs have zero addend.  */
 
-      switch (r_type)
-	{
-#ifndef RTLD_BOOTSTRAP
-	case R_MN10300_COPY:
-	  if (sym == NULL)
-	    /* This can happen in trace mode if an object could not be
-	       found.  */
-	    break;
-	  if (sym->st_size > refsym->st_size
-	      || (GLRO(dl_verbose) && sym->st_size < refsym->st_size))
-	    {
-	      extern char **_dl_argv;
-	      const char *strtab;
-
-	      strtab = (const void *) D_PTR (map, l_info[DT_STRTAB]);
-	      _dl_error_printf ("\
+  switch (r_type)
+    {
+#if !defined RTLD_BOOTSTRAP && !defined RESOLVE_CONFLICT_FIND_MAP
+    case R_MN10300_COPY:
+      if (sym == NULL)
+	/* This can happen in trace mode if an object could not be
+	   found.  */
+        break;
+      if (sym->st_size > refsym->st_size
+	  || (GLRO(dl_verbose) && sym->st_size < refsym->st_size))
+        {
+	  const char *strtab;
+
+	  strtab = (const void *) D_PTR (map, l_info[DT_STRTAB]);
+	  _dl_error_printf ("\
 %s: Symbol `%s' has different size in shared object, consider re-linking\n",
-				_dl_argv[0] ?: "<program name unknown>",
-				strtab + refsym->st_name);
-	    }
-	  memcpy (reloc_addr, (void *) value, MIN (sym->st_size,
-						   refsym->st_size));
+			    rtld_progname ?: "<program name unknown>",
+			    strtab + refsym->st_name);
+	}
+      memcpy (reloc_addr_arg, (void *) value,
+	      MIN (sym->st_size, refsym->st_size));
 	  break;
 #endif
-	case R_MN10300_GLOB_DAT:
-	case R_MN10300_JMP_SLOT:
-	  /* These addresses are always aligned.  */
-	  *reloc_addr = value;
-	  break;
-	case R_MN10300_32:
-	  COPY_UNALIGNED_WORD (value, *reloc_addr, (int) reloc_addr & 3);
-	  break;
+    case R_MN10300_GLOB_DAT:
+    case R_MN10300_JMP_SLOT:
+      /* These addresses are always aligned.  */
+      *reloc_addr = value;
+      break;
+    case R_MN10300_32:
+      COPY_UNALIGNED_WORD (value, *reloc_addr, (int) reloc_addr & 3);
+      break;
+
 #ifndef RTLD_BOOTSTRAP
-	case R_MN10300_16:
-	  COPY_UNALIGNED_HALFWORD (value, *reloc_addr, (int) reloc_addr & 1);
-	  break;
-	case R_MN10300_8:
-	  *(char *) reloc_addr = value;
-	  break;
-	case R_MN10300_PCREL32:
-	  value -= (Elf32_Addr) reloc_addr;
-	  COPY_UNALIGNED_WORD (value, *reloc_addr, (int) reloc_addr & 3);
-	  break;
-	case R_MN10300_PCREL16:
-	  value -= (Elf32_Addr) reloc_addr;
-	  COPY_UNALIGNED_HALFWORD (value, *reloc_addr, (int) reloc_addr & 1);
-	  break;
-	case R_MN10300_PCREL8:
-	  value -= (Elf32_Addr) reloc_addr;
-	  *(char *) reloc_addr = (value - (Elf32_Addr) reloc_addr);
-	  break;
-#endif
-	case R_MN10300_NONE:		/* Alright, Wilbur.  */
-	  break;
-#if !defined RTLD_BOOTSTRAP || defined _NDEBUG
-	default:
-	  _dl_reloc_bad_type (map, ELFW(R_TYPE) (reloc->r_info), 0);
-	  break;
+    case R_MN10300_16:
+      COPY_UNALIGNED_HALFWORD (value, *reloc_addr, (int) reloc_addr & 1);
+      break;
+    case R_MN10300_8:
+      *(char *) reloc_addr = value;
+      break;
+    case R_MN10300_PCREL32:
+      value -= (Elf32_Addr) reloc_addr;
+      COPY_UNALIGNED_WORD (value, *reloc_addr, (int) reloc_addr & 3);
+      break;
+    case R_MN10300_PCREL16:
+      value -= (Elf32_Addr) reloc_addr;
+      COPY_UNALIGNED_HALFWORD (value, *reloc_addr, (int) reloc_addr & 1);
+      break;
+    case R_MN10300_PCREL8:
+      value -= (Elf32_Addr) reloc_addr;
+      *(char *) reloc_addr = (value - (Elf32_Addr) reloc_addr);
+      break;
 #endif
+#if (!defined RTLD_BOOTSTRAP || USE___THREAD) \
+    && !defined RESOLVE_CONFLICT_FIND_MAP
+    case R_MN10300_TLS_DTPMOD:
+# ifdef RTLD_BOOTSTRAP
+      /* During startup the dynamic linker is always the module
+	 with index 1. */
+      *reloc_addr = 1;
+# else
+      /* Get the information from the link map returned by the
+	 resolv function.  */
+      if (sym_map != NULL)
+        *reloc_addr = sym_map->l_tls_modid;
+# endif
+      break;
+    case R_MN10300_TLS_DTPOFF:
+# ifndef RTLD_BOOTSTRAP
+      /* During relocation all TLS symbols are defined and used.
+	 Therefore the offset is already correct.  */
+      *reloc_addr = (sym == NULL ? 0 : sym->st_value) + reloc->r_addend;
+# endif
+      break;
+    case R_MN10300_TLS_TPOFF:
+      /* The offset is negative, forward from the thread pointer.  */
+# ifdef RTLD_BOOTSTRAP
+      *reloc_addr = (sym->st_value + reloc->r_addend)
+	      - (map->l_tls_offset - map->l_tls_blocksize);
+# else
+      /* We know the offset of object the symbol is contained in.
+	 It is a negative value which will be added to the
+	 thread pointer.  */
+      if (sym != NULL)
+        {
+	  CHECK_STATIC_TLS (map, sym_map);
+	  if (reloc->r_addend < 0)
+	    *reloc_addr = (sym->st_value + reloc->r_addend)
+		    - (sym_map->l_tls_offset - sym_map->l_tls_blocksize);
+	  else
+	    *reloc_addr = sym->st_value + reloc->r_addend - sym_map->l_tls_offset;
 	}
+# endif
+      break;
+#endif
+
+#if ! defined RTLD_BOOTSTRAP
+    case R_MN10300_TLS_GD:
+    case R_MN10300_TLS_LD:
+    case R_MN10300_TLS_LDO:
+    case R_MN10300_TLS_GOTIE:
+    case R_MN10300_TLS_IE:
+    case R_MN10300_TLS_LE:
+      _dl_printf("elf_machine_rela: r_type[%d] reloc_addr[%x] value[%x]\n", 
+		 r_type, (unsigned)reloc_addr, value);
+#endif /* ! RTLD_BOOTSTRAP */
 
+#if !defined RTLD_BOOTSTRAP || defined _NDEBUG
+    default:
+      _dl_reloc_bad_type (map, ELFW(R_TYPE) (reloc->r_info), 0);
+      break;
+#endif
     }
 }
 
-static inline void
+auto inline void __attribute__((always_inline))
 elf_machine_rela_relative (Elf32_Addr l_addr, const Elf32_Rela *reloc,
 			   void *const reloc_addr_arg)
 {
@@ -454,9 +473,9 @@ elf_machine_rela_relative (Elf32_Addr l_addr, const Elf32_Rela *reloc,
   COPY_UNALIGNED_WORD (value, *reloc_addr, (int)reloc_addr & 3);
 }
 
-static inline void
+auto inline void __attribute__((always_inline))
 elf_machine_lazy_rel (struct link_map *map,
-		      Elf32_Addr l_addr, const Elf32_Rela *reloc,
+		      ElfW(Addr) l_addr, const ElfW(Rela) *reloc,
 		      int skip_ifunc)
 {
   unsigned long int const r_type = ELF32_R_TYPE (reloc->r_info);
@@ -470,7 +489,16 @@ elf_machine_lazy_rel (struct link_map *map,
       /* Perform a RELATIVE reloc on the .got entry that transfers
 	 to the .plt.  */
       COPY_UNALIGNED_WORD (*reloc_addr, value, (int)reloc_addr & 3);
-      value += l_addr;
+      if (__builtin_expect (map->l_mach.plt, 0) == 0)
+        value += l_addr;
+      else
+        {
+	  /* ET_DYN PLT entry size is 24 bytes, ET_EXEC is 20 bytes.  */
+	  int entry_words = (map->l_type == lt_executable) ? 5 : 6;
+
+	  value = (map->l_mach.plt
+		 + (((Elf32_Addr) reloc_addr) - map->l_mach.gotplt) * entry_words);
+	}
       COPY_UNALIGNED_WORD (value, *reloc_addr, (int)reloc_addr & 3);
     }
   else if (__builtin_expect (r_type, R_MN10300_NONE) != R_MN10300_NONE)
@@ -478,4 +506,4 @@ elf_machine_lazy_rel (struct link_map *map,
 
 }
 
-#endif /* RESOLVE */
+#endif /* RESOLVE_MAP */
diff --git a/sysdeps/am33/dl-tls.h b/sysdeps/am33/dl-tls.h
new file mode 100644
index 0000000..fd629c6
--- /dev/null
+++ b/sysdeps/am33/dl-tls.h
@@ -0,0 +1,31 @@
+/* Thread-local storage handling in the ELF dynamic linker.  AM33 version.
+   Copyright (C) 2005 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+
+/* Type used for the representation of TLS information in the GOT.  */
+typedef struct
+{
+  unsigned long int ti_module;
+  unsigned long int ti_offset;
+} tls_index;
+
+extern void *__tls_get_addr (tls_index *ti);
+
+/* Value used for dtv entries for which the allocation is delayed.  */
+#define TLS_DTV_UNALLOCATED	((void *) -1l)
diff --git a/sysdeps/am33/dl-trampoline.S b/sysdeps/am33/dl-trampoline.S
new file mode 100644
index 0000000..5433214
--- /dev/null
+++ b/sysdeps/am33/dl-trampoline.S
@@ -0,0 +1,178 @@
+/* PLT trampolines.  AM33 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 <sysdep.h>
+
+/* We don't want to use the definition from sysdep.h */
+#undef ret
+
+	.text
+	.globl _dl_runtime_resolve
+	.type _dl_runtime_resolve, @function
+_dl_runtime_resolve:
+	#
+	# We arrive here from PLT with:
+	#   e0 => reloc_offset
+	#   e1 => link_map pointer
+	#
+	add 	-12,sp		# Preserve registers otherwise clobbered.
+	mov	d1,(20,sp)
+	mov	d0,(16,sp)
+	mov_mov	e1,d0,e0,d1
+	call	_dl_fixup,[],0	# Call resolver.
+	mov	d0,a0
+	mov	(12,sp),d1	# Copy return address back to mdr,
+	mov	d1,mdr		# in case the callee returns with retf
+	mov	(16,sp),d0	# Get register content back.
+	mov	(20,sp),d1
+	add	12,sp
+	jmp	(a0)
+	.size	_dl_runtime_resolve, .-_dl_runtime_resolve
+
+#ifndef PROF
+	.globl _dl_runtime_profile
+	.type _dl_runtime_profile, @function
+_dl_runtime_profile:
+	#
+	# We arrive here from PLT with:
+	#   e0 => reloc_offset
+	#   e1 => link_map pointer
+	#
+	# Prepare to call _dl_profile_fixup
+	#
+	# extern _dl_profile_fixup (struct link_map *l,
+	#                           ElfW(Word) reloc_arg,
+	#                           ElfW(Addr) retaddr,
+	#                           void *regs,
+	#                           long int *framesizep)
+	#
+	# Stack layout for _dl_profile_fixup call
+	#
+	#   60+ - plt call args[2-N]
+	#   56  - plt call arg2 save area
+	#   52  - plt call arg1 save area
+	#   48  - plt call return addr
+	#   44  - framesize returned from pltenter
+	#   40  - La_am33_regs.lr_sp
+	#   36  - La_am33_regs.lr_d1
+	#   32  - La_am33_regs.lr_d0
+	#   28  - saved incoming e1
+	#   24  - saved incoming e0
+	#   20  - arg5 for _dl_profile_fixup
+	#   16  - arg4 for _dl_profile_fixup
+	#   12  - arg3 for _dl_profile_fixup
+	#   8   - arg2 save area for _dl_profile_fixup call
+	#   4   - arg1 save area for _dl_profile_fixup call
+	#   0   - return addr for _dl_profile_fixup call
+
+	add	-48,sp
+	mov	e0,(24,sp)
+	mov	e1,(28,sp)
+	mov	d0,(32,sp)	# La_am33_regs.lr_d0
+	mov	d1,(36,sp)	# La_am33_regs.lr_d1
+	mov	sp,d0
+	add	48,d0
+	mov	d0,(40,sp)	# La_am33_regs.lr_sp
+
+	mov	(48,sp),d0	# retaddr
+	mov	d0,(12,sp)
+
+	mov	sp,d0
+	add	32,d0	# &La_am33_regs
+	mov	d0,(16,sp)
+	add	12,d0	# &framesize
+	mov	d0,(20,sp)
+
+	mov_mov	e1,d0,e0,d1
+	call	_dl_profile_fixup,[],0		# Call resolver.
+
+	# check whether we're wrapping this function
+	mov	(44,sp),d1
+	cmp	0,d1
+	bge	1f
+
+	mov	d0,a0
+	mov	(48,sp),d0
+	mov	d1,mdr	# in case the callee returns with retf
+	mov	(32,sp),d0
+	mov	(36,sp),d1
+	add	48,sp
+	jmp	(a0)
+1:
+	# New stack layout for function call
+	#
+	#   52+ - plt call args[2-N]
+	#   48  - plt call arg2 save area
+	#   44  - plt call arg1 save area
+	#   40  - plt call return addr
+	#   36  - saved result of _dl_profile_fixup
+	#   32  - La_am33_regs.lr_sp
+	#   28  - La_am33_regs.lr_d1
+	#   24  - La_am33_regs.lr_d0
+	#   20  - saved incoming e1
+	#   16  - saved incoming e0
+	#   12  - saved a3
+	#   8   - La_am33_retval.lrv_a0
+	#   4   - La_am33_retval.lrv_d1
+	#   0   - La_am33_retval.lrv_d0
+
+	add	8,sp	# create new frame
+	mov	d0,(36,sp)	# save result of _dl_profile_fixup
+	mov	a3,(12,sp)	# save a3
+	mov	sp,a3	# setup our frame pointer
+	sub	d1,a3,d0	# adjust stack
+	mov	d0,sp
+
+	# copy stack arguments
+	add	-16,sp
+	mov	d1,(12,sp)
+	mov	a3,d1
+	add	52,d1
+	call	memcpy,[],0
+
+	# call function
+	add 	4,sp
+	mov	(36,a3),a0	# function addr
+	mov	(24,a3),d0
+	mov	(28,a3),d1
+	calls	(a0)
+	mov	d0,(a3)
+	mov	d1,(4,a3)
+	mov	a0,(8,a3)
+
+	# call pltexit
+	add	-8,sp
+	mov	(16,a3),d1
+	mov	(20,a3),d0
+	mov	a3,a0
+	add	23,a0
+	mov	a0,(16,sp)
+	mov	a3,(20,sp)
+	call	_dl_call_pltexit,[],0
+
+	# return to caller
+	mov	(a3),d0
+	mov	(4,a3),d1
+	mov	(8,a3),a0
+	mov	a3,sp
+	mov	(12,sp),a3
+	ret	[],40
+
+	.size	_dl_runtime_profile, .-_dl_runtime_profile
+#endif
diff --git a/sysdeps/am33/elf/configure b/sysdeps/am33/elf/configure
new file mode 100644
index 0000000..7fd41dc
--- /dev/null
+++ b/sysdeps/am33/elf/configure
@@ -0,0 +1,84 @@
+as_nl='
+'
+export as_nl
+# Printing a long string crashes Solaris 7 /usr/bin/printf.
+as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
+if (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
+  as_echo='printf %s\n'
+  as_echo_n='printf %s'
+else
+  if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
+    as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
+    as_echo_n='/usr/ucb/echo -n'
+  else
+    as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
+    as_echo_n_body='eval
+      arg=$1;
+      case $arg in
+      *"$as_nl"*)
+	expr "X$arg" : "X\\(.*\\)$as_nl";
+	arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
+      esac;
+      expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
+    '
+    export as_echo_n_body
+    as_echo_n='sh -c $as_echo_n_body as_echo'
+  fi
+  export as_echo_body
+  as_echo='sh -c $as_echo_body as_echo'
+fi
+
+# This file is generated from configure.in by Autoconf.  DO NOT EDIT!
+ # Local configure fragment for sysdeps/am33/elf.
+
+if test "$usetls" != no; then
+# Check for support of thread-local storage handling in assembler and
+# linker.
+{ $as_echo "$as_me:$LINENO: checking for am33 TLS support" >&5
+$as_echo_n "checking for am33 TLS support... " >&6; }
+if test "${libc_cv_am33_tls+set}" = set; then
+  $as_echo_n "(cached) " >&6
+else
+  cat > conftest.s <<\EOF
+	.section ".tdata", "awT", @progbits
+	.globl foo
+foo:	.long	1
+	.section ".tbss", "awT", @nobits
+	.globl bar
+bar:	.skip	4
+	.text
+baz:	mov	foo@tlsgd, d0
+	mov	bar@tlsldm, d0
+	mov	bar@dtpoff, d0
+	mov	foo@gotntpoff, d0
+	mov	foo@indntpoff, d0
+	mov	bar@tpoff, d0
+EOF
+if { ac_try='${CC-cc} -c $CFLAGS conftest.s 1>&5'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  libc_cv_am33_tls=yes
+else
+  libc_cv_am33_tls=no
+fi
+rm -f conftest*
+fi
+{ $as_echo "$as_me:$LINENO: result: $libc_cv_am33_tls" >&5
+$as_echo "$libc_cv_am33_tls" >&6; }
+if test $libc_cv_am33_tls = yes; then
+  cat >>confdefs.h <<\_ACEOF
+#define HAVE_TLS_SUPPORT 1
+_ACEOF
+
+fi
+fi
+
+cat >>confdefs.h <<\_ACEOF
+#define PI_STATIC_AND_HIDDEN 1
+_ACEOF
+
diff --git a/sysdeps/am33/elf/configure.in b/sysdeps/am33/elf/configure.in
new file mode 100644
index 0000000..66797d1
--- /dev/null
+++ b/sysdeps/am33/elf/configure.in
@@ -0,0 +1,37 @@
+GLIBC_PROVIDES dnl See aclocal.m4 in the top level source directory.
+# Local configure fragment for sysdeps/am33/elf.
+
+if test "$usetls" != no; then
+# Check for support of thread-local storage handling in assembler and
+# linker.
+AC_CACHE_CHECK(for am33 TLS support, libc_cv_am33_tls, [dnl
+cat > conftest.s <<\EOF
+	.section ".tdata", "awT", @progbits
+	.globl foo
+foo:	.long	1
+	.section ".tbss", "awT", @nobits
+	.globl bar
+bar:	.skip	4
+	.text
+baz:	mov	foo@tlsgd, d0
+	mov	bar@tlsldm, d0
+	mov	bar@dtpoff, d0
+	mov	foo@gotntpoff, d0
+	mov	foo@indntpoff, d0
+	mov	bar@tpoff, d0
+EOF
+dnl
+if AC_TRY_COMMAND(${CC-cc} -c $CFLAGS conftest.s 1>&AS_MESSAGE_LOG_FD); then
+  libc_cv_am33_tls=yes
+else
+  libc_cv_am33_tls=no
+fi
+rm -f conftest*])
+if test $libc_cv_am33_tls = yes; then
+  AC_DEFINE(HAVE_TLS_SUPPORT)
+fi
+fi
+
+dnl It is always possible to access static and hidden symbols in an
+dnl position independent way.
+AC_DEFINE(PI_STATIC_AND_HIDDEN)
diff --git a/sysdeps/am33/elf/start.S b/sysdeps/am33/elf/start.S
index 518e75e..3d0d6f9 100644
--- a/sysdeps/am33/elf/start.S
+++ b/sysdeps/am33/elf/start.S
@@ -1,5 +1,5 @@
 /* Startup code compliant to the ELF MN10300 ABI.
-   Copyright (C) 1995,1996,1997,1998,2000,2001 Free Software Foundation, Inc.
+   Copyright (C) 1995,1996,1997,1998,2000,2001,2009 Free Software Foundation, Inc.
    Contributed by Alexandre Oliva  <aoliva@redhat.com>
    Based on ../../i386/elf/start.S.
    This file is part of the GNU C Library.
@@ -43,6 +43,12 @@
 	.globl _start
 	.type _start,@function
 _start:
+#ifdef SHARED
+	# Point a2 at the GOT.
+0:	mov pc,a2
+	add _GLOBAL_OFFSET_TABLE_ - (0b-.),a2
+#endif
+
 	/* Extract the arguments as encoded on the stack and set up
 	   the arguments for `main': argc, argv.  envp will be determined
 	   later in __libc_start_main.  */
@@ -51,9 +57,17 @@ _start:
 	
 	mov a3,(28,sp)		/* stack_end.  */	
 	mov d0,(24,sp)		/* rtld_fini.  */
-	mov _fini, d3
+
+#ifdef SHARED
+	mov (__libc_csu_fini@GOT,a2), d3
+	mov (__libc_csu_init@GOT,a2), d2
+	mov (main@GOT,a2), d0
+#else
+	mov __libc_csu_fini, d3
+	mov __libc_csu_init, d2
+	mov main, d0
+#endif
 	mov d3,(20,sp)		/* fini.  */
-	mov _init, d2
 	mov d2,(16,sp)		/* init.  */
 	inc4 a3
 	mov a3,(12,sp)		/* argv.  */
@@ -63,18 +77,20 @@ _start:
 	mov 0,a3
 
 	mov (32,sp), d1		/* argc.  */
-	mov BP_SYM (main), d0	/* main.  */
 
 	/* Call the user's main function, and exit with its value.
 	   But let the libc call main.    */
-	call BP_SYM (__libc_start_main),[],0
-
-	call BP_SYM (abort),[],0 /* Crash if somehow `exit' does return.  */
+#ifdef SHARED
+	call __libc_start_main@PLT,[],0
+	call abort@PLT,[],0 /* Crash if somehow `exit' does return.  */
+#else
+	call __libc_start_main,[],0
+	call abort,[],0 /* Crash if somehow `exit' does return.  */
+#endif
 
 /* Define a symbol for the first piece of initialized data.  */
 	.data
 	.globl __data_start
 __data_start:
 	.long 0
-	.weak data_start
-	data_start = __data_start
+weak_alias(__data_start, data_start)
diff --git a/sysdeps/am33/fpu/bits/fenv.h b/sysdeps/am33/fpu/bits/fenv.h
index d3a8998..d363a9c 100644
--- a/sysdeps/am33/fpu/bits/fenv.h
+++ b/sysdeps/am33/fpu/bits/fenv.h
@@ -47,6 +47,12 @@ enum
   {
     FE_TONEAREST = 0x00000,
 #define FE_TONEAREST	FE_TONEAREST
+    FE_TOWARDZERO = 0x1,
+#define FE_TOWARDZERO	FE_TOWARDZERO
+    FE_UPWARD = 0x2,
+#define FE_UPWARD	FE_UPWARD
+    FE_DOWNWARD = 0x3
+#define FE_DOWNWARD	FE_DOWNWARD
   };
 
 
diff --git a/sysdeps/am33/fpu/fclrexcpt.c b/sysdeps/am33/fpu/fclrexcpt.c
index 2b15f45..d4703c4 100644
--- a/sysdeps/am33/fpu/fclrexcpt.c
+++ b/sysdeps/am33/fpu/fclrexcpt.c
@@ -1,5 +1,5 @@
 /* Clear given exceptions in current floating-point environment.
-   Copyright (C) 1998, 1999, 2000, 2002, 2004 Free Software Foundation, Inc.
+   Copyright (C) 1998, 1999, 2000, 2002, 2004, 2009 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Alexandre Oliva <aoliva@redhat.com>
    based on corresponding file in the MIPS port.
@@ -34,15 +34,11 @@ __feclearexcept (int excepts)
   /* Read the complete control word.  */
   _FPU_GETCW (cw);
 
-  /* Clear exception flag bits and cause bits.  EF bits are cleared by
-     assigning 1 to them (and there's no way to set them); other bits
-     are copied normally.  */
-
-  cw &= ~((excepts << CAUSE_SHIFT) | FE_ALL_EXCEPT);
-  cw |= excepts;
+  /* Clear exception flag bits and cause bits.  */
+  cw &= ~((excepts << CAUSE_SHIFT) | excepts);
 
   /* Put the new data in effect.  */
-  _FPU_SETFCW (cw);
+  _FPU_SETCW (cw);
 
   /* Success.  */
   return 0;
diff --git a/sysdeps/am33/fpu/fedisblxcpt.c b/sysdeps/am33/fpu/fedisblxcpt.c
index 170f820..e5ea64c 100644
--- a/sysdeps/am33/fpu/fedisblxcpt.c
+++ b/sysdeps/am33/fpu/fedisblxcpt.c
@@ -1,5 +1,5 @@
 /* Disable floating-point exceptions.
-   Copyright (C) 2000, 2004 Free Software Foundation, Inc.
+   Copyright (C) 2000, 2004, 2009 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Alexandre Oliva <aoliva@redhat.com>
    based on corresponding file in the MIPS port.
@@ -35,6 +35,7 @@ fedisableexcept (int excepts)
   excepts &= FE_ALL_EXCEPT;
 
   new_exc &= ~(excepts << ENABLE_SHIFT);
+  new_exc &= ~_FPU_RESERVED;
   _FPU_SETCW (new_exc);
 
   return old_exc;
diff --git a/sysdeps/am33/fpu/feenablxcpt.c b/sysdeps/am33/fpu/feenablxcpt.c
index fe6d880..0730533 100644
--- a/sysdeps/am33/fpu/feenablxcpt.c
+++ b/sysdeps/am33/fpu/feenablxcpt.c
@@ -1,5 +1,5 @@
 /* Enable floating-point exceptions.
-   Copyright (C) 2000, 2004 Free Software Foundation, Inc.
+   Copyright (C) 2000, 2004, 2009 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Alexandre Oliva <aoliva@redhat.com>
    based on corresponding file in the MIPS port.
@@ -35,6 +35,7 @@ feenableexcept (int excepts)
   excepts &= FE_ALL_EXCEPT;
 
   new_exc |= excepts << ENABLE_SHIFT;
+  new_exc &= ~_FPU_RESERVED;
   _FPU_SETCW (new_exc);
 
   return old_exc;
diff --git a/sysdeps/am33/fpu/feholdexcpt.c b/sysdeps/am33/fpu/feholdexcpt.c
index 1c002d8..08129c9 100644
--- a/sysdeps/am33/fpu/feholdexcpt.c
+++ b/sysdeps/am33/fpu/feholdexcpt.c
@@ -1,5 +1,5 @@
 /* Store current floating-point environment and clear exceptions.
-   Copyright (C) 2000, 2004 Free Software Foundation, Inc.
+   Copyright (C) 2000, 2004, 2009 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Alexandre Oliva <aoliva@redhat.com>
    based on corresponding file in the MIPS port.
@@ -31,8 +31,10 @@ feholdexcept (fenv_t *envp)
   *envp = cw;
 
   /* Clear all exception enable bits and flags.  */
-  cw &= ~(_FPU_MASK_V|_FPU_MASK_Z|_FPU_MASK_O|_FPU_MASK_U|_FPU_MASK_I);
-  _FPU_SETFCW (cw);
+  cw &= ~(_FPU_MASK_V|_FPU_MASK_Z|_FPU_MASK_O|_FPU_MASK_U|_FPU_MASK_I|FE_ALL_EXCEPT);
+  _FPU_SETCW (cw);
 
   return 0;
 }
+
+libm_hidden_def (feholdexcept)
diff --git a/sysdeps/am33/fpu/fesetenv.c b/sysdeps/am33/fpu/fesetenv.c
index 110c49c..374cef0 100644
--- a/sysdeps/am33/fpu/fesetenv.c
+++ b/sysdeps/am33/fpu/fesetenv.c
@@ -1,5 +1,5 @@
 /* Install given floating-point environment.
-   Copyright (C) 1998, 1999, 2000, 2002, 2004 Free Software Foundation, Inc.
+   Copyright (C) 1998, 1999, 2000, 2002, 2004, 2009 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Alexandre Oliva <aoliva@redhat.com>
    based on corresponding file in the MIPS port.
@@ -27,29 +27,14 @@ __fesetenv (const fenv_t *envp)
 {
   fpu_control_t cw;
 
-  /* We want to clear all EF bits for the default end IEEE.  */
+  /* We want to clear all EF bits for the default and IEEE.  */
 
   if (envp == FE_DFL_ENV)
-    _FPU_SETFCW (_FPU_DEFAULT|FE_ALL_EXCEPT);
+    _FPU_SETCW (_FPU_DEFAULT);
   else if (envp == FE_NOMASK_ENV)
-    _FPU_SETFCW (_FPU_IEEE|FE_ALL_EXCEPT);
+    _FPU_SETCW (_FPU_IEEE);
   else
-    {
-      fpu_control_t temp;
-
-      _FPU_GETCW (temp);
-      cw = *envp;
-
-      /* If EF bits are cleared and the user requests them to be set,
-	 we have to fail, because there's no way to do it.  */
-      if (~temp & cw & FE_ALL_EXCEPT)
-	return -1;
-
-      /* We clear EF bits by storing a 1 in them, so flip the
-	 FE_ALL_EXCEPT bits.  */
-      cw = (cw & ~FE_ALL_EXCEPT) | (~cw & FE_ALL_EXCEPT);
-      _FPU_SETFCW (cw);
-    }
+    _FPU_SETCW (*envp);
 
   /* Success.  */
   return 0;
diff --git a/sysdeps/am33/fpu/fesetround.c b/sysdeps/am33/fpu/fesetround.c
index e77dc76..8c5818b 100644
--- a/sysdeps/am33/fpu/fesetround.c
+++ b/sysdeps/am33/fpu/fesetround.c
@@ -26,3 +26,5 @@ fesetround (int round)
      whether we're switching to it.  */
   return (round != FE_TONEAREST);
 }
+
+libm_hidden_def (fesetround)
diff --git a/sysdeps/am33/fpu/fpu_control.h b/sysdeps/am33/fpu/fpu_control.h
index de28228..de19898 100644
--- a/sysdeps/am33/fpu/fpu_control.h
+++ b/sysdeps/am33/fpu/fpu_control.h
@@ -1,5 +1,5 @@
 /* FPU control word bits.  AM33/2.0 version.
-   Copyright (C) 1996, 1997, 1998, 1999, 2000, 2004
+   Copyright (C) 1996, 1997, 1998, 1999, 2000, 2004, 2009
    Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Alexandre Oliva <aoliva@redhat.com>
@@ -52,20 +52,16 @@
 /* The fdlibm code requires strict IEEE double precision arithmetic,
    and no interrupts for exceptions, rounding to nearest.  */
 
-#define _FPU_DEFAULT  0x0000001f
+#define _FPU_DEFAULT  0x00000000
 
 /* IEEE:  same as above, but exceptions */
-#define _FPU_IEEE     0x000003ff
+#define _FPU_IEEE     0x000003e0
 
 /* Type of the control word.  */
 typedef unsigned int fpu_control_t;
 
-/* Macros for accessing the hardware control word.  _FPU_SETCW is
-   defined such that it won't modify the EF bits, that are cleared
-   when assigned bits that are set.  Use SETFCW to get them actually
-   reset.  */
-#define _FPU_SETFCW(cw) __asm__ ("fmov %0,fpcr" : : "ri" (cw))
-#define _FPU_SETCW(cw) _FPU_SETFCW((cw) & ~FE_ALL_EXCEPT)
+/* Macros for accessing the hardware control word.  */
+#define _FPU_SETCW(cw) __asm__ ("fmov %0,fpcr" : : "ri" (cw))
 #define _FPU_GETCW(cw) __asm__ ("fmov fpcr,%0" : "=r" (cw))
 
 /* Default control word set at startup.  */
diff --git a/sysdeps/am33/fpu/fraiseexcpt.c b/sysdeps/am33/fpu/fraiseexcpt.c
index 628ad56..235ac31 100644
--- a/sysdeps/am33/fpu/fraiseexcpt.c
+++ b/sysdeps/am33/fpu/fraiseexcpt.c
@@ -1,5 +1,5 @@
 /* Raise given exceptions.
-   Copyright (C) 2000, 2002, 2004 Free Software Foundation, Inc.
+   Copyright (C) 2000, 2002, 2004, 2009 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Alexandre Oliva <aoliva@redhat.com>
    based on corresponding file in the M68K port.
@@ -19,6 +19,8 @@
    <http://www.gnu.org/licenses/>.  */
 
 #include <fenv.h>
+#include <fenv_libc.h>
+#include <fpu_control.h>
 #include <float.h>
 #include <math.h>
 #include <shlib-compat.h>
@@ -26,12 +28,8 @@
 int
 __feraiseexcept (int excepts)
 {
-  /* Raise exceptions represented by EXCEPTS.  But we must raise only one
-     signal at a time.  It is important that if the overflow/underflow
-     exception and the divide by zero exception are given at the same
-     time, the overflow/underflow exception follows the divide by zero
-     exception.  */
-
+  /* Raise exceptions.  */
+#if 1
   /* First: invalid exception.  */
   if (excepts & FE_INVALID)
     {
@@ -51,7 +49,6 @@ __feraiseexcept (int excepts)
   if (excepts & FE_OVERFLOW)
     {
       float x = FLT_MAX;
-
       __asm__ __volatile__ ("fmul %0,%0" : "+f" (x));
     }
 
@@ -59,17 +56,34 @@ __feraiseexcept (int excepts)
   if (excepts & FE_UNDERFLOW)
     {
       float x = -FLT_MIN;
-
       __asm__ __volatile__ ("fmul %0,%0" : "+f" (x));
     }
 
   /* Last: inexact.  */
   if (excepts & FE_INEXACT)
     {
-      float x = 1.0f, y = 3.0f;
-      __asm__ __volatile__ ("fdiv %1,%0" : "=f" (x) : "f" (y));
+      float x, y;
+      __asm__ __volatile__ (
+	  "fmov %2,%1\n"
+	  "fmov %3,%0\n"
+	  "fadd %1,%0\n"
+          : "=f" (y)
+          : "f" (x), "i"(0x3fa00000), "i"(0x3fbfffff)) ;
     }
 
+#else
+  fexcept_t cw;
+
+  /* Get current state.  */
+  _FPU_GETCW (cw);
+
+  excepts &= FE_ALL_EXCEPT;
+  cw |= excepts | (excepts << CAUSE_SHIFT);
+
+  /* Set new state.  */
+  _FPU_SETCW (cw);
+#endif
+
   /* Success.  */
   return 0;
 }
diff --git a/sysdeps/am33/fpu/fsetexcptflg.c b/sysdeps/am33/fpu/fsetexcptflg.c
index a5bde40..c04c67e 100644
--- a/sysdeps/am33/fpu/fsetexcptflg.c
+++ b/sysdeps/am33/fpu/fsetexcptflg.c
@@ -1,5 +1,5 @@
 /* Set floating-point environment exception handling.
-   Copyright (C) 1998, 1999, 2000, 2002, 2004 Free Software Foundation, Inc.
+   Copyright (C) 1998, 1999, 2000, 2002, 2004, 2009 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Alexandre Oliva <aoliva@redhat.com>
    based on corresponding file in the MIPS port.
@@ -25,29 +25,19 @@
 int
 __fesetexceptflag (const fexcept_t *flagp, int excepts)
 {
-  fpu_control_t cw, temp;
+  fpu_control_t cw;
 
   /* Get the current exceptions.  */
   _FPU_GETCW (cw);
 
   /* Make sure the flags we want restored are legal.  */
   excepts &= FE_ALL_EXCEPT;
-  temp = *flagp & excepts;
-
-  /* If EF bits are clear and the user requests them to be set,
-     we have to fail, because there's no way to do it.  */
-  if (~(cw & excepts) & temp)
-    return -1;
-
-  /* We clear EF bits by storing a 1 in them, so flip the
-     FE_ALL_EXCEPT bits.  */
-  temp = (~temp & FE_ALL_EXCEPT);
 
   /* Now clear the bits called for, and copy them in from flagp. Note that
      we ignore all non-flag bits from *flagp, so they don't matter.  */
-  cw = (cw & ~FE_ALL_EXCEPT) | temp;
+  cw = (cw & ~excepts) | (*flagp & excepts);
 
-  _FPU_SETFCW (cw);
+  _FPU_SETCW (cw);
 
   /* Success.  */
   return 0;
diff --git a/sysdeps/am33/fpu/libm-test-ulps b/sysdeps/am33/fpu/libm-test-ulps
new file mode 100644
index 0000000..ad50fcb
--- /dev/null
+++ b/sysdeps/am33/fpu/libm-test-ulps
@@ -0,0 +1,605 @@
+# Begin of automatic generation
+
+# atan2
+Test "atan2 (-0.00756827042671106339, -.001792735857538728036) == -1.80338464113663849327153994379639112":
+float: 6
+Test "atan2 (-0.75, -1.0) == -2.49809154479650885165983415456218025":
+float: 3
+Test "atan2 (0.75, -1.0) == 2.49809154479650885165983415456218025":
+float: 3
+Test "atan2 (1.390625, 0.9296875) == 0.981498387184244311516296577615519772":
+float: 1
+
+# atanh
+Test "atanh (0.75) == 0.972955074527656652552676371721589865":
+float: 1
+
+# cacosh
+Test "Real part of: cacosh (-2 - 3 i) == -1.9833870299165354323470769028940395 + 2.1414491111159960199416055713254211 i":
+double: 1
+float: 7
+Test "Imaginary part of: cacosh (-2 - 3 i) == -1.9833870299165354323470769028940395 + 2.1414491111159960199416055713254211 i":
+double: 1
+float: 3
+
+# casin
+Test "Real part of: casin (0.75 + 1.25 i) == 0.453276177638793913448921196101971749 + 1.13239363160530819522266333696834467 i":
+double: 1
+float: 1
+
+# casinh
+Test "Real part of: casinh (-2 - 3 i) == -1.9686379257930962917886650952454982 - 0.96465850440760279204541105949953237 i":
+double: 5
+float: 1
+Test "Imaginary part of: casinh (-2 - 3 i) == -1.9686379257930962917886650952454982 - 0.96465850440760279204541105949953237 i":
+double: 3
+float: 6
+Test "Real part of: casinh (0.75 + 1.25 i) == 1.03171853444778027336364058631006594 + 0.911738290968487636358489564316731207 i":
+float: 1
+Test "Imaginary part of: casinh (0.75 + 1.25 i) == 1.03171853444778027336364058631006594 + 0.911738290968487636358489564316731207 i":
+double: 1
+float: 1
+
+# catan
+Test "Real part of: catan (-2 - 3 i) == -1.4099210495965755225306193844604208 - 0.22907268296853876629588180294200276 i":
+float: 3
+Test "Imaginary part of: catan (-2 - 3 i) == -1.4099210495965755225306193844604208 - 0.22907268296853876629588180294200276 i":
+double: 1
+float: 1
+Test "Real part of: catan (0.75 + 1.25 i) == 1.10714871779409050301706546017853704 + 0.549306144334054845697622618461262852 i":
+float: 4
+
+# catanh
+Test "Real part of: catanh (-2 - 3 i) == -0.14694666622552975204743278515471595 - 1.3389725222944935611241935759091443 i":
+double: 4
+Test "Imaginary part of: catanh (-2 - 3 i) == -0.14694666622552975204743278515471595 - 1.3389725222944935611241935759091443 i":
+float: 4
+Test "Real part of: catanh (0.75 + 1.25 i) == 0.261492138795671927078652057366532140 + 0.996825126463918666098902241310446708 i":
+double: 1
+Test "Imaginary part of: catanh (0.75 + 1.25 i) == 0.261492138795671927078652057366532140 + 0.996825126463918666098902241310446708 i":
+float: 6
+
+# cbrt
+Test "cbrt (-27.0) == -3.0":
+double: 1
+Test "cbrt (0.75) == 0.908560296416069829445605878163630251":
+double: 1
+Test "cbrt (0.9921875) == 0.997389022060725270579075195353955217":
+double: 1
+
+# ccos
+Test "Imaginary part of: ccos (-2 - 3 i) == -4.18962569096880723013255501961597373 - 9.10922789375533659797919726277886212 i":
+float: 1
+Test "Real part of: ccos (0.75 + 1.25 i) == 1.38173873063425888530729933139078645 - 1.09193013555397466170919531722024128 i":
+double: 1
+float: 1
+Test "Imaginary part of: ccos (0.75 + 1.25 i) == 1.38173873063425888530729933139078645 - 1.09193013555397466170919531722024128 i":
+float: 1
+
+# ccosh
+Test "Real part of: ccosh (-2 - 3 i) == -3.72454550491532256547397070325597253 + 0.511822569987384608834463849801875634 i":
+float: 1
+Test "Imaginary part of: ccosh (-2 - 3 i) == -3.72454550491532256547397070325597253 + 0.511822569987384608834463849801875634 i":
+float: 1
+Test "Real part of: ccosh (0.75 + 1.25 i) == 0.408242591877968807788852146397499084 + 0.780365930845853240391326216300863152 i":
+double: 1
+float: 1
+Test "Imaginary part of: ccosh (0.75 + 1.25 i) == 0.408242591877968807788852146397499084 + 0.780365930845853240391326216300863152 i":
+float: 1
+
+# cexp
+Test "Imaginary part of: cexp (-2.0 - 3.0 i) == -0.13398091492954261346140525546115575 - 0.019098516261135196432576240858800925 i":
+float: 1
+Test "Real part of: cexp (0.75 + 1.25 i) == 0.667537446429131586942201977015932112 + 2.00900045494094876258347228145863909 i":
+float: 1
+
+# clog
+Test "Imaginary part of: clog (-2 - 3 i) == 1.2824746787307683680267437207826593 - 2.1587989303424641704769327722648368 i":
+float: 3
+Test "Real part of: clog (0.75 + 1.25 i) == 0.376885901188190075998919126749298416 + 1.03037682652431246378774332703115153 i":
+float: 1
+
+# clog10
+Test "Imaginary part of: clog10 (-0 + inf i) == inf + pi/2*log10(e) i":
+float: 1
+Test "Imaginary part of: clog10 (-0 - inf i) == inf - pi/2*log10(e) i":
+float: 1
+Test "Imaginary part of: clog10 (-2 - 3 i) == 0.556971676153418384603252578971164214 - 0.937554462986374708541507952140189646 i":
+double: 1
+float: 5
+Test "Imaginary part of: clog10 (-3 + inf i) == inf + pi/2*log10(e) i":
+float: 1
+Test "Imaginary part of: clog10 (-3 - inf i) == inf - pi/2*log10(e) i":
+float: 1
+Test "Imaginary part of: clog10 (-inf + 0 i) == inf + pi*log10(e) i":
+float: 1
+Test "Imaginary part of: clog10 (-inf + 1 i) == inf + pi*log10(e) i":
+float: 1
+Test "Imaginary part of: clog10 (-inf - 0 i) == inf - pi*log10(e) i":
+float: 1
+Test "Imaginary part of: clog10 (-inf - 1 i) == inf - pi*log10(e) i":
+float: 1
+Test "Imaginary part of: clog10 (0 + inf i) == inf + pi/2*log10(e) i":
+float: 1
+Test "Imaginary part of: clog10 (0 - inf i) == inf - pi/2*log10(e) i":
+float: 1
+Test "Real part of: clog10 (0.75 + 1.25 i) == 0.163679467193165171449476605077428975 + 0.447486970040493067069984724340855636 i":
+float: 1
+Test "Imaginary part of: clog10 (3 + inf i) == inf + pi/2*log10(e) i":
+float: 1
+Test "Imaginary part of: clog10 (3 - inf i) == inf - pi/2*log10(e) i":
+float: 1
+Test "Imaginary part of: clog10 (inf + inf i) == inf + pi/4*log10(e) i":
+float: 1
+Test "Imaginary part of: clog10 (inf - inf i) == inf - pi/4*log10(e) i":
+float: 1
+
+# cos
+Test "cos (M_PI_6l * 2.0) == 0.5":
+double: 1
+float: 1
+Test "cos (M_PI_6l * 4.0) == -0.5":
+double: 2
+float: 1
+Test "cos (pi/2) == 0":
+double: 1
+float: 1
+
+# cpow
+Test "Real part of: cpow (0.75 + 1.25 i, 0.0 + 1.0 i) == 0.331825439177608832276067945276730566 + 0.131338600281188544930936345230903032 i":
+float: 1
+Test "Imaginary part of: cpow (0.75 + 1.25 i, 0.0 + 1.0 i) == 0.331825439177608832276067945276730566 + 0.131338600281188544930936345230903032 i":
+float: 1
+Test "Real part of: cpow (0.75 + 1.25 i, 0.75 + 1.25 i) == 0.117506293914473555420279832210420483 + 0.346552747708338676483025352060418001 i":
+double: 1
+float: 4
+Test "Real part of: cpow (0.75 + 1.25 i, 1.0 + 1.0 i) == 0.0846958290317209430433805274189191353 + 0.513285749182902449043287190519090481 i":
+double: 2
+float: 3
+Test "Real part of: cpow (2 + 3 i, 4 + 0 i) == -119.0 - 120.0 i":
+double: 1
+float: 4
+Test "Imaginary part of: cpow (2 + 3 i, 4 + 0 i) == -119.0 - 120.0 i":
+float: 2
+Test "Imaginary part of: cpow (e + 0 i, 0 + 2 * M_PIl i) == 1.0 + 0.0 i":
+double: 2
+float: 2
+
+# csinh
+Test "Imaginary part of: csinh (-2 - 3 i) == 3.59056458998577995201256544779481679 - 0.530921086248519805267040090660676560 i":
+double: 1
+Test "Real part of: csinh (0.75 + 1.25 i) == 0.259294854551162779153349830618433028 + 1.22863452409509552219214606515777594 i":
+float: 1
+Test "Imaginary part of: csinh (0.75 + 1.25 i) == 0.259294854551162779153349830618433028 + 1.22863452409509552219214606515777594 i":
+float: 1
+
+# csqrt
+Test "Real part of: csqrt (-2 + 3 i) == 0.89597747612983812471573375529004348 + 1.6741492280355400404480393008490519 i":
+float: 1
+Test "Real part of: csqrt (-2 - 3 i) == 0.89597747612983812471573375529004348 - 1.6741492280355400404480393008490519 i":
+float: 1
+
+# ctan
+Test "Imaginary part of: ctan (0.75 + 1.25 i) == 0.160807785916206426725166058173438663 + 0.975363285031235646193581759755216379 i":
+double: 1
+
+# ctanh
+Test "Real part of: ctanh (-2 - 3 i) == -0.965385879022133124278480269394560686 + 0.988437503832249372031403430350121098e-2 i":
+double: 1
+float: 2
+Test "Imaginary part of: ctanh (0 + pi/4 i) == 0.0 + 1.0 i":
+float: 1
+Test "Real part of: ctanh (0.75 + 1.25 i) == 1.37260757053378320258048606571226857 + 0.385795952609750664177596760720790220 i":
+double: 1
+
+# erf
+Test "erf (1.25) == 0.922900128256458230136523481197281140":
+double: 1
+
+# erfc
+Test "erfc (0.75) == 0.288844366346484868401062165408589223":
+float: 1
+Test "erfc (2.0) == 0.00467773498104726583793074363274707139":
+double: 1
+Test "erfc (4.125) == 0.542340079956506600531223408575531062e-8":
+double: 1
+
+# exp10
+Test "exp10 (-1) == 0.1":
+double: 2
+float: 1
+Test "exp10 (0.75) == 5.62341325190349080394951039776481231":
+double: 1
+float: 1
+Test "exp10 (3) == 1000":
+double: 6
+float: 2
+
+# expm1
+Test "expm1 (0.75) == 1.11700001661267466854536981983709561":
+double: 1
+Test "expm1 (1) == M_El - 1.0":
+float: 1
+
+# hypot
+Test "hypot (-0.7, -12.4) == 12.419742348374220601176836866763271":
+float: 1
+Test "hypot (-0.7, 12.4) == 12.419742348374220601176836866763271":
+float: 1
+Test "hypot (-12.4, -0.7) == 12.419742348374220601176836866763271":
+float: 1
+Test "hypot (-12.4, 0.7) == 12.419742348374220601176836866763271":
+float: 1
+Test "hypot (0.7, -12.4) == 12.419742348374220601176836866763271":
+float: 1
+Test "hypot (0.7, 12.4) == 12.419742348374220601176836866763271":
+float: 1
+Test "hypot (12.4, -0.7) == 12.419742348374220601176836866763271":
+float: 1
+Test "hypot (12.4, 0.7) == 12.419742348374220601176836866763271":
+float: 1
+
+# j0
+Test "j0 (-4.0) == -3.9714980986384737228659076845169804197562E-1":
+double: 1
+float: 1
+Test "j0 (0.75) == 0.864242275166648623555731103820923211":
+float: 1
+Test "j0 (10.0) == -0.245935764451348335197760862485328754":
+double: 2
+float: 1
+Test "j0 (4.0) == -3.9714980986384737228659076845169804197562E-1":
+double: 1
+float: 1
+Test "j0 (8.0) == 0.171650807137553906090869407851972001":
+float: 1
+
+# j1
+Test "j1 (10.0) == 0.0434727461688614366697487680258592883":
+float: 2
+Test "j1 (2.0) == 0.576724807756873387202448242269137087":
+double: 1
+Test "j1 (8.0) == 0.234636346853914624381276651590454612":
+double: 1
+
+# jn
+Test "jn (0, -4.0) == -3.9714980986384737228659076845169804197562E-1":
+double: 1
+float: 1
+Test "jn (0, 0.75) == 0.864242275166648623555731103820923211":
+float: 1
+Test "jn (0, 10.0) == -0.245935764451348335197760862485328754":
+double: 2
+float: 1
+Test "jn (0, 4.0) == -3.9714980986384737228659076845169804197562E-1":
+double: 1
+float: 1
+Test "jn (0, 8.0) == 0.171650807137553906090869407851972001":
+float: 1
+Test "jn (1, 10.0) == 0.0434727461688614366697487680258592883":
+float: 2
+Test "jn (1, 2.0) == 0.576724807756873387202448242269137087":
+double: 1
+Test "jn (1, 8.0) == 0.234636346853914624381276651590454612":
+double: 1
+Test "jn (10, 0.125) == 0.250543369809369890173993791865771547e-18":
+double: 1
+float: 1
+Test "jn (10, 0.75) == 0.149621713117596814698712483621682835e-10":
+double: 1
+float: 1
+Test "jn (10, 10.0) == 0.207486106633358857697278723518753428":
+double: 4
+float: 1
+Test "jn (10, 2.0) == 0.251538628271673670963516093751820639e-6":
+float: 3
+Test "jn (3, 0.125) == 0.406503832554912875023029337653442868e-4":
+double: 1
+float: 1
+Test "jn (3, 0.75) == 0.848438342327410884392755236884386804e-2":
+double: 1
+float: 1
+Test "jn (3, 10.0) == 0.0583793793051868123429354784103409563":
+double: 3
+float: 1
+Test "jn (3, 2.0) == 0.128943249474402051098793332969239835":
+double: 1
+
+# lgamma
+Test "lgamma (0.7) == 0.260867246531666514385732417016759578":
+double: 1
+float: 1
+Test "lgamma (1.2) == -0.853740900033158497197028392998854470e-1":
+double: 1
+float: 2
+
+# log10
+Test "log10 (0.75) == -0.124938736608299953132449886193870744":
+double: 1
+float: 2
+Test "log10 (e) == log10(e)":
+float: 1
+
+# sincos
+Test "sincos (M_PI_6l*2.0, &sin_res, &cos_res) puts 0.5 in cos_res":
+double: 1
+float: 1
+Test "sincos (M_PI_6l*2.0, &sin_res, &cos_res) puts 0.86602540378443864676372317075293616 in sin_res":
+double: 1
+float: 1
+Test "sincos (pi/2, &sin_res, &cos_res) puts 0 in cos_res":
+double: 1
+float: 1
+Test "sincos (pi/6, &sin_res, &cos_res) puts 0.86602540378443864676372317075293616 in cos_res":
+float: 1
+
+# tan
+Test "tan (pi/4) == 1":
+double: 1
+
+# tanh
+Test "tanh (-0.75) == -0.635148952387287319214434357312496495":
+float: 1
+Test "tanh (0.75) == 0.635148952387287319214434357312496495":
+float: 1
+
+# tgamma
+Test "tgamma (-0.5) == -2 sqrt (pi)":
+double: 1
+float: 1
+Test "tgamma (0.5) == sqrt (pi)":
+float: 1
+Test "tgamma (0.7) == 1.29805533264755778568117117915281162":
+double: 1
+float: 1
+
+# y0
+Test "y0 (1.0) == 0.0882569642156769579829267660235151628":
+double: 2
+float: 1
+Test "y0 (1.5) == 0.382448923797758843955068554978089862":
+double: 2
+float: 1
+Test "y0 (10.0) == 0.0556711672835993914244598774101900481":
+float: 1
+Test "y0 (8.0) == 0.223521489387566220527323400498620359":
+double: 1
+float: 1
+
+# y1
+Test "y1 (0.125) == -5.19993611253477499595928744876579921":
+double: 1
+Test "y1 (1.5) == -0.412308626973911295952829820633445323":
+float: 1
+Test "y1 (10.0) == 0.249015424206953883923283474663222803":
+double: 3
+float: 1
+Test "y1 (2.0) == -0.107032431540937546888370772277476637":
+double: 1
+float: 1
+Test "y1 (8.0) == -0.158060461731247494255555266187483550":
+double: 1
+float: 2
+
+# yn
+Test "yn (0, 1.0) == 0.0882569642156769579829267660235151628":
+double: 2
+float: 1
+Test "yn (0, 1.5) == 0.382448923797758843955068554978089862":
+double: 2
+float: 1
+Test "yn (0, 10.0) == 0.0556711672835993914244598774101900481":
+float: 1
+Test "yn (0, 8.0) == 0.223521489387566220527323400498620359":
+double: 1
+float: 1
+Test "yn (1, 0.125) == -5.19993611253477499595928744876579921":
+double: 1
+Test "yn (1, 1.5) == -0.412308626973911295952829820633445323":
+float: 1
+Test "yn (1, 10.0) == 0.249015424206953883923283474663222803":
+double: 3
+float: 1
+Test "yn (1, 2.0) == -0.107032431540937546888370772277476637":
+double: 1
+float: 1
+Test "yn (1, 8.0) == -0.158060461731247494255555266187483550":
+double: 1
+float: 2
+Test "yn (10, 0.125) == -127057845771019398.252538486899753195":
+double: 1
+Test "yn (10, 0.75) == -2133501638.90573424452445412893839236":
+double: 1
+float: 2
+Test "yn (10, 1.0) == -121618014.278689189288130426667971145":
+double: 1
+float: 2
+Test "yn (10, 10.0) == -0.359814152183402722051986577343560609":
+double: 1
+Test "yn (10, 2.0) == -129184.542208039282635913145923304214":
+double: 2
+float: 1
+Test "yn (3, 0.125) == -2612.69757350066712600220955744091741":
+double: 1
+Test "yn (3, 0.75) == -12.9877176234475433186319774484809207":
+double: 1
+float: 1
+Test "yn (3, 10.0) == -0.251362657183837329779204747654240998":
+double: 1
+float: 1
+Test "yn (3, 2.0) == -1.12778377684042778608158395773179238":
+double: 1
+
+# Maximal error of functions:
+Function: "atan2":
+float: 6
+
+Function: "atanh":
+float: 1
+
+Function: Real part of "cacosh":
+double: 1
+float: 7
+
+Function: Imaginary part of "cacosh":
+double: 1
+float: 3
+
+Function: Real part of "casin":
+double: 1
+float: 1
+
+Function: Real part of "casinh":
+double: 5
+float: 1
+
+Function: Imaginary part of "casinh":
+double: 3
+float: 6
+
+Function: Real part of "catan":
+float: 4
+
+Function: Imaginary part of "catan":
+double: 1
+float: 1
+
+Function: Real part of "catanh":
+double: 4
+
+Function: Imaginary part of "catanh":
+float: 6
+
+Function: "cbrt":
+double: 1
+
+Function: Real part of "ccos":
+double: 1
+float: 1
+
+Function: Imaginary part of "ccos":
+float: 1
+
+Function: Real part of "ccosh":
+double: 1
+float: 1
+
+Function: Imaginary part of "ccosh":
+float: 1
+
+Function: Real part of "cexp":
+float: 1
+
+Function: Imaginary part of "cexp":
+float: 1
+
+Function: Real part of "clog":
+float: 1
+
+Function: Imaginary part of "clog":
+float: 3
+
+Function: Real part of "clog10":
+float: 1
+
+Function: Imaginary part of "clog10":
+double: 1
+float: 5
+
+Function: "cos":
+double: 2
+float: 1
+
+Function: Real part of "cpow":
+double: 2
+float: 4
+
+Function: Imaginary part of "cpow":
+double: 2
+float: 2
+
+Function: Real part of "csinh":
+float: 1
+
+Function: Imaginary part of "csinh":
+double: 1
+float: 1
+
+Function: Real part of "csqrt":
+float: 1
+
+Function: Imaginary part of "ctan":
+double: 1
+
+Function: Real part of "ctanh":
+double: 1
+float: 2
+
+Function: Imaginary part of "ctanh":
+float: 1
+
+Function: "erf":
+double: 1
+
+Function: "erfc":
+double: 1
+float: 1
+
+Function: "exp10":
+double: 6
+float: 2
+
+Function: "expm1":
+double: 1
+float: 1
+
+Function: "hypot":
+float: 1
+
+Function: "j0":
+double: 2
+float: 1
+
+Function: "j1":
+double: 1
+float: 2
+
+Function: "jn":
+double: 4
+float: 3
+
+Function: "lgamma":
+double: 1
+float: 2
+
+Function: "log10":
+double: 1
+float: 2
+
+Function: "sincos":
+double: 1
+float: 1
+
+Function: "tan":
+double: 1
+
+Function: "tanh":
+float: 1
+
+Function: "tgamma":
+double: 1
+float: 1
+
+Function: "y0":
+double: 2
+float: 1
+
+Function: "y1":
+double: 3
+float: 2
+
+Function: "yn":
+double: 3
+float: 2
+
+# end of automatic generation
diff --git a/sysdeps/am33/init-misc.c b/sysdeps/am33/init-misc.c
new file mode 100644
index 0000000..f25a3c7
--- /dev/null
+++ b/sysdeps/am33/init-misc.c
@@ -0,0 +1,48 @@
+/* Define and initialize `__progname' et. al.
+   Copyright (C) 1994,1995,1996,1997,1998,2002,2010 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 <string.h>
+#include <libc-internal.h>
+
+#include <unistd.h>
+#include <ldsodefs.h>
+#include <dl-procinfo.h>
+#include <sysdep.h>
+
+char *__progname_full = (char *) "";
+char *__progname = (char *) "";
+weak_alias (__progname_full, program_invocation_name)
+weak_alias (__progname, program_invocation_short_name)
+
+unsigned long long __mn10300_hwcap __attribute__ ((nocommon));
+
+void
+__init_misc (int argc, char **argv, char **envp)
+{
+  if (argv && argv[0])
+    {
+      char *p = strrchr (argv[0], '/');
+      if (p == NULL)
+	__progname = argv[0];
+      else
+	__progname = p + 1;
+      __progname_full = argv[0];
+    }
+  __mn10300_hwcap = GLRO(dl_hwcap);
+}
diff --git a/sysdeps/am33/ldsodefs.h b/sysdeps/am33/ldsodefs.h
new file mode 100644
index 0000000..1fdeb67
--- /dev/null
+++ b/sysdeps/am33/ldsodefs.h
@@ -0,0 +1,41 @@
+/* Run-time dynamic linker data structures for loaded ELF shared objects.
+   Copyright (C) 2005 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#ifndef _AM33_LDSODEFS_H
+#define _AM33_LDSODEFS_H 1
+
+#include <elf.h>
+
+struct La_am33_regs;
+struct La_am33_retval;
+
+#define ARCH_PLTENTER_MEMBERS \
+    Elf32_Addr (*am33_gnu_pltenter) (Elf32_Sym *, unsigned int, uintptr_t *,	\
+				     uintptr_t *, struct La_am33_regs *,	\
+				     unsigned int *, const char *,		\
+				     long int *)
+
+#define ARCH_PLTEXIT_MEMBERS \
+    Elf32_Addr (*am33_gnu_pltexit) (Elf32_Sym *, unsigned int, uintptr_t *,	\
+				    uintptr_t *, struct La_am33_regs *,	     	\
+				    struct La_am33_retval *, const char *)
+
+#include_next <ldsodefs.h>
+
+#endif
diff --git a/sysdeps/am33/linuxthreads/pspinlock.c b/sysdeps/am33/linuxthreads/pspinlock.c
deleted file mode 100644
index a167497..0000000
--- a/sysdeps/am33/linuxthreads/pspinlock.c
+++ /dev/null
@@ -1,73 +0,0 @@
-/* POSIX spinlock implementation.  AM33 version.
-   Copyright 2001 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Library General Public License as
-   published by the Free Software Foundation; either version 2 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
-   Library General Public License for more details.
-
-   You should have received a copy of the GNU Library General Public
-   License along with the GNU C Library.  If not, see
-   <http://www.gnu.org/licenses/>.  */
-
-#include <errno.h>
-#include <pthread.h>
-#include "internals.h"
-
-int
-__pthread_spin_lock (pthread_spinlock_t *lock)
-{
-  __asm__ __volatile__("1: bset %1, (%0); beq 1b"
-		       : : "a" (lock), "d" (1) : "memory");
-  return 0;
-}
-weak_alias (__pthread_spin_lock, pthread_spin_lock)
-
-
-int
-__pthread_spin_trylock (pthread_spinlock_t *lock)
-{
-  int oldval = 1;
-
-  __asm__ __volatile__ ("bset %0, (%1); beq 1f; clr %0; 1:" :
-			"+d" (oldval) : "a" (lock) : "memory");
-
-  return oldval ? EBUSY : 0;
-}
-weak_alias (__pthread_spin_trylock, pthread_spin_trylock)
-
-
-int
-__pthread_spin_unlock (pthread_spinlock_t *lock)
-{
-  *lock = 0;
-  return 0;
-}
-weak_alias (__pthread_spin_unlock, pthread_spin_unlock)
-
-
-int
-__pthread_spin_init (pthread_spinlock_t *lock, int pshared)
-{
-  /* We can ignore the `pshared' parameter.  Since we are busy-waiting
-     all processes which can access the memory location `lock' points
-     to can use the spinlock.  */
-  *lock = 0;
-  return 0;
-}
-weak_alias (__pthread_spin_init, pthread_spin_init)
-
-
-int
-__pthread_spin_destroy (pthread_spinlock_t *lock)
-{
-  /* Nothing to do.  */
-  return 0;
-}
-weak_alias (__pthread_spin_destroy, pthread_spin_destroy)
diff --git a/sysdeps/am33/linuxthreads/pt-machine.h b/sysdeps/am33/linuxthreads/pt-machine.h
deleted file mode 100644
index 86d0f8b..0000000
--- a/sysdeps/am33/linuxthreads/pt-machine.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/* Machine-dependent pthreads configuration and inline functions.
-   am33 version.
-   Copyright (C) 1996,1997,1998,1999,2000,2001, 2004
-   Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-   Contributed by Alexandre Oliva <aoliva@redhat.com>
-   Based on ../i386/pt-machine.h.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Library General Public License as
-   published by the Free Software Foundation; either version 2 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
-   Library General Public License for more details.
-
-   You should have received a copy of the GNU Library General Public
-   License along with the GNU C Library.  If not, see
-   <http://www.gnu.org/licenses/>.  */
-
-#ifndef _PT_MACHINE_H
-#define _PT_MACHINE_H	1
-
-#ifndef __ASSEMBLER__
-#ifndef PT_EI
-# define PT_EI extern inline
-#endif
-
-/* Get some notion of the current stack.  Need not be exactly the top
-   of the stack, just something somewhere in the current frame.  */
-#define CURRENT_STACK_FRAME  __builtin_frame_address (0)
-
-/* Spinlock implementation; required.  */
-PT_EI long int
-testandset (int *spinlock)
-{
-  long int ret = 1;
-
-  /* This won't test&set the entire int, only the least significant
-     byte.  I hope this doesn't matter, since we can't do better.  */
-  __asm__ __volatile__ ("bset %0, %1; bne 1f; clr %0; 1:" :
-			"+d" (ret), "+m" (*(volatile int *)spinlock));
-
-  return ret;
-}
-
-
-PT_EI int
-get_eflags (void)
-{
-  int res;
-  __asm__ __volatile__ ("mov psw,%0" : "=d" (res));
-  return res;
-}
-
-
-PT_EI void
-set_eflags (int newflags)
-{
-  __asm__ __volatile__ ("mov %0,psw" : : "d" (newflags) : "cc");
-}
-
-#endif /* __ASSEMBLER__ */
-
-#endif /* pt-machine.h */
diff --git a/sysdeps/am33/machine-gmon.h b/sysdeps/am33/machine-gmon.h
new file mode 100644
index 0000000..d0c9cd5
--- /dev/null
+++ b/sysdeps/am33/machine-gmon.h
@@ -0,0 +1,28 @@
+/* am33-specific implementation of profiling support.
+   Copyright (C) 2006 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by DJ Delorie <dj@redhat.com>, 2006.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <sysdep.h>
+
+/* GCC calls _mcount directly, so we don't need the indirection.  */
+
+#define _MCOUNT_DECL(frompc, selfpc) \
+void _mcount (u_long frompc, u_long selfpc)
+
+#define MCOUNT
diff --git a/sysdeps/am33/memusage.h b/sysdeps/am33/memusage.h
index 19d7a73..d066484 100644
--- a/sysdeps/am33/memusage.h
+++ b/sysdeps/am33/memusage.h
@@ -15,7 +15,7 @@
    License along with the GNU C Library.  If not, see
    <http://www.gnu.org/licenses/>.  */
 
-#define GETSP() ({ uintptr_t stack_ptr; \
+#define GETSP() ({ register uintptr_t stack_ptr; \
 		   asm ("mov sp,%0" : "=a" (stack_ptr)); \
 		   stack_ptr; })
 
diff --git a/sysdeps/am33/nptl/Makefile b/sysdeps/am33/nptl/Makefile
new file mode 100644
index 0000000..0300693
--- /dev/null
+++ b/sysdeps/am33/nptl/Makefile
@@ -0,0 +1,21 @@
+# Copyright (C) 2005 Free Software Foundation, Inc.
+# This file is part of the GNU C Library.
+#
+# The GNU C Library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# The GNU C Library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with the GNU C Library; if not, write to the Free
+# Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+# 02111-1307 USA.
+
+ifeq ($(subdir),csu)
+gen-as-const-headers += tcb-offsets.sym
+endif
diff --git a/sysdeps/am33/nptl/jmpbuf-unwind.h b/sysdeps/am33/nptl/jmpbuf-unwind.h
new file mode 100644
index 0000000..a7df73c
--- /dev/null
+++ b/sysdeps/am33/nptl/jmpbuf-unwind.h
@@ -0,0 +1,31 @@
+/* Copyright (C) 2003, 2004, 2009 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Mark Salter <msalter@redhat.com>
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <setjmp.h>
+#include <stdint.h>
+#include <unwind.h>
+
+#define _JMPBUF_CFA_UNWINDS_ADJ(_jmpbuf, _context, _adj) \
+  _JMPBUF_UNWINDS_ADJ (_jmpbuf, (void *) _Unwind_GetCFA (_context), _adj)
+
+#define _JMPBUF_UNWINDS_ADJ(_jmpbuf, _address, _adj) \
+  ((uintptr_t)(_address) - (_adj) < (uintptr_t)(((long *)_jmpbuf)[__JMP_BUF_SP]) - (_adj))
+
+/* We use the normal lobngjmp for unwinding.  */
+#define __libc_unwind_longjmp(buf, val) __libc_longjmp (buf, val)
diff --git a/sysdeps/am33/nptl/pthread_spin_lock.c b/sysdeps/am33/nptl/pthread_spin_lock.c
new file mode 100644
index 0000000..ba146cd
--- /dev/null
+++ b/sysdeps/am33/nptl/pthread_spin_lock.c
@@ -0,0 +1,29 @@
+/* POSIX spinlock implementation.  AM33 version.
+   Copyright 2009 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Mark Salter <msalter@redhat.com>
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C 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 "pthreadP.h"
+
+int
+pthread_spin_lock (pthread_spinlock_t *lock)
+{
+  __asm__ __volatile__("1: bset %1, (%0); bne 1b"
+		       : : "a" (lock), "d" (1) : "memory", "cc");
+  return 0;
+}
diff --git a/sysdeps/am33/nptl/pthread_spin_trylock.c b/sysdeps/am33/nptl/pthread_spin_trylock.c
new file mode 100644
index 0000000..88b91d1
--- /dev/null
+++ b/sysdeps/am33/nptl/pthread_spin_trylock.c
@@ -0,0 +1,33 @@
+/* POSIX spinlock implementation.  AM33 version.
+   Copyright 2009 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Mark Salter <msalter@redhat.com>
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C 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 <errno.h>
+#include "pthreadP.h"
+
+int
+pthread_spin_trylock (pthread_spinlock_t *lock)
+{
+  int oldval = 1;
+
+  __asm__ __volatile__ ("bset %0, (%1); bne 1f; clr %0; 1:" :
+			"+d" (oldval) : "a" (lock) : "memory", "cc");
+
+  return oldval ? EBUSY : 0;
+}
diff --git a/sysdeps/am33/nptl/pthread_spin_unlock.c b/sysdeps/am33/nptl/pthread_spin_unlock.c
new file mode 100644
index 0000000..72e8faf
--- /dev/null
+++ b/sysdeps/am33/nptl/pthread_spin_unlock.c
@@ -0,0 +1,29 @@
+/* POSIX spinlock implementation.  AM33 version.
+   Copyright (C) 2009 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Mark Salter <msalter@redhat.com>
+
+   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; 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 "pthreadP.h"
+
+int
+pthread_spin_unlock (pthread_spinlock_t *lock)
+{
+  __asm__ __volatile__ ("bclr %0, (%1)"
+			: : "d" (1), "a" (lock) : "memory", "cc");
+  return 0;
+}
diff --git a/sysdeps/am33/nptl/pthreaddef.h b/sysdeps/am33/nptl/pthreaddef.h
new file mode 100644
index 0000000..a9f77ac
--- /dev/null
+++ b/sysdeps/am33/nptl/pthreaddef.h
@@ -0,0 +1,41 @@
+/* Machine-dependent pthreads configuration and inline functions.
+   AM33 version.
+   Copyright (C) 2005 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Alexandre Oliva <aoliva@redhat.com>
+
+   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; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+/* Default stack size.  */
+#define ARCH_STACK_DEFAULT_SIZE	(2 * 1024 * 1024)
+
+/* Required stack pointer alignment at beginning. */
+#define STACK_ALIGN		4
+
+/* Minimal stack size after allocating thread descriptor and guard size.  */
+#define MINIMAL_REST_STACK	2048
+
+/* Alignment requirement for TCB.  */
+#define TCB_ALIGNMENT		16
+
+/* Location of current stack frame.  */
+#define CURRENT_STACK_FRAME	__builtin_frame_address (0)
+
+/* XXX Until we have a better place keep the definitions here.  */
+
+/* While there is no such syscall.  */
+#define __exit_thread_inline(val) \
+  INLINE_SYSCALL (exit, 1, (val))
diff --git a/sysdeps/am33/nptl/tcb-offsets.sym b/sysdeps/am33/nptl/tcb-offsets.sym
new file mode 100644
index 0000000..16dfb4a
--- /dev/null
+++ b/sysdeps/am33/nptl/tcb-offsets.sym
@@ -0,0 +1,6 @@
+#include <sysdep.h>
+#include <tls.h>
+
+TID			offsetof (struct pthread, tid)
+PID			offsetof (struct pthread, pid)
+MULTIPLE_THREADS_OFFSET	offsetof (tcbhead_t, multiple_threads)
diff --git a/sysdeps/am33/nptl/tls.h b/sysdeps/am33/nptl/tls.h
new file mode 100644
index 0000000..5be3bad
--- /dev/null
+++ b/sysdeps/am33/nptl/tls.h
@@ -0,0 +1,172 @@
+/* Definition for thread-local data handling.  linuxthreads/am33 version.
+   Copyright (C) 2009 Free Software Foundation, Inc.
+   Contributed by Mark Salter <msalter@redhat.com>.
+
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#ifndef _TLS_H
+#define _TLS_H	1
+#include <dl-sysdep.h>
+#ifndef __ASSEMBLER__
+# include <stdbool.h>
+# include <stddef.h>
+# include <stdint.h>
+# include <stdlib.h>
+# include <list.h>
+
+/* Type for the dtv.  */
+typedef union dtv
+{
+  size_t counter;
+  struct
+  {
+    void *val;
+    bool is_static;
+  } pointer;
+} dtv_t;
+
+typedef struct
+{
+  void *tcb;		/* Pointer to the TCB.  Not necessary the
+			   thread descriptor used by libpthread.  */
+  dtv_t *dtv;
+  void *self;		/* Pointer to the thread descriptor.  */
+  int multiple_threads;
+  uintptr_t sysinfo;
+  uintptr_t pointer_guard;
+  int gscope_flag;
+#ifndef __ASSUME_PRIVATE_FUTEX
+  int private_futex;
+#else
+  int __unused1;
+#endif
+  /* Reservation of some values for the TM ABI.  */
+  void *__private_tm[5];
+} tcbhead_t;
+
+# define TLS_MULTIPLE_THREADS_IN_TCB 1
+
+#else /* __ASSEMBLER__ */
+# include <tcb-offsets.h>
+#endif
+
+/* Alignment requirement for the stack.  */
+#define STACK_ALIGN	4
+
+#ifndef __ASSEMBLER__
+/* Get system call information.  */
+# include <sysdep.h>
+
+/* Get the thread descriptor definition.  */
+# include <nptl/descr.h>
+
+register struct pthread *__thread_self __asm__("e2") __attribute__((used));
+
+/* This is the size of the initial TCB.  Can't be just sizeof (tcbhead_t),
+   because NPTL getpid, __libc_alloca_cutoff etc. need (almost) the whole
+   struct pthread even when not linked with -lpthread.  */
+# define TLS_INIT_TCB_SIZE sizeof (struct pthread)
+
+/* Alignment requirements for the initial TCB.  */
+# define TLS_INIT_TCB_ALIGN __alignof__ (struct pthread)
+
+/* This is the size of the TCB.  */
+# define TLS_TCB_SIZE sizeof (struct pthread)
+
+/* Alignment requirements for the TCB.  */
+# define TLS_TCB_ALIGN __alignof__ (struct pthread)
+
+/* The TCB can have any size and the memory following the address the
+   thread pointer points to is unspecified.  Allocate the TCB there.  */
+# define TLS_TCB_AT_TP	1
+
+/* Install the dtv pointer.  The pointer passed is to the element with
+   index -1 which contain the length.  */
+# define INSTALL_DTV(descr, dtvp) \
+  ((tcbhead_t *) (descr))->dtv = (dtvp) + 1
+
+/* Install new dtv for current thread.  */
+# define INSTALL_NEW_DTV(dtvp) \
+  (((tcbhead_t *) __thread_self)->dtv = (dtvp))
+
+/* Return dtv of given thread descriptor.  */
+# define GET_DTV(descr) \
+  (((tcbhead_t *) (descr))->dtv)
+
+/* Code to initially initialize the thread pointer.  This might need
+   special attention since 'errno' is not yet available and if the
+   operation can cause a failure 'errno' must not be touched.  */
+# define TLS_INIT_TP(descr, secondcall) \
+  (__thread_self = (__typeof (__thread_self)) (descr), NULL)
+
+/* Return the address of the dtv for the current thread.  */
+# define THREAD_DTV() \
+  (((tcbhead_t *) __thread_self)->dtv)
+
+/* Return the thread descriptor for the current thread.  */
+# define THREAD_SELF __thread_self
+
+/* Magic for libthread_db to know how to do THREAD_SELF.  */
+# define DB_THREAD_SELF_INCLUDE <sys/ucontext.h>
+# define DB_THREAD_SELF \
+  REGISTER (32, 32, 15 * 4, 0)
+
+/* Access to data in the thread descriptor is easy.  */
+#define THREAD_GETMEM(descr, member) \
+  descr->member
+#define THREAD_GETMEM_NC(descr, member, idx) \
+  descr->member[idx]
+#define THREAD_SETMEM(descr, member, value) \
+  descr->member = (value)
+#define THREAD_SETMEM_NC(descr, member, idx, value) \
+  descr->member[idx] = (value)
+
+/* Get/set the stack guard field in TCB head.  */
+#define THREAD_GET_POINTER_GUARD() \
+  THREAD_GETMEM (THREAD_SELF, header.pointer_guard)
+#define THREAD_SET_POINTER_GUARD(value) \
+  THREAD_SETMEM (THREAD_SELF, header.pointer_guard, value)
+# define THREAD_COPY_POINTER_GUARD(descr) \
+  ((descr)->header.pointer_guard = THREAD_GET_POINTER_GUARD ())
+
+/* Get and set the global scope generation counter in struct pthread.  */
+#define THREAD_GSCOPE_FLAG_UNUSED 0
+#define THREAD_GSCOPE_FLAG_USED   1
+#define THREAD_GSCOPE_FLAG_WAIT   2
+#define THREAD_GSCOPE_RESET_FLAG() \
+  do									     \
+    { int __res								     \
+	= atomic_exchange_rel (&THREAD_SELF->header.gscope_flag,	     \
+			       THREAD_GSCOPE_FLAG_UNUSED);		     \
+      if (__res == THREAD_GSCOPE_FLAG_WAIT)				     \
+	lll_futex_wake (&THREAD_SELF->header.gscope_flag, 1, LLL_PRIVATE);   \
+    }									     \
+  while (0)
+#define THREAD_GSCOPE_SET_FLAG() \
+  do									     \
+    {									     \
+      THREAD_SELF->header.gscope_flag = THREAD_GSCOPE_FLAG_USED;	     \
+      atomic_write_barrier ();						     \
+    }									     \
+  while (0)
+#define THREAD_GSCOPE_WAIT() \
+  GL(dl_wait_lookup_done) ()
+
+#endif /* __ASSEMBLER__ */
+
+#endif	/* tls.h */
diff --git a/sysdeps/am33/setjmp.S b/sysdeps/am33/setjmp.S
index 54b239d..97a28da 100644
--- a/sysdeps/am33/setjmp.S
+++ b/sysdeps/am33/setjmp.S
@@ -63,6 +63,10 @@ ENTRY (__sigsetjmp)
 	/* Make a tail call to __sigjmp_save; it takes the same args.  */
 	jmp __sigjmp_save
 END (__sigsetjmp)
+libc_hidden_def (_setjmp)
+
+weak_extern(_setjmp)
+weak_extern(setjmp)
 
 /* BSD `_setjmp' entry point to `sigsetjmp (..., 1)'.  */
 ENTRY (setjmp)
diff --git a/sysdeps/am33/stackinfo.h b/sysdeps/am33/stackinfo.h
index c7a7977..fa5b7e4 100644
--- a/sysdeps/am33/stackinfo.h
+++ b/sysdeps/am33/stackinfo.h
@@ -21,7 +21,13 @@
 #ifndef _STACKINFO_H
 #define _STACKINFO_H	1
 
+#include <elf.h>
+
 /* On am33 the stack grows down.  */
 #define _STACK_GROWS_DOWN	1
 
+/* Default to an executable stack. PF_X can be overridden if PT_GNU_STACK is
+ * present, but it is presumed absent.  */
+#define DEFAULT_STACK_PERMS (PF_R|PF_W|PF_X)
+
 #endif	/* stackinfo.h */
diff --git a/sysdeps/am33/sysdep.h b/sysdeps/am33/sysdep.h
index 2ddb656..8f9d4a6 100644
--- a/sysdeps/am33/sysdep.h
+++ b/sysdeps/am33/sysdep.h
@@ -1,4 +1,4 @@
-/* Copyright 2001 Free Software Foundation, Inc.
+/* Copyright 2001, 2009 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Alexandre Oliva <aoliva@redhat.com>.
    Based on ../i386/sysdep.h.
@@ -23,19 +23,10 @@
 
 /* Syntactic details of assembler.  */
 
-#ifdef HAVE_ELF
 /* For ELF we need the `.type' directive to make shared libs work right.  */
 #define ASM_TYPE_DIRECTIVE(name,typearg) .type name,typearg;
 #define ASM_SIZE_DIRECTIVE(name) .size name,.-name;
 
-/* In ELF C symbols are asm symbols.  */
-#undef	NO_UNDERSCORES
-#define NO_UNDERSCORES
-#else
-#define ASM_TYPE_DIRECTIVE(name,type)	/* Nothing is specified.  */
-#define ASM_SIZE_DIRECTIVE(name)	/* Nothing is specified.  */
-#endif
-
 /* Define an entry point visible from C.  */
 #define	ENTRY(name)							      \
   ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(name);				      \
@@ -58,13 +49,11 @@
 #define CALL_MCOUNT		/* Do nothing.  */
 #endif
 
-#ifdef	NO_UNDERSCORES
 /* Since C identifiers are not normally prefixed with an underscore
    on this system, the asm identifier `syscall_error' intrudes on the
    C name space.  Make sure we use an innocuous name.  */
 #define	syscall_error	__syscall_error
 #define mcount		_mcount
-#endif
 
 #undef JUMPTARGET
 #ifdef PIC
@@ -75,7 +64,11 @@
 
 /* Local label name for asm code. */
 #ifndef L
+#ifdef HAVE_ELF
+#define L(name)		.L##name
+#else
 #define L(name)		name
 #endif
+#endif
 
 #endif	/* __ASSEMBLER__ */
diff --git a/sysdeps/am33/tls-macros.h b/sysdeps/am33/tls-macros.h
new file mode 100644
index 0000000..6936f7e
--- /dev/null
+++ b/sysdeps/am33/tls-macros.h
@@ -0,0 +1,91 @@
+/* This file defines TLS macros for AM33.
+   Copyright (C) 2009 Free Software Foundation, Inc.
+   Contributed by Mark Salter <msalter@redhat.com>.
+
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#define TLS_LE(x) \
+  ({ int *__l;					\
+     asm ("mov  " #x "@tpoff,%0\n\t"		\
+          "add  e2, %0\n\t"			\
+	  : "=a" (__l) : : "cc");		\
+     __l; })
+
+#ifdef PIC
+# define TLS_IE(x) \
+  ({ int *__l;					\
+     asm ("mov  (" #x "@gotntpoff,a2),%0\n\t"	\
+          "add  e2, %0\n\t"			\
+	  : "=a" (__l) : : "cc");		\
+     __l; })
+#else
+# define TLS_IE(x) \
+  ({ int *__l;					\
+     asm ("mov (" #x "@indntpoff),%0\n\t"	\
+          "add  e2, %0\n\t"			\
+	  : "=a" (__l) : : "cc");		\
+     __l; })
+#endif
+
+#ifdef PIC
+# define TLS_LD(x) \
+  ({ int *__l;						\
+     asm ("mov " #x "@tlsldm,d0\n\t"			\
+          "add a2,d0\n\t"				\
+	  "call __tls_get_addr@PLT,[],0\n\t"		\
+	  "mov " #x "@dtpoff, %0\n\t"			\
+          "add a0,%0\n\t"				\
+	  : "=a" (__l) : : "a0", "d0", "cc");		\
+     __l; })
+#else
+# define TLS_LD(x) \
+  ({ int *__l; 						\
+     asm ("1:\n\t" 					\
+          "mov pc,%0\n\t"				\
+	  "add _GLOBAL_OFFSET_TABLE_  - (1b-.),%0\n\t"	\
+          "mov " #x "@tlsldm,d0\n\t"			\
+          "add %0,d0\n\t"				\
+	  "call __tls_get_addr,[],0\n\t"		\
+	  "mov " #x "@dtpoff, %0\n\t"			\
+          "add a0,%0\n\t"				\
+	  : "=a" (__l) : : "a0", "d0", "cc");		\
+     __l; })
+#endif
+
+#ifdef PIC
+# define TLS_GD(x) \
+  ({ int *__l;						\
+     asm ("mov " #x "@tlsgd,d0\n\t"			\
+          "add a2,d0\n\t"				\
+	  "call __tls_get_addr@PLT,[],0\n\t"		\
+          "mov a0,%0\n\t"				\
+	  : "=a" (__l) : : "d0", "cc" );		\
+     __l; })
+#else
+# define TLS_GD(x) \
+  ({ int *__l;						\
+     asm ("1:\n\t" 					\
+          "mov pc,%0\n\t"				\
+	  "add _GLOBAL_OFFSET_TABLE_  - (1b-.),%0\n\t"	\
+          "mov " #x "@tlsgd,d0\n\t"			\
+          "add %0,d0\n\t"				\
+	  "call __tls_get_addr,[],0\n\t"		\
+          "mov a0,%0\n\t"				\
+	  : "=a" (__l) : : "d0", "cc" );		\
+     __l; })
+#endif
diff --git a/sysdeps/am33/tst-audit.h b/sysdeps/am33/tst-audit.h
new file mode 100644
index 0000000..9c790d5
--- /dev/null
+++ b/sysdeps/am33/tst-audit.h
@@ -0,0 +1,26 @@
+/* Definitions for testing PLT entry/exit auditing.  ARM 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.  */
+
+#define pltenter la_am33_gnu_pltenter
+#define pltexit la_am33_gnu_pltexit
+#define La_regs La_am33_regs
+#define La_retval La_am33_retval
+#define int_retval lrv_d0
diff --git a/sysdeps/arm/dl-machine.h b/sysdeps/arm/dl-machine.h
index 8d905e8..f6666da 100644
--- a/sysdeps/arm/dl-machine.h
+++ b/sysdeps/arm/dl-machine.h
@@ -117,8 +117,7 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
 	{
 	  got[2] = (Elf32_Addr) &_dl_runtime_profile;
 
-	  if (GLRO(dl_profile) != NULL
-	      && _dl_name_match_p (GLRO(dl_profile), l))
+	  if (_dl_name_match_p (GLRO(dl_profile), l))
 	    /* Say that we really want profiling and the timers are
 	       started.  */
 	    GL(dl_profile_map) = l;
diff --git a/sysdeps/unix/am33/sysdep.S b/sysdeps/unix/am33/sysdep.S
index 26740c2..3c6d67d 100644
--- a/sysdeps/unix/am33/sysdep.S
+++ b/sysdeps/unix/am33/sysdep.S
@@ -22,39 +22,21 @@
 #define _ERRNO_H
 #include <bits/errno.h>
 
-.globl C_SYMBOL_NAME(errno)
-.globl syscall_error
+#ifdef IS_IN_rtld
+# include <dl-sysdep.h>		/* Defines RTLD_PRIVATE_ERRNO.  */
+#endif
+
+#include <tls.h>
 
 #undef syscall_error
-#ifdef NO_UNDERSCORES
 __syscall_error:
+#ifndef IS_IN_rtld
+	mov d0, (C_SYMBOL_NAME(errno@tpoff), e2)
+#elif RTLD_PRIVATE_ERRNO
+	mov d0, C_SYMBOL_NAME(rtld_errno)
 #else
-syscall_error:
-#endif
-#if defined (EWOULDBLOCK_sys) && EWOULDBLOCK_sys != EAGAIN
-	/* We translate the system's EWOULDBLOCK error into EAGAIN.
-	   The GNU C library always defines EWOULDBLOCK==EAGAIN.
-	   EWOULDBLOCK_sys is the original number.  */
-	cmp EWOULDBLOCK_sys,d0	/* Is it the old EWOULDBLOCK?  */
-	bne .Lnotb		/* Branch if not.  */
-	mov EAGAIN,d0		/* Yes; translate it to EAGAIN.  */
-.Lnotb:
-#endif
-#ifndef	PIC
-# ifndef _LIBC_REENTRANT
-	mov d0,(C_SYMBOL_NAME (errno))
-# else
-	movm [d2],(sp)
-	add -12,sp
-	mov d0,d2
-	call __errno_location,[],0
-	mov d2,(a0)
-	add 12,sp
-	movm (sp),[d2]
+#error "Unsupported non-TLS case"
 # endif
-#else
-# error "This shouldn't be assembled for PIC"
-#endif
 	mov -1,d0
 	mov d0,a0
 	ret
diff --git a/sysdeps/unix/sysv/linux/am33/____longjmp_chk.c b/sysdeps/unix/sysv/linux/am33/____longjmp_chk.c
new file mode 100644
index 0000000..619785d
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/am33/____longjmp_chk.c
@@ -0,0 +1,57 @@
+/* Copyright (C) 2011 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Chris Metcalf <cmetcalf@tilera.com>, 2011.
+
+   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 <jmpbuf-offsets.h>
+#include <sysdep.h>
+#include <setjmp.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stackinfo.h>
+
+#ifdef _STACK_GROWS_DOWN
+#define called_from(this, saved) ((this) < (saved))
+#else
+#define called_from(this, saved) ((this) > (saved))
+#endif
+
+extern void ____longjmp_chk (__jmp_buf __env, int __val)
+  __attribute__ ((__noreturn__));
+
+void ____longjmp_chk (__jmp_buf env, int val)
+{
+  void *this_frame = __builtin_frame_address (0);
+  void *saved_frame = JB_FRAME_ADDRESS (env);
+  INTERNAL_SYSCALL_DECL (err);
+  stack_t ss;
+
+  /* If "env" is from a frame that called us, we're all set.  */
+  if (called_from(this_frame, saved_frame))
+    __longjmp (env, val);
+
+  /* If we can't get the current stack state, give up and do the longjmp. */
+  if (INTERNAL_SYSCALL (sigaltstack, err, 2, NULL, &ss) != 0)
+    __longjmp (env, val);
+
+  /* If we we are executing on the alternate stack and within the
+     bounds, do the longjmp.  */
+  if (ss.ss_flags == SS_ONSTACK &&
+      (this_frame >= ss.ss_sp && this_frame < (ss.ss_sp + ss.ss_size)))
+    __longjmp (env, val);
+
+  __fortify_fail ("longjmp causes uninitialized stack frame");
+}
diff --git a/sysdeps/unix/sysv/linux/am33/bits/fcntl.h b/sysdeps/unix/sysv/linux/am33/bits/fcntl.h
index 33b8bcd..588e5fa 100644
--- a/sysdeps/unix/sysv/linux/am33/bits/fcntl.h
+++ b/sysdeps/unix/sysv/linux/am33/bits/fcntl.h
@@ -1,5 +1,5 @@
 /* O_*, F_*, FD_* bit values for Linux.
-   Copyright (C) 1995, 1996, 1997, 1998, 2000, Free Software Foundation, Inc.
+   Copyright (C) 1995, 1996, 1997, 1998, 2000, 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
@@ -44,6 +44,8 @@
 # define O_DIRECT	 040000	/* Direct disk access.	*/
 # define O_DIRECTORY	0200000	/* Must be a directory.	 */
 # define O_NOFOLLOW	0400000	/* Do not follow links.	 */
+# define O_NOATIME     01000000
+# define O_CLOEXEC     02000000	/* set close_on_exec */
 #endif
 
 /* For now Linux has synchronisity options for data and read operations.
@@ -77,20 +79,26 @@
 #define F_SETLK64	13	/* Set record locking info (non-blocking).  */
 #define F_SETLKW64	14	/* Set record locking info (blocking).	*/
 
-#if defined __USE_BSD || defined __USE_XOPEN2K
-# define F_SETOWN	8	/* Get owner of socket (receiver of SIGIO).  */
-# define F_GETOWN	9	/* Set owner of socket (receiver of SIGIO).  */
+#if defined __USE_BSD || defined __USE_UNIX98 || defined __USE_XOPEN2K8
+# define F_SETOWN	8	/* Get owner (process receiving SIGIO).  */
+# define F_GETOWN	9	/* Set owner (process receiving SIGIO).  */
 #endif
 
 #ifdef __USE_GNU
 # define F_SETSIG	10	/* Set number of signal to be sent.  */
 # define F_GETSIG	11	/* Get number of signal to be sent.  */
+# define F_SETOWN_EX	15	/* Get owner (thread receiving SIGIO).  */
+# define F_GETOWN_EX	16	/* Set owner (thread receiving SIGIO).  */
 #endif
 
 #ifdef __USE_GNU
 # define F_SETLEASE	1024	/* Set a lease.	 */
 # define F_GETLEASE	1025	/* Enquire what lease is active.  */
 # define F_NOTIFY	1026	/* Request notfications on a directory.	 */
+# define F_SETPIPE_SZ	1031	/* Set pipe page size array.  */
+# define F_GETPIPE_SZ	1032	/* Set pipe page size array.  */
+#endif
+#ifdef __USE_XOPEN2K8
 # define F_DUPFD_CLOEXEC 1030	/* Duplicate file descriptor with
 				   close-on-exit set.  */
 #endif
@@ -159,6 +167,24 @@ struct flock64
   };
 #endif
 
+#ifdef __USE_GNU
+/* Owner types.  */
+enum __pid_type
+  {
+    F_OWNER_TID = 0,		/* Kernel thread.  */
+    F_OWNER_PID,		/* Process.  */
+    F_OWNER_PGRP,		/* Process group.  */
+    F_OWNER_GID = F_OWNER_PGRP	/* Alternative, obsolete name.  */
+  };
+
+/* Structure to use with F_GETOWN_EX and F_SETOWN_EX.  */
+struct f_owner_ex
+  {
+    enum __pid_type type;	/* Owner type of ID.  */
+    __pid_t pid;		/* ID of owner.  */
+  };
+#endif
+
 /* Define some more compatibility macros to be backward compatible with
    BSD systems which did not managed to hide these kernel macros.  */
 #ifdef	__USE_BSD
diff --git a/sysdeps/unix/sysv/linux/am33/bits/mman.h b/sysdeps/unix/sysv/linux/am33/bits/mman.h
index 763b060..ff759b5 100644
--- a/sysdeps/unix/sysv/linux/am33/bits/mman.h
+++ b/sysdeps/unix/sysv/linux/am33/bits/mman.h
@@ -33,9 +33,9 @@
 #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
+#define PROT_GROWSDOWN	0x01000000	/* Extend change to start of
 					   growsdown vma (mprotect only).  */
-#define PROT_GROWSUP	  0x02000000	/* Extend change to start of
+#define PROT_GROWSUP	0x02000000	/* Extend change to start of
 					   growsup vma (mprotect only).  */
 
 /* Sharing types (must choose one and only one of these).  */
@@ -55,11 +55,13 @@
 
 /* These are Linux-specific.  */
 #ifdef __USE_MISC
-# define MAP_GROWSDOWN	0x0100		/* Stack-like segment.  */
-# define MAP_DENYWRITE	0x0800		/* ETXTBSY */
-# define MAP_EXECUTABLE	0x1000		/* Mark it as an executable.  */
-# define MAP_LOCKED	0x2000		/* Lock the mapping.  */
-# define MAP_NORESERVE	0x4000		/* Don't check for reservations.  */
+# define MAP_GROWSDOWN	0x00100		/* Stack-like segment.  */
+# define MAP_DENYWRITE	0x00800		/* ETXTBSY */
+# define MAP_EXECUTABLE	0x01000		/* Mark it as an executable.  */
+# define MAP_LOCKED	0x02000		/* Lock the mapping.  */
+# define MAP_NORESERVE	0x04000		/* Don't check for reservations.  */
+# define MAP_POPULATE	0x08000		/* Populate (prefault) pagetables.  */
+# define MAP_NONBLOCK	0x10000		/* Do not block on IO.  */
 #endif
 
 /* Flags to `msync'.  */
@@ -75,6 +77,7 @@
 /* Flags for `mremap'.  */
 #ifdef __USE_GNU
 # define MREMAP_MAYMOVE	1
+# define MREMAP_FIXED	2
 #endif
 
 /* Advice to `madvise'.  */
@@ -84,6 +87,9 @@
 # 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.  */
 #endif
 
 /* The POSIX people had to invent similar names for the same things.  */
diff --git a/sysdeps/unix/sysv/linux/am33/brk.c b/sysdeps/unix/sysv/linux/am33/brk.c
index a06495c..c68b360 100644
--- a/sysdeps/unix/sysv/linux/am33/brk.c
+++ b/sysdeps/unix/sysv/linux/am33/brk.c
@@ -30,7 +30,7 @@ __brk (void *addr)
 {
   void *newbrk;
 
-  newbrk = INLINE_SYSCALL (brk, 1, __ptrvalue (addr));
+  newbrk = (void *)INLINE_SYSCALL (brk, 1, __ptrvalue (addr));
 
   __curbrk = newbrk;
 
diff --git a/sysdeps/unix/sysv/linux/am33/clone.S b/sysdeps/unix/sysv/linux/am33/clone.S
index e014c4a..72fff63 100644
--- a/sysdeps/unix/sysv/linux/am33/clone.S
+++ b/sysdeps/unix/sysv/linux/am33/clone.S
@@ -1,4 +1,4 @@
-/* Copyright 2001 Free Software Foundation, Inc.
+/* Copyright 2001, 2009 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Alexandre Oliva <aoliva@redhat.com>.
    Based on ../i386/clone.S.
@@ -25,8 +25,14 @@
 #include <bits/errno.h>
 #include <asm-syntax.h>
 #include <bp-sym.h>
+#include <tcb-offsets.h>
+
+#define CLONE_VM	0x00000100
+#define CLONE_THREAD	0x00010000
+
+/* int clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg,
+	     pid_t *ptid, struct user_desc *tls, pid_t *ctid); */
 
-/* int clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg); */
 
         .text
 ENTRY (BP_SYM (__clone))
@@ -36,23 +42,50 @@ ENTRY (BP_SYM (__clone))
 	cmp	0,d1	/* no NULL stack pointers */
 	beq	L(error_inval)
 
+	movm	[d3,a2,a3], (sp)
+
+	/* At this point, stack looks like:
+
+	    sp+40: ctid
+	    sp+36: tls
+	    sp+32: ptid
+	    sp+28: arg
+	    sp+24: flags
+	    sp+20: d1_save_slot
+	    sp+16: d0_save_slot
+	    sp+12: return addr
+	    sp+8:  saved_d3
+	    sp+4:  saved_a2
+	    sp+0:  saved_a3
+	*/
+
 	/* Allocate room for a function call in the new stack, and
 	   store fn and arg in it.  They will be read back in
 	   thread_start.  */
 	mov	d1,a0
 	sub	12,a0
 	mov	d0,(a0)
-	mov	(16,sp),d1
+	mov	(28,sp),d1
 	mov	d1,(4,a0)
+#ifdef RESET_PID
+	mov	(24,sp),d1
+#else
+	clr	d1
+#endif
+	mov	d1,(8,a0)
 
 	/* Do the system call */
 	mov	a0,d1
-	mov	(12,sp),a0
-	mov	SYS_ify(clone),d0
+	mov	(24,sp),a0
+	mov	(32,sp),a3
+	mov	(40,sp),a2
+	mov	(36,sp),d3
+	mov	0+SYS_ify(clone),d0
 	syscall	0
 
 	cmp	0,d0
 	beq	thread_start
+	movm	(sp), [d3,a2,a3]
 	blt	L(to_SYSCALL_ERROR_LABEL)
 
 L(pseudo_end):
@@ -64,6 +97,21 @@ L(to_SYSCALL_ERROR_LABEL):
 	jmp	SYSCALL_ERROR_LABEL
 
 thread_start:
+#ifdef RESET_PID
+	mov	(8,sp),d0
+	mov	d0,d1
+	btst	CLONE_THREAD,d0
+	bne	1f
+	btst	CLONE_VM,d0
+	mov	-1,d0
+	bne	2f
+	mov	SYS_ify(getpid),d0
+	syscall	0
+2:
+	mov	d0,(PID,r2)
+	mov	d0,(TID,r2)
+1:
+#endif
 	mov	0,a3	/* terminate the stack frame */
 	mov	(4,sp),d0
 	mov	(sp),a0
diff --git a/sysdeps/unix/sysv/linux/am33/fxstatat.c b/sysdeps/unix/sysv/linux/am33/fxstatat.c
new file mode 100644
index 0000000..0f8b313
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/am33/fxstatat.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/i386/fxstatat.c>
diff --git a/sysdeps/unix/sysv/linux/am33/linuxthreads/sysdep-cancel.h b/sysdeps/unix/sysv/linux/am33/linuxthreads/sysdep-cancel.h
deleted file mode 100644
index 5f3dab5..0000000
--- a/sysdeps/unix/sysv/linux/am33/linuxthreads/sysdep-cancel.h
+++ /dev/null
@@ -1,158 +0,0 @@
-/* Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-   Contributed by Alexandre Oliva <aoliva@redhat.com>
-
-   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>
-#include <tls.h>
-#include <pt-machine.h>
-#ifndef __ASSEMBLER__
-# include <linuxthreads/internals.h>
-#endif
-
-#if !defined NOT_IN_libc || defined IS_IN_libpthread || defined IS_IN_librt
-
-# undef PSEUDO
-# define PSEUDO(name, syscall_name, args)				\
-  .text	;								\
- ENTRY (name)								\
-  PUSHARGS_##args							\
-  DOARGS_##args								\
-  SINGLE_THREAD_P;							\
-  bne L(pseudo_cancel);							\
-  mov SYS_ify (syscall_name),d0;					\
-  syscall 0								\
-  POPARGS_##args ;							\
-  cmp -126,d0;								\
-  bls L(pseudo_end);							\
-  jmp SYSCALL_ERROR_LABEL;						\
- L(pseudo_cancel):							\
-  add -(16+STACK_SPACE (args)),sp;					\
-  SAVE_ARGS_##args							\
-  CENABLE								\
-  mov d0,r0;								\
-  LOAD_ARGS_##args							\
-  mov SYS_ify (syscall_name),d0;					\
-  syscall 0;								\
-  mov d0,(12,sp);							\
-  mov r0,d0;								\
-  CDISABLE								\
-  mov (12,sp),d0;							\
-  add +16+STACK_SPACE (args),sp						\
-  POPARGS_##args ;							\
-  cmp -126,d0;								\
-  bls L(pseudo_end);							\
-  jmp SYSCALL_ERROR_LABEL;						\
- L(pseudo_end):								\
-  mov d0,a0
-
-/* Reserve up to 2 stack slots for a0 and d1, but fewer than that if
-   we don't have that many arguments.  */
-# define STACK_SPACE(n) (((((n) < 3) * (2 - (n))) + 2) * 4)
-
-# define SAVE_ARGS_0
-# define SAVE_ARGS_1	mov a0,(20,sp) ;
-# define SAVE_ARGS_2	SAVE_ARGS_1 mov d1,(24,sp) ;
-# define SAVE_ARGS_3	SAVE_ARGS_2
-# define SAVE_ARGS_4	SAVE_ARGS_3
-# define SAVE_ARGS_5	SAVE_ARGS_4
-# define SAVE_ARGS_6	SAVE_ARGS_5
-
-# define LOAD_ARGS_0
-# define LOAD_ARGS_1	mov (20,sp),a0 ;
-# define LOAD_ARGS_2	LOAD_ARGS_1 mov (24,sp),d1 ;
-# define LOAD_ARGS_3	LOAD_ARGS_2
-# define LOAD_ARGS_4	LOAD_ARGS_3
-# define LOAD_ARGS_5	LOAD_ARGS_4
-# define LOAD_ARGS_6	LOAD_ARGS_5
-
-# ifdef IS_IN_libpthread
-#  define CENABLE	call __pthread_enable_asynccancel,[],0;
-#  define CDISABLE	call __pthread_disable_asynccancel,[],0;
-# elif defined IS_IN_librt
-#  ifdef PIC
-#   define CENABLE	movm [a2],(sp); \
-			1: mov pc,a2; \
-			add _GLOBAL_OFFSET_TABLE_-(1b-.),a2; \
-			call +__librt_enable_asynccancel@PLT,[],0; \
-			movm (sp),[a2];
-#   define CENABLE	movm [a2],(sp); \
-			1: mov pc,a2; \
-			add _GLOBAL_OFFSET_TABLE_-(1b-.),a2; \
-			call +__librt_disable_asynccancel@PLT,[],0; \
-			movm (sp),[a2];
-#  else
-#   define CENABLE	call +__librt_enable_asynccancel,[],0;
-#   define CDISABLE	call +__librt_disable_asynccancel,[],0;
-#  endif
-# else
-#  define CENABLE	call +__libc_enable_asynccancel,[],0;
-#  define CDISABLE	call +__libc_disable_asynccancel,[],0;
-# endif
-
-#if !defined NOT_IN_libc
-# define __local_multiple_threads __libc_multiple_threads
-#elif defined IS_IN_libpthread
-# define __local_multiple_threads __pthread_multiple_threads
-#else
-# define __local_multiple_threads __librt_multiple_threads
-#endif
-
-# ifndef __ASSEMBLER__
-#  if defined FLOATING_STACKS && USE___THREAD && defined PIC
-#   define SINGLE_THREAD_P \
-  __builtin_expect (THREAD_GETMEM (THREAD_SELF,				      \
-				   p_header.data.multiple_threads) == 0, 1)
-#  else
-extern int __local_multiple_threads
-#   if !defined NOT_IN_libc || defined IS_IN_libpthread
-  attribute_hidden;
-#   else
-  ;
-#   endif
-#   define SINGLE_THREAD_P __builtin_expect (__local_multiple_threads == 0, 1)
-#  endif
-# else
-#  if !defined PIC
-#   define SINGLE_THREAD_P \
-	mov (+__local_multiple_threads),d0; \
-	cmp 0,d0
-#  elif !defined NOT_IN_libc || defined IS_IN_libpthread
-#   define SINGLE_THREAD_P \
-	movm [a2],(sp); \
-     1: mov pc,a2; \
-	add _GLOBAL_OFFSET_TABLE_-(1b-.),a2; \
-	mov (+__local_multiple_threads@GOTOFF,a2),d0; \
-	movm (sp),[a2]; \
-	cmp 0,d0
-#  else
-#   define SINGLE_THREAD_P \
-	movm [a2],(sp); \
-     1: mov pc,a2; \
-	add _GLOBAL_OFFSET_TABLE_-(1b-.),a2; \
-	mov (+__local_multiple_threads@GOT,a2),a2; \
-	mov (a2),d0; \
-	movm (sp),[a2]; \
-	cmp 0,d0
-#  endif
-# endif
-
-#elif !defined __ASSEMBLER__
-
-/* This code should never be used but we define it anyhow.  */
-# define SINGLE_THREAD_P (1)
-
-#endif
diff --git a/sysdeps/unix/sysv/linux/am33/mmap.S b/sysdeps/unix/sysv/linux/am33/mmap.S
new file mode 100644
index 0000000..e42e898
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/am33/mmap.S
@@ -0,0 +1,67 @@
+/* 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 <sysdep.h>
+#define _ERRNO_H	1
+#include <bits/errno.h>
+#include <asm-syntax.h>
+#include <bp-sym.h>
+
+/* We don't want to use the definition from sysdep.h */
+#undef ret
+
+	.text
+/*
+ *  extern void *__mmap (void *__addr, size_t __len, int __prot,
+ *		     int __flags, int __fd, __off_t __offset);
+ */
+ENTRY (BP_SYM(__mmap))
+	movm	[d2,d3,a2,a3],(sp)
+
+	/* check for offset page alignment */
+	mov	(40,sp),d2
+	btst	4095,d2
+	bne	L(inval)
+	
+	/* convert offset to pages */
+	lsr	12,d2
+	
+	/* do the syscall */
+	mov 	d0,a0       /* addr  */
+	mov	(28,sp),a3  /* prot  */
+	mov	(32,sp),a2  /* flags */
+	mov	(36,sp),d3  /* fd    */
+	
+	mov	0+SYS_ify(mmap2),d0
+	syscall	0
+	
+	/* d0 is < 0 if there was an error.  */
+	cmp 	-126,d0
+	bls 	L(pseudo_end)
+	jmp 	SYSCALL_ERROR_LABEL
+	
+L(inval):
+	mov	-EINVAL,d0
+	
+L(pseudo_end):
+	mov 	d0,a0
+	ret	[d2,d3,a2,a3],16
+
+PSEUDO_END (__mmap)
+
+weak_alias (__mmap, mmap)
diff --git a/sysdeps/unix/sysv/linux/am33/mmap64.S b/sysdeps/unix/sysv/linux/am33/mmap64.S
new file mode 100644
index 0000000..daea7e7
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/am33/mmap64.S
@@ -0,0 +1,74 @@
+/* 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 <sysdep.h>
+#define _ERRNO_H	1
+#include <bits/errno.h>
+#include <asm-syntax.h>
+#include <bp-sym.h>
+
+/* We don't want to use the definition from sysdep.h */
+#undef ret
+
+	.text
+/*
+ *  extern void *__mmap64 (void *__addr, size_t __len, int __prot,
+ *		     	int __flags, int __fd, __off64_t __offset);
+ */
+ENTRY (BP_SYM(__mmap64))
+	movm	[d2,d3,a2,a3],(sp)
+
+	/* check for offset page alignment */
+	mov	(40,sp),d3
+	btst	4095,d3
+	bne	L(inval)
+	/* check for offset overflow */
+	mov	(44,sp),a0
+	mov	a0,d2
+	asr	12,a0
+	bne	L(inval)
+
+	/* convert offset to pages */
+	asl	20,d2
+	asr	12,d3
+	or	d3,d2
+
+	/* do the syscall */
+	mov 	d0,a0       /* addr  */
+	mov	(28,sp),a3  /* prot  */
+	mov	(32,sp),a2  /* flags */
+	mov	(36,sp),d3  /* fd    */
+
+	mov	0+SYS_ify(mmap2),d0
+	syscall	0
+
+	/* d0 is < 0 if there was an error.  */
+	cmp 	-126,d0
+	bls 	L(pseudo_end)
+	jmp 	SYSCALL_ERROR_LABEL
+
+L(inval):
+	mov	-EINVAL,d0
+
+L(pseudo_end):
+	mov 	d0,a0
+	ret	[d2,d3,a2,a3],16
+
+PSEUDO_END (__mmap64)
+
+weak_alias (__mmap64, mmap64)
diff --git a/sysdeps/unix/sysv/linux/am33/nptl/Makefile b/sysdeps/unix/sysv/linux/am33/nptl/Makefile
new file mode 100644
index 0000000..5d0db48
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/am33/nptl/Makefile
@@ -0,0 +1,6 @@
+ifeq ($(subdir),nptl)
+# These tests rely on PTHREAD_KEYS_MAX.  The SJLJ exception machinery
+# in libgcc registers one key, however, so only PTHREAD_KEYS_MAX-1
+# keys are available.
+tests := $(filter-out tst-key1 tst-key4,$(tests))
+endif
diff --git a/sysdeps/unix/sysv/linux/am33/nptl/Versions b/sysdeps/unix/sysv/linux/am33/nptl/Versions
new file mode 100644
index 0000000..435c921
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/am33/nptl/Versions
@@ -0,0 +1,8 @@
+libc {
+  GLIBC_PRIVATE {
+    # A copy of sigaction lives in NPTL, and needs these.
+    __default_sa_restorer; __default_rt_sa_restorer;
+    __default_sa_restorer_v1; __default_rt_sa_restorer_v1;
+    __default_sa_restorer_v2; __default_rt_sa_restorer_v2;
+  }
+}
diff --git a/sysdeps/unix/sysv/linux/am33/nptl/bits/pthreadtypes.h b/sysdeps/unix/sysv/linux/am33/nptl/bits/pthreadtypes.h
new file mode 100644
index 0000000..2f1d66f
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/am33/nptl/bits/pthreadtypes.h
@@ -0,0 +1,173 @@
+/* Copyright (C) 2002, 2003, 2004, 2005, 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.  */
+
+#ifndef _BITS_PTHREADTYPES_H
+#define _BITS_PTHREADTYPES_H	1
+
+#define __SIZEOF_PTHREAD_ATTR_T 36
+#define __SIZEOF_PTHREAD_MUTEX_T 24
+#define __SIZEOF_PTHREAD_MUTEXATTR_T 4
+#define __SIZEOF_PTHREAD_COND_T 48
+#define __SIZEOF_PTHREAD_COND_COMPAT_T 12
+#define __SIZEOF_PTHREAD_CONDATTR_T 4
+#define __SIZEOF_PTHREAD_RWLOCK_T 32
+#define __SIZEOF_PTHREAD_RWLOCKATTR_T 8
+#define __SIZEOF_PTHREAD_BARRIER_T 20
+#define __SIZEOF_PTHREAD_BARRIERATTR_T 4
+
+
+/* Thread identifiers.  The structure of the attribute type is not
+   exposed on purpose.  */
+typedef unsigned long int pthread_t;
+
+
+union pthread_attr_t
+{
+  char __size[__SIZEOF_PTHREAD_ATTR_T];
+  long int __align;
+};
+#ifndef __have_pthread_attr_t
+typedef union pthread_attr_t pthread_attr_t;
+# define __have_pthread_attr_t	1
+#endif
+
+
+typedef struct __pthread_internal_slist
+{
+  struct __pthread_internal_slist *__next;
+} __pthread_slist_t;
+
+
+/* Data structures for mutex handling.  The structure of the attribute
+   type is not exposed on purpose.  */
+typedef union
+{
+  struct __pthread_mutex_s
+  {
+    int __lock;
+    unsigned int __count;
+    int __owner;
+    /* KIND must stay at this position in the structure to maintain
+       binary compatibility.  */
+    int __kind;
+    unsigned int __nusers;
+    __extension__ union
+    {
+      int __spins;
+      __pthread_slist_t __list;
+    };
+  } __data;
+  char __size[__SIZEOF_PTHREAD_MUTEX_T];
+  long int __align;
+} pthread_mutex_t;
+
+typedef union
+{
+  char __size[__SIZEOF_PTHREAD_MUTEXATTR_T];
+  long int __align;
+} pthread_mutexattr_t;
+
+
+/* Data structure for conditional variable handling.  The structure of
+   the attribute type is not exposed on purpose.  */
+typedef union
+{
+  struct
+  {
+    int __lock;
+    unsigned int __futex;
+    __extension__ unsigned long long int __total_seq;
+    __extension__ unsigned long long int __wakeup_seq;
+    __extension__ unsigned long long int __woken_seq;
+    void *__mutex;
+    unsigned int __nwaiters;
+    unsigned int __broadcast_seq;
+  } __data;
+  char __size[__SIZEOF_PTHREAD_COND_T];
+  __extension__ long long int __align;
+} pthread_cond_t;
+
+typedef union
+{
+  char __size[__SIZEOF_PTHREAD_CONDATTR_T];
+  long int __align;
+} pthread_condattr_t;
+
+
+/* Keys for thread-specific data */
+typedef unsigned int pthread_key_t;
+
+
+/* Once-only execution */
+typedef int pthread_once_t;
+
+
+#if defined __USE_UNIX98 || defined __USE_XOPEN2K
+/* Data structure for read-write lock variable handling.  The
+   structure of the attribute type is not exposed on purpose.  */
+typedef union
+{
+  struct
+  {
+    int __lock;
+    unsigned int __nr_readers;
+    unsigned int __readers_wakeup;
+    unsigned int __writer_wakeup;
+    unsigned int __nr_readers_queued;
+    unsigned int __nr_writers_queued;
+    /* FLAGS must stay at this position in the structure to maintain
+       binary compatibility.  */
+    unsigned char __flags;
+    unsigned char __shared;
+    unsigned char __pad1;
+    unsigned char __pad2;
+    int __writer;
+  } __data;
+  char __size[__SIZEOF_PTHREAD_RWLOCK_T];
+  long int __align;
+} pthread_rwlock_t;
+
+typedef union
+{
+  char __size[__SIZEOF_PTHREAD_RWLOCKATTR_T];
+  long int __align;
+} pthread_rwlockattr_t;
+#endif
+
+
+#ifdef __USE_XOPEN2K
+/* POSIX spinlock data type.  */
+typedef volatile int pthread_spinlock_t;
+
+
+/* POSIX barriers data type.  The structure of the type is
+   deliberately not exposed.  */
+typedef union
+{
+  char __size[__SIZEOF_PTHREAD_BARRIER_T];
+  long int __align;
+} pthread_barrier_t;
+
+typedef union
+{
+  char __size[__SIZEOF_PTHREAD_BARRIERATTR_T];
+  int __align;
+} pthread_barrierattr_t;
+#endif
+
+#endif	/* bits/pthreadtypes.h */
diff --git a/sysdeps/unix/sysv/linux/am33/nptl/bits/semaphore.h b/sysdeps/unix/sysv/linux/am33/nptl/bits/semaphore.h
new file mode 100644
index 0000000..7fb117a
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/am33/nptl/bits/semaphore.h
@@ -0,0 +1,37 @@
+/* Copyright (C) 2002, 2005, 2007, 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.  */
+
+#ifndef _SEMAPHORE_H
+# error "Never use <bits/semaphore.h> directly; include <semaphore.h> instead."
+#endif
+
+
+#define __SIZEOF_SEM_T	16
+
+
+/* Value returned if `sem_open' failed.  */
+#define SEM_FAILED      ((sem_t *) 0)
+
+/* Maximum value the semaphore can have.  */
+#define SEM_VALUE_MAX   (2147483647)
+
+typedef union
+{
+  char __size[__SIZEOF_SEM_T];
+  long int __align;
+} sem_t;
diff --git a/sysdeps/unix/sysv/linux/am33/nptl/clone.S b/sysdeps/unix/sysv/linux/am33/nptl/clone.S
new file mode 100644
index 0000000..23750b3
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/am33/nptl/clone.S
@@ -0,0 +1,3 @@
+#define RESET_PID
+#include <tcb-offsets.h>
+#include "../clone.S"
diff --git a/sysdeps/unix/sysv/linux/am33/nptl/fork.c b/sysdeps/unix/sysv/linux/am33/nptl/fork.c
new file mode 100644
index 0000000..a1ac7b4
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/am33/nptl/fork.c
@@ -0,0 +1,31 @@
+/* Copyright (C) 2009 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Mark Salter <msalter@redhat.com>, 2009
+
+   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 <sched.h>
+#include <signal.h>
+#include <sysdep.h>
+#include <tls.h>
+
+
+#define ARCH_FORK()							\
+  INLINE_SYSCALL (clone, 5,						\
+		  CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID | SIGCHLD,	\
+		  NULL, NULL, &THREAD_SELF->tid, NULL)
+
+#include <nptl/sysdeps/unix/sysv/linux/fork.c>
diff --git a/sysdeps/unix/sysv/linux/am33/nptl/libc_pthread_init.c b/sysdeps/unix/sysv/linux/am33/nptl/libc_pthread_init.c
new file mode 100644
index 0000000..48d4ab5
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/am33/nptl/libc_pthread_init.c
@@ -0,0 +1,92 @@
+/* Copyright (C) 2002,2003,2005,2006,2007,2009,2010 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+   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 <unistd.h>
+#include <list.h>
+#include <fork.h>
+#include <dl-sysdep.h>
+#include <tls.h>
+#include <string.h>
+#include <pthreadP.h>
+#include <bits/libc-lock.h>
+#include <sysdep.h>
+#include <ldsodefs.h>
+
+extern unsigned long long __mn10300_hwcap;
+
+#ifdef TLS_MULTIPLE_THREADS_IN_TCB
+void
+#else
+extern int __libc_multiple_threads attribute_hidden;
+
+int *
+#endif
+__libc_pthread_init (ptr, reclaim, functions)
+     unsigned long int *ptr;
+     void (*reclaim) (void);
+     const struct pthread_functions *functions;
+{
+  /* Remember the pointer to the generation counter in libpthread.  */
+  __fork_generation_pointer = ptr;
+
+  /* This needs to be initialized before running anything requiring
+     atomic compare and exchange */
+  __mn10300_hwcap = GLRO(dl_hwcap);
+
+  /* Called by a child after fork.  */
+  __register_atfork (NULL, NULL, reclaim, NULL);
+
+#ifdef SHARED
+  /* Copy the function pointers into an array in libc.  This enables
+     access with just one memory reference but moreso, it prevents
+     hijacking the function pointers with just one pointer change.  We
+     "encrypt" the function pointers since we cannot write-protect the
+     array easily enough.  */
+  union ptrhack
+  {
+    struct pthread_functions pf;
+# define NPTRS (sizeof (struct pthread_functions) / sizeof (void *))
+    void *parr[NPTRS];
+  } __attribute__ ((may_alias)) const *src;
+  union ptrhack *dest;
+
+  src = (const void *) functions;
+  dest = (void *) &__libc_pthread_functions;
+
+  for (size_t cnt = 0; cnt < NPTRS; ++cnt)
+    {
+      void *p = src->parr[cnt];
+      PTR_MANGLE (p);
+      dest->parr[cnt] = p;
+    }
+  __libc_pthread_functions_init = 1;
+#endif
+
+#ifndef TLS_MULTIPLE_THREADS_IN_TCB
+  return &__libc_multiple_threads;
+#endif
+}
+
+#ifdef SHARED
+libc_freeres_fn (freeres_libptread)
+{
+  if (__libc_pthread_functions_init)
+    PTHFCT_CALL (ptr_freeres, ());
+}
+#endif
diff --git a/sysdeps/unix/sysv/linux/am33/nptl/lowlevellock.h b/sysdeps/unix/sysv/linux/am33/nptl/lowlevellock.h
new file mode 100644
index 0000000..b632f2f
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/am33/nptl/lowlevellock.h
@@ -0,0 +1,293 @@
+/* Copyright (C) 2005, 2006, 2007, 2008, 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.  */
+
+#ifndef _LOWLEVELLOCK_H
+#define _LOWLEVELLOCK_H	1
+
+#include <time.h>
+#include <sys/param.h>
+#include <bits/pthreadtypes.h>
+#include <atomic.h>
+#include <sysdep.h>
+#include <kernel-features.h>
+
+#define FUTEX_WAIT		0
+#define FUTEX_WAKE		1
+#define FUTEX_REQUEUE		3
+#define FUTEX_CMP_REQUEUE	4
+#define FUTEX_WAKE_OP		5
+#define FUTEX_OP_CLEAR_WAKE_IF_GT_ONE	((4 << 24) | 1)
+#define FUTEX_LOCK_PI		6
+#define FUTEX_UNLOCK_PI		7
+#define FUTEX_TRYLOCK_PI	8
+#define FUTEX_WAIT_BITSET	9
+#define FUTEX_WAKE_BITSET	10
+#define FUTEX_PRIVATE_FLAG	128
+#define FUTEX_CLOCK_REALTIME	256
+
+#define FUTEX_BITSET_MATCH_ANY	0xffffffff
+
+/* Values for 'private' parameter of locking macros.  Yes, the
+   definition seems to be backwards.  But it is not.  The bit will be
+   reversed before passing to the system call.  */
+#define LLL_PRIVATE	0
+#define LLL_SHARED	FUTEX_PRIVATE_FLAG
+
+
+#if !defined NOT_IN_libc || defined IS_IN_rtld
+/* In libc.so or ld.so all futexes are private.  */
+# ifdef __ASSUME_PRIVATE_FUTEX
+#  define __lll_private_flag(fl, private) \
+  ((fl) | FUTEX_PRIVATE_FLAG)
+# else
+#  define __lll_private_flag(fl, private) \
+  ((fl) | THREAD_GETMEM (THREAD_SELF, header.private_futex))
+# endif
+#else
+# ifdef __ASSUME_PRIVATE_FUTEX
+#  define __lll_private_flag(fl, private) \
+  (((fl) | FUTEX_PRIVATE_FLAG) ^ (private))
+# else
+#  define __lll_private_flag(fl, private) \
+  (__builtin_constant_p (private)					      \
+   ? ((private) == 0							      \
+      ? ((fl) | THREAD_GETMEM (THREAD_SELF, header.private_futex))	      \
+      : (fl))								      \
+   : ((fl) | (((private) ^ FUTEX_PRIVATE_FLAG)				      \
+	      & THREAD_GETMEM (THREAD_SELF, header.private_futex))))
+# endif
+#endif
+
+
+#define lll_futex_wait(futexp, val, private) \
+  lll_futex_timed_wait(futexp, val, NULL, private)
+
+#define lll_futex_timed_wait(futexp, val, timespec, private) \
+  ({									      \
+    INTERNAL_SYSCALL_DECL (__err);					      \
+    long int __ret;							      \
+    __ret = INTERNAL_SYSCALL (futex, __err, 4, (futexp),		      \
+			      __lll_private_flag (FUTEX_WAIT, private),	      \
+			      (val), (timespec));			      \
+    __ret;		      \
+  })
+
+#define lll_futex_wake(futexp, nr, private) \
+  ({									      \
+    INTERNAL_SYSCALL_DECL (__err);					      \
+    long int __ret;							      \
+    __ret = INTERNAL_SYSCALL (futex, __err, 4, (futexp),		      \
+			      __lll_private_flag (FUTEX_WAKE, private),	      \
+			      (nr), 0);					      \
+    __ret;		      \
+  })
+
+#define lll_robust_dead(futexv, private) \
+  do									      \
+    {									      \
+      int *__futexp = &(futexv);					      \
+      atomic_or (__futexp, FUTEX_OWNER_DIED);				      \
+      lll_futex_wake (__futexp, 1, private);				      \
+    }									      \
+  while (0)
+
+/* Returns non-zero if error happened, zero if success.  */
+#define lll_futex_requeue(futexp, nr_wake, nr_move, mutex, val, private) \
+  ({									      \
+    INTERNAL_SYSCALL_DECL (__err);					      \
+    long int __ret;							      \
+    __ret = INTERNAL_SYSCALL (futex, __err, 6, (futexp),		      \
+			      __lll_private_flag (FUTEX_CMP_REQUEUE, private),\
+			      (nr_wake), (nr_move), (mutex), (val));	      \
+    INTERNAL_SYSCALL_ERROR_P (__ret, __err);				      \
+  })
+
+
+/* Returns non-zero if error happened, zero if success.  */
+#define lll_futex_wake_unlock(futexp, nr_wake, nr_wake2, futexp2, private) \
+  ({									      \
+    INTERNAL_SYSCALL_DECL (__err);					      \
+    long int __ret;							      \
+    __ret = INTERNAL_SYSCALL (futex, __err, 6, (futexp),		      \
+			      __lll_private_flag (FUTEX_WAKE_OP, private),    \
+			      (nr_wake), (nr_wake2), (futexp2),		      \
+			      FUTEX_OP_CLEAR_WAKE_IF_GT_ONE);		      \
+    INTERNAL_SYSCALL_ERROR_P (__ret, __err);				      \
+  })
+
+
+static inline int __attribute__((always_inline))
+__lll_trylock(int *futex)
+{
+  return atomic_compare_and_exchange_val_acq (futex, 1, 0) != 0;
+}
+#define lll_trylock(lock)	__lll_trylock (&(lock))
+
+
+static inline int __attribute__((always_inline))
+__lll_cond_trylock(int *futex)
+{
+  return atomic_compare_and_exchange_val_acq (futex, 2, 0) != 0;
+}
+#define lll_cond_trylock(lock)	__lll_cond_trylock (&(lock))
+
+
+static inline int __attribute__((always_inline))
+__lll_robust_trylock(int *futex, int id)
+{
+  return atomic_compare_and_exchange_val_acq (futex, id, 0) != 0;
+}
+#define lll_robust_trylock(lock, id) \
+  __lll_robust_trylock (&(lock), id)
+
+extern void __lll_lock_wait_private (int *futex) attribute_hidden;
+extern void __lll_lock_wait (int *futex, int private) attribute_hidden;
+extern int __lll_robust_lock_wait (int *futex, int private) attribute_hidden;
+
+#define __lll_lock(futex, private)					      \
+  ((void) ({								      \
+    int *__futex = (futex);						      \
+    if (__builtin_expect (atomic_compare_and_exchange_bool_acq (__futex,      \
+								1, 0), 0))    \
+      {									      \
+	if (__builtin_constant_p (private) && (private) == LLL_PRIVATE)	      \
+	  __lll_lock_wait_private (__futex);				      \
+	else								      \
+	  __lll_lock_wait (__futex, private);				      \
+      }									      \
+  }))
+#define lll_lock(futex, private) __lll_lock (&(futex), private)
+
+
+#define __lll_robust_lock(futex, id, private)				      \
+  ({									      \
+    int *__futex = (futex);						      \
+    int __val = 0;							      \
+									      \
+    if (__builtin_expect (atomic_compare_and_exchange_bool_acq (__futex, id,  \
+								0), 0))	      \
+      __val = __lll_robust_lock_wait (__futex, private);		      \
+    __val;								      \
+  })
+#define lll_robust_lock(futex, id, private) \
+  __lll_robust_lock (&(futex), id, private)
+
+
+static inline void __attribute__ ((always_inline))
+__lll_cond_lock (int *futex, int private)
+{
+  if (atomic_compare_and_exchange_bool_acq (futex, 2, 0) != 0)
+    __lll_lock_wait (futex, private);
+}
+#define lll_cond_lock(futex, private) __lll_cond_lock (&(futex), private)
+
+
+#define lll_robust_cond_lock(futex, id, private) \
+  __lll_robust_lock (&(futex), (id) | FUTEX_WAITERS, private)
+
+
+extern int __lll_timedlock_wait (int *futex, const struct timespec *,
+				 int private) attribute_hidden;
+extern int __lll_robust_timedlock_wait (int *futex, const struct timespec *,
+					int private) attribute_hidden;
+
+static inline int __attribute__ ((always_inline))
+__lll_timedlock (int *futex, const struct timespec *abstime, int private)
+{
+  int result = 0;
+  if (atomic_compare_and_exchange_bool_acq (futex, 1, 0) != 0)
+    result = __lll_timedlock_wait (futex, abstime, private);
+  return result;
+}
+#define lll_timedlock(futex, abstime, private) \
+  __lll_timedlock (&(futex), abstime, private)
+
+
+static inline int __attribute__ ((always_inline))
+__lll_robust_timedlock (int *futex, const struct timespec *abstime,
+			int id, int private)
+{
+  int result = 0;
+  if (atomic_compare_and_exchange_bool_acq (futex, id, 0) != 0)
+    result = __lll_robust_timedlock_wait (futex, abstime, private);
+  return result;
+}
+#define lll_robust_timedlock(futex, abstime, id, private) \
+  __lll_robust_timedlock (&(futex), abstime, id, private)
+
+
+#define __lll_unlock(futex, private) \
+  (void)							\
+    ({ int *__futex = (futex);					\
+       int __oldval = atomic_exchange_rel (__futex, 0);		\
+       if (__builtin_expect (__oldval > 1, 0))			\
+	 lll_futex_wake (__futex, 1, private);			\
+    })
+#define lll_unlock(futex, private) __lll_unlock(&(futex), private)
+
+
+#define __lll_robust_unlock(futex, private) \
+  (void)							\
+    ({ int *__futex = (futex);					\
+       int __oldval = atomic_exchange_rel (__futex, 0);		\
+       if (__builtin_expect (__oldval & FUTEX_WAITERS, 0))	\
+	 lll_futex_wake (__futex, 1, private);			\
+    })
+#define lll_robust_unlock(futex, private) \
+  __lll_robust_unlock(&(futex), private)
+
+
+#define lll_islocked(futex) \
+  (futex != 0)
+
+
+/* Our internal lock implementation is identical to the binary-compatible
+   mutex implementation. */
+
+/* Initializers for lock.  */
+#define LLL_LOCK_INITIALIZER		(0)
+#define LLL_LOCK_INITIALIZER_LOCKED	(1)
+
+/* The states of a lock are:
+    0  -  untaken
+    1  -  taken by one user
+   >1  -  taken by more users */
+
+/* The kernel notifies a process which uses CLONE_CLEARTID via futex
+   wakeup when the clone terminates.  The memory location contains the
+   thread ID while the clone is running and is reset to zero
+   afterwards.	*/
+#define lll_wait_tid(tid) \
+  do {					\
+    __typeof (tid) __tid;		\
+    while ((__tid = (tid)) != 0)	\
+      lll_futex_wait (&(tid), __tid, LLL_SHARED);\
+  } while (0)
+
+extern int __lll_timedwait_tid (int *, const struct timespec *)
+     attribute_hidden;
+
+#define lll_timedwait_tid(tid, abstime) \
+  ({							\
+    int __res = 0;					\
+    if ((tid) != 0)					\
+      __res = __lll_timedwait_tid (&(tid), (abstime));	\
+    __res;						\
+  })
+
+#endif	/* lowlevellock.h */
diff --git a/sysdeps/unix/sysv/linux/am33/nptl/pt-vfork.S b/sysdeps/unix/sysv/linux/am33/nptl/pt-vfork.S
new file mode 100644
index 0000000..f663a84
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/am33/nptl/pt-vfork.S
@@ -0,0 +1,36 @@
+/* Copyright (C) 2009 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Mark Salter <msalter@redhat.com>, 2005.
+
+   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 <tcb-offsets.h>
+
+/* Save the PID value.  */
+# define SAVE_PID \
+	mov	(PID,e2), d1; 			\
+	clr	d0;				\
+	sub	d1, d0;				\
+	mov	d0, (PID,e2)
+
+/* Restore the old PID value in the parent.  */
+# define RESTORE_PID \
+	and	d0,d0;				\
+	beq	1f;				\
+	mov	d1, (PID,e2);			\
+1:
+
+#include "../vfork.S"
diff --git a/sysdeps/unix/sysv/linux/am33/nptl/pthread_once.c b/sysdeps/unix/sysv/linux/am33/nptl/pthread_once.c
new file mode 100644
index 0000000..d81ecd4
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/am33/nptl/pthread_once.c
@@ -0,0 +1,99 @@
+/* Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include "pthreadP.h"
+#include <lowlevellock.h>
+
+unsigned long int __fork_generation attribute_hidden;
+
+static void
+clear_once_control (void *arg)
+{
+  pthread_once_t *once_control = (pthread_once_t *) arg;
+
+  *once_control = 0;
+  lll_futex_wake (once_control, INT_MAX, LLL_PRIVATE);
+}
+
+int
+__pthread_once (pthread_once_t *once_control, void (*init_routine) (void))
+{
+  for (;;)
+    {
+      int oldval;
+      int newval;
+
+      /* Pseudo code:
+	 newval = __fork_generation | 1;
+	 oldval = *once_control;
+	 if ((oldval & 2) == 0)
+	   *once_control = newval;
+	 Do this atomically.
+      */
+      do
+	{
+	  newval = __fork_generation | 1;
+	  oldval = *once_control;
+	  if (oldval & 2)
+	    break;
+	} while (atomic_compare_and_exchange_val_acq (once_control, newval, oldval) != oldval);
+
+      /* Check if the initializer has already been done.  */
+      if ((oldval & 2) != 0)
+	return 0;
+
+      /* Check if another thread already runs the initializer.	*/
+      if ((oldval & 1) == 0)
+	break;
+
+      /* Check whether the initializer execution was interrupted by a fork.  */
+      if (oldval != newval)
+	break;
+
+      /* Same generation, some other thread was faster. Wait.  */
+      lll_futex_wait (once_control, oldval, LLL_PRIVATE);
+    }
+
+  /* This thread is the first here.  Do the initialization.
+     Register a cleanup handler so that in case the thread gets
+     interrupted the initialization can be restarted.  */
+  pthread_cleanup_push (clear_once_control, once_control);
+
+  init_routine ();
+
+  pthread_cleanup_pop (0);
+
+  /* Say that the initialisation is done.  */
+  *once_control = __fork_generation | 2;
+
+  /* Wake up all other threads.  */
+  lll_futex_wake (once_control, INT_MAX, LLL_PRIVATE);
+
+  return 0;
+}
+weak_alias (__pthread_once, pthread_once)
+strong_alias (__pthread_once, __pthread_once_internal)
+
+#if defined(__USING_SJLJ_EXCEPTIONS__) && !defined(__PIC__)
+/* When statically linked, if pthread_create is used, this file
+   will be brought in.  The exception handling code in GCC assumes
+   that if pthread_create is available, so are these.  */
+const void *include_pthread_getspecific attribute_hidden = pthread_getspecific;
+const void *include_pthread_setspecific attribute_hidden = pthread_setspecific;
+const void *include_pthread_key_create attribute_hidden = pthread_key_create;
+#endif
diff --git a/sysdeps/unix/sysv/linux/am33/nptl/sysdep-cancel.h b/sysdeps/unix/sysv/linux/am33/nptl/sysdep-cancel.h
new file mode 100644
index 0000000..a7c62f8
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/am33/nptl/sysdep-cancel.h
@@ -0,0 +1,116 @@
+/* Copyright (C) 2002, 2003, 2004, 2005, 2009 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Alexandre Oliva <aoliva@redhat.com>
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <sysdep.h>
+#include <tls.h>
+#ifndef __ASSEMBLER__
+# include <nptl/pthreadP.h>
+#endif
+
+#if !defined NOT_IN_libc || defined IS_IN_libpthread || defined IS_IN_librt
+
+# undef PSEUDO
+# define PSEUDO(name, syscall_name, args)				  \
+  .text	;								  \
+ ENTRY (name)								  \
+  PUSHARGS_##args							  \
+  DOARGS_##args								  \
+  SINGLE_THREAD_P;							  \
+  bne L(pseudo_cancel);							  \
+  mov 0+SYS_ify (syscall_name),d0;					  \
+  syscall 0								  \
+  POPARGS_##args ;							  \
+  cmp -126,d0;								  \
+  bls L(pseudo_end);							  \
+  bra SYSCALL_ERROR_LABEL;						  \
+ L(pseudo_cancel):							  \
+  add -(20+STACK_SPACE (args)),sp;					  \
+  SAVE_ARGS_##args							  \
+  CENABLE								  \
+  mov d0,(16,sp);							  \
+  LOAD_ARGS_##args							  \
+  mov 0+SYS_ify (syscall_name),d0;					  \
+  syscall 0;								  \
+  mov d0,(12,sp);							  \
+  mov (16,sp),d0;							  \
+  CDISABLE								  \
+  mov (12,sp),d0;							  \
+  add +20+STACK_SPACE (args),sp						  \
+  POPARGS_##args ;							  \
+  cmp -126,d0;								  \
+  bls L(pseudo_end);							  \
+  bra SYSCALL_ERROR_LABEL;						  \
+ L(pseudo_end):								  \
+  mov d0,a0;
+
+
+/* Reserve up to 2 stack slots for a0 and d1, but fewer than that if
+   we don't have that many arguments.  */
+# define STACK_SPACE(n)   8 /*(((((n) < 3) * (n)) + (((n) >= 3) * 2)) * 4)*/
+
+# define SAVE_ARGS_0
+# define SAVE_ARGS_1	mov a0,(20,sp) ;
+# define SAVE_ARGS_2	SAVE_ARGS_1 mov d1,(24,sp) ;
+# define SAVE_ARGS_3	SAVE_ARGS_2
+# define SAVE_ARGS_4	SAVE_ARGS_3
+# define SAVE_ARGS_5	SAVE_ARGS_4
+# define SAVE_ARGS_6	SAVE_ARGS_5
+
+# define LOAD_ARGS_0
+# define LOAD_ARGS_1	mov (20,sp),a0 ;
+# define LOAD_ARGS_2	LOAD_ARGS_1 mov (24,sp),d1 ;
+# define LOAD_ARGS_3	LOAD_ARGS_2
+# define LOAD_ARGS_4	LOAD_ARGS_3
+# define LOAD_ARGS_5	LOAD_ARGS_4
+# define LOAD_ARGS_6	LOAD_ARGS_5
+
+# ifdef IS_IN_libpthread
+#  define CENABLE	call __pthread_enable_asynccancel,[],0;
+#  define CDISABLE	call __pthread_disable_asynccancel,[],0;
+# elif defined IS_IN_librt
+#  define CENABLE	call __librt_enable_asynccancel,[],0;
+#  define CDISABLE	call __librt_disable_asynccancel,[],0;
+# else
+#  define CENABLE	call __libc_enable_asynccancel,[],0;
+#  define CDISABLE	call __libc_disable_asynccancel,[],0;
+# endif
+
+# ifndef __ASSEMBLER__
+#  define SINGLE_THREAD_P \
+  __builtin_expect (THREAD_GETMEM (THREAD_SELF, \
+				   header.multiple_threads) == 0, 1)
+# else
+#  define SINGLE_THREAD_P mov (MULTIPLE_THREADS_OFFSET,e2),d0 ; \
+                          cmp  0,d0
+# endif
+
+
+#elif !defined __ASSEMBLER__
+
+/* This code should never be used but we define it anyhow.  */
+# define SINGLE_THREAD_P (1)
+# define NO_CANCELLATION 1
+
+#endif
+
+#ifndef __ASSEMBLER__
+# define RTLD_SINGLE_THREAD_P \
+  __builtin_expect (THREAD_GETMEM (THREAD_SELF, \
+				   header.multiple_threads) == 0, 1)
+#endif
diff --git a/sysdeps/unix/sysv/linux/am33/nptl/unwind-forcedunwind.c b/sysdeps/unix/sysv/linux/am33/nptl/unwind-forcedunwind.c
new file mode 100644
index 0000000..9f82b2e
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/am33/nptl/unwind-forcedunwind.c
@@ -0,0 +1,140 @@
+/* Copyright (C) 2003, 2005, 2009 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Jakub Jelinek <jakub@redhat.com>.
+   Modified for AM33 by Mark Salter <msalter@redhat.com>.
+
+   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; 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 <dlfcn.h>
+#include <stdio.h>
+#include <unwind.h>
+#include <pthreadP.h>
+
+static void *libgcc_s_handle;
+static void (*libgcc_s_resume) (struct _Unwind_Exception *exc);
+static _Unwind_Reason_Code (*libgcc_s_personality)
+  (int, _Unwind_Action, _Unwind_Exception_Class, struct _Unwind_Exception *,
+   struct _Unwind_Context *);
+static _Unwind_Reason_Code (*libgcc_s_forcedunwind)
+  (struct _Unwind_Exception *, _Unwind_Stop_Fn, void *);
+static _Unwind_Word (*libgcc_s_getcfa) (struct _Unwind_Context *);
+static void (*libgcc_s_register) (struct SjLj_Function_Context *);
+static void (*libgcc_s_unregister) (struct SjLj_Function_Context *);
+
+void
+__attribute_noinline__
+pthread_cancel_init (void)
+{
+  void *resume, *personality, *forcedunwind, *getcfa, *_register, *unregister;
+  void *handle;
+
+  if (__builtin_expect (libgcc_s_handle != NULL, 1))
+    {
+      /* Force gcc to reload all values.  */
+      asm volatile ("" ::: "memory");
+      return;
+    }
+
+  handle = __libc_dlopen ("libgcc_s.so.1");
+
+  if (handle == NULL
+      || (_register = __libc_dlsym (handle, "_Unwind_SjLj_Register")) == NULL
+      || (unregister = __libc_dlsym (handle, "_Unwind_SjLj_Unregister")) == NULL
+      || (resume = __libc_dlsym (handle, "_Unwind_SjLj_Resume")) == NULL
+      || (personality = __libc_dlsym (handle, "__gcc_personality_sj0")) == NULL
+      || (forcedunwind = __libc_dlsym (handle, "_Unwind_SjLj_ForcedUnwind"))
+	 == NULL
+      || (getcfa = __libc_dlsym (handle, "_Unwind_GetCFA")) == NULL)
+    __libc_fatal ("libgcc_s.so.1 must be installed for pthread_cancel to work\n");
+
+  libgcc_s_resume = resume;
+  libgcc_s_personality = personality;
+  libgcc_s_forcedunwind = forcedunwind;
+  libgcc_s_register = _register;
+  libgcc_s_unregister = unregister;
+  libgcc_s_getcfa = getcfa;
+  /* Make sure libgcc_s_getcfa is written last.  Otherwise,
+     pthread_cancel_init might return early even when the pointer the
+     caller is interested in is not initialized yet.  */
+  atomic_write_barrier ();
+  libgcc_s_handle = handle;
+}
+
+void
+__libc_freeres_fn_section
+__unwind_freeres (void)
+{
+  void *handle = libgcc_s_handle;
+  if (handle != NULL)
+    {
+      libgcc_s_handle = NULL;
+      __libc_dlclose (handle);
+    }
+}
+
+void
+_Unwind_Resume (struct _Unwind_Exception *exc)
+{
+  if (__builtin_expect (libgcc_s_resume == NULL, 0))
+    pthread_cancel_init ();
+  libgcc_s_resume (exc);
+}
+
+_Unwind_Reason_Code
+__gcc_personality_v0 (int version, _Unwind_Action actions,
+		      _Unwind_Exception_Class exception_class,
+                      struct _Unwind_Exception *ue_header,
+                      struct _Unwind_Context *context)
+{
+  if (__builtin_expect (libgcc_s_personality == NULL, 0))
+    pthread_cancel_init ();
+  return libgcc_s_personality (version, actions, exception_class,
+			       ue_header, context);
+}
+
+_Unwind_Reason_Code
+_Unwind_ForcedUnwind (struct _Unwind_Exception *exc, _Unwind_Stop_Fn stop,
+		      void *stop_argument)
+{
+  if (__builtin_expect (libgcc_s_forcedunwind == NULL, 0))
+    pthread_cancel_init ();
+  return libgcc_s_forcedunwind (exc, stop, stop_argument);
+}
+
+_Unwind_Word
+_Unwind_GetCFA (struct _Unwind_Context *context)
+{
+  if (__builtin_expect (libgcc_s_getcfa == NULL, 0))
+    pthread_cancel_init ();
+  return libgcc_s_getcfa (context);
+}
+
+void
+_Unwind_SjLj_Register (struct SjLj_Function_Context *fc)
+{
+  if (__builtin_expect (libgcc_s_register == NULL, 0))
+    pthread_cancel_init ();
+  return libgcc_s_register (fc);
+}
+
+void
+_Unwind_SjLj_Unregister (struct SjLj_Function_Context *fc)
+{
+  if (__builtin_expect (libgcc_s_unregister == NULL, 0))
+    pthread_cancel_init ();
+  return libgcc_s_unregister (fc);
+}
+
diff --git a/sysdeps/unix/sysv/linux/am33/nptl/unwind-resume.c b/sysdeps/unix/sysv/linux/am33/nptl/unwind-resume.c
new file mode 100644
index 0000000..8dcfd34
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/am33/nptl/unwind-resume.c
@@ -0,0 +1,87 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Jakub Jelinek <jakub@redhat.com>.
+
+   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; 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 <dlfcn.h>
+#include <stdio.h>
+#include <unwind.h>
+
+static void (*libgcc_s_resume) (struct _Unwind_Exception *exc);
+static _Unwind_Reason_Code (*libgcc_s_personality)
+  (int, _Unwind_Action, _Unwind_Exception_Class, struct _Unwind_Exception *,
+   struct _Unwind_Context *);
+static void (*libgcc_s_sjlj_register) (struct SjLj_Function_Context *);
+static void (*libgcc_s_sjlj_unregister) (struct SjLj_Function_Context *);
+
+static void
+init (void)
+{
+  void *resume, *personality;
+  void *handle;
+  void *sjlj_register, *sjlj_unregister;
+
+  handle = __libc_dlopen ("libgcc_s.so.1");
+
+  if (handle == NULL
+      || (sjlj_register = __libc_dlsym (handle, "_Unwind_SjLj_Register")) == NULL
+      || (sjlj_unregister = __libc_dlsym (handle, "_Unwind_SjLj_Unregister")) == NULL
+      || (resume = __libc_dlsym (handle, "_Unwind_SjLj_Resume")) == NULL
+      || (personality = __libc_dlsym (handle, "__gcc_personality_sj0")) == NULL)
+    __libc_fatal ("libgcc_s.so.1 must be installed for pthread_cancel to work\n");
+
+  libgcc_s_resume = resume;
+  libgcc_s_personality = personality;
+  libgcc_s_sjlj_register = sjlj_register;
+  libgcc_s_sjlj_unregister = sjlj_unregister;
+}
+
+void
+_Unwind_Resume (struct _Unwind_Exception *exc)
+{
+  if (__builtin_expect (libgcc_s_resume == NULL, 0))
+    init ();
+  libgcc_s_resume (exc);
+}
+
+_Unwind_Reason_Code
+__gcc_personality_v0 (int version, _Unwind_Action actions,
+		      _Unwind_Exception_Class exception_class,
+                      struct _Unwind_Exception *ue_header,
+                      struct _Unwind_Context *context)
+{
+  if (__builtin_expect (libgcc_s_personality == NULL, 0))
+    init ();
+  return libgcc_s_personality (version, actions, exception_class,
+			       ue_header, context);
+}
+
+void
+_Unwind_SjLj_Register (struct SjLj_Function_Context *fc)
+{
+  if (__builtin_expect (libgcc_s_sjlj_register == NULL, 0))
+    init ();
+  libgcc_s_sjlj_register (fc);
+}
+
+void
+_Unwind_SjLj_Unregister (struct SjLj_Function_Context *fc)
+{
+  if (__builtin_expect (libgcc_s_sjlj_unregister == NULL, 0))
+    init ();
+  libgcc_s_sjlj_unregister (fc);
+}
diff --git a/sysdeps/unix/sysv/linux/am33/nptl/unwind.h b/sysdeps/unix/sysv/linux/am33/nptl/unwind.h
new file mode 100644
index 0000000..af916c5
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/am33/nptl/unwind.h
@@ -0,0 +1,52 @@
+/* Exception handling and frame unwind runtime interface routines.
+   Copyright (C) 2005 Free Software Foundation, Inc.
+
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+/* Exception handling and frame unwind runtime interface routines.
+   Copyright (C) 2005 Free Software Foundation, Inc.
+
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#ifndef _AM33_UNWIND_H
+#define _AM33_UNWIND_H
+
+#include <sysdeps/generic/unwind.h>
+
+/* Call the SjLj versions of these functions.  */
+
+#define _Unwind_ForcedUnwind _Unwind_SjLj_ForcedUnwind
+#define _Unwind_Resume       _Unwind_SjLj_Resume
+#define __gcc_personality_v0 __gcc_personality_sj0
+
+
+#endif /* unwind.h  */
diff --git a/sysdeps/unix/sysv/linux/am33/nptl/vfork.S b/sysdeps/unix/sysv/linux/am33/nptl/vfork.S
new file mode 100644
index 0000000..191d886
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/am33/nptl/vfork.S
@@ -0,0 +1,37 @@
+/* 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 <tcb-offsets.h>
+
+/* Save the PID value.  */
+# define SAVE_PID \
+	mov	(PID,e2), d1; 			\
+	clr	d0;				\
+	sub	d1, d0;				\
+	bne	1f;				\
+	mov	0x8000000, d0;			\
+1:	mov	d0, (PID,e2)
+
+/* Restore the old PID value in the parent.  */
+# define RESTORE_PID \
+	and	d0,d0;				\
+	beq	1f;				\
+	mov	d1, (PID,e2);			\
+1:
+
+#include "../vfork.S"
diff --git a/sysdeps/unix/sysv/linux/am33/profil-counter.h b/sysdeps/unix/sysv/linux/am33/profil-counter.h
index f4b7eaa..3d6e8e8 100644
--- a/sysdeps/unix/sysv/linux/am33/profil-counter.h
+++ b/sysdeps/unix/sysv/linux/am33/profil-counter.h
@@ -1,5 +1,5 @@
 /* Low-level statistical profiling support function.  Linux/am33 version.
-   Copyright (C) 1996, 1997, 1998, 2001 Free Software Foundation, Inc.
+   Copyright (C) 1996, 1997, 1998, 2001, 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
@@ -20,7 +20,7 @@
 #include <sigcontextinfo.h>
 
 static void
-profil_counter (int signo, SIGCONTEXT scp)
+profil_counter (int signo, struct sigcontext *ctx)
 {
-  profil_count ((void *) GET_PC (scp));
+  profil_count ((void *)ctx->pc);
 }
diff --git a/sysdeps/unix/sysv/linux/am33/socket.S b/sysdeps/unix/sysv/linux/am33/socket.S
index b4d3caa..398194c 100644
--- a/sysdeps/unix/sysv/linux/am33/socket.S
+++ b/sysdeps/unix/sysv/linux/am33/socket.S
@@ -1,4 +1,4 @@
-/* Copyright 2001 Free Software Foundation, Inc.
+/* Copyright 2001, 2009 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Alexandre Oliva <aoliva@redhat.com>.
    Based on ../i386/socket.S.
@@ -17,7 +17,7 @@
    License along with the GNU C Library.  If not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
+#include <sysdep-cancel.h>
 #include <socketcall.h>
 
 #define P(a, b) P2(a, b)
@@ -46,7 +46,11 @@ ENTRY (__socket)
 	mov d0,(4,sp)
 	mov d1,(8,sp)
 
-	mov SYS_ify(socketcall),d0	/* System call number in d0.  */
+#if defined NEED_CANCELLATION && defined CENABLE
+	SINGLE_THREAD_P
+	bne .Lsocket_cancel
+#endif
+	mov 0+SYS_ify(socketcall),d0	/* System call number in d0.  */
 
 	/* Use ## so `socket' is a separate token that might be #define'd.  */
 	mov P(SOCKOP_,socket),a0	/* Subcode is first arg to syscall.  */
@@ -61,10 +65,39 @@ ENTRY (__socket)
 	bls L(pseudo_end)
 	jmp SYSCALL_ERROR_LABEL
 
-	/* Successful; return the syscall's value.  */
 L(pseudo_end):
+	mov d0,a0
 	ret
 
+#if defined NEED_CANCELLATION && defined CENABLE
+.Lsocket_cancel:
+	add -20,sp
+
+	/* Enable asynchronous cancellation.  */
+	CENABLE
+	mov d0,(16,sp)
+
+	mov 0+SYS_ify(socketcall),d0	/* System call number in d0.  */
+
+	/* Use ## so `socket' is a separate token that might be #define'd.  */
+	mov P(SOCKOP_,socket),a0	/* Subcode is first arg to syscall.  */
+	mov sp,d1
+	add 24,d1			/* Address of args is 2nd arg.  */
+
+        /* Do the system call trap.  */
+	syscall 0
+
+	/* Restore the cancellation.  */
+	mov d0,(12,sp)
+	mov (16,sp),d0
+	CDISABLE
+	mov (12,sp),d0
+	add 20,sp
+	cmp -126,d0
+	bls L(pseudo_end)
+	jmp SYSCALL_ERROR_LABEL
+#endif
+
 PSEUDO_END (__socket)
 
 #ifndef NO_WEAK_ALIAS
diff --git a/sysdeps/unix/sysv/linux/am33/sys/procfs.h b/sysdeps/unix/sysv/linux/am33/sys/procfs.h
new file mode 100644
index 0000000..2beb956
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/am33/sys/procfs.h
@@ -0,0 +1,124 @@
+/* Copyright (C) 1996, 1997, 1999, 2000, 2003, 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.  */
+
+#ifndef _SYS_PROCFS_H
+#define _SYS_PROCFS_H	1
+
+/* This is somewhat modelled after the file of the same name on SVR4
+   systems.  It provides a definition of the core file format for ELF
+   used on Linux.  It doesn't have anything to do with the /proc file
+   system, even though Linux has one.
+
+   Anyway, the whole purpose of this file is for GDB and GDB only.
+   Don't read too much into it.  Don't use it for anything other than
+   GDB unless you know what you are doing.  */
+
+#include <features.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/user.h>
+
+__BEGIN_DECLS
+
+/* Type for a general-purpose register.  */
+typedef unsigned long elf_greg_t;
+
+/* And the whole bunch of them.  We could have used `struct
+   user_regs_struct' directly in the typedef, but tradition says that
+   the register set is an array, which does have some peculiar
+   semantics, so leave it that way.  */
+#define ELF_NGREG (sizeof (struct user_regs) / sizeof(elf_greg_t))
+typedef elf_greg_t elf_gregset_t[ELF_NGREG];
+
+typedef struct
+  {
+    unsigned long	pr_fpregs[32];
+    unsigned long	pr_fpcr;
+  } elf_fpregset_t;
+
+
+/* Signal info.  */
+struct elf_siginfo
+  {
+    int si_signo;			/* Signal number.  */
+    int si_code;			/* Extra code.  */
+    int si_errno;			/* Errno.  */
+  };
+
+
+/* Definitions to generate Intel SVR4-like core files.  These mostly
+   have the same names as the SVR4 types with "elf_" tacked on the
+   front to prevent clashes with Linux definitions, and the typedef
+   forms have been avoided.  This is mostly like the SVR4 structure,
+   but more Linuxy, with things that Linux does not support and which
+   GDB doesn't really use excluded.  */
+
+struct elf_prstatus
+  {
+    struct elf_siginfo pr_info;		/* Info associated with signal.  */
+    short int pr_cursig;		/* Current signal.  */
+    unsigned long int pr_sigpend;	/* Set of pending signals.  */
+    unsigned long int pr_sighold;	/* Set of held signals.  */
+    __pid_t pr_pid;
+    __pid_t pr_ppid;
+    __pid_t pr_pgrp;
+    __pid_t pr_sid;
+    struct timeval pr_utime;		/* User time.  */
+    struct timeval pr_stime;		/* System time.  */
+    struct timeval pr_cutime;		/* Cumulative user time.  */
+    struct timeval pr_cstime;		/* Cumulative system time.  */
+    elf_gregset_t pr_reg;		/* GP registers.  */
+    int pr_fpvalid;			/* True if math copro being used.  */
+  };
+
+
+#define ELF_PRARGSZ     (80)    /* Number of chars for args.  */
+
+struct elf_prpsinfo
+  {
+    char pr_state;			/* Numeric process state.  */
+    char pr_sname;			/* Char for pr_state.  */
+    char pr_zomb;			/* Zombie.  */
+    char pr_nice;			/* Nice val.  */
+    unsigned long int pr_flag;		/* Flags.  */
+    unsigned short int pr_uid;
+    unsigned short int pr_gid;
+    int pr_pid, pr_ppid, pr_pgrp, pr_sid;
+    /* Lots missing */
+    char pr_fname[16];			/* Filename of executable.  */
+    char pr_psargs[ELF_PRARGSZ];	/* Initial part of arg list.  */
+  };
+
+/* Addresses.  */
+typedef void *psaddr_t;
+
+/* Register sets.  Linux has different names.  */
+typedef elf_gregset_t prgregset_t;
+typedef elf_fpregset_t prfpregset_t;
+
+/* We don't have any differences between processes and threads,
+   therefore have only one PID type.  */
+typedef __pid_t lwpid_t;
+
+/* Process status and info.  In the end we do provide typedefs for them.  */
+typedef struct elf_prstatus prstatus_t;
+typedef struct elf_prpsinfo prpsinfo_t;
+
+__END_DECLS
+
+#endif	/* sys/procfs.h */
diff --git a/sysdeps/unix/sysv/linux/am33/sys/ucontext.h b/sysdeps/unix/sysv/linux/am33/sys/ucontext.h
new file mode 100644
index 0000000..7745952
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/am33/sys/ucontext.h
@@ -0,0 +1,127 @@
+/* Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#ifndef _SYS_UCONTEXT_H
+#define _SYS_UCONTEXT_H	1
+
+#include <features.h>
+#include <signal.h>
+
+/* We need the signal context definitions even if they are not used
+   included in <signal.h>.  */
+#include <bits/sigcontext.h>
+
+
+/* Type for general register.  */
+typedef unsigned long greg_t;
+
+/* Number of general registers.  */
+#define NGREG	26
+
+/* Container for all general registers.  */
+typedef greg_t gregset_t[NGREG];
+
+#ifdef __USE_GNU
+/* Number of each register is the `gregset_t' array.  */
+enum
+{
+  R_D0 = 0,
+# define R_D0		R_D0
+  R_D1,
+# define R_D1		R_D1
+  R_D2,
+# define R_D2		R_D2
+  R_D3,
+# define R_D3		R_D3
+  R_A0,
+# define R_A0		R_A0
+  R_A1,
+# define R_A1		R_A1
+  R_A2,
+# define R_A2		R_A2
+  R_A3,
+# define R_A3		R_A3
+  R_E0,
+# define R_E0		R_E0
+  R_E1,
+# define R_E1		R_E1
+  R_E2,
+# define R_E2		R_E2
+  R_E3,
+# define R_E3		R_E3
+  R_E4,
+# define R_E4		R_E4
+  R_E5,
+# define R_E5		R_E5
+  R_E6,
+# define R_E6		R_E6
+  R_E7,
+# define R_E7		R_E7
+  R_LAR,
+# define R_LAR	R_LAR
+  R_LIR,
+# define R_LIR	R_LIR
+  R_MDR,
+# define R_MDR	R_MDR
+  R_MCVF,
+# define R_MCVF	R_MCVF
+  R_MCRL,
+# define R_MCRL	R_MCRL
+  R_MCRH,
+# define R_MCRH	R_MCRH
+  R_MDRQ,
+# define R_MDRQ	R_MDRQ
+  R_SP,
+# define R_SP		R_SP
+  R_EPSW,
+# define R_EPSW	R_EPSW
+  R_PC,
+# define R_PC		R_PC
+};
+#endif
+
+struct _libc_fpstate
+{
+  unsigned long fs[32];
+  unsigned long int fpcr;
+};
+
+/* Structure to describe FPU registers.  */
+typedef struct _libc_fpstate *fpregset_t;
+
+/* Context to describe whole processor state.  */
+typedef struct
+  {
+    gregset_t gregs;
+    /* Due to Linux's history we have to use a pointer here.  The SysV/i386
+       ABI requires a struct with the values.  */
+    fpregset_t fpregs;
+    unsigned long int oldmask;
+  } mcontext_t;
+
+/* Userlevel context.  */
+typedef struct ucontext
+  {
+    unsigned long int uc_flags;
+    struct ucontext *uc_link;
+    stack_t uc_stack;
+    mcontext_t uc_mcontext;
+    __sigset_t uc_sigmask;
+  } ucontext_t;
+
+#endif /* sys/ucontext.h */
diff --git a/sysdeps/unix/sysv/linux/am33/sys/user.h b/sysdeps/unix/sysv/linux/am33/sys/user.h
new file mode 100644
index 0000000..d4a7687
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/am33/sys/user.h
@@ -0,0 +1,47 @@
+/* Copyright (C) 2000, 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.  */
+
+#ifndef _SYS_USER_H
+#define _SYS_USER_H	1
+
+struct user_regs {
+	unsigned long uregs[27];
+};
+
+struct user {
+/* We start with the registers, to mimic the way that "memory" is returned
+   from the ptrace(3,...) function.  */
+	struct user_regs regs;		/* Where the registers are actually stored */
+/* The rest of this junk is to help gdb figure out what goes where */
+	unsigned long int u_tsize;	/* Text segment size (pages). */
+	unsigned long int u_dsize;	/* Data segment size (pages). */
+	unsigned long int u_ssize;	/* Stack segment size (pages). */
+	unsigned long start_code;     /* Starting virtual address of text. */
+	unsigned long start_stack;	/* Starting virtual address of stack area.
+					   This is actually the bottom of the stack,
+					   the top of the stack is always found in the
+					   esp register.  */
+	long int signal;     		/* Signal that caused the core dump. */
+	int reserved;			/* No longer used */
+	unsigned long u_ar0;		/* Used by gdb to help find the values for */
+	/* the registers. */
+	unsigned long magic;		/* To uniquely identify a core file */
+	char u_comm[32];		/* User command that was responsible */
+};
+
+#endif	/* _SYS_USER_H */
diff --git a/sysdeps/unix/sysv/linux/am33/sysdep.h b/sysdeps/unix/sysv/linux/am33/sysdep.h
index 68f93f8..1da7adc 100644
--- a/sysdeps/unix/sysv/linux/am33/sysdep.h
+++ b/sysdeps/unix/sysv/linux/am33/sysdep.h
@@ -1,4 +1,4 @@
-/* Copyright 2001, 2004 Free Software Foundation, Inc.
+/* Copyright 2001, 2004, 2009 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Alexandre Oliva <aoliva@redhat.com>.
    Based on ../i386/sysdep.h.
@@ -21,7 +21,17 @@
 #define _LINUX_AM33_SYSDEP_H 1
 
 /* There is some commonality.  */
-#include "../../../am33/sysdep.h"
+#include <sysdeps/unix/am33/sysdep.h>
+
+/* Defines RTLD_PRIVATE_ERRNO and USE_DL_SYSINFO.  */
+#include <dl-sysdep.h>
+
+#include <tls.h>
+
+/* In order to get __set_errno() definition in INLINE_SYSCALL.  */
+#ifndef __ASSEMBLER__
+#include <errno.h>
+#endif
 
 /* For Linux we can use the system call table in the header file
 	/usr/include/asm/unistd.h
@@ -30,9 +40,8 @@
 #undef SYS_ify
 #define SYS_ify(syscall_name)	__NR_##syscall_name
 
-/* ELF-like local names start with `.L'.  */
-#undef L
-#define L(name)	.L##name
+/* The following must match the kernel's <asm/elf.h>.  */
+#define HWCAP_MN10300_ATOMIC_OP_UNIT		1
 
 #ifdef __ASSEMBLER__
 
@@ -160,7 +169,7 @@
 #define DO_CALL(syscall_name, args)			      		      \
     PUSHARGS_##args							      \
     DOARGS_##args							      \
-    mov SYS_ify (syscall_name),d0;					      \
+    mov 0+SYS_ify (syscall_name),d0;					      \
     syscall 0								      \
     POPARGS_##args
 
@@ -201,6 +210,114 @@
 
 #else	/* !__ASSEMBLER__ */
 
+#define SETUP_ARGS_0()				\
+    register long __sc0 asm ("d0") = __sc0v
+
+#define SETUP_ARGS_1(arg1)			\
+    long __sc1v = (long) (arg1);		\
+    register long __sc0 asm ("d0") = __sc0v;	\
+    register long __sc1 asm ("a0") = __sc1v
+
+#define SETUP_ARGS_2(arg1,arg2)			\
+    long __sc1v = (long) (arg1);		\
+    long __sc2v = (long) (arg2);		\
+    register long __sc0 asm ("d0") = __sc0v;	\
+    register long __sc1 asm ("a0") = __sc1v;	\
+    register long __sc2 asm ("d1") = __sc2v;
+
+/* We can't tell whether a3 is going to be eliminated in the enclosing
+   function, so we have to assume it isn't. */
+#define SETUP_ARGS_3(arg1,arg2,arg3)		\
+    long __sc1v = (long) (arg1);		\
+    long __sc2v = (long) (arg2);		\
+    long __sc3v = (long) (arg3);		\
+    register long __sc0 asm ("d0") = __sc0v;	\
+    register long __sc1 asm ("a0") = __sc1v;	\
+    register long __sc2 asm ("d1") = __sc2v;	\
+    register long __sc3c asm ("e0") = __sc3v;
+
+
+/* We need to handle PIC register (a2) similarly to a3 */
+#ifdef PIC
+#define SETUP_A2() \
+    register long __sc4 asm ("a2") = __sc4;			\
+    register long __sc4c asm ("e1") = __sc4v;			\
+    __asm__ __volatile__ ("mov_mov %0,%1,%1,%0"			\
+			  : "+r" (__sc4c), "+r" (__sc4));
+
+#else
+#define SETUP_A2() \
+    register long __sc4 asm ("a2") = __sc4v;
+#endif
+
+#define SETUP_ARGS_4(arg1,arg2,arg3,arg4)	\
+    long __sc1v = (long) (arg1);		\
+    long __sc2v = (long) (arg2);		\
+    long __sc3v = (long) (arg3);		\
+    long __sc4v = (long) (arg4);		\
+    register long __sc0 asm ("d0") = __sc0v;	\
+    register long __sc1 asm ("a0") = __sc1v;	\
+    register long __sc2 asm ("d1") = __sc2v;	\
+    register long __sc3c asm ("e0") = __sc3v;	\
+    SETUP_A2()
+
+#define SETUP_ARGS_5(arg1,arg2,arg3,arg4,arg5)	\
+    long __sc1v = (long) (arg1);		\
+    long __sc2v = (long) (arg2);		\
+    long __sc3v = (long) (arg3);		\
+    long __sc4v = (long) (arg4);		\
+    long __sc5v = (long) (arg5);		\
+    register long __sc0 asm ("d0") = __sc0v;	\
+    register long __sc1 asm ("a0") = __sc1v;	\
+    register long __sc2 asm ("d1") = __sc2v;	\
+    register long __sc5 asm ("d3") = __sc5v;	\
+    register long __sc3c asm ("e0") = __sc3v;	\
+    SETUP_A2()
+
+#define SETUP_ARGS_6(arg1,arg2,arg3,arg4,arg5,arg6)	\
+    long __sc1v = (long) (arg1);		\
+    long __sc2v = (long) (arg2);		\
+    long __sc3v = (long) (arg3);		\
+    long __sc4v = (long) (arg4);		\
+    long __sc5v = (long) (arg5);		\
+    long __sc6v = (long) (arg6);		\
+    register long __sc0 asm ("d0") = __sc0v;	\
+    register long __sc1 asm ("a0") = __sc1v;	\
+    register long __sc2 asm ("d1") = __sc2v;	\
+    register long __sc5 asm ("d3") = __sc5v;	\
+    register long __sc6 asm ("d2") = __sc6v;	\
+    register long __sc3c asm ("e0") = __sc3v;	\
+    SETUP_A2()
+
+#define ASM_IN_0
+#define ASM_IN_1  "r" (__sc1)
+#define ASM_IN_2  ASM_IN_1 , "r" (__sc2)
+#define ASM_IN_3  ASM_IN_2 , "r" (__sc3c)
+#ifdef PIC
+#define ASM_IN_4  ASM_IN_3 , "r" (__sc4), "r" (__sc4c)
+#else
+#define ASM_IN_4  ASM_IN_3 , "r" (__sc4)
+#endif
+#define ASM_IN_5  ASM_IN_4 , "r" (__sc5)
+#define ASM_IN_6  ASM_IN_5 , "r" (__sc6)
+
+#define CLEANUP_ARGS_0()
+#define CLEANUP_ARGS_1()
+#define CLEANUP_ARGS_2()
+
+#define CLEANUP_ARGS_3()
+
+#ifdef PIC
+#define CLEANUP_ARGS_4()					\
+    __asm__ __volatile__ ("mov_mov %0,%1,%1,%0"			\
+			  : "+r" (__sc4c), "+r" (__sc4));
+#else
+#define CLEANUP_ARGS_4() CLEANUP_ARGS_3()
+#endif
+
+#define CLEANUP_ARGS_5() CLEANUP_ARGS_4()
+#define CLEANUP_ARGS_6() CLEANUP_ARGS_4()
+
 /* Define a macro which expands inline into the wrapper code for a system
    call.  */
 #undef INLINE_SYSCALL
@@ -214,11 +331,37 @@
       }									\
     (int) resultvar; })
 
-#define INTERNAL_SYSCALL(name, err, nr, args...)			\
-({									\
-	register long __sc0 asm ("d0") = __NR_##name; 			\
-	inline_syscall##nr(name, ## args);				\
-	__sc0;								\
+#define INTERNAL_SYSCALL(name, err, nr, args...)	\
+({							\
+   long __sc0v = (long) __NR_##name;			\
+   SETUP_ARGS_##nr(args);				\
+							\
+   __asm__ __volatile__ ("mov_mov e0,a3,a3,e0\n"	\
+			 "syscall 0\n"			\
+			 "mov_mov e0,a3,a3,e0\n"	\
+			 : "+d" (__sc0)			\
+			 : ASM_IN_##nr			\
+			 : "memory");			\
+							\
+   CLEANUP_ARGS_##nr();					\
+   __sc0;						\
+})
+
+#undef INTERNAL_SYSCALL_NCS
+#define INTERNAL_SYSCALL_NCS(name, err, nr, args...)	\
+({							\
+   long __sc0v = (long) name;				\
+   SETUP_ARGS_##nr(args);				\
+							\
+   __asm__ __volatile__ ("mov_mov e0,a3,a3,e0\n"	\
+			 "syscall 0\n"			\
+			 "mov_mov e0,a3,a3,e0\n"	\
+			 : "+d" (__sc0)			\
+			 : ASM_IN_##nr			\
+			 : "memory");			\
+							\
+   CLEANUP_ARGS_##nr();					\
+   __sc0;						\
 })
 
 #undef INTERNAL_SYSCALL_DECL
@@ -231,86 +374,10 @@
 #undef INTERNAL_SYSCALL_ERRNO
 #define INTERNAL_SYSCALL_ERRNO(val, err) (-(val))
 
-#define inline_syscall0(name,dummy...) \
-__asm__ __volatile__ ("syscall 0" \
-	              : "+d" (__sc0) \
-	              : : "memory")
-
-#define inline_syscall1(name,arg1) \
-register long __sc1 asm ("a0") = (long) (arg1); \
-inline_syscall0 (name); \
-__asm__ __volatile__ ("" : : "r" (__sc1))
-
-#define inline_syscall2(name,arg1,arg2) \
-register long __sc2 asm ("d1") = (long) (arg2); \
-inline_syscall1 (name,(arg1)); \
-__asm__ __volatile__ ("" : : "r" (__sc2))
-
-/* We can't tell whether a3 is going to be eliminated in the enclosing
-   function, so we have to assume it isn't.  We first load the value
-   of any arguments into their registers, except for a3 itself, that
-   may be needed to load the value of the other arguments.  Then, we
-   save a3's value in some other register, and load the argument value
-   into a3.  We have to force both a3 and its copy to be live in
-   different registers at the same time, to avoid having the copy
-   spilled and the value reloaded into the same register, in which
-   case we'd be unable to get the value of a3 back, should the stack
-   slot reference be (offset,a3).  */
-#define inline_syscall3(name,arg1,arg2,arg3) \
-long __sc3v = (long) (arg3); \
-register long __sc1 asm ("a0") = (long) (arg1); \
-register long __sc2 asm ("d1") = (long) (arg2); \
-register long __sc3 asm ("a3") = __sc3;	\
-register long __sc3c; \
-__asm__ __volatile__ ("mov %1,%0" : "=&r" (__sc3c) : "r" (__sc3)); \
-__sc3 = __sc3v; \
-__asm__ __volatile__ ("" : : "r" (__sc3c), "r" (__sc3)); \
-inline_syscall0 (name); \
-__sc3 = __sc3c; \
-__asm__ __volatile__ ("" : : "r" (__sc3), "r" (__sc2), "r" (__sc1))
-
-#ifdef PIC
-/* Since a2 is the PIC register, it requires similar handling as a3
-   when we're generating PIC, as a2's value may be needed to load
-   arguments whose values live in global variables.  The difference is
-   that we don't need to require its value to be live in a register;
-   it may well be in a stack slot, as long as we save it before
-   clobbering a3 and restore it after restoring a3.  */
-#define inline_syscall4(name,arg1,arg2,arg3,arg4) \
-long __sc4v = (long) (arg4); \
-long __sc3v = (long) (arg3); \
-register long __sc1 asm ("a0") = (long) (arg1); \
-register long __sc2 asm ("d1") = (long) (arg2); \
-register long __sc3 asm ("a3") = __sc3;	\
-register long __sc3c; \
-register long __sc4 asm ("a2") = __sc4;	\
-long __sc4c = __sc4; \
-__sc4 = __sc4v; \
-__asm__ __volatile__ ("mov %1,%0" : "=&r" (__sc3c) : "r" (__sc3)); \
-__sc3 = __sc3v; \
-__asm__ __volatile__ ("" : : "r" (__sc3c), "r" (__sc3), "r" (__sc4)); \
-inline_syscall0 (name); \
-__sc3 = __sc3c; \
-__sc4 = __sc4c; \
-__asm__ __volatile__ ("" : : "r" (__sc4), "r" (__sc3), \
-			     "r" (__sc2), "r" (__sc1))
-#else
-#define inline_syscall4(name,arg1,arg2,arg3,arg4) \
-register long __sc4 asm ("a2") = (long) (arg4); \
-inline_syscall3 (name,(arg1),(arg2),(arg3)); \
-__asm__ __volatile__ ("" : : "r" (__sc4))
-#endif
-
-#define inline_syscall5(name,arg1,arg2,arg3,arg4,arg5) \
-register long __sc5 asm ("d3") = (long) (arg5); \
-inline_syscall4 (name,(arg1),(arg2),(arg3),(arg4)); \
-__asm__ __volatile__ ("" : : "r" (__sc5))
-
-#define inline_syscall6(name,arg1,arg2,arg3,arg4,arg5,arg6) \
-register long __sc6 asm ("d2") = (long) (arg6); \
-inline_syscall5 (name,(arg1),(arg2),(arg3),(arg4),(arg5)); \
-__asm__ __volatile__ ("" : : "r" (__sc6))
-
 #endif	/* __ASSEMBLER__ */
 
+/* Pointer mangling is not yet supported for AM33.  */
+#define PTR_MANGLE(var) (void) (var)
+#define PTR_DEMANGLE(var) (void) (var)
+
 #endif /* linux/am33/sysdep.h */
diff --git a/sysdeps/unix/sysv/linux/am33/vfork.S b/sysdeps/unix/sysv/linux/am33/vfork.S
new file mode 100644
index 0000000..eca4cc7
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/am33/vfork.S
@@ -0,0 +1,62 @@
+/* Copyright (C) 1999, 2002, 2004, 2005, 2008, 2009 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Mark Salter <msalter@redhat.com>.
+   Based on i386 version.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <sysdep.h>
+#define _ERRNO_H	1
+#include <bits/errno.h>
+#include <kernel-features.h>
+
+/* Clone the calling process, but without copying the whole address space.
+   The calling process is suspended until the new process exits or is
+   replaced by a call to `execve'.  Return -1 for errors, 0 to the new process,
+   and the process ID of the new process to the old process.  */
+
+ENTRY (__vfork)
+
+#ifdef __NR_vfork
+
+# ifdef SAVE_PID
+	SAVE_PID
+# endif
+	mov	0+SYS_ify (vfork), d0
+
+	# We must save the return address in a register otherwise child
+	# process will corrupt it before parent returns.
+	mov	(sp),a0
+	syscall 0
+	mov	a0,(sp)
+
+# ifdef RESTORE_PID
+	RESTORE_PID
+# endif
+
+	cmp	-129, d0
+	bls	L(pseudo_end)
+	jmp	SYSCALL_ERROR_LABEL
+  L(pseudo_end):
+	rets
+#else
+#error "__NR_vfork not defined"
+#endif
+
+PSEUDO_END (__vfork)
+libc_hidden_def (__vfork)
+
+weak_alias (__vfork, vfork)
-- 
1.7.10.2


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]