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

classic Classic list List threaded Threaded
7 messages Options
Reply | Threaded
Open this post in threaded view
|

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

Mark Salter-2
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 <[hidden email]>.
+
+# 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 <[hidden email]>.
    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 <[hidden email]>
+   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  <[hidden email]>
    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 <[hidden email]>
    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 <[hidden email]>
    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 <[hidden email]>
    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 <[hidden email]>
    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 <[hidden email]>
    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 <[hidden email]>
@@ -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 <[hidden email]>
    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 <[hidden email]>
    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 <[hidden email]>
-   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 <[hidden email]>, 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 <[hidden email]>
+
+   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 <[hidden email]>
+
+   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 <[hidden email]>
+
+   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 <[hidden email]>
+
+   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 <[hidden email]>
+
+   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 <[hidden email]>.
+
+   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 <[hidden email]>.
    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 <[hidden email]>.
+
+   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 <[hidden email]>, 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 <[hidden email]>.
    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 <[hidden email]>
-
-   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 <[hidden email]>, 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 <[hidden email]>, 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 <[hidden email]>, 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 <[hidden email]>
+
+   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 <[hidden email]>.
+   Modified for AM33 by Mark Salter <[hidden email]>.
+
+   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 <[hidden email]>.
+
+   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 <[hidden email]>.
    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 <[hidden email]>.
    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 <[hidden email]>.
+   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

Reply | Threaded
Open this post in threaded view
|

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

Joseph Myers
On Mon, 18 Jun 2012, Mark Salter wrote:

> 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.

General observations:

* New files should use a URL instead of an FSF postal address; that change
was made globally in libc and ports.

* There should be an ABI test baseline in
sysdeps/unix/sysv/linux/am33/nptl/.

* There should be a C++ types baseline in data/ (and a localplt one if the
generic one doesn't suffice).

* sysdeps/unix/sysv/linux/am33/configure.in should change
arch_minimum_kernel to 2.6.25, the version where am33 support went into
kernel.org kernels, and you should have a kernel-features.h unless the
libc version is fully correct about when features were supported on am33.

* Use copyright ranges (<year>-2012) in all new or changed files with more
than one copyright year.  Some files appear to be missing copyright date
updates.

Specific comments:

> 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

You're patching a file that nothing (in libc, ports or this patch) uses.  
Remove it instead.  It's probably a good idea to check all am33 port files
(after this patch) to make sure they are actually used.

> 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

> +/* 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]))

This belongs in jmpbuf-unwind.h, not bits/setjmp.h.  The other definitions
you add belong in jmpbuf-offsets.h, not bits/setjmp.h.

> +#if !defined RTLD_BOOTSTRAP || USE___THREAD

USE___THREAD is an obsolete macro.

> +#if (!defined RTLD_BOOTSTRAP || USE___THREAD) \

Likewise.

> diff --git a/sysdeps/am33/elf/configure.in b/sysdeps/am33/elf/configure.in

/elf/ sysdeps directories are no longer used, so this belongs directly in
sysdeps/am33/.

> +if test "$usetls" != no; then

Obsolete conditional.

> +if test $libc_cv_am33_tls = yes; then
> +  AC_DEFINE(HAVE_TLS_SUPPORT)
> +fi

Obsolete macro.  Instead, use AC_MSG_ERROR if TLS support is missing.

> diff --git a/sysdeps/am33/fpu/feholdexcpt.c b/sysdeps/am33/fpu/feholdexcpt.c
> +libm_hidden_def (feholdexcept)
> diff --git a/sysdeps/am33/fpu/fesetround.c b/sysdeps/am33/fpu/fesetround.c
> +libm_hidden_def (fesetround)

I think you need such changes to fegetenv.c, fesetenv.c, feupdateenv.c,
fraiseexcpt.c and ftestexcept.c as well.

> 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 @@

That looks too short to have been recently generated ... once you have
testing working you should regenerate this for current glibc, starting
with an empty file.

> diff --git a/sysdeps/am33/init-misc.c b/sysdeps/am33/init-misc.c

I do wonder whether overriding this file is really the best way to
initialize something architecture-specific ... maybe someone else has a
better way to do it?

> +#ifdef HAVE_ELF
> +#define L(name) .L##name
> +#else

HAVE_ELF is obsolete.

> diff --git a/sysdeps/arm/dl-machine.h b/sysdeps/arm/dl-machine.h

You should not be modifying files for another machine when submitting a
port.  If you wish to submit this patch, you need to do so separately,
with its own rationale.

> 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

Do you need changes to O_SYNC and O_DSYNC to match 2.6.33+ kernels (see
<http://sourceware.org/ml/libc-ports/2009-12/msg00013.html>)?

You'll want to compare with other architectures - it looks like there are
various other ways this patch does not update bits/fcntl.h to be fully in
sync regarding what macros are defined under what conditions, what
functions are declared, etc.

> 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

Again, does not appear to be a complete update.

> 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;
> +  }
> +}

Too much copying from other ports - these are ARM-specific and don't exist
for am33.

> +strong_alias (__pthread_once, __pthread_once_internal)

We removed those aliases, replacing them by hidden_def.

There may be more issues with the port not being up to date with global
changes, but they would probably be easier to see once the above issues
are fixed and the fixed patch checked in, rather than trying to compare
the combination of the old port and this patch against other ports.

--
Joseph S. Myers
[hidden email]
Reply | Threaded
Open this post in threaded view
|

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

Joseph Myers
Another point: you don't have a syscalls.list for am33, so as a 32-bit
architecture that means you'll probably be missing prlimit64 and
fanotify_mark (as generating ABI baselines, and comparing them with those
for other architectures, might show).  So you should add one - and an
appropriate Versions file to put those functions in the version actually
adding them for am33.

Regarding versions - shlib-versions should ideally be set up to avoid
symbols at versions that didn't exist in working form for am33.  See how
Tile avoids versions before 2.12, and between 2.12 and 2.15.  If you
haven't had any versions between 2.9 and 2.16 you could cause intermediate
symbol versions not to exist for am33, for example (you might need to
declare explicitly all past symbol versions that should exist for am33;
I'm not sure).

--
Joseph S. Myers
[hidden email]
Reply | Threaded
Open this post in threaded view
|

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

Joseph Myers
In reply to this post by Joseph Myers
On Mon, 18 Jun 2012, Joseph S. Myers wrote:

> * sysdeps/unix/sysv/linux/am33/configure.in should change
> arch_minimum_kernel to 2.6.25, the version where am33 support went into
> kernel.org kernels, and you should have a kernel-features.h unless the
> libc version is fully correct about when features were supported on am33.

A clarification here: I think 2.6.25 is now the earliest reasonable
arch_minimum_kernel for am33, but if there were any kernel features
required by NPTL or other parts of the port that only went in some time
after 2.6.25, then it's possible that in fact something more recent should
be listed for arch_minimum_kernel.

--
Joseph S. Myers
[hidden email]
Reply | Threaded
Open this post in threaded view
|

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

Joseph Myers
In reply to this post by Mark Salter-2
Any news on updating this patch for my review comments posted in June
2012, and for all the subsequent relevant global changes in glibc for
which the port wasn't updated (or for which new files in the patch need
updating), with a view to getting it checked in so a further review of how
current the port is regarding global changes can be made on the basis of a
substantially working checked-in port?  I really don't think it makes
sense just to leave the port around in such a bit-rotten state; either it
should be fixed, or it should be removed from glibc (with of course the
potential to add a port to this architecture again in future if one is
posted that is up-to-date with current glibc).

--
Joseph S. Myers
[hidden email]
Reply | Threaded
Open this post in threaded view
|

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

Mark Salter-2
On Tue, 2014-01-21 at 22:53 +0000, Joseph S. Myers wrote:

> Any news on updating this patch for my review comments posted in June
> 2012, and for all the subsequent relevant global changes in glibc for
> which the port wasn't updated (or for which new files in the patch need
> updating), with a view to getting it checked in so a further review of how
> current the port is regarding global changes can be made on the basis of a
> substantially working checked-in port?  I really don't think it makes
> sense just to leave the port around in such a bit-rotten state; either it
> should be fixed, or it should be removed from glibc (with of course the
> potential to add a port to this architecture again in future if one is
> posted that is up-to-date with current glibc).
>

Sorry about letting this linger. At this point, I think removing it is
the thing to do. The tls bits never got to upstream gcc and I ran into
issues with the toolchain I couldn't get past.


Reply | Threaded
Open this post in threaded view
|

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

Joseph Myers
On Tue, 21 Jan 2014, Mark Salter wrote:

> Sorry about letting this linger. At this point, I think removing it is
> the thing to do. The tls bits never got to upstream gcc and I ran into
> issues with the toolchain I couldn't get past.

Thanks - I'll remove it after 2.19 branches.

--
Joseph S. Myers
[hidden email]