about summary refs log tree commit diff
path: root/ports/sysdeps/arm
diff options
context:
space:
mode:
authorJoseph Myers <joseph@codesourcery.com>2012-07-01 13:06:41 +0000
committerJoseph Myers <joseph@codesourcery.com>2012-07-01 13:06:41 +0000
commite64ac02c24b43659048622714afdc92fedf561fa (patch)
tree37162878b72d302de351788bec4c9360c9d55f1d /ports/sysdeps/arm
parenta20c2b3c87aebc7d4b090c622d36480263b80042 (diff)
downloadglibc-e64ac02c24b43659048622714afdc92fedf561fa.tar.gz
glibc-e64ac02c24b43659048622714afdc92fedf561fa.tar.xz
glibc-e64ac02c24b43659048622714afdc92fedf561fa.zip
Move all files into ports/ subdirectory in preparation for merge with glibc glibc-2.16-ports-before-merge
Diffstat (limited to 'ports/sysdeps/arm')
-rw-r--r--ports/sysdeps/arm/Implies3
-rw-r--r--ports/sysdeps/arm/Makefile35
-rw-r--r--ports/sysdeps/arm/Versions20
-rw-r--r--ports/sysdeps/arm/__longjmp.S111
-rw-r--r--ports/sysdeps/arm/abi-note.S9
-rw-r--r--ports/sysdeps/arm/aeabi_assert.c26
-rw-r--r--ports/sysdeps/arm/aeabi_atexit.c27
-rw-r--r--ports/sysdeps/arm/aeabi_errno_addr.c24
-rw-r--r--ports/sysdeps/arm/aeabi_lcsts.c98
-rw-r--r--ports/sysdeps/arm/aeabi_localeconv.c24
-rw-r--r--ports/sysdeps/arm/aeabi_math.c41
-rw-r--r--ports/sysdeps/arm/aeabi_mb_cur_max.c27
-rw-r--r--ports/sysdeps/arm/aeabi_memclr.c30
-rw-r--r--ports/sysdeps/arm/aeabi_memcpy.c31
-rw-r--r--ports/sysdeps/arm/aeabi_memmove.c31
-rw-r--r--ports/sysdeps/arm/aeabi_memset.c30
-rw-r--r--ports/sysdeps/arm/aeabi_sighandlers.S53
-rw-r--r--ports/sysdeps/arm/aeabi_unwind_cpp_pr1.c51
-rw-r--r--ports/sysdeps/arm/arm-mcount.S108
-rw-r--r--ports/sysdeps/arm/armv6t2/memchr.S163
-rw-r--r--ports/sysdeps/arm/armv7/Implies2
-rw-r--r--ports/sysdeps/arm/backtrace.c125
-rw-r--r--ports/sysdeps/arm/bits/endian.h10
-rw-r--r--ports/sysdeps/arm/bits/fenv.h73
-rw-r--r--ports/sysdeps/arm/bits/link.h65
-rw-r--r--ports/sysdeps/arm/bits/linkmap.h5
-rw-r--r--ports/sysdeps/arm/bits/mathdef.h56
-rw-r--r--ports/sysdeps/arm/bits/setjmp.h37
-rw-r--r--ports/sysdeps/arm/bsd-_setjmp.S29
-rw-r--r--ports/sysdeps/arm/bsd-setjmp.S28
-rwxr-xr-xports/sysdeps/arm/configure335
-rw-r--r--ports/sysdeps/arm/configure.in68
-rw-r--r--ports/sysdeps/arm/crti.S93
-rw-r--r--ports/sysdeps/arm/crtn.S55
-rw-r--r--ports/sysdeps/arm/dl-irel.h51
-rw-r--r--ports/sysdeps/arm/dl-lookupcfg.h27
-rw-r--r--ports/sysdeps/arm/dl-machine.h694
-rw-r--r--ports/sysdeps/arm/dl-sysdep.h23
-rw-r--r--ports/sysdeps/arm/dl-tls.h31
-rw-r--r--ports/sysdeps/arm/dl-tlsdesc.S218
-rw-r--r--ports/sysdeps/arm/dl-tlsdesc.h68
-rw-r--r--ports/sysdeps/arm/dl-trampoline.S217
-rw-r--r--ports/sysdeps/arm/fclrexcpt.c60
-rw-r--r--ports/sysdeps/arm/fedisblxcpt.c50
-rw-r--r--ports/sysdeps/arm/feenablxcpt.c50
-rw-r--r--ports/sysdeps/arm/fegetenv.c51
-rw-r--r--ports/sysdeps/arm/fegetexcept.c42
-rw-r--r--ports/sysdeps/arm/fegetround.c42
-rw-r--r--ports/sysdeps/arm/feholdexcpt.c53
-rw-r--r--ports/sysdeps/arm/fesetenv.c56
-rw-r--r--ports/sysdeps/arm/fesetround.c56
-rw-r--r--ports/sysdeps/arm/feupdateenv.c59
-rw-r--r--ports/sysdeps/arm/fgetexcptflg.c53
-rw-r--r--ports/sysdeps/arm/find_exidx.c79
-rw-r--r--ports/sysdeps/arm/fpu_control.h63
-rw-r--r--ports/sysdeps/arm/fraiseexcpt.c109
-rw-r--r--ports/sysdeps/arm/frame.h27
-rw-r--r--ports/sysdeps/arm/framestate.c1
-rw-r--r--ports/sysdeps/arm/fsetexcptflg.c59
-rw-r--r--ports/sysdeps/arm/ftestexcept.c43
-rw-r--r--ports/sysdeps/arm/gccframe.h21
-rw-r--r--ports/sysdeps/arm/gmp-mparam.h36
-rw-r--r--ports/sysdeps/arm/jmpbuf-offsets.h19
-rw-r--r--ports/sysdeps/arm/jmpbuf-unwind.h35
-rw-r--r--ports/sysdeps/arm/ldsodefs.h40
-rw-r--r--ports/sysdeps/arm/libc-tls.c32
-rw-r--r--ports/sysdeps/arm/libm-test-ulps1845
-rw-r--r--ports/sysdeps/arm/machine-gmon.h33
-rw-r--r--ports/sysdeps/arm/memcpy.S263
-rw-r--r--ports/sysdeps/arm/memmove.S279
-rw-r--r--ports/sysdeps/arm/memset.S64
-rw-r--r--ports/sysdeps/arm/memusage.h20
-rw-r--r--ports/sysdeps/arm/nptl/Makefile20
-rw-r--r--ports/sysdeps/arm/nptl/pthread_spin_lock.c29
-rw-r--r--ports/sysdeps/arm/nptl/pthread_spin_trylock.c26
-rw-r--r--ports/sysdeps/arm/nptl/pthreaddef.h46
-rw-r--r--ports/sysdeps/arm/nptl/tcb-offsets.sym11
-rw-r--r--ports/sysdeps/arm/nptl/tls.h151
-rw-r--r--ports/sysdeps/arm/preconfigure50
-rw-r--r--ports/sysdeps/arm/rtld-global-offsets.sym7
-rw-r--r--ports/sysdeps/arm/setfpucw.c46
-rw-r--r--ports/sysdeps/arm/setjmp.S98
-rw-r--r--ports/sysdeps/arm/shlib-versions9
-rw-r--r--ports/sysdeps/arm/stackinfo.h33
-rw-r--r--ports/sysdeps/arm/start.S148
-rw-r--r--ports/sysdeps/arm/strlen.S72
-rw-r--r--ports/sysdeps/arm/sys/ucontext.h94
-rw-r--r--ports/sysdeps/arm/sysdep.h120
-rw-r--r--ports/sysdeps/arm/tls-macros.h78
-rw-r--r--ports/sysdeps/arm/tlsdesc.c160
-rw-r--r--ports/sysdeps/arm/tlsdesc.sym15
-rw-r--r--ports/sysdeps/arm/tst-audit.h25
-rw-r--r--ports/sysdeps/arm/unwind-dw2-fde-glibc.c79
-rw-r--r--ports/sysdeps/arm/unwind-pe.c1
94 files changed, 8210 insertions, 0 deletions
diff --git a/ports/sysdeps/arm/Implies b/ports/sysdeps/arm/Implies
new file mode 100644
index 0000000000..780c4e2467
--- /dev/null
+++ b/ports/sysdeps/arm/Implies
@@ -0,0 +1,3 @@
+wordsize-32
+ieee754/flt-32
+ieee754/dbl-64
diff --git a/ports/sysdeps/arm/Makefile b/ports/sysdeps/arm/Makefile
new file mode 100644
index 0000000000..5fd5136328
--- /dev/null
+++ b/ports/sysdeps/arm/Makefile
@@ -0,0 +1,35 @@
+ifeq ($(subdir),elf)
+sysdep-dl-routines += tlsdesc dl-tlsdesc
+sysdep_routines += aeabi_unwind_cpp_pr1 find_exidx tlsdesc dl-tlsdesc
+sysdep-rtld-routines += aeabi_unwind_cpp_pr1 tlsdesc dl-tlsdesc
+shared-only-routines += aeabi_unwind_cpp_pr1
+endif
+
+ifeq ($(subdir),csu)
+# get offset to rtld_global._dl_hwcap
+gen-as-const-headers += rtld-global-offsets.sym tlsdesc.sym
+aeabi_constants = aeabi_lcsts aeabi_sighandlers aeabi_math
+aeabi_routines = aeabi_assert aeabi_localeconv aeabi_errno_addr \
+	aeabi_mb_cur_max aeabi_atexit aeabi_memclr aeabi_memcpy \
+	aeabi_memmove aeabi_memset
+
+sysdep_routines += $(aeabi_constants) $(aeabi_routines)
+static-only-routines += $(aeabi_constants)
+endif
+
+# to pull in __aeabi_read_tp, needed for tls
+ifeq ($(subdir),malloc)
+$(objpfx)libmemusage.so: $(common-objpfx)libc_nonshared.a
+endif
+
+ifeq ($(subdir),gmon)
+sysdep_routines += arm-mcount
+endif
+
+ifeq ($(subdir),debug)
+CFLAGS-backtrace.c += -funwind-tables
+endif
+
+ifeq ($(subdir),math)
+$(objpfx)libm.so: $(elfobjdir)/ld.so
+endif
diff --git a/ports/sysdeps/arm/Versions b/ports/sysdeps/arm/Versions
new file mode 100644
index 0000000000..5f2af29c38
--- /dev/null
+++ b/ports/sysdeps/arm/Versions
@@ -0,0 +1,20 @@
+libc {
+  GLIBC_2.4 {
+    # ARM EABI compatibility routines
+    __aeabi_assert;
+    __aeabi_atexit;
+    __aeabi_errno_addr;
+    __aeabi_localeconv;
+    __aeabi_MB_CUR_MAX;
+    __aeabi_memclr; __aeabi_memclr4; __aeabi_memclr8;
+    __aeabi_memcpy; __aeabi_memcpy4; __aeabi_memcpy8;
+    __aeabi_memmove; __aeabi_memmove4; __aeabi_memmove8;
+    __aeabi_memset; __aeabi_memset4; __aeabi_memset8;
+
+    # Helper routines
+    __gnu_Unwind_Find_exidx;
+  }
+  GLIBC_2.8 {
+    __gnu_mcount_nc;
+  }
+}
diff --git a/ports/sysdeps/arm/__longjmp.S b/ports/sysdeps/arm/__longjmp.S
new file mode 100644
index 0000000000..cc802c15bd
--- /dev/null
+++ b/ports/sysdeps/arm/__longjmp.S
@@ -0,0 +1,111 @@
+/* longjmp for ARM.
+   Copyright (C) 1997, 1998, 2005, 2006, 2009, 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, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <sysdep.h>
+#define _SETJMP_H
+#define _ASM
+#include <bits/setjmp.h>
+#include <rtld-global-offsets.h>
+
+/* __longjmp(jmpbuf, val) */
+
+ENTRY (__longjmp)
+	mov	ip, r0
+	movs	r0, r1		/* get the return value in place */
+	moveq	r0, #1		/* can't let setjmp() return zero! */
+
+#ifdef CHECK_SP
+	ldr	r4, [ip, #32]	/* jmpbuf's sp */
+	cfi_undefined (r4)
+	CHECK_SP (r4)
+#endif
+	LOADREGS(ia, ip!, {v1-v6, sl, fp, sp, lr})
+	cfi_restore (v1)
+	cfi_restore (v2)
+	cfi_restore (v3)
+	cfi_restore (v4)
+	cfi_restore (v5)
+	cfi_restore (v6)
+	cfi_restore (sl)
+	cfi_restore (fp)
+	cfi_restore (sp)
+	cfi_restore (lr)
+
+#ifdef IS_IN_rtld
+  	ldr	a2, 1f
+	ldr	a3, Lrtld_local_ro
+0:	add	a2, pc, a2
+	add	a2, a2, a3
+	ldr	a2, [a2, #RTLD_GLOBAL_RO_DL_HWCAP_OFFSET]
+#else
+#ifdef PIC
+  	ldr	a2, 1f
+	ldr	a3, Lrtld_global_ro
+0:	add	a2, pc, a2
+	ldr	a2, [a2, a3]
+	ldr	a2, [a2, #RTLD_GLOBAL_RO_DL_HWCAP_OFFSET]
+#else
+	ldr	a2, Lhwcap
+	ldr	a2, [a2, #0]
+#endif
+#endif
+
+	tst	a2, #HWCAP_ARM_VFP
+	beq	Lno_vfp
+
+	/* Restore the VFP registers.  */
+	/* Following instruction is vldmia ip!, {d8-d15}.  */
+	ldc	p11, cr8, [r12], #64
+	/* Restore the floating-point status register.  */
+	ldr     a3, [ip], #4
+	/* Following instruction is fmxr fpscr, a3.  */
+	mcr	p10, 7, a3, cr1, cr0, 0
+Lno_vfp:
+
+	tst	a2, #HWCAP_ARM_IWMMXT
+	beq	Lno_iwmmxt
+
+	/* Restore the call-preserved iWMMXt registers.  */
+	/* Following instructions are wldrd wr10, [ip], #8 (etc.)  */
+	ldcl	p1, cr10, [r12], #8
+	ldcl	p1, cr11, [r12], #8
+	ldcl	p1, cr12, [r12], #8
+	ldcl	p1, cr13, [r12], #8
+	ldcl	p1, cr14, [r12], #8
+	ldcl	p1, cr15, [r12], #8
+Lno_iwmmxt:
+
+	DO_RET(lr)
+
+#ifdef IS_IN_rtld
+1:	.long	_GLOBAL_OFFSET_TABLE_ - 0b - 8
+Lrtld_local_ro:
+	.long	C_SYMBOL_NAME(_rtld_local_ro)(GOTOFF)
+#else
+#ifdef PIC
+1:	.long	_GLOBAL_OFFSET_TABLE_ - 0b - 8
+Lrtld_global_ro:
+	.long	C_SYMBOL_NAME(_rtld_global_ro)(GOT)
+#else
+Lhwcap:
+	.long	C_SYMBOL_NAME(_dl_hwcap)
+#endif
+#endif
+
+END (__longjmp)
diff --git a/ports/sysdeps/arm/abi-note.S b/ports/sysdeps/arm/abi-note.S
new file mode 100644
index 0000000000..1060c3d280
--- /dev/null
+++ b/ports/sysdeps/arm/abi-note.S
@@ -0,0 +1,9 @@
+/* Tag_ABI_align8_preserved: This code preserves 8-byte
+   alignment in any callee.  */
+	.eabi_attribute 25, 1
+/* Tag_ABI_align8_needed: This code may require 8-byte alignment from
+   the caller.  */
+	.eabi_attribute 24, 1
+
+#include <csu/abi-note.S>
+
diff --git a/ports/sysdeps/arm/aeabi_assert.c b/ports/sysdeps/arm/aeabi_assert.c
new file mode 100644
index 0000000000..c8fb188913
--- /dev/null
+++ b/ports/sysdeps/arm/aeabi_assert.c
@@ -0,0 +1,26 @@
+/* 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, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <assert.h>
+#include <stdlib.h>
+
+void
+__aeabi_assert (const char *assertion, const char *file,
+		unsigned int line)
+{
+  __assert_fail (assertion, file, line, NULL);
+}
diff --git a/ports/sysdeps/arm/aeabi_atexit.c b/ports/sysdeps/arm/aeabi_atexit.c
new file mode 100644
index 0000000000..5427fae961
--- /dev/null
+++ b/ports/sysdeps/arm/aeabi_atexit.c
@@ -0,0 +1,27 @@
+/* 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, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <stdlib.h>
+
+/* Register a function to be called by exit or when a shared library
+   is unloaded.  This routine is like __cxa_atexit, but uses the
+   calling sequence required by the ARM EABI.  */
+int
+__aeabi_atexit (void *arg, void (*func) (void *), void *d)
+{
+  return __cxa_atexit (func, arg, d);
+}
diff --git a/ports/sysdeps/arm/aeabi_errno_addr.c b/ports/sysdeps/arm/aeabi_errno_addr.c
new file mode 100644
index 0000000000..b9ee3a5fdd
--- /dev/null
+++ b/ports/sysdeps/arm/aeabi_errno_addr.c
@@ -0,0 +1,24 @@
+/* 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, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <errno.h>
+
+volatile int *
+__aeabi_errno_addr (void)
+{
+  return &errno;
+}
diff --git a/ports/sysdeps/arm/aeabi_lcsts.c b/ports/sysdeps/arm/aeabi_lcsts.c
new file mode 100644
index 0000000000..c53800d6c6
--- /dev/null
+++ b/ports/sysdeps/arm/aeabi_lcsts.c
@@ -0,0 +1,98 @@
+/* Link-time constants for ARM EABI.
+   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.
+
+   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/>.  */
+
+/* The ARM EABI requires that we provide ISO compile-time constants as
+   link-time constants.  Some portable applications may reference these.  */
+
+#include <errno.h>
+#include <limits.h>
+#include <locale.h>
+#include <setjmp.h>
+#include <signal.h>
+#include <stdio.h>
+#include <time.h>
+
+#define eabi_constant2(X,Y) const int __aeabi_##X attribute_hidden = Y
+#define eabi_constant(X) const int __aeabi_##X attribute_hidden = X
+
+eabi_constant (EDOM);
+eabi_constant (ERANGE);
+eabi_constant (EILSEQ);
+
+eabi_constant (MB_LEN_MAX);
+
+eabi_constant (LC_COLLATE);
+eabi_constant (LC_CTYPE);
+eabi_constant (LC_MONETARY);
+eabi_constant (LC_NUMERIC);
+eabi_constant (LC_TIME);
+eabi_constant (LC_ALL);
+
+/* The value of __aeabi_JMP_BUF_SIZE is the number of doublewords in a
+   jmp_buf.  */
+eabi_constant2 (JMP_BUF_SIZE, sizeof (jmp_buf) / 8);
+
+eabi_constant (SIGABRT);
+eabi_constant (SIGFPE);
+eabi_constant (SIGILL);
+eabi_constant (SIGINT);
+eabi_constant (SIGSEGV);
+eabi_constant (SIGTERM);
+
+eabi_constant2 (IOFBF, _IOFBF);
+eabi_constant2 (IOLBF, _IOLBF);
+eabi_constant2 (IONBF, _IONBF);
+eabi_constant (BUFSIZ);
+eabi_constant (FOPEN_MAX);
+eabi_constant (TMP_MAX);
+eabi_constant (FILENAME_MAX);
+eabi_constant (L_tmpnam);
+
+FILE *__aeabi_stdin attribute_hidden;
+FILE *__aeabi_stdout attribute_hidden;
+FILE *__aeabi_stderr attribute_hidden;
+
+static void __attribute__ ((used))
+setup_aeabi_stdio (void)
+{
+  __aeabi_stdin = stdin;
+  __aeabi_stdout = stdout;
+  __aeabi_stderr = stderr;
+}
+
+static void (*fp) (void) __attribute__ ((used, section (".preinit_array")))
+  = setup_aeabi_stdio;
+
+eabi_constant (CLOCKS_PER_SEC);
diff --git a/ports/sysdeps/arm/aeabi_localeconv.c b/ports/sysdeps/arm/aeabi_localeconv.c
new file mode 100644
index 0000000000..233dc62049
--- /dev/null
+++ b/ports/sysdeps/arm/aeabi_localeconv.c
@@ -0,0 +1,24 @@
+/* Copyright (C) 2004, 2005, 2008 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <locale.h>
+
+struct lconv *
+__aeabi_localeconv (void)
+{
+  return __localeconv ();
+}
diff --git a/ports/sysdeps/arm/aeabi_math.c b/ports/sysdeps/arm/aeabi_math.c
new file mode 100644
index 0000000000..d7bcd56714
--- /dev/null
+++ b/ports/sysdeps/arm/aeabi_math.c
@@ -0,0 +1,41 @@
+/* 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.
+
+   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 <math.h>
+
+const double __aeabi_HUGE_VAL attribute_hidden = HUGE_VAL;
+const long double __aeabi_HUGE_VALL attribute_hidden = HUGE_VALL;
+const float __aeabi_HUGE_VALF attribute_hidden = HUGE_VALF;
+const float __aeabi_INFINITY attribute_hidden = INFINITY;
+const float __aeabi_NAN attribute_hidden = NAN;
diff --git a/ports/sysdeps/arm/aeabi_mb_cur_max.c b/ports/sysdeps/arm/aeabi_mb_cur_max.c
new file mode 100644
index 0000000000..3c03a9ae3a
--- /dev/null
+++ b/ports/sysdeps/arm/aeabi_mb_cur_max.c
@@ -0,0 +1,27 @@
+/* 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, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <langinfo.h>
+#include <locale.h>
+#include <stdlib.h>
+#include <locale/localeinfo.h>
+
+int
+__aeabi_MB_CUR_MAX (void)
+{
+  return MB_CUR_MAX;
+}
diff --git a/ports/sysdeps/arm/aeabi_memclr.c b/ports/sysdeps/arm/aeabi_memclr.c
new file mode 100644
index 0000000000..e2974520e5
--- /dev/null
+++ b/ports/sysdeps/arm/aeabi_memclr.c
@@ -0,0 +1,30 @@
+/* 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, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <string.h>
+
+/* Clear memory.  Can't alias to bzero because it's not defined in the
+   same translation unit.  */
+void
+__aeabi_memclr (void *dest, size_t n)
+{
+  __bzero (dest, n);
+}
+
+/* Versions of the above which may assume memory alignment.  */
+strong_alias (__aeabi_memclr, __aeabi_memclr4)
+strong_alias (__aeabi_memclr, __aeabi_memclr8)
diff --git a/ports/sysdeps/arm/aeabi_memcpy.c b/ports/sysdeps/arm/aeabi_memcpy.c
new file mode 100644
index 0000000000..403a7ef525
--- /dev/null
+++ b/ports/sysdeps/arm/aeabi_memcpy.c
@@ -0,0 +1,31 @@
+/* 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, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <string.h>
+
+/* Copy memory like memcpy, but no return value required.  Can't alias
+   to memcpy because it's not defined in the same translation
+   unit.  */
+void
+__aeabi_memcpy (void *dest, const void *src, size_t n)
+{
+  memcpy (dest, src, n);
+}
+
+/* Versions of the above which may assume memory alignment.  */
+strong_alias (__aeabi_memcpy, __aeabi_memcpy4)
+strong_alias (__aeabi_memcpy, __aeabi_memcpy8)
diff --git a/ports/sysdeps/arm/aeabi_memmove.c b/ports/sysdeps/arm/aeabi_memmove.c
new file mode 100644
index 0000000000..e824946a79
--- /dev/null
+++ b/ports/sysdeps/arm/aeabi_memmove.c
@@ -0,0 +1,31 @@
+/* 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, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <string.h>
+
+/* Copy memory like memmove, but no return value required.  Can't
+   alias to memmove because it's not defined in the same translation
+   unit.  */
+void
+__aeabi_memmove (void *dest, const void *src, size_t n)
+{
+  memmove (dest, src, n);
+}
+
+/* Versions of the above which may assume memory alignment.  */
+strong_alias (__aeabi_memmove, __aeabi_memmove4)
+strong_alias (__aeabi_memmove, __aeabi_memmove8)
diff --git a/ports/sysdeps/arm/aeabi_memset.c b/ports/sysdeps/arm/aeabi_memset.c
new file mode 100644
index 0000000000..b7775f9196
--- /dev/null
+++ b/ports/sysdeps/arm/aeabi_memset.c
@@ -0,0 +1,30 @@
+/* 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, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <string.h>
+
+/* Set memory like memset, but different argument order and no return
+   value required.  */
+void
+__aeabi_memset (void *dest, size_t n, int c)
+{
+  memset (dest, c, n);
+}
+
+/* Versions of the above which may assume memory alignment.  */
+strong_alias (__aeabi_memset, __aeabi_memset4)
+strong_alias (__aeabi_memset, __aeabi_memset8)
diff --git a/ports/sysdeps/arm/aeabi_sighandlers.S b/ports/sysdeps/arm/aeabi_sighandlers.S
new file mode 100644
index 0000000000..082039e9cd
--- /dev/null
+++ b/ports/sysdeps/arm/aeabi_sighandlers.S
@@ -0,0 +1,53 @@
+/* Link-time constants for ARM EABI - signal handlers.
+   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.
+
+   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/>.  */
+
+/* The ARM EABI defines these as "functions".  */
+
+#include <sysdep.h>
+
+	.global __aeabi_SIG_DFL
+	.hidden __aeabi_SIG_DFL
+	.type __aeabi_SIG_DFL, %function
+	.set __aeabi_SIG_DFL, 0
+
+	.global __aeabi_SIG_IGN
+	.hidden __aeabi_SIG_IGN
+	.type __aeabi_SIG_IGN, %function
+	.set __aeabi_SIG_IGN, 1
+
+	.global __aeabi_SIG_ERR
+	.hidden __aeabi_SIG_ERR
+	.type __aeabi_SIG_ERR, %function
+	.set __aeabi_SIG_ERR, -1
diff --git a/ports/sysdeps/arm/aeabi_unwind_cpp_pr1.c b/ports/sysdeps/arm/aeabi_unwind_cpp_pr1.c
new file mode 100644
index 0000000000..5dbbd9b0a1
--- /dev/null
+++ b/ports/sysdeps/arm/aeabi_unwind_cpp_pr1.c
@@ -0,0 +1,51 @@
+/* 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, see
+   <http://www.gnu.org/licenses/>.  */
+
+/* Because some objects in ld.so and libc.so are built with
+   -fexceptions, we end up with references to this personality
+   routine.  However, these libraries are not linked against
+   libgcc_eh.a, so we need a dummy definition.   This routine will
+   never actually be called.  */
+
+#include <stdlib.h>
+
+attribute_hidden
+void
+__aeabi_unwind_cpp_pr0 (void)
+{
+#ifndef IS_IN_rtld
+  abort ();
+#endif
+}
+
+attribute_hidden
+void
+__aeabi_unwind_cpp_pr1 (void)
+{
+#ifndef IS_IN_rtld
+  abort ();
+#endif
+}
+
+attribute_hidden
+void
+__aeabi_unwind_cpp_pr2 (void)
+{
+#ifndef IS_IN_rtld
+  abort ();
+#endif
+}
diff --git a/ports/sysdeps/arm/arm-mcount.S b/ports/sysdeps/arm/arm-mcount.S
new file mode 100644
index 0000000000..5ee66bea02
--- /dev/null
+++ b/ports/sysdeps/arm/arm-mcount.S
@@ -0,0 +1,108 @@
+/* Implementation of profiling support.  ARM EABI version.
+   Copyright (C) 2008, 2009, 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, see
+   <http://www.gnu.org/licenses/>.  */
+
+/* Don't call mcount when calling mcount...  */
+#undef PROF
+
+#include <sysdep.h>
+
+
+#ifdef __thumb2__
+	.thumb
+	.syntax unified
+#endif
+
+
+/* Use an assembly stub with a special ABI.  The calling lr has been
+   pushed to the stack (which will be misaligned).  We should preserve
+   all registers except ip and pop a word off the stack.
+
+   NOTE: This assumes mcount_internal does not clobber any non-core
+   (coprocessor) registers.  Currently this is true, but may require
+   additional attention in the future.
+
+   The calling sequence looks something like:
+func:
+   push {lr}
+   bl __gnu_mount_nc
+   <function body>
+*/
+
+ENTRY(__gnu_mcount_nc)
+	push {r0, r1, r2, r3, lr}
+	cfi_adjust_cfa_offset (20)
+	cfi_rel_offset (r0, 0)
+	cfi_rel_offset (r1, 4)
+	cfi_rel_offset (r2, 8)
+	cfi_rel_offset (r3, 12)
+	cfi_rel_offset (lr, 16)
+	bic r1, lr, #1
+	ldr r0, [sp, #20]
+	bl __mcount_internal
+	pop {r0, r1, r2, r3, ip, lr}
+	cfi_adjust_cfa_offset (-24)
+	cfi_restore (r0)
+	cfi_restore (r1)
+	cfi_restore (r2)
+	cfi_restore (r3)
+	cfi_register (lr, ip)
+	bx ip
+END(__gnu_mcount_nc)
+
+
+/* Provide old mcount for backwards compatibility.  This requires
+   code be compiled with APCS frame pointers.  */
+
+ENTRY(_mcount)
+	stmdb sp!, {r0, r1, r2, r3, fp, lr}
+	cfi_adjust_cfa_offset (24)
+	cfi_rel_offset (r0, 0)
+	cfi_rel_offset (r1, 4)
+	cfi_rel_offset (r2, 8)
+	cfi_rel_offset (r3, 12)
+	cfi_rel_offset (fp, 16)
+	cfi_rel_offset (lr, 20)
+#ifdef __thumb2__
+	movs r0, fp
+	ittt ne
+	ldrne r0, [r0, #-4]
+#else
+	movs fp, fp
+	ldrne r0, [fp, #-4]
+#endif
+	movnes r1, lr
+	blne __mcount_internal
+#ifdef __thumb2__
+	ldmia sp!, {r0, r1, r2, r3, fp, pc}
+#else
+	ldmia sp!, {r0, r1, r2, r3, fp, lr}
+	cfi_adjust_cfa_offset (-24)
+	cfi_restore (r0)
+	cfi_restore (r1)
+	cfi_restore (r2)
+	cfi_restore (r3)
+	cfi_restore (fp)
+	cfi_restore (lr)
+	bx lr
+#endif
+END(_mcount)
+
+/* The canonical name for the function is `_mcount' in both C and asm,
+   but some old asm code might assume it's `mcount'.  */
+#undef mcount
+weak_alias (_mcount, mcount)
diff --git a/ports/sysdeps/arm/armv6t2/memchr.S b/ports/sysdeps/arm/armv6t2/memchr.S
new file mode 100644
index 0000000000..69ea320e89
--- /dev/null
+++ b/ports/sysdeps/arm/armv6t2/memchr.S
@@ -0,0 +1,163 @@
+/* Copyright (C) 2011 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Code contributed by Dave Gilbert <david.gilbert@linaro.org>
+
+   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>
+
+@ This memchr routine is optimised on a Cortex-A9 and should work on all ARMv7
+@ and ARMv6T2 processors.  It has a fast path for short sizes, and has an
+@ optimised path for large data sets; the worst case is finding the match early
+@ in a large data set.
+@ Note: The use of cbz/cbnz means it's Thumb only
+
+@ 2011-07-15 david.gilbert@linaro.org
+@    Copy from Cortex strings release 21 and change license
+@ http://bazaar.launchpad.net/~linaro-toolchain-dev/cortex-strings/trunk/view/head:/src/linaro-a9/memchr.S
+@    Change function declarations/entry/exit
+@ 2011-12-01 david.gilbert@linaro.org
+@    Add some fixes from comments received (including use of ldrd instead ldm)
+@ 2011-12-07 david.gilbert@linaro.org
+@    Removed cbz from align loop - can't be taken
+
+@ this lets us check a flag in a 00/ff byte easily in either endianness
+#ifdef __ARMEB__
+#define CHARTSTMASK(c) 1<<(31-(c*8))
+#else
+#define CHARTSTMASK(c) 1<<(c*8)
+#endif
+	.syntax unified
+
+	.text
+	.thumb
+
+@ ---------------------------------------------------------------------------
+	.thumb_func
+	.global memchr
+	.type memchr,%function
+ENTRY(memchr)
+	@ r0 = start of memory to scan
+	@ r1 = character to look for
+	@ r2 = length
+	@ returns r0 = pointer to character or NULL if not found
+	and	r1,r1,#0xff	@ Don't think we can trust the caller to actually pass a char
+
+	cmp	r2,#16		@ If it's short don't bother with anything clever
+	blt	20f
+
+	tst	r0, #7		@ If it's already aligned skip the next bit
+	beq	10f
+
+	@ Work up to an aligned point
+5:
+	ldrb	r3, [r0],#1
+	subs	r2, r2, #1
+	cmp	r3, r1
+	beq	50f		@ If it matches exit found
+	tst	r0, #7
+	bne	5b		@ If not aligned yet then do next byte
+
+10:
+	@ At this point, we are aligned, we know we have at least 8 bytes to work with
+	push	{r4,r5,r6,r7}
+	cfi_adjust_cfa_offset (16)
+	cfi_rel_offset (r4, 0)
+	cfi_rel_offset (r5, 4)
+	cfi_rel_offset (r6, 8)
+	cfi_rel_offset (r7, 12)
+
+	cfi_remember_state
+
+	orr	r1, r1, r1, lsl #8	@ expand the match word across to all bytes
+	orr	r1, r1, r1, lsl #16
+	bic	r4, r2, #7	@ Number of double words to work with * 8
+	mvns	r7, #0		@ all F's
+	movs	r3, #0
+
+15:
+	ldrd 	r5,r6, [r0],#8
+	subs	r4, r4, #8
+	eor	r5,r5, r1	@ Get it so that r5,r6 have 00's where the bytes match the target
+	eor	r6,r6, r1
+	uadd8	r5, r5, r7	@ Parallel add 0xff - sets the GE bits for anything that wasn't 0
+	sel	r5, r3, r7	@ bytes are 00 for none-00 bytes, or ff for 00 bytes - NOTE INVERSION
+	uadd8	r6, r6, r7	@ Parallel add 0xff - sets the GE bits for anything that wasn't 0
+	sel	r6, r5, r7	@ chained....bytes are 00 for none-00 bytes, or ff for 00 bytes - NOTE INVERSION
+	cbnz	r6, 60f
+	bne	15b		@ (Flags from the subs above) If not run out of bytes then go around again
+
+	pop	{r4,r5,r6,r7}
+	cfi_adjust_cfa_offset (-16)
+	cfi_restore (r4)
+	cfi_restore (r5)
+	cfi_restore (r6)
+	cfi_restore (r7)
+
+	and	r1,r1,#0xff	@ Get r1 back to a single character from the expansion above
+	and	r2,r2,#7	@ Leave the count remaining as the number after the double words have been done
+
+20:
+	cbz	r2, 40f		@ 0 length or hit the end already then not found
+
+21:  @ Post aligned section, or just a short call
+	ldrb	r3,[r0],#1
+	subs	r2,r2,#1
+	eor	r3,r3,r1	@ r3 = 0 if match - doesn't break flags from sub
+	cbz	r3, 50f
+	bne	21b		@ on r2 flags
+
+40:
+	movs	r0,#0		@ not found
+	DO_RET(lr)
+
+50:
+	subs	r0,r0,#1	@ found
+	DO_RET(lr)
+
+60:  @ We're here because the fast path found a hit - now we have to track down exactly which word it was
+     @ r0 points to the start of the double word after the one that was tested
+     @ r5 has the 00/ff pattern for the first word, r6 has the chained value
+	cfi_restore_state
+	cmp	r5, #0
+	itte	eq
+	moveq	r5, r6		@ the end is in the 2nd word
+	subeq	r0,r0,#3	@ Points to 2nd byte of 2nd word
+	subne	r0,r0,#7	@ or 2nd byte of 1st word
+
+	@ r0 currently points to the 2nd byte of the word containing the hit
+	tst	r5, # CHARTSTMASK(0)	@ 1st character
+	bne	61f
+	adds	r0,r0,#1
+	tst	r5, # CHARTSTMASK(1)	@ 2nd character
+	ittt	eq
+	addeq	r0,r0,#1
+	tsteq	r5, # (3<<15)		@ 2nd & 3rd character
+	@ If not the 3rd must be the last one
+	addeq	r0,r0,#1
+
+61:
+	pop	{r4,r5,r6,r7}
+	cfi_adjust_cfa_offset (-16)
+	cfi_restore (r4)
+	cfi_restore (r5)
+	cfi_restore (r6)
+	cfi_restore (r7)
+
+	subs	r0,r0,#1
+	DO_RET(lr)
+
+END(memchr)
+libc_hidden_builtin_def (memchr)
diff --git a/ports/sysdeps/arm/armv7/Implies b/ports/sysdeps/arm/armv7/Implies
new file mode 100644
index 0000000000..c6cd0eb877
--- /dev/null
+++ b/ports/sysdeps/arm/armv7/Implies
@@ -0,0 +1,2 @@
+# We can do everything that 6T2 can
+arm/armv6t2
diff --git a/ports/sysdeps/arm/backtrace.c b/ports/sysdeps/arm/backtrace.c
new file mode 100644
index 0000000000..3d839e628c
--- /dev/null
+++ b/ports/sysdeps/arm/backtrace.c
@@ -0,0 +1,125 @@
+/* Return backtrace of current program state.
+   Copyright (C) 2008, 2009 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Kazu Hirata <kazu@codesourcery.com>, 2008.
+
+   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 <bits/libc-lock.h>
+#include <dlfcn.h>
+#include <execinfo.h>
+#include <stdlib.h>
+#include <unwind.h>
+
+struct trace_arg
+{
+  void **array;
+  int cnt, size;
+};
+
+#ifdef SHARED
+static _Unwind_Reason_Code (*unwind_backtrace) (_Unwind_Trace_Fn, void *);
+static _Unwind_VRS_Result (*unwind_vrs_get) (_Unwind_Context *,
+					     _Unwind_VRS_RegClass,
+					     _uw,
+					     _Unwind_VRS_DataRepresentation,
+					     void *);
+
+static void *libgcc_handle;
+
+static void
+init (void)
+{
+  libgcc_handle = __libc_dlopen ("libgcc_s.so.1");
+
+  if (libgcc_handle == NULL)
+    return;
+
+  unwind_backtrace = __libc_dlsym (libgcc_handle, "_Unwind_Backtrace");
+  unwind_vrs_get = __libc_dlsym (libgcc_handle, "_Unwind_VRS_Get");
+  if (unwind_vrs_get == NULL)
+    unwind_backtrace = NULL;
+}
+
+/* This function is identical to "_Unwind_GetGR", except that it uses
+   "unwind_vrs_get" instead of "_Unwind_VRS_Get".  */
+static inline _Unwind_Word
+unwind_getgr (_Unwind_Context *context, int regno)
+{
+  _uw val;
+  unwind_vrs_get (context, _UVRSC_CORE, regno, _UVRSD_UINT32, &val);
+  return val;
+}
+
+/* This macro is identical to the _Unwind_GetIP macro, except that it
+   uses "unwind_getgr" instead of "_Unwind_GetGR".  */
+# define unwind_getip(context) \
+  (unwind_getgr (context, 15) & ~(_Unwind_Word)1)
+#else
+# define unwind_backtrace _Unwind_Backtrace
+# define unwind_getip _Unwind_GetIP
+#endif
+
+static _Unwind_Reason_Code
+backtrace_helper (struct _Unwind_Context *ctx, void *a)
+{
+  struct trace_arg *arg = a;
+
+  /* We are first called with address in the __backtrace function.
+     Skip it.  */
+  if (arg->cnt != -1)
+    arg->array[arg->cnt] = (void *) unwind_getip (ctx);
+  if (++arg->cnt == arg->size)
+    return _URC_END_OF_STACK;
+  return _URC_NO_REASON;
+}
+
+int
+__backtrace (array, size)
+     void **array;
+     int size;
+{
+  struct trace_arg arg = { .array = array, .size = size, .cnt = -1 };
+#ifdef SHARED
+  __libc_once_define (static, once);
+
+  __libc_once (once, init);
+  if (unwind_backtrace == NULL)
+    return 0;
+#endif
+
+  if (size >= 1)
+    unwind_backtrace (backtrace_helper, &arg);
+
+  if (arg.cnt > 1 && arg.array[arg.cnt - 1] == NULL)
+    --arg.cnt;
+  return arg.cnt != -1 ? arg.cnt : 0;
+}
+weak_alias (__backtrace, backtrace)
+libc_hidden_def (__backtrace)
+
+
+#ifdef SHARED
+/* Free all resources if necessary.  */
+libc_freeres_fn (free_mem)
+{
+  unwind_backtrace = NULL;
+  if (libgcc_handle != NULL)
+    {
+      __libc_dlclose (libgcc_handle);
+      libgcc_handle = NULL;
+    }
+}
+#endif
diff --git a/ports/sysdeps/arm/bits/endian.h b/ports/sysdeps/arm/bits/endian.h
new file mode 100644
index 0000000000..f49f6ab1c9
--- /dev/null
+++ b/ports/sysdeps/arm/bits/endian.h
@@ -0,0 +1,10 @@
+#ifndef _ENDIAN_H
+# error "Never use <bits/endian.h> directly; include <endian.h> instead."
+#endif
+
+/* ARM can be either big or little endian.  */
+#ifdef __ARMEB__
+#define __BYTE_ORDER __BIG_ENDIAN
+#else
+#define __BYTE_ORDER __LITTLE_ENDIAN
+#endif
diff --git a/ports/sysdeps/arm/bits/fenv.h b/ports/sysdeps/arm/bits/fenv.h
new file mode 100644
index 0000000000..006ccf5288
--- /dev/null
+++ b/ports/sysdeps/arm/bits/fenv.h
@@ -0,0 +1,73 @@
+/* Copyright (C) 2004, 2005, 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.
+
+   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/>.  */
+
+#ifndef _FENV_H
+# error "Never use <bits/fenv.h> directly; include <fenv.h> instead."
+#endif
+
+/* Define bits representing exceptions in the FPU status word.  */
+enum
+  {
+    FE_INVALID = 1,
+#define FE_INVALID FE_INVALID
+    FE_DIVBYZERO = 2,
+#define FE_DIVBYZERO FE_DIVBYZERO
+    FE_OVERFLOW = 4,
+#define FE_OVERFLOW FE_OVERFLOW
+    FE_UNDERFLOW = 8,
+#define FE_UNDERFLOW FE_UNDERFLOW
+    FE_INEXACT = 16,
+#define FE_INEXACT FE_INEXACT
+  };
+
+/* Amount to shift by to convert an exception to a mask bit.  */
+#define FE_EXCEPT_SHIFT	8
+
+/* All supported exceptions.  */
+#define FE_ALL_EXCEPT	\
+	(FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW | FE_UNDERFLOW | FE_INEXACT)
+
+/* VFP supports all of the four defined rounding modes.  */
+enum
+  {
+    FE_TONEAREST = 0,
+#define FE_TONEAREST FE_TONEAREST
+    FE_UPWARD = 0x400000,
+#define FE_UPWARD FE_UPWARD
+    FE_DOWNWARD = 0x800000,
+#define FE_DOWNWARD FE_DOWNWARD
+    FE_TOWARDZERO = 0xc00000
+#define FE_TOWARDZERO FE_TOWARDZERO
+  };
+
+/* Type representing exception flags. */
+typedef unsigned int fexcept_t;
+
+/* Type representing floating-point environment.  */
+typedef struct
+  {
+    unsigned int __cw;
+  }
+fenv_t;
+
+/* If the default argument is used we use this value.  */
+#define FE_DFL_ENV	((fenv_t *) -1l)
+
+#ifdef __USE_GNU
+/* Floating-point environment where none of the exceptions are masked.  */
+# define FE_NOMASK_ENV  ((const fenv_t *) -2)
+#endif
diff --git a/ports/sysdeps/arm/bits/link.h b/ports/sysdeps/arm/bits/link.h
new file mode 100644
index 0000000000..37b94c509f
--- /dev/null
+++ b/ports/sysdeps/arm/bits/link.h
@@ -0,0 +1,65 @@
+/* Copyright (C) 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, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef	_LINK_H
+# error "Never include <bits/link.h> directly; use <link.h> instead."
+#endif
+
+
+/* Registers for entry into PLT on ARM.  */
+typedef struct La_arm_regs
+{
+  uint32_t lr_reg[4];
+  uint32_t lr_sp;
+  uint32_t lr_lr;
+  /* Coprocessor registers used for argument passing.  The data
+     stored here depends on the coprocessors available in the
+     system which are used for function calls in the current ABI.
+     VFP uses eight 64-bit registers, and iWMMXt uses ten.  */
+  uint32_t lr_coproc[42];
+} La_arm_regs;
+
+/* Return values for calls from PLT on ARM.  */
+typedef struct La_arm_retval
+{
+  /* Up to four integer registers can be used for a return value in
+     some ABIs (APCS complex long double).  */
+  uint32_t lrv_reg[4];
+
+  /* Any coprocessor registers which might be used to return values
+     in the current ABI.  */
+  uint32_t lrv_coproc[12];
+} La_arm_retval;
+
+
+__BEGIN_DECLS
+
+extern Elf32_Addr la_arm_gnu_pltenter (Elf32_Sym *__sym, unsigned int __ndx,
+				       uintptr_t *__refcook,
+				       uintptr_t *__defcook,
+				       La_arm_regs *__regs,
+				       unsigned int *__flags,
+				       const char *__symname,
+				       long int *__framesizep);
+extern unsigned int la_arm_gnu_pltexit (Elf32_Sym *__sym, unsigned int __ndx,
+					uintptr_t *__refcook,
+					uintptr_t *__defcook,
+					const La_arm_regs *__inregs,
+					La_arm_retval *__outregs,
+					const char *__symname);
+
+__END_DECLS
diff --git a/ports/sysdeps/arm/bits/linkmap.h b/ports/sysdeps/arm/bits/linkmap.h
new file mode 100644
index 0000000000..7c2b4a6da8
--- /dev/null
+++ b/ports/sysdeps/arm/bits/linkmap.h
@@ -0,0 +1,5 @@
+struct link_map_machine
+  {
+    Elf32_Addr plt; /* Address of .plt */
+    void *tlsdesc_table; /* Address of TLS descriptor hash table.  */
+  };
diff --git a/ports/sysdeps/arm/bits/mathdef.h b/ports/sysdeps/arm/bits/mathdef.h
new file mode 100644
index 0000000000..37e9226745
--- /dev/null
+++ b/ports/sysdeps/arm/bits/mathdef.h
@@ -0,0 +1,56 @@
+/* Copyright (C) 1999, 2000, 2004, 2006, 2007, 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, see
+   <http://www.gnu.org/licenses/>.  */
+
+#if !defined _MATH_H && !defined _COMPLEX_H
+# error "Never use <bits/mathdef.h> directly; include <math.h> instead"
+#endif
+
+#if defined  __USE_ISOC99 && defined _MATH_H && !defined _MATH_H_MATHDEF
+# define _MATH_H_MATHDEF	1
+
+/* GCC does not promote `float' values to `double'.  */
+typedef float float_t;		/* `float' expressions are evaluated as
+				   `float'.  */
+typedef double double_t;	/* `double' expressions are evaluated as
+				   `double'.  */
+
+/* The values returned by `ilogb' for 0 and NaN respectively.  */
+# define FP_ILOGB0	(-2147483647)
+# define FP_ILOGBNAN	(2147483647)
+
+/* The GCC 4.6 compiler will define __FP_FAST_FMA{,F,L} if the fma{,f,l}
+   builtins are supported.  */
+# if __FP_FAST_FMA
+#  define FP_FAST_FMA 1
+# endif
+
+# if __FP_FAST_FMAF
+#  define FP_FAST_FMAF 1
+# endif
+
+# if __FP_FAST_FMAL
+#  define FP_FAST_FMAL 1
+# endif
+
+#endif	/* ISO C99 */
+
+#ifndef __NO_LONG_DOUBLE_MATH
+/* Signal that we do not really have a `long double'.  This disables the
+   declaration of all the `long double' function variants.  */
+# define __NO_LONG_DOUBLE_MATH	1
+#endif
diff --git a/ports/sysdeps/arm/bits/setjmp.h b/ports/sysdeps/arm/bits/setjmp.h
new file mode 100644
index 0000000000..bdc41ce86e
--- /dev/null
+++ b/ports/sysdeps/arm/bits/setjmp.h
@@ -0,0 +1,37 @@
+/* Copyright (C) 2004, 2005, 2006, 2009 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   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/>.  */
+
+/* Define the machine-dependent type `jmp_buf'.  ARM EABI version.  */
+
+#ifndef _BITS_SETJMP_H
+#define _BITS_SETJMP_H 1
+
+#if !defined _SETJMP_H && !defined _PTHREAD_H
+# error "Never include <bits/setjmp.h> directly; use <setjmp.h> instead."
+#endif
+
+#ifndef _ASM
+/* The exact set of registers saved may depend on the particular core
+   in use, as some coprocessor registers may need to be saved.  The C
+   Library ABI requires that the buffer be 8-byte aligned, and
+   recommends that the buffer contain 64 words.  The first 28 words
+   are occupied by v1-v6, sl, fp, sp, pc, d8-d15, and fpscr.  (Note
+   that d8-15 require 17 words, due to the use of fstmx.)  */
+typedef int __jmp_buf[64] __attribute__((__aligned__ (8)));
+#endif
+
+#endif
diff --git a/ports/sysdeps/arm/bsd-_setjmp.S b/ports/sysdeps/arm/bsd-_setjmp.S
new file mode 100644
index 0000000000..d27ef94425
--- /dev/null
+++ b/ports/sysdeps/arm/bsd-_setjmp.S
@@ -0,0 +1,29 @@
+/* BSD `_setjmp' entry point to `sigsetjmp (..., 0)'.  ARM version.
+   Copyright (C) 1997, 1998, 2002, 2008 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+/* This just does a tail-call to `__sigsetjmp (ARG, 1)'.
+   We cannot do it in C because it must be a tail-call, so frame-unwinding
+   in setjmp doesn't clobber the state restored by longjmp.  */
+
+#include <sysdep.h>
+
+ENTRY (_setjmp)
+	mov	r1, #0
+	b	PLTJMP(HIDDEN_JUMPTARGET(__sigsetjmp))
+END (_setjmp)
+libc_hidden_def (_setjmp)
diff --git a/ports/sysdeps/arm/bsd-setjmp.S b/ports/sysdeps/arm/bsd-setjmp.S
new file mode 100644
index 0000000000..bc2097e79a
--- /dev/null
+++ b/ports/sysdeps/arm/bsd-setjmp.S
@@ -0,0 +1,28 @@
+/* BSD `setjmp' entry point to `sigsetjmp (..., 1)'.  ARM version.
+   Copyright (C) 1997, 1998, 2008 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+/* This just does a tail-call to `__sigsetjmp (ARG, 1)'.
+   We cannot do it in C because it must be a tail-call, so frame-unwinding
+   in setjmp doesn't clobber the state restored by longjmp.  */
+
+#include <sysdep.h>
+
+ENTRY (setjmp)
+	mov	r1, #1
+	b	PLTJMP(HIDDEN_JUMPTARGET(__sigsetjmp))
+END (setjmp)
diff --git a/ports/sysdeps/arm/configure b/ports/sysdeps/arm/configure
new file mode 100755
index 0000000000..665151fead
--- /dev/null
+++ b/ports/sysdeps/arm/configure
@@ -0,0 +1,335 @@
+
+# as_fn_set_status STATUS
+# -----------------------
+# Set $? to STATUS, without forking.
+as_fn_set_status ()
+{
+  return $1
+} # as_fn_set_status
+
+# as_fn_exit STATUS
+# -----------------
+# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
+as_fn_exit ()
+{
+  set +e
+  as_fn_set_status $1
+  exit $1
+} # as_fn_exit
+# as_fn_arith ARG...
+# ------------------
+# Perform arithmetic evaluation on the ARGs, and store the result in the
+# global $as_val. Take advantage of shells that can avoid forks. The arguments
+# must be portable across $(()) and expr.
+if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
+  eval 'as_fn_arith ()
+  {
+    as_val=$(( $* ))
+  }'
+else
+  as_fn_arith ()
+  {
+    as_val=`expr "$@" || test $? -eq 1`
+  }
+fi # as_fn_arith
+
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+   test "X`expr 00001 : '.*\(...\)'`" = X001; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
+  as_basename=basename
+else
+  as_basename=false
+fi
+
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+	 X"$0" : 'X\(//\)$' \| \
+	 X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X/"$0" |
+    sed '/^.*\/\([^/][^/]*\)\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\/\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\/\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+
+
+  as_lineno_1=$LINENO as_lineno_1a=$LINENO
+  as_lineno_2=$LINENO as_lineno_2a=$LINENO
+  eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" &&
+  test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || {
+  # Blame Lee E. McMahon (1931-1989) for sed's syntax.  :-)
+  sed -n '
+    p
+    /[$]LINENO/=
+  ' <$as_myself |
+    sed '
+      s/[$]LINENO.*/&-/
+      t lineno
+      b
+      :lineno
+      N
+      :loop
+      s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/
+      t loop
+      s/-\n.*//
+    ' >$as_me.lineno &&
+  chmod +x "$as_me.lineno" ||
+    { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; }
+
+  # Don't try to exec as it changes $[0], causing all sort of problems
+  # (the dirname of $[0] is not the place where we might find the
+  # original and so on.  Autoconf is especially sensitive to this).
+  . "./$as_me.lineno"
+  # Exit status is that of the last command.
+  exit
+}
+
+# This file is generated from configure.in by Autoconf.  DO NOT EDIT!
+ # Local configure fragment for sysdeps/arm.
+
+# Check for support of thread-local storage handling in assembler and
+# linker.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ARM TLS support" >&5
+$as_echo_n "checking for ARM TLS support... " >&6; }
+if ${libc_cv_arm_tls+:} false; 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
+.word	foo(tpoff)
+.word	foo(tlsgd)
+EOF
+if { ac_try='${CC-cc} -c $CFLAGS conftest.s 1>&5'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then
+  libc_cv_arm_tls=yes
+else
+  libc_cv_arm_tls=no
+fi
+rm -f conftest*
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_arm_tls" >&5
+$as_echo "$libc_cv_arm_tls" >&6; }
+if test $libc_cv_arm_tls = no; then
+  as_fn_error $? "the assembler must support TLS" "$LINENO" 5
+fi
+
+#AC_DEFINE(PI_STATIC_AND_HIDDEN)
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the CFI directive .cfi_sections is supported" >&5
+$as_echo_n "checking whether the CFI directive .cfi_sections is supported... " >&6; }
+if ${libc_cv_asm_cfi_directive_sections+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat > conftest.s <<EOF
+	.text
+	.cfi_sections .debug_frame, .eh_frame
+	.cfi_startproc
+	.cfi_endproc
+EOF
+  if { ac_try='${CC-cc} $ASFLAGS -c conftest.s 1>&5'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then
+    libc_cv_asm_cfi_directive_sections=yes
+  else
+    libc_cv_asm_cfi_directive_sections=no
+  fi
+  rm -f conftest*
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_asm_cfi_directive_sections" >&5
+$as_echo "$libc_cv_asm_cfi_directive_sections" >&6; }
+if test $libc_cv_asm_cfi_directive_sections != yes; then
+  as_fn_error $? "need .cfi_sections in this configuration" "$LINENO" 5
+fi
+
+# We check to see if the compiler and flags are
+# selecting the hard-float ABI and if they are then
+# we set libc_cv_arm_pcs_vfp to yes which causes
+# HAVE_ARM_PCS_VFP to be defined in config.h and
+# in include/libc-symbols.h and thus available to
+# shlib-versions to select the appropriate name for
+# the dynamic linker via %ifdef.
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5
+$as_echo_n "checking for grep that handles long lines and -e... " >&6; }
+if ${ac_cv_path_GREP+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -z "$GREP"; then
+  ac_path_GREP_found=false
+  # Loop through the user's path and test for each of PROGNAME-LIST
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_prog in grep ggrep; do
+    for ac_exec_ext in '' $ac_executable_extensions; do
+      ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext"
+      { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue
+# Check for GNU ac_path_GREP and select it if it is found.
+  # Check for GNU $ac_path_GREP
+case `"$ac_path_GREP" --version 2>&1` in
+*GNU*)
+  ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;;
+*)
+  ac_count=0
+  $as_echo_n 0123456789 >"conftest.in"
+  while :
+  do
+    cat "conftest.in" "conftest.in" >"conftest.tmp"
+    mv "conftest.tmp" "conftest.in"
+    cp "conftest.in" "conftest.nl"
+    $as_echo 'GREP' >> "conftest.nl"
+    "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+    as_fn_arith $ac_count + 1 && ac_count=$as_val
+    if test $ac_count -gt ${ac_path_GREP_max-0}; then
+      # Best one so far, save it but keep looking for a better one
+      ac_cv_path_GREP="$ac_path_GREP"
+      ac_path_GREP_max=$ac_count
+    fi
+    # 10*(2^10) chars as input seems more than enough
+    test $ac_count -gt 10 && break
+  done
+  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+      $ac_path_GREP_found && break 3
+    done
+  done
+  done
+IFS=$as_save_IFS
+  if test -z "$ac_cv_path_GREP"; then
+    as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+  fi
+else
+  ac_cv_path_GREP=$GREP
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5
+$as_echo "$ac_cv_path_GREP" >&6; }
+ GREP="$ac_cv_path_GREP"
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5
+$as_echo_n "checking for egrep... " >&6; }
+if ${ac_cv_path_EGREP+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if echo a | $GREP -E '(a|b)' >/dev/null 2>&1
+   then ac_cv_path_EGREP="$GREP -E"
+   else
+     if test -z "$EGREP"; then
+  ac_path_EGREP_found=false
+  # Loop through the user's path and test for each of PROGNAME-LIST
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_prog in egrep; do
+    for ac_exec_ext in '' $ac_executable_extensions; do
+      ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext"
+      { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue
+# Check for GNU ac_path_EGREP and select it if it is found.
+  # Check for GNU $ac_path_EGREP
+case `"$ac_path_EGREP" --version 2>&1` in
+*GNU*)
+  ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;;
+*)
+  ac_count=0
+  $as_echo_n 0123456789 >"conftest.in"
+  while :
+  do
+    cat "conftest.in" "conftest.in" >"conftest.tmp"
+    mv "conftest.tmp" "conftest.in"
+    cp "conftest.in" "conftest.nl"
+    $as_echo 'EGREP' >> "conftest.nl"
+    "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+    as_fn_arith $ac_count + 1 && ac_count=$as_val
+    if test $ac_count -gt ${ac_path_EGREP_max-0}; then
+      # Best one so far, save it but keep looking for a better one
+      ac_cv_path_EGREP="$ac_path_EGREP"
+      ac_path_EGREP_max=$ac_count
+    fi
+    # 10*(2^10) chars as input seems more than enough
+    test $ac_count -gt 10 && break
+  done
+  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+      $ac_path_EGREP_found && break 3
+    done
+  done
+  done
+IFS=$as_save_IFS
+  if test -z "$ac_cv_path_EGREP"; then
+    as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+  fi
+else
+  ac_cv_path_EGREP=$EGREP
+fi
+
+   fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5
+$as_echo "$ac_cv_path_EGREP" >&6; }
+ EGREP="$ac_cv_path_EGREP"
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the compiler is using the ARM hard-float ABI" >&5
+$as_echo_n "checking whether the compiler is using the ARM hard-float ABI... " >&6; }
+if ${libc_cv_arm_pcs_vfp+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#ifdef __ARM_PCS_VFP
+                      yes
+                     #endif
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "yes" >/dev/null 2>&1; then :
+  libc_cv_arm_pcs_vfp=yes
+else
+  libc_cv_arm_pcs_vfp=no
+fi
+rm -f conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_arm_pcs_vfp" >&5
+$as_echo "$libc_cv_arm_pcs_vfp" >&6; }
+if test $libc_cv_arm_pcs_vfp = yes; then
+  $as_echo "#define HAVE_ARM_PCS_VFP 1" >>confdefs.h
+
+fi
diff --git a/ports/sysdeps/arm/configure.in b/ports/sysdeps/arm/configure.in
new file mode 100644
index 0000000000..64cef5f94e
--- /dev/null
+++ b/ports/sysdeps/arm/configure.in
@@ -0,0 +1,68 @@
+GLIBC_PROVIDES dnl See aclocal.m4 in the top level source directory.
+# Local configure fragment for sysdeps/arm.
+
+# Check for support of thread-local storage handling in assembler and
+# linker.
+AC_CACHE_CHECK(for ARM TLS support, libc_cv_arm_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
+.word	foo(tpoff)
+.word	foo(tlsgd)
+EOF
+dnl
+if AC_TRY_COMMAND(${CC-cc} -c $CFLAGS conftest.s 1>&AS_MESSAGE_LOG_FD); then
+  libc_cv_arm_tls=yes
+else
+  libc_cv_arm_tls=no
+fi
+rm -f conftest*])
+if test $libc_cv_arm_tls = no; then
+  AC_MSG_ERROR([the assembler must support TLS])
+fi
+
+dnl It is always possible to access static and hidden symbols in an
+dnl position independent way.
+dnl NOTE: This feature was added by the GCC TLS patches.  We should test for
+dnl it.  Until we do, don't define it.
+#AC_DEFINE(PI_STATIC_AND_HIDDEN)
+
+AC_CACHE_CHECK([whether the CFI directive .cfi_sections is supported],
+  [libc_cv_asm_cfi_directive_sections],
+  [cat > conftest.s <<EOF
+	.text
+	.cfi_sections .debug_frame, .eh_frame
+	.cfi_startproc
+	.cfi_endproc
+EOF
+  if AC_TRY_COMMAND(${CC-cc} $ASFLAGS -c conftest.s 1>&AS_MESSAGE_LOG_FD); then
+    libc_cv_asm_cfi_directive_sections=yes
+  else
+    libc_cv_asm_cfi_directive_sections=no
+  fi
+  rm -f conftest*])
+if test $libc_cv_asm_cfi_directive_sections != yes; then
+  AC_MSG_ERROR([need .cfi_sections in this configuration])
+fi
+
+# We check to see if the compiler and flags are
+# selecting the hard-float ABI and if they are then
+# we set libc_cv_arm_pcs_vfp to yes which causes
+# HAVE_ARM_PCS_VFP to be defined in config.h and
+# in include/libc-symbols.h and thus available to
+# shlib-versions to select the appropriate name for
+# the dynamic linker via %ifdef.
+AC_CACHE_CHECK([whether the compiler is using the ARM hard-float ABI],
+  [libc_cv_arm_pcs_vfp],
+  [AC_EGREP_CPP(yes,[#ifdef __ARM_PCS_VFP
+                      yes
+                     #endif
+  ], libc_cv_arm_pcs_vfp=yes, libc_cv_arm_pcs_vfp=no)])
+if test $libc_cv_arm_pcs_vfp = yes; then
+  AC_DEFINE(HAVE_ARM_PCS_VFP)
+fi
diff --git a/ports/sysdeps/arm/crti.S b/ports/sysdeps/arm/crti.S
new file mode 100644
index 0000000000..a203d6a22c
--- /dev/null
+++ b/ports/sysdeps/arm/crti.S
@@ -0,0 +1,93 @@
+/* Special .init and .fini section support for ARM.
+   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:
+	ldr r3, .LGOT
+	ldr r2, .LGOT+4
+.LPIC:
+	add r3, pc, r3
+	ldr r2, [r3, r2]
+	cmp r2, #0
+	bxeq lr
+	b PREINIT_FUNCTION
+	.p2align 2
+.LGOT:
+	.word _GLOBAL_OFFSET_TABLE_-(.LPIC+8)
+	.word PREINIT_FUNCTION(GOT)
+#endif
+
+	.section .init,"ax",%progbits
+	.p2align 2
+	.globl _init
+	.type _init, %function
+_init:
+	stmfd sp!, {r3, lr}
+#if PREINIT_FUNCTION_WEAK
+	bl call_weak_fn
+#else
+	bl PREINIT_FUNCTION
+#endif
+
+	.section .fini,"ax",%progbits
+	.p2align 2
+	.globl _fini
+	.type _fini, %function
+_fini:
+	stmfd sp!, {r3, lr}
diff --git a/ports/sysdeps/arm/crtn.S b/ports/sysdeps/arm/crtn.S
new file mode 100644
index 0000000000..28e3153108
--- /dev/null
+++ b/ports/sysdeps/arm/crtn.S
@@ -0,0 +1,55 @@
+/* Special .init and .fini section support for ARM.
+   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
+#ifdef __ARM_ARCH_4T__
+	ldmfd sp!, {r3, lr}
+	bx lr
+#else
+	ldmfd sp!, {r3, pc}
+#endif
+
+	.section .fini,"ax",%progbits
+#ifdef __ARM_ARCH_4T__
+	ldmfd sp!, {r3, lr}
+	bx lr
+#else
+	ldmfd sp!, {r3, pc}
+#endif
diff --git a/ports/sysdeps/arm/dl-irel.h b/ports/sysdeps/arm/dl-irel.h
new file mode 100644
index 0000000000..5b1964e90e
--- /dev/null
+++ b/ports/sysdeps/arm/dl-irel.h
@@ -0,0 +1,51 @@
+/* Machine-dependent ELF indirect relocation inline functions.
+   ARM version.
+   Copyright (C) 2009, 2010, 2011 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef _DL_IREL_H
+#define _DL_IREL_H
+
+#include <stdio.h>
+#include <unistd.h>
+
+#define ELF_MACHINE_IREL	1
+
+static inline Elf32_Addr
+__attribute ((always_inline))
+elf_ifunc_invoke (Elf32_Addr addr)
+{
+  return ((Elf32_Addr (*) (unsigned long int)) (addr)) (GLRO(dl_hwcap));
+}
+
+static inline void
+__attribute ((always_inline))
+elf_irel (const Elf32_Rel *reloc)
+{
+  Elf32_Addr *const reloc_addr = (void *) reloc->r_offset;
+  const unsigned long int r_type = ELF32_R_TYPE (reloc->r_info);
+
+  if (__builtin_expect (r_type == R_ARM_IRELATIVE, 1))
+    {
+      Elf32_Addr value = elf_ifunc_invoke (*reloc_addr);
+      *reloc_addr = value;
+    }
+  else
+    __libc_fatal ("unexpected reloc type in static binary");
+}
+
+#endif /* dl-irel.h */
diff --git a/ports/sysdeps/arm/dl-lookupcfg.h b/ports/sysdeps/arm/dl-lookupcfg.h
new file mode 100644
index 0000000000..bf3acd07c1
--- /dev/null
+++ b/ports/sysdeps/arm/dl-lookupcfg.h
@@ -0,0 +1,27 @@
+/* Configuration of lookup functions.
+   Copyright (C) 2006, 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, see
+   <http://www.gnu.org/licenses/>.  */
+
+#define DL_UNMAP_IS_SPECIAL
+
+#include_next <dl-lookupcfg.h>
+
+struct link_map;
+
+extern void internal_function _dl_unmap (struct link_map *map);
+
+#define DL_UNMAP(map) _dl_unmap (map)
diff --git a/ports/sysdeps/arm/dl-machine.h b/ports/sysdeps/arm/dl-machine.h
new file mode 100644
index 0000000000..8d905e8ad9
--- /dev/null
+++ b/ports/sysdeps/arm/dl-machine.h
@@ -0,0 +1,694 @@
+/* Machine-dependent ELF dynamic relocation inline functions.  ARM version.
+   Copyright (C) 1995,1996,1997,1998,1999,2000,2001,2002,2003,2004,2005,
+	2006, 2009, 2010, 2011 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef dl_machine_h
+#define dl_machine_h
+
+#define ELF_MACHINE_NAME "ARM"
+
+#include <sys/param.h>
+#include <tls.h>
+#include <dl-tlsdesc.h>
+#include <dl-irel.h>
+
+#define CLEAR_CACHE(BEG,END)						\
+  INTERNAL_SYSCALL_ARM (cacheflush, , 3, (BEG), (END), 0)
+
+/* Return nonzero iff ELF header is compatible with the running host.  */
+static inline int __attribute__ ((unused))
+elf_machine_matches_host (const Elf32_Ehdr *ehdr)
+{
+  return ehdr->e_machine == EM_ARM;
+}
+
+
+/* Return the link-time address of _DYNAMIC.  Conveniently, this is the
+   first element of the GOT.  We used to use the PIC register to do this
+   without a constant pool reference, but GCC 4.2 will use a pseudo-register
+   for the PIC base, so it may not be in r10.  */
+static inline Elf32_Addr __attribute__ ((unused))
+elf_machine_dynamic (void)
+{
+  Elf32_Addr dynamic;
+#ifdef __thumb2__
+  long tmp;
+  asm ("ldr\t%0, 1f\n\t"
+       "adr\t%1, 1f\n\t"
+       "ldr\t%0, [%0, %1]\n\t"
+       "b 2f\n"
+       ".align 2\n"
+       "1: .word _GLOBAL_OFFSET_TABLE_ - 1b\n"
+       "2:" : "=r" (dynamic), "=r"(tmp));
+#else
+  asm ("ldr %0, 2f\n"
+       "1: ldr %0, [pc, %0]\n"
+       "b 3f\n"
+       "2: .word _GLOBAL_OFFSET_TABLE_ - (1b+8)\n"
+       "3:" : "=r" (dynamic));
+#endif
+  return dynamic;
+}
+
+
+/* Return the run-time load address of the shared object.  */
+static inline Elf32_Addr __attribute__ ((unused))
+elf_machine_load_address (void)
+{
+  extern void __dl_start asm ("_dl_start");
+  Elf32_Addr got_addr = (Elf32_Addr) &__dl_start;
+  Elf32_Addr pcrel_addr;
+#ifdef __thumb__
+  /* Clear the low bit of the funciton address.  */
+  got_addr &= ~(Elf32_Addr) 1;
+#endif
+  asm ("adr %0, _dl_start" : "=r" (pcrel_addr));
+  return pcrel_addr - got_addr;
+}
+
+
+/* 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.  */
+
+static inline int __attribute__ ((unused))
+elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
+{
+  Elf32_Addr *got;
+  extern void _dl_runtime_resolve (Elf32_Word);
+  extern void _dl_runtime_profile (Elf32_Word);
+
+  if (l->l_info[DT_JMPREL] && lazy)
+    {
+      /* patb: this is different than i386 */
+      /* The GOT entries for functions in the PLT have not yet been filled
+	 in.  Their initial contents will arrange when called to push an
+	 index into the .got section, load ip with &_GLOBAL_OFFSET_TABLE_[3],
+	 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.  */
+      if (got[1])
+	l->l_mach.plt = got[1] + l->l_addr;
+      got[1] = (Elf32_Addr) l;	/* Identify this shared object.  */
+
+      /* The got[2] entry contains the address of a function which gets
+	 called to get the address of a so far unresolved function and
+	 jump to it.  The profiling extension of the dynamic linker allows
+	 to intercept the calls to collect information.  In this case we
+	 don't store the address in the GOT so that all future calls also
+	 end in this function.  */
+      if (profile)
+	{
+	  got[2] = (Elf32_Addr) &_dl_runtime_profile;
+
+	  if (GLRO(dl_profile) != NULL
+	      && _dl_name_match_p (GLRO(dl_profile), l))
+	    /* Say that we really want profiling and the timers are
+	       started.  */
+	    GL(dl_profile_map) = l;
+	}
+      else
+	/* This function will get called to fix up the GOT entry indicated by
+	   the offset on the stack, and then jump to the resolved address.  */
+	got[2] = (Elf32_Addr) &_dl_runtime_resolve;
+    }
+
+  if (l->l_info[ADDRIDX (DT_TLSDESC_GOT)] && lazy)
+    *(Elf32_Addr*)(D_PTR (l, l_info[ADDRIDX (DT_TLSDESC_GOT)]) + l->l_addr)
+      = (Elf32_Addr) &_dl_tlsdesc_lazy_resolver;
+
+  return lazy;
+}
+
+#if defined(__USE_BX__)
+#define BX(x) "bx\t" #x
+#else
+#define BX(x) "mov\tpc, " #x
+#endif
+
+/* Mask identifying addresses reserved for the user program,
+   where the dynamic linker should not map anything.  */
+#define ELF_MACHINE_USER_ADDRESS_MASK	0xf8000000UL
+
+/* 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 ("\
+.text\n\
+.globl _start\n\
+.type _start, %function\n\
+.globl _dl_start_user\n\
+.type _dl_start_user, %function\n\
+_start:\n\
+	@ we are PIC code, so get global offset table\n\
+	ldr	sl, .L_GET_GOT\n\
+	@ See if we were run as a command with the executable file\n\
+	@ name as an extra leading argument.\n\
+	ldr	r4, .L_SKIP_ARGS\n\
+	@ at start time, all the args are on the stack\n\
+	mov	r0, sp\n\
+	bl	_dl_start\n\
+	@ returns user entry point in r0\n\
+_dl_start_user:\n\
+	adr	r6, .L_GET_GOT\n\
+	add	sl, sl, r6\n\
+	ldr	r4, [sl, r4]\n\
+	@ save the entry point in another register\n\
+	mov	r6, r0\n\
+	@ get the original arg count\n\
+	ldr	r1, [sp]\n\
+	@ get the argv address\n\
+	add	r2, sp, #4\n\
+	@ Fix up the stack if necessary.\n\
+	cmp	r4, #0\n\
+	bne	.L_fixup_stack\n\
+.L_done_fixup:\n\
+	@ compute envp\n\
+	add	r3, r2, r1, lsl #2\n\
+	add	r3, r3, #4\n\
+	@ now we call _dl_init\n\
+	ldr	r0, .L_LOADED\n\
+	ldr	r0, [sl, r0]\n\
+	@ call _dl_init\n\
+	bl	_dl_init_internal(PLT)\n\
+	@ load the finalizer function\n\
+	ldr	r0, .L_FINI_PROC\n\
+	add	r0, sl, r0\n\
+	@ jump to the user_s entry point\n\
+	" BX(r6) "\n\
+\n\
+	@ iWMMXt and EABI targets require the stack to be eight byte\n\
+	@ aligned - shuffle arguments etc.\n\
+.L_fixup_stack:\n\
+	@ subtract _dl_skip_args from original arg count\n\
+	sub	r1, r1, r4\n\
+	@ store the new argc in the new stack location\n\
+	str	r1, [sp]\n\
+	@ find the first unskipped argument\n\
+	mov	r3, r2\n\
+	add	r4, r2, r4, lsl #2\n\
+	@ shuffle argv down\n\
+1:	ldr	r5, [r4], #4\n\
+	str	r5, [r3], #4\n\
+	cmp	r5, #0\n\
+	bne	1b\n\
+	@ shuffle envp down\n\
+1:	ldr	r5, [r4], #4\n\
+	str	r5, [r3], #4\n\
+	cmp	r5, #0\n\
+	bne	1b\n\
+	@ shuffle auxv down\n\
+1:	ldmia	r4!, {r0, r5}\n\
+	stmia	r3!, {r0, r5}\n\
+	cmp	r0, #0\n\
+	bne	1b\n\
+	@ Update _dl_argv\n\
+	ldr	r3, .L_ARGV\n\
+	str	r2, [sl, r3]\n\
+	b	.L_done_fixup\n\
+\n\
+.L_GET_GOT:\n\
+	.word	_GLOBAL_OFFSET_TABLE_ - .L_GET_GOT\n\
+.L_SKIP_ARGS:\n\
+	.word	_dl_skip_args(GOTOFF)\n\
+.L_FINI_PROC:\n\
+	.word	_dl_fini(GOTOFF)\n\
+.L_ARGV:\n\
+	.word	_dl_argv(GOTOFF)\n\
+.L_LOADED:\n\
+	.word	_rtld_local(GOTOFF)\n\
+.previous\n\
+");
+
+/* ELF_RTYPE_CLASS_PLT iff TYPE describes relocation of a PLT entry or
+   TLS variable, so undefined references 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.  */
+#ifndef RTLD_BOOTSTRAP
+# define elf_machine_type_class(type) \
+  ((((type) == R_ARM_JUMP_SLOT || (type) == R_ARM_TLS_DTPMOD32		\
+     || (type) == R_ARM_TLS_DTPOFF32 || (type) == R_ARM_TLS_TPOFF32	\
+     || (type) == R_ARM_TLS_DESC)					\
+    * ELF_RTYPE_CLASS_PLT)						\
+   | (((type) == R_ARM_COPY) * ELF_RTYPE_CLASS_COPY))
+#else
+#define elf_machine_type_class(type) \
+  ((((type) == R_ARM_JUMP_SLOT) * ELF_RTYPE_CLASS_PLT)	\
+   | (((type) == R_ARM_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_ARM_JUMP_SLOT
+
+/* ARM never uses Elf32_Rela relocations for the dynamic linker.
+   Prelinked libraries may use Elf32_Rela though.  */
+#define ELF_MACHINE_PLT_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)
+{
+  if (GLRO(dl_platform) != NULL && *GLRO(dl_platform) == '\0')
+    /* Avoid an empty string which would disturb us.  */
+    GLRO(dl_platform) = NULL;
+}
+
+static inline Elf32_Addr
+elf_machine_fixup_plt (struct link_map *map, lookup_t t,
+		       const Elf32_Rel *reloc,
+		       Elf32_Addr *reloc_addr, Elf32_Addr value)
+{
+  return *reloc_addr = value;
+}
+
+/* Return the final value of a plt relocation.  */
+static inline Elf32_Addr
+elf_machine_plt_value (struct link_map *map, const Elf32_Rel *reloc,
+		       Elf32_Addr value)
+{
+  return value;
+}
+
+#endif /* !dl_machine_h */
+
+
+/* ARM never uses Elf32_Rela relocations for the dynamic linker.
+   Prelinked libraries may use Elf32_Rela though.  */
+#define ELF_MACHINE_NO_RELA defined RTLD_BOOTSTRAP
+
+/* Names of the architecture-specific auditing callback functions.  */
+#define ARCH_LA_PLTENTER arm_gnu_pltenter
+#define ARCH_LA_PLTEXIT arm_gnu_pltexit
+
+#ifdef RESOLVE_MAP
+
+/* Deal with an out-of-range PC24 reloc.  */
+auto Elf32_Addr
+fix_bad_pc24 (Elf32_Addr *const reloc_addr, Elf32_Addr value)
+{
+  static void *fix_page;
+  static unsigned int fix_offset;
+  static size_t pagesize;
+  Elf32_Word *fix_address;
+
+  if (! fix_page)
+    {
+      if (! pagesize)
+	pagesize = getpagesize ();
+      fix_page = mmap (NULL, pagesize, PROT_READ | PROT_WRITE | PROT_EXEC,
+		       MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+      if (! fix_page)
+	assert (! "could not map page for fixup");
+      fix_offset = 0;
+    }
+
+  fix_address = (Elf32_Word *)(fix_page + fix_offset);
+  fix_address[0] = 0xe51ff004;	/* ldr pc, [pc, #-4] */
+  fix_address[1] = value;
+
+  fix_offset += 8;
+  if (fix_offset >= pagesize)
+    fix_page = NULL;
+
+  return (Elf32_Addr)fix_address;
+}
+
+/* Perform the relocation specified by RELOC and SYM (which is fully resolved).
+   MAP is the object containing the reloc.  */
+
+auto inline void
+__attribute__ ((always_inline))
+elf_machine_rel (struct link_map *map, const Elf32_Rel *reloc,
+		 const Elf32_Sym *sym, const struct r_found_version *version,
+		 void *const reloc_addr_arg, int skip_ifunc)
+{
+  Elf32_Addr *const reloc_addr = reloc_addr_arg;
+  const unsigned int r_type = ELF32_R_TYPE (reloc->r_info);
+
+#if !defined RTLD_BOOTSTRAP || !defined HAVE_Z_COMBRELOC
+  if (__builtin_expect (r_type == R_ARM_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.  */
+#  ifndef SHARED
+      weak_extern (_dl_rtld_map);
+#  endif
+      if (map != &GL(dl_rtld_map)) /* Already done in rtld itself.  */
+# endif
+	*reloc_addr += map->l_addr;
+    }
+# ifndef RTLD_BOOTSTRAP
+  else if (__builtin_expect (r_type == R_ARM_NONE, 0))
+    return;
+# endif
+  else
+#endif
+    {
+      const Elf32_Sym *const refsym = sym;
+      struct link_map *sym_map = RESOLVE_MAP (&sym, version, r_type);
+      Elf32_Addr value = sym_map == NULL ? 0 : sym_map->l_addr + sym->st_value;
+
+      if (sym != NULL
+	  && __builtin_expect (ELFW(ST_TYPE) (sym->st_info) == STT_GNU_IFUNC, 0)
+	  && __builtin_expect (sym->st_shndx != SHN_UNDEF, 1)
+	  && __builtin_expect (!skip_ifunc, 1))
+	value = elf_ifunc_invoke (value);
+
+      switch (r_type)
+	{
+	case R_ARM_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",
+				rtld_progname ?: "<program name unknown>",
+				strtab + refsym->st_name);
+	    }
+	  memcpy (reloc_addr_arg, (void *) value,
+		  MIN (sym->st_size, refsym->st_size));
+	  break;
+	case R_ARM_GLOB_DAT:
+	case R_ARM_JUMP_SLOT:
+# ifdef RTLD_BOOTSTRAP
+	  /* Fix weak undefined references.  */
+	  if (sym != NULL && sym->st_value == 0)
+	    *reloc_addr = 0;
+	  else
+# endif
+	    *reloc_addr = value;
+	  break;
+	case R_ARM_ABS32:
+	  {
+# ifndef RTLD_BOOTSTRAP
+	   /* 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.  */
+#  ifndef SHARED
+	    weak_extern (_dl_rtld_map);
+#  endif
+	    if (map == &GL(dl_rtld_map))
+	      /* Undo the relocation done here during bootstrapping.
+		 Now we will relocate it anew, possibly using a
+		 binding found in the user program or a loaded library
+		 rather than the dynamic linker's built-in definitions
+		 used while loading those libraries.  */
+	      value -= map->l_addr + refsym->st_value;
+# endif
+	    *reloc_addr += value;
+	    break;
+	  }
+	case R_ARM_TLS_DESC:
+	  {
+	    struct tlsdesc volatile *td =
+	      (struct tlsdesc volatile *)reloc_addr;
+
+# ifndef RTLD_BOOTSTRAP
+	    if (! sym)
+	      td->entry = _dl_tlsdesc_undefweak;
+	    else
+# endif
+	      {
+		value = sym->st_value + td->argument.value;
+
+# ifndef RTLD_BOOTSTRAP
+#  ifndef SHARED
+		CHECK_STATIC_TLS (map, sym_map);
+#  else
+		if (!TRY_STATIC_TLS (map, sym_map))
+		  {
+		    td->argument.pointer
+		      = _dl_make_tlsdesc_dynamic (sym_map, value);
+		    td->entry = _dl_tlsdesc_dynamic;
+		  }
+		else
+#  endif
+# endif
+		{
+		  td->argument.value = value + sym_map->l_tls_offset;
+		  td->entry = _dl_tlsdesc_return;
+		}
+	      }
+	    }
+	    break;
+	case R_ARM_PC24:
+	  {
+	     Elf32_Sword addend;
+	     Elf32_Addr newvalue, topbits;
+
+	     addend = *reloc_addr & 0x00ffffff;
+	     if (addend & 0x00800000) addend |= 0xff000000;
+
+	     newvalue = value - (Elf32_Addr)reloc_addr + (addend << 2);
+	     topbits = newvalue & 0xfe000000;
+	     if (topbits != 0xfe000000 && topbits != 0x00000000)
+	       {
+		 newvalue = fix_bad_pc24(reloc_addr, value)
+		   - (Elf32_Addr)reloc_addr + (addend << 2);
+		 topbits = newvalue & 0xfe000000;
+		 if (topbits != 0xfe000000 && topbits != 0x00000000)
+		   {
+		     _dl_signal_error (0, map->l_name, NULL,
+				       "R_ARM_PC24 relocation out of range");
+		   }
+	       }
+	     newvalue >>= 2;
+	     value = (*reloc_addr & 0xff000000) | (newvalue & 0x00ffffff);
+	     *reloc_addr = value;
+	  }
+	  break;
+#if !defined RTLD_BOOTSTRAP
+	case R_ARM_TLS_DTPMOD32:
+	  /* Get the information from the link map returned by the
+	     resolv function.  */
+	  if (sym_map != NULL)
+	    *reloc_addr = sym_map->l_tls_modid;
+	  break;
+
+	case R_ARM_TLS_DTPOFF32:
+	  if (sym != NULL)
+	    *reloc_addr += sym->st_value;
+	  break;
+
+	case R_ARM_TLS_TPOFF32:
+	  if (sym != NULL)
+	    {
+	      CHECK_STATIC_TLS (map, sym_map);
+	      *reloc_addr += sym->st_value + sym_map->l_tls_offset;
+	    }
+	  break;
+	case R_ARM_IRELATIVE:
+	  value = map->l_addr + *reloc_addr;
+	  value = ((Elf32_Addr (*) (void)) value) ();
+	  *reloc_addr = value;
+	  break;
+#endif
+	default:
+	  _dl_reloc_bad_type (map, r_type, 0);
+	  break;
+	}
+    }
+}
+
+# ifndef RTLD_BOOTSTRAP
+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)
+{
+  Elf32_Addr *const reloc_addr = reloc_addr_arg;
+  const unsigned int r_type = ELF32_R_TYPE (reloc->r_info);
+
+  if (__builtin_expect (r_type == R_ARM_RELATIVE, 0))
+    *reloc_addr = map->l_addr + reloc->r_addend;
+  else if (__builtin_expect (r_type == R_ARM_NONE, 0))
+    return;
+  else
+    {
+# ifndef RESOLVE_CONFLICT_FIND_MAP
+      const Elf32_Sym *const refsym = sym;
+# endif
+      struct link_map *sym_map = RESOLVE_MAP (&sym, version, r_type);
+      Elf32_Addr value = sym_map == NULL ? 0 : sym_map->l_addr + sym->st_value;
+
+      if (sym != NULL
+	  && __builtin_expect (ELFW(ST_TYPE) (sym->st_info) == STT_GNU_IFUNC, 0)
+	  && __builtin_expect (sym->st_shndx != SHN_UNDEF, 1)
+	  && __builtin_expect (!skip_ifunc, 1))
+	value = elf_ifunc_invoke (value);
+
+      switch (r_type)
+	{
+#  ifndef RESOLVE_CONFLICT_FIND_MAP
+	  /* Not needed for dl-conflict.c.  */
+	case R_ARM_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",
+				rtld_progname ?: "<program name unknown>",
+				strtab + refsym->st_name);
+	    }
+	  memcpy (reloc_addr_arg, (void *) value,
+		  MIN (sym->st_size, refsym->st_size));
+	  break;
+#  endif /* !RESOLVE_CONFLICT_FIND_MAP */
+	case R_ARM_GLOB_DAT:
+	case R_ARM_JUMP_SLOT:
+	case R_ARM_ABS32:
+	  *reloc_addr = value + reloc->r_addend;
+	  break;
+	case R_ARM_PC24:
+	  {
+	     Elf32_Addr newvalue, topbits;
+
+	     newvalue = value + reloc->r_addend - (Elf32_Addr)reloc_addr;
+	     topbits = newvalue & 0xfe000000;
+	     if (topbits != 0xfe000000 && topbits != 0x00000000)
+	       {
+		 newvalue = fix_bad_pc24(reloc_addr, value)
+		   - (Elf32_Addr)reloc_addr + (reloc->r_addend << 2);
+		 topbits = newvalue & 0xfe000000;
+		 if (topbits != 0xfe000000 && topbits != 0x00000000)
+		   {
+		     _dl_signal_error (0, map->l_name, NULL,
+				       "R_ARM_PC24 relocation out of range");
+		   }
+	       }
+	     newvalue >>= 2;
+	     value = (*reloc_addr & 0xff000000) | (newvalue & 0x00ffffff);
+	     *reloc_addr = value;
+	  }
+	  break;
+#if !defined RTLD_BOOTSTRAP
+	case R_ARM_TLS_DTPMOD32:
+	  /* Get the information from the link map returned by the
+	     resolv function.  */
+	  if (sym_map != NULL)
+	    *reloc_addr = sym_map->l_tls_modid;
+	  break;
+
+	case R_ARM_TLS_DTPOFF32:
+	  *reloc_addr = (sym == NULL ? 0 : sym->st_value) + reloc->r_addend;
+	  break;
+
+	case R_ARM_TLS_TPOFF32:
+	  if (sym != NULL)
+	    {
+	      CHECK_STATIC_TLS (map, sym_map);
+	      *reloc_addr = (sym->st_value + sym_map->l_tls_offset
+			     + reloc->r_addend);
+	    }
+	  break;
+	case R_ARM_IRELATIVE:
+	  value = map->l_addr + *reloc_addr;
+	  value = ((Elf32_Addr (*) (void)) value) ();
+	  *reloc_addr = value;
+	  break;
+#endif
+	default:
+	  _dl_reloc_bad_type (map, r_type, 0);
+	  break;
+	}
+    }
+}
+# endif
+
+auto inline void
+__attribute__ ((always_inline))
+elf_machine_rel_relative (Elf32_Addr l_addr, const Elf32_Rel *reloc,
+			  void *const reloc_addr_arg)
+{
+  Elf32_Addr *const reloc_addr = reloc_addr_arg;
+  *reloc_addr += l_addr;
+}
+
+# ifndef RTLD_BOOTSTRAP
+auto inline void
+__attribute__ ((always_inline))
+elf_machine_rela_relative (Elf32_Addr l_addr, const Elf32_Rela *reloc,
+			   void *const reloc_addr_arg)
+{
+  Elf32_Addr *const reloc_addr = reloc_addr_arg;
+  *reloc_addr = l_addr + reloc->r_addend;
+}
+# endif
+
+auto inline void
+__attribute__ ((always_inline))
+elf_machine_lazy_rel (struct link_map *map,
+		      Elf32_Addr l_addr, const Elf32_Rel *reloc,
+		      int skip_ifunc)
+{
+  Elf32_Addr *const reloc_addr = (void *) (l_addr + reloc->r_offset);
+  const unsigned int r_type = ELF32_R_TYPE (reloc->r_info);
+  /* Check for unexpected PLT reloc type.  */
+  if (__builtin_expect (r_type == R_ARM_JUMP_SLOT, 1))
+    {
+      if (__builtin_expect (map->l_mach.plt, 0) == 0)
+	*reloc_addr += l_addr;
+      else
+	*reloc_addr = map->l_mach.plt;
+    }
+  else if (__builtin_expect (r_type == R_ARM_TLS_DESC, 1))
+    {
+      struct tlsdesc volatile *td =
+	(struct tlsdesc volatile *)reloc_addr;
+
+      /* The linker must have given us the parameter we need in the
+	 first GOT entry, and left the second one empty. We fill the
+	 last with the resolver address */
+      assert (td->entry == 0);
+      td->entry = (void*)(D_PTR (map, l_info[ADDRIDX (DT_TLSDESC_PLT)])
+			  + map->l_addr);
+    }
+  else
+    _dl_reloc_bad_type (map, r_type, 1);
+}
+
+#endif /* RESOLVE_MAP */
diff --git a/ports/sysdeps/arm/dl-sysdep.h b/ports/sysdeps/arm/dl-sysdep.h
new file mode 100644
index 0000000000..91c754b12c
--- /dev/null
+++ b/ports/sysdeps/arm/dl-sysdep.h
@@ -0,0 +1,23 @@
+/* System-specific settings for dynamic linker code.  Alpha version.
+   Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   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_next <dl-sysdep.h>
+
+/* _dl_argv cannot be attribute_relro, because _dl_start_user
+   might write into it after _dl_start returns.  */
+#define DL_ARGV_NOT_RELRO 1
diff --git a/ports/sysdeps/arm/dl-tls.h b/ports/sysdeps/arm/dl-tls.h
new file mode 100644
index 0000000000..ada45f78c8
--- /dev/null
+++ b/ports/sysdeps/arm/dl-tls.h
@@ -0,0 +1,31 @@
+/* Thread-local storage handling in the ELF dynamic linker.  ARM version.
+   Copyright (C) 2005, 2011 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+
+/* Type used for the representation of TLS information in the GOT.  */
+typedef struct dl_tls_index
+{
+  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/ports/sysdeps/arm/dl-tlsdesc.S b/ports/sysdeps/arm/dl-tlsdesc.S
new file mode 100644
index 0000000000..f21555281f
--- /dev/null
+++ b/ports/sysdeps/arm/dl-tlsdesc.S
@@ -0,0 +1,218 @@
+/* Thread-local storage handling in the ELF dynamic linker.  ARM version.
+   Copyright (C) 2006, 2010, 2011 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <sysdep.h>
+#include <tls.h>
+#include "tlsdesc.h"
+
+#ifdef __USE_BX__
+  #define BX(x)	bx x
+#else
+  #define BX(x)	mov pc, x
+#endif
+
+	.text
+	@ emit debug information with cfi
+	@ use arm-specific pseudos for unwinding itself
+	.cfi_sections .debug_frame
+	.hidden _dl_tlsdesc_return
+	.global	_dl_tlsdesc_return
+	.type	_dl_tlsdesc_return,#function
+	cfi_startproc
+	.fnstart
+	.align 2
+_dl_tlsdesc_return:
+	ldr	r0, [r0]
+	BX	(lr)
+	.fnend
+	cfi_endproc
+	.size	_dl_tlsdesc_return, .-_dl_tlsdesc_return
+
+	.hidden _dl_tlsdesc_undefweak
+	.global	_dl_tlsdesc_undefweak
+	.type	_dl_tlsdesc_undefweak,#function
+	cfi_startproc
+	.fnstart
+	.align 2
+_dl_tlsdesc_undefweak:
+	@ Are we allowed a misaligned stack pointer calling read_tp?
+	.save	{lr}
+	stmdb 	sp!, {lr}
+	cfi_adjust_cfa_offset (4)
+	cfi_rel_offset (lr,0)
+	bl 	__aeabi_read_tp
+	rsb 	r0, r0, #0
+	ldmia 	sp!, {lr}
+	cfi_adjust_cfa_offset (-4)
+	cfi_restore (lr)
+	BX	(lr)
+
+	cfi_endproc
+	.fnend
+	.size	_dl_tlsdesc_undefweak, .-_dl_tlsdesc_undefweak
+
+#ifdef SHARED
+	.hidden _dl_tlsdesc_dynamic
+	.global	_dl_tlsdesc_dynamic
+	.type	_dl_tlsdesc_dynamic,#function
+
+
+/*
+	The assembly code that follows is a rendition of the following
+	C code, hand-optimized a little bit.
+
+ptrdiff_t
+_dl_tlsdesc_dynamic(struct tlsdesc *tdp)
+{
+       struct tlsdesc_dynamic_arg *td = tdp->argument.pointer;
+       dtv_t *dtv = (dtv_t *)THREAD_DTV();
+       if (__builtin_expect (td->gen_count <= dtv[0].counter
+                             && dtv[td->tlsinfo.ti_module].pointer.val
+                                != TLS_DTV_UNALLOCATED,
+                             1))
+               return dtv[td->tlsinfo.ti_module].pointer.val +
+                       td->tlsinfo.ti_offset - __builtin_thread_pointer();
+
+       return __tls_get_addr (&td->tlsinfo) - __builtin_thread_pointer();
+}
+
+*/
+	cfi_startproc
+	.fnstart
+	.align 2
+_dl_tlsdesc_dynamic:
+	/* Our calling convention is to clobber r0, r1 and the processor
+	   flags.  All others that are modified must be saved */
+	.save	{r2,r3,r4,lr}
+	stmdb   sp!, {r2,r3,r4,lr}
+	cfi_adjust_cfa_offset (16)
+	cfi_rel_offset (r2,0)
+	cfi_rel_offset (r3,4)
+	cfi_rel_offset (r4,8)
+	cfi_rel_offset (lr,12)
+	ldr	r1, [r0] /* td */
+	bl	__aeabi_read_tp
+	mov	r4, r0 /* r4 = tp */
+	ldr	r0, [r0]
+	ldr	r2, [r1, #8] /* gen_count */
+	ldr	r3, [r0]
+	cmp	r2, r3
+	bhi	1f
+	ldr	r3, [r1]
+	ldr	r2, [r0, r3, lsl #3]
+	cmn	r2, #1
+	ldrne	r3, [r1, #4]
+	addne	r3, r2, r3
+	rsbne	r0, r4, r3
+	bne	2f
+1:	mov	r0, r1
+	bl	__tls_get_addr
+	rsb	r0, r4, r0
+2:	ldmia	sp!, {r2,r3,r4, lr}
+	cfi_adjust_cfa_offset (-16)
+	cfi_restore (lr)
+	cfi_restore (r4)
+	cfi_restore (r3)
+	cfi_restore (r2)
+	BX      (lr)
+	.fnend
+	cfi_endproc
+	.size	_dl_tlsdesc_dynamic, .-_dl_tlsdesc_dynamic
+#endif /* SHARED */
+
+/* lazy resolved for tls descriptors.  */
+	.hidden _dl_tlsdesc_lazy_resolver
+	.global	_dl_tlsdesc_lazy_resolver
+	.type	_dl_tlsdesc_lazy_resolver,#function
+	cfi_startproc
+	.fnstart
+	.align 2
+_dl_tlsdesc_lazy_resolver:
+	/* r0 points at the tlsdesc,
+	   r1 points at the GOT
+	   r2 was pushed by the trampoline and used as a temp,
+	      we need to pop it here.
+	  We push the remaining call-clobbered registers here, and also
+	  R1 -- to keep the stack correctly aligned.  */
+	/* Tell the unwinder that r2 has already been pushed.  */
+	.save	{r2}
+	cfi_adjust_cfa_offset (4)
+	cfi_rel_offset (r2, 0)
+	.save	{r0,r1,r3,ip,lr}
+	stmdb	sp!, {r0, r1, r3, ip, lr}
+	cfi_adjust_cfa_offset (20)
+	cfi_rel_offset (r0, 0)
+	cfi_rel_offset (r1, 4)
+	cfi_rel_offset (r3, 8)
+	cfi_rel_offset (ip, 12)
+	cfi_rel_offset (lr, 16)
+	bl	_dl_tlsdesc_lazy_resolver_fixup
+	ldmia	sp!, {r0, r1, r3, ip, lr}
+	cfi_adjust_cfa_offset (-20)
+	cfi_restore (lr)
+	cfi_restore (ip)
+	cfi_restore (r3)
+	cfi_restore (r1)
+	cfi_restore (r0)
+	ldmia	sp!, {r2}
+	cfi_adjust_cfa_offset (-4)
+	cfi_restore (r2)
+	ldr	r1, [r0, #4]
+	BX	(r1)
+	.fnend
+	cfi_endproc
+	.size	_dl_tlsdesc_lazy_resolver, .-_dl_tlsdesc_lazy_resolver
+
+/* Holder for lazy tls descriptors being resolve in another thread.
+   Same ABI as the lazy resolver itself.  */
+	.hidden _dl_tlsdesc_resolve_hold
+	.global	_dl_tlsdesc_resolve_hold
+	.type	_dl_tlsdesc_resolve_hold,#function
+	cfi_startproc
+	.fnstart
+	.align 2
+_dl_tlsdesc_resolve_hold:
+	/* Tell the unwinder that r2 has already been pushed.  */
+	.save	{r2}
+	cfi_adjust_cfa_offset (4)
+	cfi_rel_offset (r2, 0)
+	.save	{r0,r1,r3,ip,lr}
+	stmdb   sp!, {r0, r1, r3, ip, lr}
+	cfi_adjust_cfa_offset (20)
+	cfi_rel_offset (r0, 0)
+	cfi_rel_offset (r1, 4)
+	cfi_rel_offset (r3, 8)
+	cfi_rel_offset (ip, 12)
+	cfi_rel_offset (lr, 16)
+	adr	r2, _dl_tlsdesc_resolve_hold
+	bl	_dl_tlsdesc_resolve_hold_fixup
+	ldmia   sp!, {r0, r1, r3, ip, lr}
+	cfi_adjust_cfa_offset (-20)
+	cfi_restore (lr)
+	cfi_restore (ip)
+	cfi_restore (r3)
+	cfi_restore (r1)
+	cfi_restore (r0)
+	ldmia   sp!, {r2}
+	cfi_adjust_cfa_offset (-4)
+	cfi_restore (r2)
+	ldr     r1, [r0, #4]
+	BX      (r1)
+	.fnend
+	cfi_endproc
+	.size	_dl_tlsdesc_resolve_hold, .-_dl_tlsdesc_resolve_hold
diff --git a/ports/sysdeps/arm/dl-tlsdesc.h b/ports/sysdeps/arm/dl-tlsdesc.h
new file mode 100644
index 0000000000..2b1131c55a
--- /dev/null
+++ b/ports/sysdeps/arm/dl-tlsdesc.h
@@ -0,0 +1,68 @@
+/* Thread-local storage descriptor handling in the ELF dynamic linker.
+   ARM version.
+   Copyright (C) 2005, 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; witout 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/>.  */
+
+#ifndef _ARM_DL_TLSDESC_H
+# define _ARM_DL_TLSDESC_H 1
+
+/* Use this to access DT_TLSDESC_PLT and DT_TLSDESC_GOT.  */
+#ifndef ADDRIDX
+# define ADDRIDX(tag) (DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGNUM \
+		       + DT_EXTRANUM + DT_VALNUM + DT_ADDRTAGIDX (tag))
+#endif
+
+/* Type used to represent a TLS descriptor in the GOT.  */
+struct tlsdesc
+{
+  union
+    {
+      void *pointer;
+      long value;
+    } argument;
+  ptrdiff_t (*entry)(struct tlsdesc *);
+};
+
+
+typedef struct dl_tls_index
+{
+  unsigned long int ti_module;
+  unsigned long int ti_offset;
+} tls_index;
+
+/* Type used as the argument in a TLS descriptor for a symbol that
+   needs dynamic TLS offsets.  */
+struct tlsdesc_dynamic_arg
+{
+  tls_index tlsinfo;
+  size_t gen_count;
+};
+
+extern ptrdiff_t attribute_hidden
+  _dl_tlsdesc_return(struct tlsdesc *),
+  _dl_tlsdesc_undefweak(struct tlsdesc *),
+  _dl_tlsdesc_resolve_hold(struct tlsdesc *),
+  _dl_tlsdesc_lazy_resolver(struct tlsdesc *);
+
+# ifdef SHARED
+extern void *_dl_make_tlsdesc_dynamic (struct link_map *map, size_t ti_offset);
+
+extern ptrdiff_t attribute_hidden
+  _dl_tlsdesc_dynamic(struct tlsdesc *);
+# endif
+
+#endif
diff --git a/ports/sysdeps/arm/dl-trampoline.S b/ports/sysdeps/arm/dl-trampoline.S
new file mode 100644
index 0000000000..370bda3467
--- /dev/null
+++ b/ports/sysdeps/arm/dl-trampoline.S
@@ -0,0 +1,217 @@
+/* PLT trampolines.  ARM version.
+   Copyright (C) 2005, 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, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <sysdep.h>
+#include <libc-symbols.h>
+
+#if defined(__USE_BX__)
+#define BX(x) bx	x
+#else
+#define BX(x) mov	pc, x
+#endif
+
+	.text
+	.globl _dl_runtime_resolve
+	.type _dl_runtime_resolve, #function
+	.cfi_sections .debug_frame
+	cfi_startproc
+	.align 2
+_dl_runtime_resolve:
+	cfi_adjust_cfa_offset (4)
+	cfi_rel_offset (lr, 0)
+
+	@ we get called with
+	@ 	stack[0] contains the return address from this call
+	@	ip contains &GOT[n+3] (pointer to function)
+	@	lr points to &GOT[2]
+
+	@ Save arguments.  We save r4 to realign the stack.
+	stmdb	sp!,{r0-r4}
+	cfi_adjust_cfa_offset (20)
+	cfi_rel_offset (r0, 0)
+	cfi_rel_offset (r1, 4)
+	cfi_rel_offset (r2, 8)
+	cfi_rel_offset (r3, 12)
+
+	@ get pointer to linker struct
+	ldr	r0, [lr, #-4]
+
+	@ prepare to call _dl_fixup()
+	@ change &GOT[n+3] into 8*n        NOTE: reloc are 8 bytes each
+	sub	r1, ip, lr
+	sub	r1, r1, #4
+	add	r1, r1, r1
+
+	@ call fixup routine
+	bl	_dl_fixup
+
+	@ save the return
+	mov	ip, r0
+
+	@ get arguments and return address back.  We restore r4
+	@ only to realign the stack.
+	ldmia	sp!, {r0-r4,lr}
+	cfi_adjust_cfa_offset (-24)
+
+	@ jump to the newly found address
+	BX(ip)
+
+	cfi_endproc
+	.size _dl_runtime_resolve, .-_dl_runtime_resolve
+
+#ifndef PROF
+	.globl _dl_runtime_profile
+	.type _dl_runtime_profile, #function
+	.cfi_sections .debug_frame
+	cfi_startproc
+	.align 2
+_dl_runtime_profile:
+	cfi_adjust_cfa_offset (4)
+	cfi_rel_offset (lr, 0)
+
+	@ we get called with
+	@ 	stack[0] contains the return address from this call
+	@	ip contains &GOT[n+3] (pointer to function)
+	@	lr points to &GOT[2]
+
+	@ Stack layout:
+	@ 212 - saved lr
+	@ 208 - framesize returned from pltenter
+	@ 16 - La_arm_regs
+	@ 8 - Saved two arguments to _dl_profile_fixup
+	@ 4 - Saved result of _dl_profile_fixup
+	@ 0 - outgoing argument to _dl_profile_fixup
+	@ For now, we only save the general purpose registers.
+
+	sub	sp, sp, #196
+	cfi_adjust_cfa_offset (196)
+	stmia	sp, {r0-r3}
+	cfi_rel_offset (r0, 0)
+	cfi_rel_offset (r1, 4)
+	cfi_rel_offset (r2, 8)
+	cfi_rel_offset (r3, 12)
+
+	sub	sp, sp, #16
+	cfi_adjust_cfa_offset (16)
+
+	@ Save sp and lr.
+	add	r0, sp, #216
+	str	r0, [sp, #32]
+	ldr	r2, [sp, #212]
+	str	r2, [sp, #36]
+
+	@ get pointer to linker struct
+	ldr	r0, [lr, #-4]
+
+	@ prepare to call _dl_profile_fixup()
+	@ change &GOT[n+3] into 8*n        NOTE: reloc are 8 bytes each
+	sub	r1, ip, lr
+	sub	r1, r1, #4
+	add	r1, r1, r1
+
+	@ Save these two arguments for pltexit.
+	add	r3, sp, #8
+	stmia	r3!, {r0,r1}
+
+	@ Set up extra args for _dl_profile_fixup.
+	@ r2 and r3 are already loaded.
+	add	ip, sp, #208
+	str	ip, [sp, #0]
+
+	@ call profiling fixup routine
+	bl	_dl_profile_fixup
+
+	@ The address to call is now in r0.
+
+	@ Check whether we're wrapping this function.
+	ldr	ip, [sp, #208]
+	cmp	ip, #0
+	bge	1f
+	cfi_remember_state
+
+	@ save the return
+	mov	ip, r0
+
+	@ get arguments and return address back
+	add	sp, sp, #16
+	cfi_adjust_cfa_offset (-16)
+	ldmia	sp, {r0-r3,sp,lr}
+	cfi_adjust_cfa_offset (-200)
+
+	@ jump to the newly found address
+	BX(ip)
+
+	cfi_restore_state
+1:
+	@ The new frame size is in ip.
+
+	@ New stack layout:
+	@ 268 - saved r7
+	@ 264 - saved result of _dl_profile_fixup
+	@ 72 - La_arm_regs
+	@ 64 - Saved two arguments to _dl_profile_fixup
+	@ 0 - La_arm_retval
+	@ For now, we only save the general purpose registers.
+
+	@ Build the new frame.
+	str	r7, [sp, #212]
+	cfi_rel_offset (r7, 212)
+	sub	r7, sp, #56
+	cfi_def_cfa_register (r7)
+	cfi_adjust_cfa_offset (56)
+	sub	sp, sp, ip
+	bic	sp, sp, #7
+
+	@ Save the _dl_profile_fixup result around the call to memcpy.
+	str	r0, [r7, #264]
+
+	@ Copy the stack arguments.
+	mov	r0, sp
+	add	r1, r7, #272
+	mov	r2, ip
+	bl	memcpy
+
+	@ Call the function.
+	add	ip, r7, #72
+	ldmia	ip, {r0-r3}
+	ldr	ip, [r7, #264]
+	mov	lr, pc
+	BX(ip)
+	stmia	r7, {r0-r3}
+
+	@ Call pltexit.
+	add	ip, r7, #64
+	ldmia	ip, {r0,r1}
+	add	r2, r7, #72
+	add	r3, r7, #0
+	bl	_dl_call_pltexit
+
+	@ Return to caller.
+	ldmia	r7, {r0-r3}
+	mov	sp, r7
+	cfi_def_cfa_register (sp)
+	ldr	r7, [sp, #268]
+	ldr	lr, [sp, #92]
+	add	sp, sp, #272
+	cfi_adjust_cfa_offset (-272)
+	BX(lr)
+
+	cfi_endproc
+	.size _dl_runtime_profile, .-_dl_runtime_profile
+#endif
+	.previous
diff --git a/ports/sysdeps/arm/fclrexcpt.c b/ports/sysdeps/arm/fclrexcpt.c
new file mode 100644
index 0000000000..ddedc3573c
--- /dev/null
+++ b/ports/sysdeps/arm/fclrexcpt.c
@@ -0,0 +1,60 @@
+/* Clear given exceptions in current floating-point environment.
+   Copyright (C) 1997,98,99,2000,01,05,11 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <fenv.h>
+#include <fpu_control.h>
+
+#include <unistd.h>
+#include <ldsodefs.h>
+#include <dl-procinfo.h>
+#include <sysdep.h>
+
+int
+__feclearexcept (int excepts)
+{
+  if (GLRO (dl_hwcap) & HWCAP_ARM_VFP)
+    {
+      unsigned long int temp;
+
+      /* Mask out unsupported bits/exceptions.  */
+      excepts &= FE_ALL_EXCEPT;
+
+      /* Get the current floating point status. */
+      _FPU_GETCW (temp);
+
+      /* Clear the relevant bits.  */
+      temp = (temp & ~FE_ALL_EXCEPT) | (temp & FE_ALL_EXCEPT & ~excepts);
+
+      /* Put the new data in effect.  */
+      _FPU_SETCW (temp);
+
+      /* Success.  */
+      return 0;
+    }
+
+  /* Unsupported, so fail unless nothing needs to be done.  */
+  return (excepts != 0);
+}
+
+#include <shlib-compat.h>
+#if SHLIB_COMPAT (libm, GLIBC_2_1, GLIBC_2_2)
+strong_alias (__feclearexcept, __old_feclearexcept)
+compat_symbol (libm, __old_feclearexcept, feclearexcept, GLIBC_2_1);
+#endif
+
+versioned_symbol (libm, __feclearexcept, feclearexcept, GLIBC_2_2);
diff --git a/ports/sysdeps/arm/fedisblxcpt.c b/ports/sysdeps/arm/fedisblxcpt.c
new file mode 100644
index 0000000000..c9c62a48ef
--- /dev/null
+++ b/ports/sysdeps/arm/fedisblxcpt.c
@@ -0,0 +1,50 @@
+/* Disable floating-point exceptions.
+   Copyright (C) 2001, 2005 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Philip Blundell <philb@gnu.org>, 2001.
+
+   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 <fenv.h>
+#include <fpu_control.h>
+
+#include <unistd.h>
+#include <ldsodefs.h>
+#include <dl-procinfo.h>
+#include <sysdep.h>
+
+int
+fedisableexcept (int excepts)
+{
+  if (GLRO (dl_hwcap) & HWCAP_ARM_VFP)
+    {
+      unsigned long int new_exc, old_exc;
+
+      _FPU_GETCW(new_exc);
+
+      old_exc = (new_exc >> FE_EXCEPT_SHIFT) & FE_ALL_EXCEPT;
+
+      excepts &= FE_ALL_EXCEPT;
+
+      new_exc &= ~(excepts << FE_EXCEPT_SHIFT);
+
+      _FPU_SETCW(new_exc);
+
+      return old_exc;
+    }
+
+  /* Unsupported, so return -1 for failure.  */
+  return -1;
+}
diff --git a/ports/sysdeps/arm/feenablxcpt.c b/ports/sysdeps/arm/feenablxcpt.c
new file mode 100644
index 0000000000..3b2b934f57
--- /dev/null
+++ b/ports/sysdeps/arm/feenablxcpt.c
@@ -0,0 +1,50 @@
+/* Enable floating-point exceptions.
+   Copyright (C) 2001, 2005 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Philip Blundell <philb@gnu.org>, 2001.
+
+   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 <fenv.h>
+#include <fpu_control.h>
+
+#include <unistd.h>
+#include <ldsodefs.h>
+#include <dl-procinfo.h>
+#include <sysdep.h>
+
+int
+feenableexcept (int excepts)
+{
+  if (GLRO (dl_hwcap) & HWCAP_ARM_VFP)
+    {
+      unsigned long int new_exc, old_exc;
+
+      _FPU_GETCW(new_exc);
+
+      old_exc = (new_exc >> FE_EXCEPT_SHIFT) & FE_ALL_EXCEPT;
+
+      excepts &= FE_ALL_EXCEPT;
+
+      new_exc |= (excepts << FE_EXCEPT_SHIFT);
+
+      _FPU_SETCW(new_exc);
+
+      return old_exc;
+    }
+
+  /* Unsupported, so return -1 for failure.  */
+  return -1;
+}
diff --git a/ports/sysdeps/arm/fegetenv.c b/ports/sysdeps/arm/fegetenv.c
new file mode 100644
index 0000000000..c638635df4
--- /dev/null
+++ b/ports/sysdeps/arm/fegetenv.c
@@ -0,0 +1,51 @@
+/* Store current floating-point environment.
+   Copyright (C) 1997,98,99,2000,01,05,10 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <fenv.h>
+#include <fpu_control.h>
+
+#include <unistd.h>
+#include <ldsodefs.h>
+#include <dl-procinfo.h>
+#include <sysdep.h>
+
+int
+__fegetenv (fenv_t *envp)
+{
+  if (GLRO (dl_hwcap) & HWCAP_ARM_VFP)
+    {
+      unsigned long int temp;
+      _FPU_GETCW (temp);
+      envp->__cw = temp;
+
+      /* Success.  */
+      return 0;
+    }
+
+  /* Unsupported, so fail.  */
+  return 1;
+}
+
+#include <shlib-compat.h>
+#if SHLIB_COMPAT (libm, GLIBC_2_1, GLIBC_2_2)
+strong_alias (__fegetenv, __old_fegetenv)
+compat_symbol (libm, __old_fegetenv, fegetenv, GLIBC_2_1);
+#endif
+
+libm_hidden_ver (__fegetenv, fegetenv)
+versioned_symbol (libm, __fegetenv, fegetenv, GLIBC_2_2);
diff --git a/ports/sysdeps/arm/fegetexcept.c b/ports/sysdeps/arm/fegetexcept.c
new file mode 100644
index 0000000000..929d6c5cfa
--- /dev/null
+++ b/ports/sysdeps/arm/fegetexcept.c
@@ -0,0 +1,42 @@
+/* Get floating-point exceptions.
+   Copyright (C) 2001, 2005 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Philip Blundell <philb@gnu.org>, 2001
+
+   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 <fenv.h>
+#include <fpu_control.h>
+
+#include <unistd.h>
+#include <ldsodefs.h>
+#include <dl-procinfo.h>
+#include <sysdep.h>
+
+int
+fegetexcept (void)
+{
+  if (GLRO (dl_hwcap) & HWCAP_ARM_VFP)
+    {
+      unsigned long temp;
+
+      _FPU_GETCW (temp);
+
+      return (temp >> FE_EXCEPT_SHIFT) & FE_ALL_EXCEPT;
+    }
+
+  /* Unsupported. Return all exceptions disabled.  */
+  return 0;
+}
diff --git a/ports/sysdeps/arm/fegetround.c b/ports/sysdeps/arm/fegetround.c
new file mode 100644
index 0000000000..df1049706b
--- /dev/null
+++ b/ports/sysdeps/arm/fegetround.c
@@ -0,0 +1,42 @@
+/* Return current rounding direction.
+   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, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <fenv.h>
+#include <fpu_control.h>
+
+#include <unistd.h>
+#include <ldsodefs.h>
+#include <dl-procinfo.h>
+#include <sysdep.h>
+
+int
+fegetround (void)
+{
+  if (GLRO (dl_hwcap) & HWCAP_ARM_VFP)
+    {
+      unsigned int temp;
+
+      /* Get the current environment.  */
+      _FPU_GETCW (temp);
+
+      return temp & FE_TOWARDZERO;
+    }
+
+  /* The current soft-float implementation only handles TONEAREST.  */
+  return FE_TONEAREST;
+}
diff --git a/ports/sysdeps/arm/feholdexcpt.c b/ports/sysdeps/arm/feholdexcpt.c
new file mode 100644
index 0000000000..4aed48bb39
--- /dev/null
+++ b/ports/sysdeps/arm/feholdexcpt.c
@@ -0,0 +1,53 @@
+/* Store current floating-point environment and clear exceptions.
+   Copyright (C) 1997, 1998, 1999, 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, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <fenv.h>
+#include <fpu_control.h>
+
+#include <unistd.h>
+#include <ldsodefs.h>
+#include <dl-procinfo.h>
+#include <sysdep.h>
+
+int
+feholdexcept (fenv_t *envp)
+{
+  if (GLRO (dl_hwcap) & HWCAP_ARM_VFP)
+    {
+      unsigned long int temp;
+
+      /* Store the environment.  */
+      _FPU_GETCW(temp);
+      envp->__cw = temp;
+
+      /* Now set all exceptions to non-stop.  */
+      temp &= ~(FE_ALL_EXCEPT << FE_EXCEPT_SHIFT);
+
+      /* And clear all exception flags.  */
+      temp &= ~FE_ALL_EXCEPT;
+
+      _FPU_SETCW(temp);
+
+      return 0;
+    }
+
+  /* Unsupported, so fail.  */
+  return 1;
+}
+
+libm_hidden_def (feholdexcept)
diff --git a/ports/sysdeps/arm/fesetenv.c b/ports/sysdeps/arm/fesetenv.c
new file mode 100644
index 0000000000..61370325e2
--- /dev/null
+++ b/ports/sysdeps/arm/fesetenv.c
@@ -0,0 +1,56 @@
+/* Install given floating-point environment.
+   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, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <fenv.h>
+#include <fpu_control.h>
+
+#include <unistd.h>
+#include <ldsodefs.h>
+#include <dl-procinfo.h>
+#include <sysdep.h>
+
+int
+__fesetenv (const fenv_t *envp)
+{
+  if (GLRO (dl_hwcap) & HWCAP_ARM_VFP)
+    {
+      unsigned int temp;
+
+      _FPU_GETCW (temp);
+      temp &= _FPU_RESERVED;
+
+      if (envp == FE_DFL_ENV)
+	temp |= _FPU_DEFAULT;
+      else if (envp == FE_NOMASK_ENV)
+	temp |= _FPU_IEEE;
+      else
+	temp |= envp->__cw & ~_FPU_RESERVED;
+
+      _FPU_SETCW (temp);
+
+      /* Success.  */
+      return 0;
+    }
+
+  /* Unsupported, so fail.  */
+  return 1;
+}
+
+#include <shlib-compat.h>
+libm_hidden_ver (__fesetenv, fesetenv)
+versioned_symbol (libm, __fesetenv, fesetenv, GLIBC_2_2);
diff --git a/ports/sysdeps/arm/fesetround.c b/ports/sysdeps/arm/fesetround.c
new file mode 100644
index 0000000000..997bd98f5a
--- /dev/null
+++ b/ports/sysdeps/arm/fesetround.c
@@ -0,0 +1,56 @@
+/* Set current rounding direction.
+   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, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <fenv.h>
+#include <fpu_control.h>
+
+#include <unistd.h>
+#include <ldsodefs.h>
+#include <dl-procinfo.h>
+#include <sysdep.h>
+
+int
+fesetround (int round)
+{
+  if (GLRO (dl_hwcap) & HWCAP_ARM_VFP)
+    {
+      fpu_control_t temp;
+
+      switch (round)
+	{
+	case FE_TONEAREST:
+	case FE_UPWARD:
+	case FE_DOWNWARD:
+	case FE_TOWARDZERO:
+	  _FPU_GETCW (temp);
+	  temp = (temp & ~FE_TOWARDZERO) | round;
+	  _FPU_SETCW (temp);
+	  return 0;
+	default:
+	  return 1;
+	}
+    }
+  else if (round == FE_TONEAREST)
+    /* This is the only supported rounding mode for soft-fp.  */
+    return 0;
+
+  /* Unsupported, so fail.  */
+  return 1;
+}
+
+libm_hidden_def (fesetround)
diff --git a/ports/sysdeps/arm/feupdateenv.c b/ports/sysdeps/arm/feupdateenv.c
new file mode 100644
index 0000000000..98f265432c
--- /dev/null
+++ b/ports/sysdeps/arm/feupdateenv.c
@@ -0,0 +1,59 @@
+/* Install given floating-point environment and raise exceptions.
+   Copyright (C) 1997, 1999, 2000, 2008, 2010 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+   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 <fenv.h>
+#include <fpu_control.h>
+
+#include <unistd.h>
+#include <ldsodefs.h>
+#include <dl-procinfo.h>
+#include <sysdep.h>
+
+int
+__feupdateenv (const fenv_t *envp)
+{
+  if (GLRO (dl_hwcap) & HWCAP_ARM_VFP)
+    {
+      unsigned int temp;
+
+      /* Get the current exception state.  */
+      _FPU_GETCW (temp);
+
+      /* Install new environment.  */
+      fesetenv (envp);
+
+      /* Raise the saved exceptions.  */
+      feraiseexcept (temp & FE_ALL_EXCEPT);
+
+      /* Success.  */
+      return 0;
+    }
+
+  /* Unsupported, so fail.  */
+  return 1;
+}
+
+#include <shlib-compat.h>
+#if SHLIB_COMPAT (libm, GLIBC_2_1, GLIBC_2_2)
+strong_alias (__feupdateenv, __old_feupdateenv)
+compat_symbol (libm, __old_feupdateenv, feupdateenv, GLIBC_2_1);
+#endif
+
+libm_hidden_ver (__feupdateenv, feupdateenv)
+versioned_symbol (libm, __feupdateenv, feupdateenv, GLIBC_2_2);
diff --git a/ports/sysdeps/arm/fgetexcptflg.c b/ports/sysdeps/arm/fgetexcptflg.c
new file mode 100644
index 0000000000..41661a2e29
--- /dev/null
+++ b/ports/sysdeps/arm/fgetexcptflg.c
@@ -0,0 +1,53 @@
+/* Store current representation for exceptions.
+   Copyright (C) 1997, 1999, 2000, 2008 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+   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 <fenv.h>
+#include <fpu_control.h>
+
+#include <unistd.h>
+#include <ldsodefs.h>
+#include <dl-procinfo.h>
+#include <sysdep.h>
+
+int
+__fegetexceptflag (fexcept_t *flagp, int excepts)
+{
+  if (GLRO (dl_hwcap) & HWCAP_ARM_VFP)
+    {
+      unsigned long temp;
+
+      /* Get the current exceptions.  */
+      _FPU_GETCW (temp);
+
+      *flagp = temp & excepts & FE_ALL_EXCEPT;
+
+      /* Success.  */
+      return 0;
+    }
+
+  /* Unsupported, so fail.  */
+  return 1;
+}
+
+#include <shlib-compat.h>
+#if SHLIB_COMPAT (libm, GLIBC_2_1, GLIBC_2_2)
+strong_alias (__fegetexceptflag, __old_fegetexceptflag)
+compat_symbol (libm, __old_fegetexceptflag, fegetexceptflag, GLIBC_2_1);
+#endif
+versioned_symbol (libm, __fegetexceptflag, fegetexceptflag, GLIBC_2_2);
diff --git a/ports/sysdeps/arm/find_exidx.c b/ports/sysdeps/arm/find_exidx.c
new file mode 100644
index 0000000000..12ade46d87
--- /dev/null
+++ b/ports/sysdeps/arm/find_exidx.c
@@ -0,0 +1,79 @@
+/* Copyright (C) 2005, 2008 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <link.h>
+#include <unwind.h>
+
+struct unw_eh_callback_data
+{
+  _Unwind_Ptr pc;
+  _Unwind_Ptr exidx_start;
+  int exidx_len;
+};
+
+
+/* Callback to determins if the PC lies within an object, and remember the
+   location of the exception index table if it does.  */
+
+static int
+find_exidx_callback (struct dl_phdr_info * info, size_t size, void * ptr)
+{
+  struct unw_eh_callback_data * data;
+  const ElfW(Phdr) *phdr;
+  int i;
+  int match;
+  _Unwind_Ptr load_base;
+
+  data = (struct unw_eh_callback_data *) ptr;
+  load_base = info->dlpi_addr;
+  phdr = info->dlpi_phdr;
+
+  match = 0;
+  for (i = info->dlpi_phnum; i > 0; i--, phdr++)
+    {
+      if (phdr->p_type == PT_LOAD)
+        {
+          _Unwind_Ptr vaddr = phdr->p_vaddr + load_base;
+          if (data->pc >= vaddr && data->pc < vaddr + phdr->p_memsz)
+            match = 1;
+        }
+      else if (phdr->p_type == PT_ARM_EXIDX)
+	{
+	  data->exidx_start = (_Unwind_Ptr) (phdr->p_vaddr + load_base);
+	  data->exidx_len = phdr->p_memsz;
+	}
+    }
+
+  return match;
+}
+
+
+/* Find the exception index table containing PC.  */
+
+_Unwind_Ptr
+__gnu_Unwind_Find_exidx (_Unwind_Ptr pc, int * pcount)
+{
+  struct unw_eh_callback_data data;
+
+  data.pc = pc;
+  data.exidx_start = 0;
+  if (__dl_iterate_phdr (find_exidx_callback, &data) <= 0)
+    return 0;
+
+  *pcount = data.exidx_len / 8;
+  return data.exidx_start;
+}
diff --git a/ports/sysdeps/arm/fpu_control.h b/ports/sysdeps/arm/fpu_control.h
new file mode 100644
index 0000000000..635bc7d4ee
--- /dev/null
+++ b/ports/sysdeps/arm/fpu_control.h
@@ -0,0 +1,63 @@
+/* FPU control word definitions.  ARM VFP version.
+   Copyright (C) 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, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef _FPU_CONTROL_H
+#define _FPU_CONTROL_H
+
+#if !defined(_LIBC) && defined(__SOFTFP__)
+
+#define _FPU_RESERVED 0xffffffff
+#define _FPU_DEFAULT  0x00000000
+typedef unsigned int fpu_control_t;
+#define _FPU_GETCW(cw) 0
+#define _FPU_SETCW(cw) do { } while (0)
+extern fpu_control_t __fpu_control;
+
+#else
+
+/* masking of interrupts */
+#define _FPU_MASK_IM	0x00000100	/* invalid operation */
+#define _FPU_MASK_ZM	0x00000200	/* divide by zero */
+#define _FPU_MASK_OM	0x00000400	/* overflow */
+#define _FPU_MASK_UM	0x00000800	/* underflow */
+#define _FPU_MASK_PM	0x00001000	/* inexact */
+
+/* Some bits in the FPSCR are not yet defined.  They must be preserved when
+   modifying the contents.  */
+#define _FPU_RESERVED	0x0e08e0e0
+#define _FPU_DEFAULT    0x00000000
+/* Default + exceptions enabled. */
+#define _FPU_IEEE	(_FPU_DEFAULT | 0x00001f00)
+
+/* Type of the control word.  */
+typedef unsigned int fpu_control_t;
+
+/* Macros for accessing the hardware control word.  */
+/* This is fmrx %0, fpscr.  */
+#define _FPU_GETCW(cw) \
+  __asm__ __volatile__ ("mrc p10, 7, %0, cr1, cr0, 0" : "=r" (cw))
+/* This is fmxr fpscr, %0.  */
+#define _FPU_SETCW(cw) \
+  __asm__ __volatile__ ("mcr p10, 7, %0, cr1, cr0, 0" : : "r" (cw))
+
+/* Default control word set at startup.  */
+extern fpu_control_t __fpu_control;
+
+#endif /* __SOFTFP__ */
+
+#endif /* _FPU_CONTROL_H */
diff --git a/ports/sysdeps/arm/fraiseexcpt.c b/ports/sysdeps/arm/fraiseexcpt.c
new file mode 100644
index 0000000000..0a4368839f
--- /dev/null
+++ b/ports/sysdeps/arm/fraiseexcpt.c
@@ -0,0 +1,109 @@
+/* Raise given exceptions.
+   Copyright (C) 2004, 2005, 2011 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <fpu_control.h>
+#include <fenv.h>
+#include <float.h>
+
+#include <unistd.h>
+#include <ldsodefs.h>
+#include <dl-procinfo.h>
+#include <sysdep.h>
+
+int
+feraiseexcept (int excepts)
+{
+  if (GLRO (dl_hwcap) & HWCAP_ARM_VFP)
+    {
+      int fpscr;
+      const float fp_zero = 0.0, fp_one = 1.0, fp_max = FLT_MAX,
+                  fp_min = FLT_MIN, fp_1e32 = 1.0e32f, fp_two = 2.0,
+		  fp_three = 3.0;
+
+      /* Raise exceptions represented by EXPECTS.  But we must raise only
+	 one signal at a time.  It is important that if the overflow/underflow
+	 exception and the inexact exception are given at the same time,
+	 the overflow/underflow exception follows the inexact exception.  After
+	 each exception we read from the fpscr, to force the exception to be
+	 raised immediately.  */
+
+      /* There are additional complications because this file may be compiled
+         without VFP support enabled, and we also can't assume that the
+	 assembler has VFP instructions enabled. To get around this we use the
+	 generic coprocessor mnemonics and avoid asking GCC to put float values
+	 in VFP registers.  */
+
+      /* First: invalid exception.  */
+      if (FE_INVALID & excepts)
+	__asm__ __volatile__ (
+	  "ldc p10, cr0, %1\n\t"                        /* flds s0, %1  */
+	  "cdp p10, 8, cr0, cr0, cr0, 0\n\t"            /* fdivs s0, s0, s0  */
+	  "mrc p10, 7, %0, cr1, cr0, 0" : "=r" (fpscr)  /* fmrx %0, fpscr  */
+			                : "m" (fp_zero)
+					: "s0");
+
+      /* Next: division by zero.  */
+      if (FE_DIVBYZERO & excepts)
+	__asm__ __volatile__ (
+	  "ldc p10, cr0, %1\n\t"                        /* flds s0, %1  */
+	  "ldcl p10, cr0, %2\n\t"                       /* flds s1, %2  */
+	  "cdp p10, 8, cr0, cr0, cr0, 1\n\t"            /* fdivs s0, s0, s1  */
+	  "mrc p10, 7, %0, cr1, cr0, 0" : "=r" (fpscr)  /* fmrx %0, fpscr  */
+			                : "m" (fp_one), "m" (fp_zero)
+					: "s0", "s1");
+
+      /* Next: overflow.  */
+      if (FE_OVERFLOW & excepts)
+	/* There's no way to raise overflow without also raising inexact.  */
+	__asm__ __volatile__ (
+	  "ldc p10, cr0, %1\n\t"                        /* flds s0, %1  */
+	  "ldcl p10, cr0, %2\n\t"                       /* flds s1, %2  */
+	  "cdp p10, 3, cr0, cr0, cr0, 1\n\t"            /* fadds s0, s0, s1  */
+	  "mrc p10, 7, %0, cr1, cr0, 0" : "=r" (fpscr)  /* fmrx %0, fpscr  */
+			                : "m" (fp_max), "m" (fp_1e32)
+					: "s0", "s1");
+
+      /* Next: underflow.  */
+      if (FE_UNDERFLOW & excepts)
+	__asm__ __volatile__ (
+	  "ldc p10, cr0, %1\n\t"                        /* flds s0, %1  */
+	  "ldcl p10, cr0, %2\n\t"                       /* flds s1, %2  */
+	  "cdp p10, 8, cr0, cr0, cr0, 1\n\t"            /* fdivs s0, s0, s1  */
+	  "mrc p10, 7, %0, cr1, cr0, 0" : "=r" (fpscr)  /* fmrx %0, fpscr  */
+			                : "m" (fp_min), "m" (fp_three)
+					: "s0", "s1");
+
+      /* Last: inexact.  */
+      if (FE_INEXACT & excepts)
+	__asm__ __volatile__ (
+	  "ldc p10, cr0, %1\n\t"                        /* flds s0, %1  */
+	  "ldcl p10, cr0, %2\n\t"                       /* flds s1, %2  */
+	  "cdp p10, 8, cr0, cr0, cr0, 1\n\t"            /* fdivs s0, s0, s1  */
+	  "mrc p10, 7, %0, cr1, cr0, 0" : "=r" (fpscr)  /* fmrx %0, fpscr  */
+			                : "m" (fp_two), "m" (fp_three)
+					: "s0", "s1");
+
+      /* Success.  */
+      return 0;
+    }
+
+  /* Unsupported, so fail unless nothing needs to be done.  */
+  return (excepts != 0);
+}
+
+libm_hidden_def (feraiseexcept)
diff --git a/ports/sysdeps/arm/frame.h b/ports/sysdeps/arm/frame.h
new file mode 100644
index 0000000000..a98729b688
--- /dev/null
+++ b/ports/sysdeps/arm/frame.h
@@ -0,0 +1,27 @@
+/* Definition of stack frame structure.  ARM/APCS version.
+   Copyright (C) 2000, 2002 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+/* This is the APCS stack backtrace structure.  */
+struct layout
+{
+  struct layout *__unbounded next;
+  void *__unbounded sp;
+  void *__unbounded return_address;
+};
+
+#define FIRST_FRAME_POINTER ADVANCE_STACK_FRAME (__builtin_frame_address (0))
diff --git a/ports/sysdeps/arm/framestate.c b/ports/sysdeps/arm/framestate.c
new file mode 100644
index 0000000000..710cecca97
--- /dev/null
+++ b/ports/sysdeps/arm/framestate.c
@@ -0,0 +1 @@
+/* Empty */
diff --git a/ports/sysdeps/arm/fsetexcptflg.c b/ports/sysdeps/arm/fsetexcptflg.c
new file mode 100644
index 0000000000..bee51a96a2
--- /dev/null
+++ b/ports/sysdeps/arm/fsetexcptflg.c
@@ -0,0 +1,59 @@
+/* Set floating-point environment exception handling.
+   Copyright (C) 1997,98,99,2000,01,05,08,11 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <fenv.h>
+#include <math.h>
+#include <fpu_control.h>
+
+#include <unistd.h>
+#include <ldsodefs.h>
+#include <dl-procinfo.h>
+#include <sysdep.h>
+
+int
+__fesetexceptflag (const fexcept_t *flagp, int excepts)
+{
+  if (GLRO (dl_hwcap) & HWCAP_ARM_VFP)
+    {
+      fexcept_t temp;
+
+      /* Get the current environment.  */
+      _FPU_GETCW (temp);
+
+      /* Set the desired exception mask.  */
+      temp &= ~(excepts & FE_ALL_EXCEPT);
+      temp |= (*flagp & excepts & FE_ALL_EXCEPT);
+
+      /* Save state back to the FPU.  */
+      _FPU_SETCW (temp);
+
+      /* Success.  */
+      return 0;
+    }
+
+  /* Unsupported, so fail unless nothing needs to be done.  */
+  return (excepts != 0);
+}
+
+#include <shlib-compat.h>
+#if SHLIB_COMPAT (libm, GLIBC_2_1, GLIBC_2_2)
+strong_alias (__fesetexceptflag, __old_fesetexceptflag)
+compat_symbol (libm, __old_fesetexceptflag, fesetexceptflag, GLIBC_2_1);
+#endif
+
+versioned_symbol (libm, __fesetexceptflag, fesetexceptflag, GLIBC_2_2);
diff --git a/ports/sysdeps/arm/ftestexcept.c b/ports/sysdeps/arm/ftestexcept.c
new file mode 100644
index 0000000000..06817d2fe0
--- /dev/null
+++ b/ports/sysdeps/arm/ftestexcept.c
@@ -0,0 +1,43 @@
+/* Test exception in current environment.
+   Copyright (C) 1997, 1998, 2005, 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, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <fenv.h>
+#include <fpu_control.h>
+
+#include <unistd.h>
+#include <ldsodefs.h>
+#include <dl-procinfo.h>
+#include <sysdep.h>
+
+int
+fetestexcept (int excepts)
+{
+  if (GLRO (dl_hwcap) & HWCAP_ARM_VFP)
+    {
+      fexcept_t temp;
+
+      /* Get current exceptions.  */
+      _FPU_GETCW(temp);
+
+      return temp & excepts & FE_ALL_EXCEPT;
+    }
+
+  /* Unsupported, return 0.  */
+  return 0;
+}
+libm_hidden_def (fetestexcept)
diff --git a/ports/sysdeps/arm/gccframe.h b/ports/sysdeps/arm/gccframe.h
new file mode 100644
index 0000000000..166d8fb59b
--- /dev/null
+++ b/ports/sysdeps/arm/gccframe.h
@@ -0,0 +1,21 @@
+/* Definition of object in frame unwind info.  arm version.
+   Copyright (C) 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 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/>.  */
+
+#define FIRST_PSEUDO_REGISTER 27
+
+#include <sysdeps/generic/gccframe.h>
diff --git a/ports/sysdeps/arm/gmp-mparam.h b/ports/sysdeps/arm/gmp-mparam.h
new file mode 100644
index 0000000000..b391b68f06
--- /dev/null
+++ b/ports/sysdeps/arm/gmp-mparam.h
@@ -0,0 +1,36 @@
+/* gmp-mparam.h -- Compiler/machine parameter header file.
+
+Copyright (C) 1991, 1993, 1994, 1995, 2005 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 2.1 of the License, or (at your
+option) any later version.
+
+The GNU MP Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MP Library.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#define BITS_PER_MP_LIMB 32
+#define BYTES_PER_MP_LIMB 4
+#define BITS_PER_LONGINT 32
+#define BITS_PER_INT 32
+#define BITS_PER_SHORTINT 16
+#define BITS_PER_CHAR 8
+
+#if defined(__ARMEB__)
+# define IEEE_DOUBLE_MIXED_ENDIAN 0
+# define IEEE_DOUBLE_BIG_ENDIAN 1
+#elif defined(__VFP_FP__)
+# define IEEE_DOUBLE_MIXED_ENDIAN 0
+# define IEEE_DOUBLE_BIG_ENDIAN 0
+#else
+# define IEEE_DOUBLE_BIG_ENDIAN 0
+# define IEEE_DOUBLE_MIXED_ENDIAN 1
+#endif
diff --git a/ports/sysdeps/arm/jmpbuf-offsets.h b/ports/sysdeps/arm/jmpbuf-offsets.h
new file mode 100644
index 0000000000..642a9657d5
--- /dev/null
+++ b/ports/sysdeps/arm/jmpbuf-offsets.h
@@ -0,0 +1,19 @@
+/* Private macros for accessing __jmp_buf contents.  ARM EABI version.
+   Copyright (C) 2007 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#define __JMP_BUF_SP		8
diff --git a/ports/sysdeps/arm/jmpbuf-unwind.h b/ports/sysdeps/arm/jmpbuf-unwind.h
new file mode 100644
index 0000000000..d3a58d03a2
--- /dev/null
+++ b/ports/sysdeps/arm/jmpbuf-unwind.h
@@ -0,0 +1,35 @@
+/* Copyright (C) 2005,2006 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <setjmp.h>
+#include <jmpbuf-offsets.h>
+#include <stdint.h>
+#include <unwind.h>
+
+/* Test if longjmp to JMPBUF would unwind the frame
+   containing a local variable at ADDRESS.  */
+#define _JMPBUF_UNWINDS(jmpbuf, address, demangle) \
+  ((void *) (address) < (void *) demangle (jmpbuf[__JMP_BUF_SP]))
+
+#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) (_jmpbuf)[__JMP_BUF_SP] - (_adj))
+
+/* We use the normal longjmp for unwinding.  */
+#define __libc_unwind_longjmp(buf, val) __libc_longjmp (buf, val)
diff --git a/ports/sysdeps/arm/ldsodefs.h b/ports/sysdeps/arm/ldsodefs.h
new file mode 100644
index 0000000000..aa323d3ecd
--- /dev/null
+++ b/ports/sysdeps/arm/ldsodefs.h
@@ -0,0 +1,40 @@
+/* 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, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef _ARM_LDSODEFS_H
+#define _ARM_LDSODEFS_H 1
+
+#include <elf.h>
+
+struct La_arm_regs;
+struct La_arm_retval;
+
+#define ARCH_PLTENTER_MEMBERS \
+    Elf32_Addr (*arm_gnu_pltenter) (Elf32_Sym *, unsigned int, uintptr_t *,  \
+				    uintptr_t *, struct La_arm_regs *,	     \
+				    unsigned int *, const char *,	     \
+				    long int *)
+
+#define ARCH_PLTEXIT_MEMBERS \
+    Elf32_Addr (*arm_gnu_pltexit) (Elf32_Sym *, unsigned int, uintptr_t *,   \
+				   uintptr_t *, struct La_arm_regs *,	     \
+				   struct La_arm_retval *, const char *)
+
+#include_next <ldsodefs.h>
+
+#endif
diff --git a/ports/sysdeps/arm/libc-tls.c b/ports/sysdeps/arm/libc-tls.c
new file mode 100644
index 0000000000..747de1c995
--- /dev/null
+++ b/ports/sysdeps/arm/libc-tls.c
@@ -0,0 +1,32 @@
+/* Thread-local storage handling in the ELF dynamic linker.  ARM version.
+   Copyright (C) 2005, 2011 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <csu/libc-tls.c>
+#include <dl-tls.h>
+
+/* On ARM, linker optimizations are not required, so __tls_get_addr
+   can be called even in statically linked binaries.  In this case module
+   must be always 1 and PT_TLS segment exist in the binary, otherwise it
+   would not link.  */
+
+void *
+__tls_get_addr (tls_index *ti)
+{
+  dtv_t *dtv = THREAD_DTV ();
+  return (char *) dtv[1].pointer.val + ti->ti_offset;
+}
diff --git a/ports/sysdeps/arm/libm-test-ulps b/ports/sysdeps/arm/libm-test-ulps
new file mode 100644
index 0000000000..51356dddb6
--- /dev/null
+++ b/ports/sysdeps/arm/libm-test-ulps
@@ -0,0 +1,1845 @@
+# Begin of automatic generation
+
+# acos_downward
+Test "acos_downward (-0) == pi/2":
+float: 1
+ifloat: 1
+Test "acos_downward (-0.5) == M_PI_6l*4.0":
+double: 1
+idouble: 1
+Test "acos_downward (-1) == pi":
+float: 1
+ifloat: 1
+Test "acos_downward (0) == pi/2":
+float: 1
+ifloat: 1
+Test "acos_downward (0.5) == M_PI_6l*2.0":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+# acos_towardzero
+Test "acos_towardzero (-0) == pi/2":
+float: 1
+ifloat: 1
+Test "acos_towardzero (-0.5) == M_PI_6l*4.0":
+double: 1
+idouble: 1
+Test "acos_towardzero (-1) == pi":
+float: 1
+ifloat: 1
+Test "acos_towardzero (0) == pi/2":
+float: 1
+ifloat: 1
+Test "acos_towardzero (0.5) == M_PI_6l*2.0":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+# asin_downward
+Test "asin_downward (-0.5) == -pi/6":
+double: 1
+idouble: 1
+Test "asin_downward (0.5) == pi/6":
+double: 1
+idouble: 1
+Test "asin_downward (1.0) == pi/2":
+float: 1
+ifloat: 1
+
+# asin_towardzero
+Test "asin_towardzero (-0.5) == -pi/6":
+double: 1
+idouble: 1
+Test "asin_towardzero (-1.0) == -pi/2":
+float: 1
+ifloat: 1
+Test "asin_towardzero (0.5) == pi/6":
+double: 1
+idouble: 1
+Test "asin_towardzero (1.0) == pi/2":
+float: 1
+ifloat: 1
+
+# asin_upward
+Test "asin_upward (-1.0) == -pi/2":
+float: 1
+ifloat: 1
+
+# atan2
+Test "atan2 (-0.75, -1.0) == -2.49809154479650885165983415456218025":
+float: 1
+ifloat: 1
+Test "atan2 (0.75, -1.0) == 2.49809154479650885165983415456218025":
+float: 1
+ifloat: 1
+Test "atan2 (1.390625, 0.9296875) == 0.981498387184244311516296577615519772":
+float: 1
+ifloat: 1
+
+# atanh
+Test "atanh (0.75) == 0.972955074527656652552676371721589865":
+float: 1
+ifloat: 1
+
+# cacos
+Test "Imaginary part of: cacos (+0 + 0.5 i) == pi/2 - 0.4812118250596034474977589134243684231352 i":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+Test "Imaginary part of: cacos (+0 + 1.0 i) == pi/2 - 0.8813735870195430252326093249797923090282 i":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+Test "Imaginary part of: cacos (+0 + 1.5 i) == pi/2 - 1.194763217287109304111930828519090523536 i":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+Test "Imaginary part of: cacos (+0 - 0.5 i) == pi/2 + 0.4812118250596034474977589134243684231352 i":
+float: 1
+ifloat: 1
+Test "Imaginary part of: cacos (+0 - 1.0 i) == pi/2 + 0.8813735870195430252326093249797923090282 i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "Imaginary part of: cacos (+0 - 1.5 i) == pi/2 + 1.194763217287109304111930828519090523536 i":
+double: 1
+idouble: 1
+Test "Imaginary part of: cacos (-0 + 0.5 i) == pi/2 - 0.4812118250596034474977589134243684231352 i":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+Test "Imaginary part of: cacos (-0 + 1.0 i) == pi/2 - 0.8813735870195430252326093249797923090282 i":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+Test "Imaginary part of: cacos (-0 + 1.5 i) == pi/2 - 1.194763217287109304111930828519090523536 i":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+Test "Imaginary part of: cacos (-0 - 0.5 i) == pi/2 + 0.4812118250596034474977589134243684231352 i":
+float: 1
+ifloat: 1
+Test "Imaginary part of: cacos (-0 - 1.0 i) == pi/2 + 0.8813735870195430252326093249797923090282 i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "Imaginary part of: cacos (-0 - 1.5 i) == pi/2 + 1.194763217287109304111930828519090523536 i":
+double: 1
+idouble: 1
+Test "Imaginary part of: cacos (-1.5 + +0 i) == pi - 0.9624236501192068949955178268487368462704 i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "Real part of: cacos (0.5 + +0 i) == 1.047197551196597746154214461093167628066 - 0 i":
+double: 1
+idouble: 1
+Test "Real part of: cacos (0.5 - 0 i) == 1.047197551196597746154214461093167628066 + +0 i":
+double: 1
+idouble: 1
+Test "Imaginary part of: cacos (1.5 + +0 i) == +0 - 0.9624236501192068949955178268487368462704 i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+# cacosh
+Test "Real part of: cacosh (+0 + 0.5 i) == 0.4812118250596034474977589134243684231352 + pi/2 i":
+float: 1
+ifloat: 1
+Test "Real part of: cacosh (+0 + 1.0 i) == 0.8813735870195430252326093249797923090282 + pi/2 i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "Real part of: cacosh (+0 + 1.5 i) == 1.194763217287109304111930828519090523536 + pi/2 i":
+double: 1
+idouble: 1
+Test "Real part of: cacosh (+0 - 0.5 i) == 0.4812118250596034474977589134243684231352 - pi/2 i":
+float: 1
+ifloat: 1
+Test "Real part of: cacosh (+0 - 1.0 i) == 0.8813735870195430252326093249797923090282 - pi/2 i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "Real part of: cacosh (+0 - 1.5 i) == 1.194763217287109304111930828519090523536 - pi/2 i":
+double: 1
+idouble: 1
+Test "Real part of: cacosh (-0 + 0.5 i) == 0.4812118250596034474977589134243684231352 + pi/2 i":
+float: 1
+ifloat: 1
+Test "Real part of: cacosh (-0 + 1.0 i) == 0.8813735870195430252326093249797923090282 + pi/2 i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "Real part of: cacosh (-0 + 1.5 i) == 1.194763217287109304111930828519090523536 + pi/2 i":
+double: 1
+idouble: 1
+Test "Real part of: cacosh (-0 - 0.5 i) == 0.4812118250596034474977589134243684231352 - pi/2 i":
+float: 1
+ifloat: 1
+Test "Real part of: cacosh (-0 - 1.0 i) == 0.8813735870195430252326093249797923090282 - pi/2 i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "Real part of: cacosh (-0 - 1.5 i) == 1.194763217287109304111930828519090523536 - pi/2 i":
+double: 1
+idouble: 1
+Test "Imaginary part of: cacosh (-0.5 + +0 i) == +0 + 2.094395102393195492308428922186335256131 i":
+double: 1
+idouble: 1
+Test "Imaginary part of: cacosh (-0.5 - 0 i) == +0 - 2.094395102393195492308428922186335256131 i":
+double: 1
+idouble: 1
+Test "Real part of: cacosh (-1.5 + +0 i) == 0.9624236501192068949955178268487368462704 + pi i":
+float: 1
+ifloat: 1
+Test "Real part of: cacosh (-1.5 - 0 i) == 0.9624236501192068949955178268487368462704 - pi i":
+float: 1
+ifloat: 1
+Test "Imaginary part of: cacosh (-2 - 3 i) == 1.9833870299165354323470769028940395 - 2.1414491111159960199416055713254211 i":
+float: 1
+ifloat: 1
+Test "Real part of: cacosh (1.5 + +0 i) == 0.9624236501192068949955178268487368462704 + +0 i":
+float: 1
+ifloat: 1
+Test "Real part of: cacosh (1.5 - 0 i) == 0.9624236501192068949955178268487368462704 - 0 i":
+float: 1
+ifloat: 1
+
+# casin
+Test "Imaginary part of: casin (+0 + 0.5 i) == +0 + 0.4812118250596034474977589134243684231352 i":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+Test "Imaginary part of: casin (+0 + 1.0 i) == +0 + 0.8813735870195430252326093249797923090282 i":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+Test "Imaginary part of: casin (+0 + 1.5 i) == +0 + 1.194763217287109304111930828519090523536 i":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+Test "Imaginary part of: casin (+0 - 0.5 i) == +0 - 0.4812118250596034474977589134243684231352 i":
+float: 1
+ifloat: 1
+Test "Imaginary part of: casin (+0 - 1.0 i) == +0 - 0.8813735870195430252326093249797923090282 i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "Imaginary part of: casin (+0 - 1.5 i) == +0 - 1.194763217287109304111930828519090523536 i":
+double: 1
+idouble: 1
+Test "Imaginary part of: casin (-0 + 0.5 i) == -0 + 0.4812118250596034474977589134243684231352 i":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+Test "Imaginary part of: casin (-0 + 1.0 i) == -0 + 0.8813735870195430252326093249797923090282 i":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+Test "Imaginary part of: casin (-0 + 1.5 i) == -0 + 1.194763217287109304111930828519090523536 i":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+Test "Imaginary part of: casin (-0 - 0.5 i) == -0 - 0.4812118250596034474977589134243684231352 i":
+float: 1
+ifloat: 1
+Test "Imaginary part of: casin (-0 - 1.0 i) == -0 - 0.8813735870195430252326093249797923090282 i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "Imaginary part of: casin (-0 - 1.5 i) == -0 - 1.194763217287109304111930828519090523536 i":
+double: 1
+idouble: 1
+Test "Imaginary part of: casin (-1.5 + +0 i) == -pi/2 + 0.9624236501192068949955178268487368462704 i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "Real part of: casin (0.75 + 1.25 i) == 0.453276177638793913448921196101971749 + 1.13239363160530819522266333696834467 i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "Imaginary part of: casin (1.5 + +0 i) == pi/2 + 0.9624236501192068949955178268487368462704 i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+# casinh
+Test "Real part of: casinh (-0 + 1.5 i) == -0.9624236501192068949955178268487368462704 + pi/2 i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "Real part of: casinh (-0 - 1.5 i) == -0.9624236501192068949955178268487368462704 - pi/2 i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "Real part of: casinh (-0.5 + +0 i) == -0.4812118250596034474977589134243684231352 + +0 i":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+Test "Real part of: casinh (-0.5 - 0 i) == -0.4812118250596034474977589134243684231352 - 0 i":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+Test "Real part of: casinh (-1.0 + +0 i) == -0.8813735870195430252326093249797923090282 + +0 i":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+Test "Real part of: casinh (-1.0 - 0 i) == -0.8813735870195430252326093249797923090282 - 0 i":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+Test "Real part of: casinh (-1.5 + +0 i) == -1.194763217287109304111930828519090523536 + +0 i":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+Test "Real part of: casinh (-1.5 - 0 i) == -1.194763217287109304111930828519090523536 - 0 i":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+Test "Real part of: casinh (-2 - 3 i) == -1.9686379257930962917886650952454982 - 0.96465850440760279204541105949953237 i":
+double: 5
+float: 1
+idouble: 5
+ifloat: 1
+Test "Imaginary part of: casinh (-2 - 3 i) == -1.9686379257930962917886650952454982 - 0.96465850440760279204541105949953237 i":
+double: 3
+float: 6
+idouble: 3
+ifloat: 6
+Test "Real part of: casinh (0.5 + +0 i) == 0.4812118250596034474977589134243684231352 + +0 i":
+float: 1
+ifloat: 1
+Test "Real part of: casinh (0.5 - 0 i) == 0.4812118250596034474977589134243684231352 - 0 i":
+float: 1
+ifloat: 1
+Test "Real part of: casinh (0.75 + 1.25 i) == 1.03171853444778027336364058631006594 + 0.911738290968487636358489564316731207 i":
+float: 1
+ifloat: 1
+Test "Imaginary part of: casinh (0.75 + 1.25 i) == 1.03171853444778027336364058631006594 + 0.911738290968487636358489564316731207 i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "Real part of: casinh (1.0 + +0 i) == 0.8813735870195430252326093249797923090282 + +0 i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "Real part of: casinh (1.0 - 0 i) == 0.8813735870195430252326093249797923090282 - 0 i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "Real part of: casinh (1.5 + +0 i) == 1.194763217287109304111930828519090523536 + +0 i":
+double: 1
+idouble: 1
+Test "Real part of: casinh (1.5 - 0 i) == 1.194763217287109304111930828519090523536 - 0 i":
+double: 1
+idouble: 1
+
+# catan
+Test "Imaginary part of: catan (-2 - 3 i) == -1.4099210495965755225306193844604208 - 0.22907268296853876629588180294200276 i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+# catanh
+Test "Real part of: catanh (-2 - 3 i) == -0.14694666622552975204743278515471595 - 1.3389725222944935611241935759091443 i":
+double: 4
+idouble: 4
+Test "Real part of: catanh (0.75 + 1.25 i) == 0.261492138795671927078652057366532140 + 0.996825126463918666098902241310446708 i":
+double: 1
+idouble: 1
+
+# cbrt
+Test "cbrt (-27.0) == -3.0":
+double: 1
+idouble: 1
+Test "cbrt (0.75) == 0.908560296416069829445605878163630251":
+double: 1
+idouble: 1
+Test "cbrt (0.9921875) == 0.997389022060725270579075195353955217":
+double: 1
+idouble: 1
+
+# ccos
+Test "Imaginary part of: ccos (-0.75 + 710.5 i) == 1.347490911916428129246890157395342279438e308 + 1.255317763348154410745082950806112487736e308 i":
+double: 1
+idouble: 1
+Test "Imaginary part of: ccos (-0.75 + 89.5 i) == 2.708024460708609732016532185663087200560e38 + 2.522786001038096774676288412995370563339e38 i":
+float: 1
+ifloat: 1
+Test "Imaginary part of: ccos (-0.75 - 710.5 i) == 1.347490911916428129246890157395342279438e308 - 1.255317763348154410745082950806112487736e308 i":
+double: 1
+idouble: 1
+Test "Imaginary part of: ccos (-0.75 - 89.5 i) == 2.708024460708609732016532185663087200560e38 - 2.522786001038096774676288412995370563339e38 i":
+float: 1
+ifloat: 1
+Test "Imaginary part of: ccos (-2 - 3 i) == -4.18962569096880723013255501961597373 - 9.10922789375533659797919726277886212 i":
+float: 1
+ifloat: 1
+Test "Real part of: ccos (0.75 + 1.25 i) == 1.38173873063425888530729933139078645 - 1.09193013555397466170919531722024128 i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "Imaginary part of: ccos (0.75 + 1.25 i) == 1.38173873063425888530729933139078645 - 1.09193013555397466170919531722024128 i":
+float: 1
+ifloat: 1
+Test "Imaginary part of: ccos (0.75 + 710.5 i) == 1.347490911916428129246890157395342279438e308 - 1.255317763348154410745082950806112487736e308 i":
+double: 1
+idouble: 1
+Test "Imaginary part of: ccos (0.75 + 89.5 i) == 2.708024460708609732016532185663087200560e38 - 2.522786001038096774676288412995370563339e38 i":
+float: 1
+ifloat: 1
+Test "Imaginary part of: ccos (0.75 - 710.5 i) == 1.347490911916428129246890157395342279438e308 + 1.255317763348154410745082950806112487736e308 i":
+double: 1
+idouble: 1
+Test "Imaginary part of: ccos (0.75 - 89.5 i) == 2.708024460708609732016532185663087200560e38 + 2.522786001038096774676288412995370563339e38 i":
+float: 1
+ifloat: 1
+Test "Imaginary part of: ccos (0x1p-1074 + 1440 i) == inf - 5.981479269486130556466515778180916082415e301 i":
+double: 1
+idouble: 1
+
+# ccosh
+Test "Real part of: ccosh (-2 - 3 i) == -3.72454550491532256547397070325597253 + 0.511822569987384608834463849801875634 i":
+float: 1
+ifloat: 1
+Test "Imaginary part of: ccosh (-2 - 3 i) == -3.72454550491532256547397070325597253 + 0.511822569987384608834463849801875634 i":
+float: 1
+ifloat: 1
+Test "Imaginary part of: ccosh (-710.5 + 0.75 i) == 1.347490911916428129246890157395342279438e308 - 1.255317763348154410745082950806112487736e308 i":
+double: 1
+idouble: 1
+Test "Imaginary part of: ccosh (-710.5 - 0.75 i) == 1.347490911916428129246890157395342279438e308 + 1.255317763348154410745082950806112487736e308 i":
+double: 1
+idouble: 1
+Test "Imaginary part of: ccosh (-89.5 + 0.75 i) == 2.708024460708609732016532185663087200560e38 - 2.522786001038096774676288412995370563339e38 i":
+float: 1
+ifloat: 1
+Test "Imaginary part of: ccosh (-89.5 - 0.75 i) == 2.708024460708609732016532185663087200560e38 + 2.522786001038096774676288412995370563339e38 i":
+float: 1
+ifloat: 1
+Test "Real part of: ccosh (0.75 + 1.25 i) == 0.408242591877968807788852146397499084 + 0.780365930845853240391326216300863152 i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "Imaginary part of: ccosh (0.75 + 1.25 i) == 0.408242591877968807788852146397499084 + 0.780365930845853240391326216300863152 i":
+float: 1
+ifloat: 1
+Test "Imaginary part of: ccosh (1440 + 0x1p-1074 i) == inf + 5.981479269486130556466515778180916082415e301 i":
+double: 1
+idouble: 1
+Test "Imaginary part of: ccosh (710.5 + 0.75 i) == 1.347490911916428129246890157395342279438e308 + 1.255317763348154410745082950806112487736e308 i":
+double: 1
+idouble: 1
+Test "Imaginary part of: ccosh (710.5 - 0.75 i) == 1.347490911916428129246890157395342279438e308 - 1.255317763348154410745082950806112487736e308 i":
+double: 1
+idouble: 1
+Test "Imaginary part of: ccosh (89.5 + 0.75 i) == 2.708024460708609732016532185663087200560e38 + 2.522786001038096774676288412995370563339e38 i":
+float: 1
+ifloat: 1
+Test "Imaginary part of: ccosh (89.5 - 0.75 i) == 2.708024460708609732016532185663087200560e38 - 2.522786001038096774676288412995370563339e38 i":
+float: 1
+ifloat: 1
+
+# cexp
+Test "Imaginary part of: cexp (-2.0 - 3.0 i) == -0.13398091492954261346140525546115575 - 0.019098516261135196432576240858800925 i":
+float: 1
+ifloat: 1
+Test "Imaginary part of: cexp (-95 + 0.75 i) == 4.039714446238306526889476684000081624047e-42 + 3.763383677300535390271646960780570275931e-42 i":
+double: 1
+idouble: 1
+Test "Real part of: cexp (0.75 + 1.25 i) == 0.667537446429131586942201977015932112 + 2.00900045494094876258347228145863909 i":
+float: 1
+ifloat: 1
+Test "Imaginary part of: cexp (1440 + 0x1p-1074 i) == inf + 1.196295853897226111293303155636183216483e302 i":
+double: 1
+idouble: 1
+Test "Real part of: cexp (50 + 0x1p127 i) == 4.053997150228616856622417636046265337193e21 + 3.232070315463388524466674772633810238819e21 i":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+Test "Imaginary part of: cexp (50 + 0x1p127 i) == 4.053997150228616856622417636046265337193e21 + 3.232070315463388524466674772633810238819e21 i":
+double: 1
+idouble: 1
+Test "Real part of: cexp (500 + 0x1p1023 i) == -1.159886268932754433233243794561351783426e217 + 7.904017694554466595359379965081774849708e216 i":
+double: 1
+idouble: 1
+Test "Real part of: cexp (709.8125 + 0.75 i) == 1.355121963080879535248452862759108365762e308 + 1.262426823598609432507811340856186873507e308 i":
+double: 1
+idouble: 1
+Test "Imaginary part of: cexp (709.8125 + 0.75 i) == 1.355121963080879535248452862759108365762e308 + 1.262426823598609432507811340856186873507e308 i":
+double: 1
+idouble: 1
+Test "Real part of: cexp (88.75 + 0.75 i) == 2.558360358486542817001900410314204322891e38 + 2.383359453227311447654736314679677655100e38 i":
+float: 1
+ifloat: 1
+Test "Imaginary part of: cexp (88.75 + 0.75 i) == 2.558360358486542817001900410314204322891e38 + 2.383359453227311447654736314679677655100e38 i":
+float: 2
+ifloat: 2
+
+# clog
+Test "Real part of: clog (0.75 + 1.25 i) == 0.376885901188190075998919126749298416 + 1.03037682652431246378774332703115153 i":
+float: 1
+ifloat: 1
+Test "Real part of: clog (0x1p-1074 + 0x1p-1074 i) == -744.0934983311012896593986823853525458290 + pi/4 i":
+double: 1
+idouble: 1
+Test "Real part of: clog (0x1p-147 + 0x1p-147 i) == -101.5460619520319878296245057936228672231 + pi/4 i":
+float: 1
+ifloat: 1
+
+# clog10
+Test "Imaginary part of: clog10 (-0 + inf i) == inf + pi/2*log10(e) i":
+float: 1
+ifloat: 1
+Test "Imaginary part of: clog10 (-0 - inf i) == inf - pi/2*log10(e) i":
+float: 1
+ifloat: 1
+Test "Imaginary part of: clog10 (-2 - 3 i) == 0.556971676153418384603252578971164214 - 0.937554462986374708541507952140189646 i":
+double: 1
+idouble: 1
+Test "Imaginary part of: clog10 (-3 + inf i) == inf + pi/2*log10(e) i":
+float: 1
+ifloat: 1
+Test "Imaginary part of: clog10 (-3 - inf i) == inf - pi/2*log10(e) i":
+float: 1
+ifloat: 1
+Test "Imaginary part of: clog10 (-inf + 0 i) == inf + pi*log10(e) i":
+float: 1
+ifloat: 1
+Test "Imaginary part of: clog10 (-inf + 1 i) == inf + pi*log10(e) i":
+float: 1
+ifloat: 1
+Test "Imaginary part of: clog10 (-inf - 0 i) == inf - pi*log10(e) i":
+float: 1
+ifloat: 1
+Test "Imaginary part of: clog10 (-inf - 1 i) == inf - pi*log10(e) i":
+float: 1
+ifloat: 1
+Test "Imaginary part of: clog10 (0 + inf i) == inf + pi/2*log10(e) i":
+float: 1
+ifloat: 1
+Test "Imaginary part of: clog10 (0 - inf i) == inf - pi/2*log10(e) i":
+float: 1
+ifloat: 1
+Test "Real part of: clog10 (0.75 + 1.25 i) == 0.163679467193165171449476605077428975 + 0.447486970040493067069984724340855636 i":
+float: 1
+ifloat: 1
+Test "Imaginary part of: clog10 (0x1.fffffep+127 + 0x1.fffffep+127 i) == 38.68235441693561449174780668781319348761 + pi/4*log10(e) i":
+float: 1
+ifloat: 1
+Test "Real part of: clog10 (0x1.fffffep+127 + 1.0 i) == 38.53183941910362389414093724045094697423 + 1.276276851248440096917018665609900318458e-39 i":
+float: 1
+ifloat: 1
+Test "Real part of: clog10 (0x1p-1074 + 0x1p-1074 i) == -323.1557003452838130619487034867432642357 + pi/4*log10(e) i":
+double: 1
+idouble: 1
+Test "Imaginary part of: clog10 (0x1p-147 + 0x1p-147 i) == -44.10089436477324509881274807713822842154 + pi/4*log10(e) i":
+float: 1
+ifloat: 1
+Test "Imaginary part of: clog10 (0x1p-149 + 0x1p-149 i) == -44.70295435610120748924022586658721447508 + pi/4*log10(e) i":
+float: 1
+ifloat: 1
+Test "Imaginary part of: clog10 (3 + inf i) == inf + pi/2*log10(e) i":
+float: 1
+ifloat: 1
+Test "Imaginary part of: clog10 (3 - inf i) == inf - pi/2*log10(e) i":
+float: 1
+ifloat: 1
+Test "Imaginary part of: clog10 (inf + inf i) == inf + pi/4*log10(e) i":
+float: 1
+ifloat: 1
+Test "Imaginary part of: clog10 (inf - inf i) == inf - pi/4*log10(e) i":
+float: 1
+ifloat: 1
+
+# cos
+Test "cos (M_PI_6l * 2.0) == 0.5":
+double: 1
+idouble: 1
+Test "cos (M_PI_6l * 4.0) == -0.5":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+
+# cos_downward
+Test "cos_downward (1) == 0.5403023058681397174009366074429766037323":
+float: 1
+ifloat: 1
+Test "cos_downward (2) == -0.4161468365471423869975682295007621897660":
+float: 1
+ifloat: 1
+Test "cos_downward (3) == -0.9899924966004454572715727947312613023937":
+float: 1
+ifloat: 1
+Test "cos_downward (4) == -0.6536436208636119146391681830977503814241":
+float: 1
+ifloat: 1
+Test "cos_downward (5) == 0.2836621854632262644666391715135573083344":
+float: 1
+ifloat: 1
+Test "cos_downward (7) == 0.7539022543433046381411975217191820122183":
+float: 1
+ifloat: 1
+Test "cos_downward (8) == -0.1455000338086135258688413818311946826093":
+float: 1
+ifloat: 1
+
+# cos_tonearest
+Test "cos_tonearest (7) == 0.7539022543433046381411975217191820122183":
+float: 1
+ifloat: 1
+
+# cos_towardzero
+Test "cos_towardzero (2) == -0.4161468365471423869975682295007621897660":
+float: 1
+ifloat: 1
+Test "cos_towardzero (3) == -0.9899924966004454572715727947312613023937":
+float: 1
+ifloat: 1
+Test "cos_towardzero (5) == 0.2836621854632262644666391715135573083344":
+float: 1
+ifloat: 1
+Test "cos_towardzero (7) == 0.7539022543433046381411975217191820122183":
+float: 1
+ifloat: 1
+Test "cos_towardzero (8) == -0.1455000338086135258688413818311946826093":
+float: 1
+ifloat: 1
+
+# cos_upward
+Test "cos_upward (10) == -0.8390715290764524522588639478240648345199":
+float: 1
+ifloat: 1
+Test "cos_upward (6) == 0.9601702866503660205456522979229244054519":
+float: 1
+ifloat: 1
+Test "cos_upward (7) == 0.7539022543433046381411975217191820122183":
+float: 1
+ifloat: 1
+Test "cos_upward (9) == -0.9111302618846769883682947111811653112463":
+float: 2
+ifloat: 2
+
+# cosh_downward
+Test "cosh_downward (22) == 1792456423.065795780980053377632656584997":
+float: 1
+ifloat: 1
+Test "cosh_downward (23) == 4872401723.124451300068625740569997090344":
+float: 1
+ifloat: 1
+Test "cosh_downward (24) == 13244561064.92173614708845674912733665919":
+float: 1
+ifloat: 1
+
+# cosh_towardzero
+Test "cosh_towardzero (22) == 1792456423.065795780980053377632656584997":
+float: 1
+ifloat: 1
+Test "cosh_towardzero (23) == 4872401723.124451300068625740569997090344":
+float: 1
+ifloat: 1
+Test "cosh_towardzero (24) == 13244561064.92173614708845674912733665919":
+float: 1
+ifloat: 1
+
+# cpow
+Test "Real part of: cpow (0.75 + 1.25 i, 0.0 + 1.0 i) == 0.331825439177608832276067945276730566 + 0.131338600281188544930936345230903032 i":
+float: 1
+ifloat: 1
+Test "Imaginary part of: cpow (0.75 + 1.25 i, 0.0 + 1.0 i) == 0.331825439177608832276067945276730566 + 0.131338600281188544930936345230903032 i":
+float: 1
+ifloat: 1
+Test "Real part of: cpow (0.75 + 1.25 i, 0.75 + 1.25 i) == 0.117506293914473555420279832210420483 + 0.346552747708338676483025352060418001 i":
+double: 1
+float: 4
+idouble: 1
+ifloat: 4
+Test "Real part of: cpow (0.75 + 1.25 i, 1.0 + 1.0 i) == 0.0846958290317209430433805274189191353 + 0.513285749182902449043287190519090481 i":
+double: 2
+float: 3
+idouble: 2
+ifloat: 3
+Test "Real part of: cpow (2 + 3 i, 4 + 0 i) == -119.0 - 120.0 i":
+double: 1
+float: 4
+idouble: 1
+ifloat: 4
+Test "Imaginary part of: cpow (2 + 3 i, 4 + 0 i) == -119.0 - 120.0 i":
+float: 2
+ifloat: 2
+Test "Imaginary part of: cpow (e + 0 i, 0 + 2 * M_PIl i) == 1.0 + 0.0 i":
+double: 2
+float: 2
+idouble: 2
+ifloat: 2
+
+# csin
+Test "Real part of: csin (-0.75 + 710.5 i) == -1.255317763348154410745082950806112487736e308 + 1.347490911916428129246890157395342279438e308 i":
+double: 1
+idouble: 1
+Test "Real part of: csin (-0.75 + 89.5 i) == -2.522786001038096774676288412995370563339e38 + 2.708024460708609732016532185663087200560e38 i":
+float: 1
+ifloat: 1
+Test "Real part of: csin (-0.75 - 710.5 i) == -1.255317763348154410745082950806112487736e308 - 1.347490911916428129246890157395342279438e308 i":
+double: 1
+idouble: 1
+Test "Real part of: csin (-0.75 - 89.5 i) == -2.522786001038096774676288412995370563339e38 - 2.708024460708609732016532185663087200560e38 i":
+float: 1
+ifloat: 1
+Test "Real part of: csin (0.75 + 710.5 i) == 1.255317763348154410745082950806112487736e308 + 1.347490911916428129246890157395342279438e308 i":
+double: 1
+idouble: 1
+Test "Real part of: csin (0.75 + 89.5 i) == 2.522786001038096774676288412995370563339e38 + 2.708024460708609732016532185663087200560e38 i":
+float: 1
+ifloat: 1
+Test "Real part of: csin (0.75 - 710.5 i) == 1.255317763348154410745082950806112487736e308 - 1.347490911916428129246890157395342279438e308 i":
+double: 1
+idouble: 1
+Test "Real part of: csin (0.75 - 89.5 i) == 2.522786001038096774676288412995370563339e38 - 2.708024460708609732016532185663087200560e38 i":
+float: 1
+ifloat: 1
+Test "Real part of: csin (0x1p-1074 + 1440 i) == 5.981479269486130556466515778180916082415e301 + inf i":
+double: 1
+idouble: 1
+
+# csinh
+Test "Imaginary part of: csinh (-2 - 3 i) == 3.59056458998577995201256544779481679 - 0.530921086248519805267040090660676560 i":
+double: 1
+idouble: 1
+Test "Imaginary part of: csinh (-710.5 + 0.75 i) == -1.347490911916428129246890157395342279438e308 + 1.255317763348154410745082950806112487736e308 i":
+double: 1
+idouble: 1
+Test "Imaginary part of: csinh (-710.5 - 0.75 i) == -1.347490911916428129246890157395342279438e308 - 1.255317763348154410745082950806112487736e308 i":
+double: 1
+idouble: 1
+Test "Imaginary part of: csinh (-89.5 + 0.75 i) == -2.708024460708609732016532185663087200560e38 + 2.522786001038096774676288412995370563339e38 i":
+float: 1
+ifloat: 1
+Test "Imaginary part of: csinh (-89.5 - 0.75 i) == -2.708024460708609732016532185663087200560e38 - 2.522786001038096774676288412995370563339e38 i":
+float: 1
+ifloat: 1
+Test "Real part of: csinh (0.75 + 1.25 i) == 0.259294854551162779153349830618433028 + 1.22863452409509552219214606515777594 i":
+float: 1
+ifloat: 1
+Test "Imaginary part of: csinh (0.75 + 1.25 i) == 0.259294854551162779153349830618433028 + 1.22863452409509552219214606515777594 i":
+float: 1
+ifloat: 1
+Test "Imaginary part of: csinh (1440 + 0x1p-1074 i) == inf + 5.981479269486130556466515778180916082415e301 i":
+double: 1
+idouble: 1
+Test "Imaginary part of: csinh (710.5 + 0.75 i) == 1.347490911916428129246890157395342279438e308 + 1.255317763348154410745082950806112487736e308 i":
+double: 1
+idouble: 1
+Test "Imaginary part of: csinh (710.5 - 0.75 i) == 1.347490911916428129246890157395342279438e308 - 1.255317763348154410745082950806112487736e308 i":
+double: 1
+idouble: 1
+Test "Imaginary part of: csinh (89.5 + 0.75 i) == 2.708024460708609732016532185663087200560e38 + 2.522786001038096774676288412995370563339e38 i":
+float: 1
+ifloat: 1
+Test "Imaginary part of: csinh (89.5 - 0.75 i) == 2.708024460708609732016532185663087200560e38 - 2.522786001038096774676288412995370563339e38 i":
+float: 1
+ifloat: 1
+
+# csqrt
+Test "Real part of: csqrt (-2 + 3 i) == 0.89597747612983812471573375529004348 + 1.6741492280355400404480393008490519 i":
+float: 1
+ifloat: 1
+Test "Real part of: csqrt (-2 - 3 i) == 0.89597747612983812471573375529004348 - 1.6741492280355400404480393008490519 i":
+float: 1
+ifloat: 1
+Test "Imaginary part of: csqrt (0x1.fffffep+127 + 1.0 i) == 1.844674352395372953599975585936590505260e+19 + 2.710505511993121390769065968615872097053e-20 i":
+float: 1
+ifloat: 1
+Test "Real part of: csqrt (0x1.fffffffffffffp+1023 + 0x1.fffffffffffffp+1023 i) == 1.473094556905565378990473658199034571917e+154 + 6.101757441282702188537080005372547713595e+153 i":
+double: 1
+idouble: 1
+Test "Imaginary part of: csqrt (0x1.fffffffffffffp+1023 + 0x1.fffffffffffffp+1023 i) == 1.473094556905565378990473658199034571917e+154 + 6.101757441282702188537080005372547713595e+153 i":
+double: 1
+idouble: 1
+Test "Imaginary part of: csqrt (0x1.fffffffffffffp+1023 + 0x1p+1023 i) == 1.379778091031440685006200821918878702861e+154 + 3.257214233483129514781233066898042490248e+153 i":
+double: 1
+idouble: 1
+
+# ctan
+Test "Real part of: ctan (-2 - 3 i) == 0.376402564150424829275122113032269084e-2 - 1.00323862735360980144635859782192726 i":
+float: 1
+ifloat: 1
+Test "Imaginary part of: ctan (-2 - 3 i) == 0.376402564150424829275122113032269084e-2 - 1.00323862735360980144635859782192726 i":
+double: 1
+idouble: 1
+Test "Imaginary part of: ctan (0.75 + 1.25 i) == 0.160807785916206426725166058173438663 + 0.975363285031235646193581759755216379 i":
+double: 1
+idouble: 1
+Test "Real part of: ctan (0x1p1023 + 1 i) == -0.2254627924997545057926782581695274244229 + 0.8786063118883068695462540226219865087189 i":
+double: 1
+idouble: 1
+Test "Imaginary part of: ctan (0x1p127 + 1 i) == 0.2446359391192790896381501310437708987204 + 0.9101334047676183761532873794426475906201 i":
+double: 1
+idouble: 1
+Test "Real part of: ctan (0x3.243f6cp-1 + 0 i) == -2.287733242885645987394874673945769518150e7 + 0.0 i":
+float: 1
+ifloat: 1
+
+# ctanh
+Test "Real part of: ctanh (-2 - 3 i) == -0.965385879022133124278480269394560686 + 0.988437503832249372031403430350121098e-2 i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "Imaginary part of: ctanh (-2 - 3 i) == -0.965385879022133124278480269394560686 + 0.988437503832249372031403430350121098e-2 i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "Imaginary part of: ctanh (0 + 0x3.243f6cp-1 i) == 0.0 - 2.287733242885645987394874673945769518150e7 i":
+float: 1
+ifloat: 1
+Test "Imaginary part of: ctanh (0 + pi/4 i) == 0.0 + 1.0 i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "Real part of: ctanh (0.75 + 1.25 i) == 1.37260757053378320258048606571226857 + 0.385795952609750664177596760720790220 i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "Imaginary part of: ctanh (0.75 + 1.25 i) == 1.37260757053378320258048606571226857 + 0.385795952609750664177596760720790220 i":
+float: 2
+ifloat: 2
+Test "Imaginary part of: ctanh (1 + 0x1p1023 i) == 0.8786063118883068695462540226219865087189 - 0.2254627924997545057926782581695274244229 i":
+double: 1
+idouble: 1
+Test "Real part of: ctanh (1 + 0x1p127 i) == 0.9101334047676183761532873794426475906201 + 0.2446359391192790896381501310437708987204 i":
+double: 1
+idouble: 1
+
+# erf
+Test "erf (1.25) == 0.922900128256458230136523481197281140":
+double: 1
+idouble: 1
+
+# erfc
+Test "erfc (0x1.f7303cp+1) == 2.705500297238986897105236321218861842255e-8":
+double: 1
+idouble: 1
+Test "erfc (0x1.ffa002p+2) == 1.233585992097580296336099501489175967033e-29":
+float: 1
+ifloat: 1
+Test "erfc (2.0) == 0.00467773498104726583793074363274707139":
+double: 1
+idouble: 1
+Test "erfc (4.125) == 0.542340079956506600531223408575531062e-8":
+double: 1
+idouble: 1
+
+# exp10
+Test "exp10 (-1) == 0.1":
+double: 1
+idouble: 1
+Test "exp10 (-305) == 1.0e-305":
+double: 1
+idouble: 1
+Test "exp10 (-36) == 1.0e-36":
+double: 1
+idouble: 1
+Test "exp10 (3) == 1000":
+double: 1
+idouble: 1
+Test "exp10 (36) == 1.0e36":
+double: 1
+idouble: 1
+
+# exp_downward
+Test "exp_downward (2) == e^2":
+float: 1
+ifloat: 1
+Test "exp_downward (3) == e^3":
+float: 1
+ifloat: 1
+
+# exp_towardzero
+Test "exp_towardzero (2) == e^2":
+float: 1
+ifloat: 1
+Test "exp_towardzero (3) == e^3":
+float: 1
+ifloat: 1
+
+# exp_upward
+Test "exp_upward (1) == e":
+float: 1
+ifloat: 1
+
+# expm1
+Test "expm1 (0.75) == 1.11700001661267466854536981983709561":
+double: 1
+idouble: 1
+Test "expm1 (1) == M_El - 1.0":
+float: 1
+ifloat: 1
+Test "expm1 (500.0) == 1.4035922178528374107397703328409120821806e+217":
+double: 1
+idouble: 1
+
+# hypot
+Test "hypot (-0.7, -12.4) == 12.419742348374220601176836866763271":
+float: 1
+ifloat: 1
+Test "hypot (-0.7, 12.4) == 12.419742348374220601176836866763271":
+float: 1
+ifloat: 1
+Test "hypot (-12.4, -0.7) == 12.419742348374220601176836866763271":
+float: 1
+ifloat: 1
+Test "hypot (-12.4, 0.7) == 12.419742348374220601176836866763271":
+float: 1
+ifloat: 1
+Test "hypot (0.7, -12.4) == 12.419742348374220601176836866763271":
+float: 1
+ifloat: 1
+Test "hypot (0.7, 12.4) == 12.419742348374220601176836866763271":
+float: 1
+ifloat: 1
+Test "hypot (12.4, -0.7) == 12.419742348374220601176836866763271":
+float: 1
+ifloat: 1
+Test "hypot (12.4, 0.7) == 12.419742348374220601176836866763271":
+float: 1
+ifloat: 1
+
+# j0
+Test "j0 (-4.0) == -3.9714980986384737228659076845169804197562E-1":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "j0 (0.75) == 0.864242275166648623555731103820923211":
+float: 1
+ifloat: 1
+Test "j0 (0x1.d7ce3ap+107) == 2.775523647291230802651040996274861694514e-17":
+float: 2
+ifloat: 2
+Test "j0 (10.0) == -0.245935764451348335197760862485328754":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+Test "j0 (2.0) == 0.223890779141235668051827454649948626":
+float: 2
+ifloat: 2
+Test "j0 (4.0) == -3.9714980986384737228659076845169804197562E-1":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "j0 (8.0) == 0.171650807137553906090869407851972001":
+float: 1
+ifloat: 1
+
+# j1
+Test "j1 (0x1.3ffp+74) == 1.818984347516051243459364437186082741567e-12":
+double: 1
+idouble: 1
+Test "j1 (0x1.ff00000000002p+840) == 1.846591691699331493194965158699937660696e-127":
+double: 1
+idouble: 1
+Test "j1 (10.0) == 0.0434727461688614366697487680258592883":
+float: 2
+ifloat: 2
+Test "j1 (2.0) == 0.576724807756873387202448242269137087":
+double: 1
+idouble: 1
+Test "j1 (8.0) == 0.234636346853914624381276651590454612":
+double: 1
+idouble: 1
+
+# jn
+Test "jn (0, -4.0) == -3.9714980986384737228659076845169804197562E-1":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "jn (0, 0.75) == 0.864242275166648623555731103820923211":
+float: 1
+ifloat: 1
+Test "jn (0, 10.0) == -0.245935764451348335197760862485328754":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+Test "jn (0, 2.0) == 0.223890779141235668051827454649948626":
+float: 2
+ifloat: 2
+Test "jn (0, 4.0) == -3.9714980986384737228659076845169804197562E-1":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "jn (0, 8.0) == 0.171650807137553906090869407851972001":
+float: 1
+ifloat: 1
+Test "jn (1, 10.0) == 0.0434727461688614366697487680258592883":
+float: 2
+ifloat: 2
+Test "jn (1, 2.0) == 0.576724807756873387202448242269137087":
+double: 1
+idouble: 1
+Test "jn (1, 8.0) == 0.234636346853914624381276651590454612":
+double: 1
+idouble: 1
+Test "jn (10, 0.125) == 0.250543369809369890173993791865771547e-18":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "jn (10, 0.75) == 0.149621713117596814698712483621682835e-10":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "jn (10, 10.0) == 0.207486106633358857697278723518753428":
+double: 4
+float: 3
+idouble: 4
+ifloat: 3
+Test "jn (10, 2.0) == 0.251538628271673670963516093751820639e-6":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+Test "jn (2, 0x1.ffff62p+99) == -4.43860668048170034334926693188979974489e-16":
+double: 2
+float: 2
+idouble: 2
+ifloat: 2
+Test "jn (2, 2.4048255576957729) == 0.43175480701968038399746111312430703":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+Test "jn (3, 0.125) == 0.406503832554912875023029337653442868e-4":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "jn (3, 0.75) == 0.848438342327410884392755236884386804e-2":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "jn (3, 10.0) == 0.0583793793051868123429354784103409563":
+double: 3
+float: 1
+idouble: 3
+ifloat: 1
+Test "jn (3, 2.0) == 0.128943249474402051098793332969239835":
+float: 1
+ifloat: 1
+Test "jn (3, 2.4048255576957729) == 0.19899990535769083404042146764530813":
+double: 3
+idouble: 3
+Test "jn (4, 2.4048255576957729) == 0.647466661641779720084932282551219891E-1":
+double: 1
+idouble: 1
+Test "jn (5, 2.4048255576957729) == 0.163892432048058525099230549946147698E-1":
+double: 3
+float: 1
+idouble: 3
+ifloat: 1
+Test "jn (6, 2.4048255576957729) == 0.34048184720278336646673682895929161E-2":
+double: 4
+float: 3
+idouble: 4
+ifloat: 3
+Test "jn (7, 2.4048255576957729) == 0.60068836573295394221291569249883076E-3":
+double: 3
+float: 5
+idouble: 3
+ifloat: 5
+Test "jn (8, 2.4048255576957729) == 0.92165786705344923232879022467054148E-4":
+double: 3
+float: 2
+idouble: 3
+ifloat: 2
+Test "jn (9, 2.4048255576957729) == 0.12517270977961513005428966643852564E-4":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+
+# lgamma
+Test "lgamma (0.7) == 0.260867246531666514385732417016759578":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "lgamma (1.2) == -0.853740900033158497197028392998854470e-1":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+
+# log10
+Test "log10 (0.75) == -0.124938736608299953132449886193870744":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+Test "log10 (e) == log10(e)":
+float: 1
+ifloat: 1
+
+# log1p
+Test "log1p (-0.25) == -0.287682072451780927439219005993827432":
+float: 1
+ifloat: 1
+
+# pow
+Test "pow (0x0.ffffffp0, -0x1p24) == 2.7182819094701610539628664526874952929416":
+float: 1
+ifloat: 1
+Test "pow (0x0.ffffffp0, 0x1p24) == 0.3678794302077803437135155590023422899744":
+float: 1
+ifloat: 1
+Test "pow (0x1.000002p0, 0x1p24) == 7.3890552180866447284268641248075832310141":
+float: 1
+ifloat: 1
+
+# pow_downward
+Test "pow_downward (1.5, 1.03125) == 1.519127098714743184071644334163037684948":
+float: 1
+ifloat: 1
+
+# pow_towardzero
+Test "pow_towardzero (1.5, 1.03125) == 1.519127098714743184071644334163037684948":
+float: 1
+ifloat: 1
+
+# pow_upward
+Test "pow_upward (1.0625, 1.125) == 1.070582293028761362162622578677070098674":
+float: 1
+ifloat: 1
+
+# sin_downward
+Test "sin_downward (10) == -0.5440211108893698134047476618513772816836":
+float: 1
+ifloat: 1
+Test "sin_downward (3) == 0.1411200080598672221007448028081102798469":
+float: 1
+ifloat: 1
+Test "sin_downward (5) == -0.9589242746631384688931544061559939733525":
+float: 1
+ifloat: 1
+Test "sin_downward (6) == -0.2794154981989258728115554466118947596280":
+float: 1
+ifloat: 1
+
+# sin_tonearest
+Test "sin_tonearest (1) == 0.8414709848078965066525023216302989996226":
+float: 1
+ifloat: 1
+
+# sin_towardzero
+Test "sin_towardzero (1) == 0.8414709848078965066525023216302989996226":
+float: 1
+ifloat: 1
+Test "sin_towardzero (10) == -0.5440211108893698134047476618513772816836":
+float: 1
+ifloat: 1
+Test "sin_towardzero (4) == -0.7568024953079282513726390945118290941359":
+float: 1
+ifloat: 1
+Test "sin_towardzero (5) == -0.9589242746631384688931544061559939733525":
+float: 1
+ifloat: 1
+Test "sin_towardzero (9) == 0.4121184852417565697562725663524351793439":
+float: 1
+ifloat: 1
+
+# sin_upward
+Test "sin_upward (1) == 0.8414709848078965066525023216302989996226":
+float: 1
+ifloat: 1
+Test "sin_upward (2) == 0.9092974268256816953960198659117448427023":
+float: 2
+ifloat: 2
+Test "sin_upward (4) == -0.7568024953079282513726390945118290941359":
+float: 1
+ifloat: 1
+Test "sin_upward (9) == 0.4121184852417565697562725663524351793439":
+float: 1
+ifloat: 1
+
+# sincos
+Test "sincos (M_PI_6l*2.0, &sin_res, &cos_res) puts 0.5 in cos_res":
+double: 1
+idouble: 1
+Test "sincos (M_PI_6l*2.0, &sin_res, &cos_res) puts 0.86602540378443864676372317075293616 in sin_res":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "sincos (pi/6, &sin_res, &cos_res) puts 0.86602540378443864676372317075293616 in cos_res":
+float: 1
+ifloat: 1
+
+# sinh_downward
+Test "sinh_downward (22) == 1792456423.065795780701106568345764104225":
+float: 1
+ifloat: 1
+Test "sinh_downward (23) == 4872401723.124451299966006944252978187305":
+float: 1
+ifloat: 1
+Test "sinh_downward (24) == 13244561064.92173614705070540368454568168":
+float: 1
+ifloat: 1
+
+# sinh_towardzero
+Test "sinh_towardzero (22) == 1792456423.065795780701106568345764104225":
+float: 1
+ifloat: 1
+Test "sinh_towardzero (23) == 4872401723.124451299966006944252978187305":
+float: 1
+ifloat: 1
+Test "sinh_towardzero (24) == 13244561064.92173614705070540368454568168":
+float: 1
+ifloat: 1
+
+# tan_downward
+Test "tan_downward (1) == 1.5574077246549022305069748074583601730873":
+float: 1
+ifloat: 1
+Test "tan_downward (10) == 0.6483608274590866712591249330098086768169":
+float: 1
+ifloat: 1
+Test "tan_downward (2) == -2.1850398632615189916433061023136825434320":
+float: 1
+ifloat: 1
+Test "tan_downward (6) == -0.2910061913847491570536995888681755428312":
+float: 1
+ifloat: 1
+Test "tan_downward (8) == -6.7997114552203786999252627596086333648814":
+float: 1
+ifloat: 1
+Test "tan_downward (9) == -0.4523156594418098405903708757987855343087":
+float: 1
+ifloat: 1
+
+# tan_towardzero
+Test "tan_towardzero (10) == 0.6483608274590866712591249330098086768169":
+float: 1
+ifloat: 1
+Test "tan_towardzero (3) == -0.1425465430742778052956354105339134932261":
+float: 1
+ifloat: 1
+Test "tan_towardzero (4) == 1.1578212823495775831373424182673239231198":
+float: 1
+ifloat: 1
+Test "tan_towardzero (5) == -3.3805150062465856369827058794473439087096":
+float: 1
+ifloat: 1
+Test "tan_towardzero (9) == -0.4523156594418098405903708757987855343087":
+float: 1
+ifloat: 1
+
+# tan_upward
+Test "tan_upward (1) == 1.5574077246549022305069748074583601730873":
+float: 1
+ifloat: 1
+Test "tan_upward (10) == 0.6483608274590866712591249330098086768169":
+float: 1
+ifloat: 1
+Test "tan_upward (3) == -0.1425465430742778052956354105339134932261":
+float: 1
+ifloat: 1
+Test "tan_upward (5) == -3.3805150062465856369827058794473439087096":
+float: 1
+ifloat: 1
+
+# tgamma
+Test "tgamma (-0.5) == -2 sqrt (pi)":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "tgamma (0.5) == sqrt (pi)":
+float: 1
+ifloat: 1
+Test "tgamma (0.7) == 1.29805533264755778568117117915281162":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+# y0
+Test "y0 (0x1.3ffp+74) == 1.818984347516051243459467456433028748678e-12":
+double: 1
+idouble: 1
+Test "y0 (0x1.ff00000000002p+840) == 1.846591691699331493194965158699937660696e-127":
+double: 1
+idouble: 1
+Test "y0 (1.0) == 0.0882569642156769579829267660235151628":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+Test "y0 (1.5) == 0.382448923797758843955068554978089862":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+Test "y0 (10.0) == 0.0556711672835993914244598774101900481":
+float: 1
+ifloat: 1
+Test "y0 (8.0) == 0.223521489387566220527323400498620359":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+# y1
+Test "y1 (0.125) == -5.19993611253477499595928744876579921":
+double: 1
+idouble: 1
+Test "y1 (0x1.27e204p+99) == -8.881610148467797208469612080785210013461e-16":
+double: 1
+idouble: 1
+Test "y1 (1.5) == -0.412308626973911295952829820633445323":
+float: 1
+ifloat: 1
+Test "y1 (10.0) == 0.249015424206953883923283474663222803":
+double: 3
+float: 1
+idouble: 3
+ifloat: 1
+Test "y1 (2.0) == -0.107032431540937546888370772277476637":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "y1 (8.0) == -0.158060461731247494255555266187483550":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+
+# yn
+Test "yn (0, 1.0) == 0.0882569642156769579829267660235151628":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+Test "yn (0, 1.5) == 0.382448923797758843955068554978089862":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+Test "yn (0, 10.0) == 0.0556711672835993914244598774101900481":
+float: 1
+ifloat: 1
+Test "yn (0, 8.0) == 0.223521489387566220527323400498620359":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "yn (1, 0.125) == -5.19993611253477499595928744876579921":
+double: 1
+idouble: 1
+Test "yn (1, 1.5) == -0.412308626973911295952829820633445323":
+float: 1
+ifloat: 1
+Test "yn (1, 10.0) == 0.249015424206953883923283474663222803":
+double: 3
+float: 1
+idouble: 3
+ifloat: 1
+Test "yn (1, 2.0) == -0.107032431540937546888370772277476637":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "yn (1, 8.0) == -0.158060461731247494255555266187483550":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+Test "yn (10, 0.125) == -127057845771019398.252538486899753195":
+double: 1
+idouble: 1
+Test "yn (10, 0.75) == -2133501638.90573424452445412893839236":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "yn (10, 1.0) == -121618014.278689189288130426667971145":
+double: 1
+idouble: 1
+Test "yn (10, 10.0) == -0.359814152183402722051986577343560609":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "yn (10, 2.0) == -129184.542208039282635913145923304214":
+double: 2
+idouble: 2
+Test "yn (3, 0.125) == -2612.69757350066712600220955744091741":
+double: 1
+idouble: 1
+Test "yn (3, 0.75) == -12.9877176234475433186319774484809207":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "yn (3, 10.0) == -0.251362657183837329779204747654240998":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "yn (3, 2.0) == -1.12778377684042778608158395773179238":
+double: 1
+idouble: 1
+
+# Maximal error of functions:
+Function: "acos_downward":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+Function: "acos_towardzero":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+Function: "asin_downward":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+Function: "asin_towardzero":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+Function: "asin_upward":
+float: 1
+ifloat: 1
+
+Function: "atan2":
+float: 1
+ifloat: 1
+
+Function: "atanh":
+float: 1
+ifloat: 1
+
+Function: Real part of "cacos":
+double: 1
+idouble: 1
+
+Function: Imaginary part of "cacos":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+
+Function: Real part of "cacosh":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+Function: Imaginary part of "cacosh":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+Function: Real part of "casin":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+Function: Imaginary part of "casin":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+
+Function: Real part of "casinh":
+double: 5
+float: 1
+idouble: 5
+ifloat: 1
+
+Function: Imaginary part of "casinh":
+double: 3
+float: 6
+idouble: 3
+ifloat: 6
+
+Function: Imaginary part of "catan":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+Function: Real part of "catanh":
+double: 4
+idouble: 4
+
+Function: "cbrt":
+double: 1
+idouble: 1
+
+Function: Real part of "ccos":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+Function: Imaginary part of "ccos":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+Function: Real part of "ccosh":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+Function: Imaginary part of "ccosh":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+Function: Real part of "cexp":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+
+Function: Imaginary part of "cexp":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+
+Function: Real part of "clog":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+Function: Real part of "clog10":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+Function: Imaginary part of "clog10":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+Function: "cos":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+
+Function: "cos_downward":
+float: 1
+ifloat: 1
+
+Function: "cos_tonearest":
+float: 1
+ifloat: 1
+
+Function: "cos_towardzero":
+float: 1
+ifloat: 1
+
+Function: "cos_upward":
+float: 2
+ifloat: 2
+
+Function: "cosh_downward":
+float: 1
+ifloat: 1
+
+Function: "cosh_towardzero":
+float: 1
+ifloat: 1
+
+Function: Real part of "cpow":
+double: 2
+float: 4
+idouble: 2
+ifloat: 4
+
+Function: Imaginary part of "cpow":
+double: 2
+float: 2
+idouble: 2
+ifloat: 2
+
+Function: Real part of "csin":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+Function: Real part of "csinh":
+float: 1
+ifloat: 1
+
+Function: Imaginary part of "csinh":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+Function: Real part of "csqrt":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+Function: Imaginary part of "csqrt":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+Function: Real part of "ctan":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+Function: Imaginary part of "ctan":
+double: 1
+idouble: 1
+
+Function: Real part of "ctanh":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+Function: Imaginary part of "ctanh":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+
+Function: "erf":
+double: 1
+idouble: 1
+
+Function: "erfc":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+Function: "exp10":
+double: 1
+idouble: 1
+
+Function: "exp_downward":
+float: 1
+ifloat: 1
+
+Function: "exp_towardzero":
+float: 1
+ifloat: 1
+
+Function: "exp_upward":
+float: 1
+ifloat: 1
+
+Function: "expm1":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+Function: "hypot":
+float: 1
+ifloat: 1
+
+Function: "j0":
+double: 2
+float: 2
+idouble: 2
+ifloat: 2
+
+Function: "j1":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+
+Function: "jn":
+double: 4
+float: 5
+idouble: 4
+ifloat: 5
+
+Function: "lgamma":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+
+Function: "log10":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+
+Function: "log1p":
+float: 1
+ifloat: 1
+
+Function: "pow":
+float: 1
+ifloat: 1
+
+Function: "pow_downward":
+float: 1
+ifloat: 1
+
+Function: "pow_towardzero":
+float: 1
+ifloat: 1
+
+Function: "pow_upward":
+float: 1
+ifloat: 1
+
+Function: "sin_downward":
+float: 1
+ifloat: 1
+
+Function: "sin_tonearest":
+float: 1
+ifloat: 1
+
+Function: "sin_towardzero":
+float: 1
+ifloat: 1
+
+Function: "sin_upward":
+float: 2
+ifloat: 2
+
+Function: "sincos":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+Function: "sinh_downward":
+float: 1
+ifloat: 1
+
+Function: "sinh_towardzero":
+float: 1
+ifloat: 1
+
+Function: "tan":
+double: 1
+idouble: 1
+
+Function: "tan_downward":
+float: 1
+ifloat: 1
+
+Function: "tan_towardzero":
+float: 1
+ifloat: 1
+
+Function: "tan_upward":
+float: 1
+ifloat: 1
+
+Function: "tgamma":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+Function: "y0":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+
+Function: "y1":
+double: 3
+float: 2
+idouble: 3
+ifloat: 2
+
+Function: "yn":
+double: 3
+float: 2
+idouble: 3
+ifloat: 2
+
+# end of automatic generation
diff --git a/ports/sysdeps/arm/machine-gmon.h b/ports/sysdeps/arm/machine-gmon.h
new file mode 100644
index 0000000000..671d6b176b
--- /dev/null
+++ b/ports/sysdeps/arm/machine-gmon.h
@@ -0,0 +1,33 @@
+/* Machine-dependent definitions for profiling support.  ARM EABI version.
+   Copyright (C) 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, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <sysdep.h>
+
+/* GCC for the ARM cannot compile __builtin_return_address(N) for N != 0, 
+   so we must use an assembly stub.  */
+
+/* We must not pollute the global namespace.  */
+#define mcount_internal __mcount_internal
+
+extern void mcount_internal (u_long frompc, u_long selfpc) internal_function;
+#define _MCOUNT_DECL(frompc, selfpc) \
+  void internal_function mcount_internal (u_long frompc, u_long selfpc)
+
+
+/* Define MCOUNT as empty since we have the implementation in another file.  */
+#define MCOUNT
diff --git a/ports/sysdeps/arm/memcpy.S b/ports/sysdeps/arm/memcpy.S
new file mode 100644
index 0000000000..08f7f76ecf
--- /dev/null
+++ b/ports/sysdeps/arm/memcpy.S
@@ -0,0 +1,263 @@
+/* Copyright (C) 2006, 2009 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   Contributed by MontaVista Software, Inc. (written by Nicolas Pitre)
+
+   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>
+
+/*
+ * Data preload for architectures that support it (ARM V5TE and above)
+ */
+#if (!defined (__ARM_ARCH_2__) && !defined (__ARM_ARCH_3__) \
+     && !defined (__ARM_ARCH_3M__) && !defined (__ARM_ARCH_4__) \
+     && !defined (__ARM_ARCH_4T__) && !defined (__ARM_ARCH_5__) \
+     && !defined (__ARM_ARCH_5T__))
+#define PLD(code...)    code
+#else
+#define PLD(code...)
+#endif
+
+/*
+ * This can be used to enable code to cacheline align the source pointer.
+ * Experiments on tested architectures (StrongARM and XScale) didn't show
+ * this a worthwhile thing to do.  That might be different in the future.
+ */
+//#define CALGN(code...)        code
+#define CALGN(code...)
+
+/*
+ * Endian independent macros for shifting bytes within registers.
+ */
+#ifndef __ARMEB__
+#define pull            lsr
+#define push            lsl
+#else
+#define pull            lsl
+#define push            lsr
+#endif
+
+		.text
+
+/* Prototype: void *memcpy(void *dest, const void *src, size_t n); */
+
+ENTRY(memcpy)
+
+		stmfd	sp!, {r0, r4, lr}
+		cfi_adjust_cfa_offset (12)
+		cfi_rel_offset (r4, 4)
+		cfi_rel_offset (lr, 8)
+
+		cfi_remember_state
+
+		subs	r2, r2, #4
+		blt	8f
+		ands	ip, r0, #3
+	PLD(	pld	[r1, #0]		)
+		bne	9f
+		ands	ip, r1, #3
+		bne	10f
+
+1:		subs	r2, r2, #(28)
+		stmfd	sp!, {r5 - r8}
+		cfi_adjust_cfa_offset (16)
+		cfi_rel_offset (r5, 0)
+		cfi_rel_offset (r6, 4)
+		cfi_rel_offset (r7, 8)
+		cfi_rel_offset (r8, 12)
+		blt	5f
+
+	CALGN(	ands	ip, r1, #31		)
+	CALGN(	rsb	r3, ip, #32		)
+	CALGN(	sbcnes	r4, r3, r2		)  @ C is always set here
+	CALGN(	bcs	2f			)
+	CALGN(	adr	r4, 6f			)
+	CALGN(	subs	r2, r2, r3		)  @ C gets set
+	CALGN(	add	pc, r4, ip		)
+
+	PLD(	pld	[r1, #0]		)
+2:	PLD(	subs	r2, r2, #96		)
+	PLD(	pld	[r1, #28]		)
+	PLD(	blt	4f			)
+	PLD(	pld	[r1, #60]		)
+	PLD(	pld	[r1, #92]		)
+
+3:	PLD(	pld	[r1, #124]		)
+4:		ldmia	r1!, {r3, r4, r5, r6, r7, r8, ip, lr}
+		subs	r2, r2, #32
+		stmia	r0!, {r3, r4, r5, r6, r7, r8, ip, lr}
+		bge	3b
+	PLD(	cmn	r2, #96			)
+	PLD(	bge	4b			)
+
+5:		ands	ip, r2, #28
+		rsb	ip, ip, #32
+		addne	pc, pc, ip		@ C is always clear here
+		b	7f
+6:		nop
+		ldr	r3, [r1], #4
+		ldr	r4, [r1], #4
+		ldr	r5, [r1], #4
+		ldr	r6, [r1], #4
+		ldr	r7, [r1], #4
+		ldr	r8, [r1], #4
+		ldr	lr, [r1], #4
+
+		add	pc, pc, ip
+		nop
+		nop
+		str	r3, [r0], #4
+		str	r4, [r0], #4
+		str	r5, [r0], #4
+		str	r6, [r0], #4
+		str	r7, [r0], #4
+		str	r8, [r0], #4
+		str	lr, [r0], #4
+
+	CALGN(	bcs	2b			)
+
+7:		ldmfd	sp!, {r5 - r8}
+		cfi_adjust_cfa_offset (-16)
+		cfi_restore (r5)
+		cfi_restore (r6)
+		cfi_restore (r7)
+		cfi_restore (r8)
+
+8:		movs	r2, r2, lsl #31
+		ldrneb	r3, [r1], #1
+		ldrcsb	r4, [r1], #1
+		ldrcsb	ip, [r1]
+		strneb	r3, [r0], #1
+		strcsb	r4, [r0], #1
+		strcsb	ip, [r0]
+
+#if defined (__ARM_ARCH_4T__) && defined(__THUMB_INTERWORK__)
+		ldmfd	sp!, {r0, r4, lr}
+		cfi_adjust_cfa_offset (-12)
+		cfi_restore (r4)
+		cfi_restore (lr)
+		bx      lr
+#else
+		ldmfd	sp!, {r0, r4, pc}
+#endif
+
+		cfi_restore_state
+
+9:		rsb	ip, ip, #4
+		cmp	ip, #2
+		ldrgtb	r3, [r1], #1
+		ldrgeb	r4, [r1], #1
+		ldrb	lr, [r1], #1
+		strgtb	r3, [r0], #1
+		strgeb	r4, [r0], #1
+		subs	r2, r2, ip
+		strb	lr, [r0], #1
+		blt	8b
+		ands	ip, r1, #3
+		beq	1b
+
+10:		bic	r1, r1, #3
+		cmp	ip, #2
+		ldr	lr, [r1], #4
+		beq	17f
+		bgt	18f
+
+
+		.macro	forward_copy_shift pull push
+
+		subs	r2, r2, #28
+		blt	14f
+
+	CALGN(	ands	ip, r1, #31		)
+	CALGN(	rsb	ip, ip, #32		)
+	CALGN(	sbcnes	r4, ip, r2		)  @ C is always set here
+	CALGN(	subcc	r2, r2, ip		)
+	CALGN(	bcc	15f			)
+
+11:		stmfd	sp!, {r5 - r9}
+		cfi_adjust_cfa_offset (20)
+		cfi_rel_offset (r5, 0)
+		cfi_rel_offset (r6, 4)
+		cfi_rel_offset (r7, 8)
+		cfi_rel_offset (r8, 12)
+		cfi_rel_offset (r9, 16)
+
+	PLD(	pld	[r1, #0]		)
+	PLD(	subs	r2, r2, #96		)
+	PLD(	pld	[r1, #28]		)
+	PLD(	blt	13f			)
+	PLD(	pld	[r1, #60]		)
+	PLD(	pld	[r1, #92]		)
+
+12:	PLD(	pld	[r1, #124]		)
+13:		ldmia	r1!, {r4, r5, r6, r7}
+		mov	r3, lr, pull #\pull
+		subs	r2, r2, #32
+		ldmia	r1!, {r8, r9, ip, lr}
+		orr	r3, r3, r4, push #\push
+		mov	r4, r4, pull #\pull
+		orr	r4, r4, r5, push #\push
+		mov	r5, r5, pull #\pull
+		orr	r5, r5, r6, push #\push
+		mov	r6, r6, pull #\pull
+		orr	r6, r6, r7, push #\push
+		mov	r7, r7, pull #\pull
+		orr	r7, r7, r8, push #\push
+		mov	r8, r8, pull #\pull
+		orr	r8, r8, r9, push #\push
+		mov	r9, r9, pull #\pull
+		orr	r9, r9, ip, push #\push
+		mov	ip, ip, pull #\pull
+		orr	ip, ip, lr, push #\push
+		stmia	r0!, {r3, r4, r5, r6, r7, r8, r9, ip}
+		bge	12b
+	PLD(	cmn	r2, #96			)
+	PLD(	bge	13b			)
+
+		ldmfd	sp!, {r5 - r9}
+		cfi_adjust_cfa_offset (-20)
+		cfi_restore (r5)
+		cfi_restore (r6)
+		cfi_restore (r7)
+		cfi_restore (r8)
+		cfi_restore (r9)
+
+14:		ands	ip, r2, #28
+		beq	16f
+
+15:		mov	r3, lr, pull #\pull
+		ldr	lr, [r1], #4
+		subs	ip, ip, #4
+		orr	r3, r3, lr, push #\push
+		str	r3, [r0], #4
+		bgt	15b
+	CALGN(	cmp	r2, #0			)
+	CALGN(	bge	11b			)
+
+16:		sub	r1, r1, #(\push / 8)
+		b	8b
+
+		.endm
+
+
+		forward_copy_shift	pull=8	push=24
+
+17:		forward_copy_shift	pull=16	push=16
+
+18:		forward_copy_shift	pull=24	push=8
+
+END(memcpy)
+libc_hidden_builtin_def (memcpy)
diff --git a/ports/sysdeps/arm/memmove.S b/ports/sysdeps/arm/memmove.S
new file mode 100644
index 0000000000..4ec6567064
--- /dev/null
+++ b/ports/sysdeps/arm/memmove.S
@@ -0,0 +1,279 @@
+/* Copyright (C) 2006, 2008, 2009 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   Contributed by MontaVista Software, Inc. (written by Nicolas Pitre)
+
+   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>
+
+/*
+ * Data preload for architectures that support it (ARM V5TE and above)
+ */
+#if (!defined (__ARM_ARCH_2__) && !defined (__ARM_ARCH_3__) \
+     && !defined (__ARM_ARCH_3M__) && !defined (__ARM_ARCH_4__) \
+     && !defined (__ARM_ARCH_4T__) && !defined (__ARM_ARCH_5__) \
+     && !defined (__ARM_ARCH_5T__))
+#define PLD(code...)    code
+#else
+#define PLD(code...)
+#endif
+
+/*
+ * This can be used to enable code to cacheline align the source pointer.
+ * Experiments on tested architectures (StrongARM and XScale) didn't show
+ * this a worthwhile thing to do.  That might be different in the future.
+ */
+//#define CALGN(code...)        code
+#define CALGN(code...)
+
+/*
+ * Endian independent macros for shifting bytes within registers.
+ */
+#ifndef __ARMEB__
+#define pull            lsr
+#define push            lsl
+#else
+#define pull            lsl
+#define push            lsr
+#endif
+
+		.text
+
+/*
+ * Prototype: void *memmove(void *dest, const void *src, size_t n);
+ *
+ * Note:
+ *
+ * If the memory regions don't overlap, we simply branch to memcpy which is
+ * normally a bit faster. Otherwise the copy is done going downwards.
+ */
+
+ENTRY(memmove)
+
+		subs	ip, r0, r1
+		cmphi	r2, ip
+#ifdef NOT_IN_libc
+		bls	memcpy
+#else
+		bls	HIDDEN_JUMPTARGET(memcpy)
+#endif
+
+		stmfd	sp!, {r0, r4, lr}
+		cfi_adjust_cfa_offset (12)
+		cfi_rel_offset (r4, 4)
+		cfi_rel_offset (lr, 8)
+
+		cfi_remember_state
+
+		add	r1, r1, r2
+		add	r0, r0, r2
+		subs	r2, r2, #4
+		blt	8f
+		ands	ip, r0, #3
+	PLD(	pld	[r1, #-4]		)
+		bne	9f
+		ands	ip, r1, #3
+		bne	10f
+
+1:		subs	r2, r2, #(28)
+		stmfd	sp!, {r5 - r8}
+		cfi_adjust_cfa_offset (16)
+		cfi_rel_offset (r5, 0)
+		cfi_rel_offset (r6, 4)
+		cfi_rel_offset (r7, 8)
+		cfi_rel_offset (r8, 12)
+		blt	5f
+
+	CALGN(	ands	ip, r1, #31		)
+	CALGN(	sbcnes	r4, ip, r2		)  @ C is always set here
+	CALGN(	bcs	2f			)
+	CALGN(	adr	r4, 6f			)
+	CALGN(	subs	r2, r2, ip		)  @ C is set here
+	CALGN(	add	pc, r4, ip		)
+
+	PLD(	pld	[r1, #-4]		)
+2:	PLD(	subs	r2, r2, #96		)
+	PLD(	pld	[r1, #-32]		)
+	PLD(	blt	4f			)
+	PLD(	pld	[r1, #-64]		)
+	PLD(	pld	[r1, #-96]		)
+
+3:	PLD(	pld	[r1, #-128]		)
+4:		ldmdb	r1!, {r3, r4, r5, r6, r7, r8, ip, lr}
+		subs	r2, r2, #32
+		stmdb	r0!, {r3, r4, r5, r6, r7, r8, ip, lr}
+		bge	3b
+	PLD(	cmn	r2, #96			)
+	PLD(	bge	4b			)
+
+5:		ands	ip, r2, #28
+		rsb	ip, ip, #32
+		addne	pc, pc, ip		@ C is always clear here
+		b	7f
+6:		nop
+		ldr	r3, [r1, #-4]!
+		ldr	r4, [r1, #-4]!
+		ldr	r5, [r1, #-4]!
+		ldr	r6, [r1, #-4]!
+		ldr	r7, [r1, #-4]!
+		ldr	r8, [r1, #-4]!
+		ldr	lr, [r1, #-4]!
+
+		add	pc, pc, ip
+		nop
+		nop
+		str	r3, [r0, #-4]!
+		str	r4, [r0, #-4]!
+		str	r5, [r0, #-4]!
+		str	r6, [r0, #-4]!
+		str	r7, [r0, #-4]!
+		str	r8, [r0, #-4]!
+		str	lr, [r0, #-4]!
+
+	CALGN(	bcs	2b			)
+
+7:		ldmfd	sp!, {r5 - r8}
+		cfi_adjust_cfa_offset (-16)
+		cfi_restore (r5)
+		cfi_restore (r6)
+		cfi_restore (r7)
+		cfi_restore (r8)
+
+8:		movs	r2, r2, lsl #31
+		ldrneb	r3, [r1, #-1]!
+		ldrcsb	r4, [r1, #-1]!
+		ldrcsb	ip, [r1, #-1]
+		strneb	r3, [r0, #-1]!
+		strcsb	r4, [r0, #-1]!
+		strcsb	ip, [r0, #-1]
+
+#if defined (__ARM_ARCH_4T__) && defined (__THUMB_INTERWORK__)
+		ldmfd	sp!, {r0, r4, lr}
+		cfi_adjust_cfa_offset (-12)
+		cfi_restore (r4)
+		cfi_restore (lr)
+		bx      lr
+#else
+		ldmfd	sp!, {r0, r4, pc}
+#endif
+
+		cfi_restore_state
+
+9:		cmp	ip, #2
+		ldrgtb	r3, [r1, #-1]!
+		ldrgeb	r4, [r1, #-1]!
+		ldrb	lr, [r1, #-1]!
+		strgtb	r3, [r0, #-1]!
+		strgeb	r4, [r0, #-1]!
+		subs	r2, r2, ip
+		strb	lr, [r0, #-1]!
+		blt	8b
+		ands	ip, r1, #3
+		beq	1b
+
+10:		bic	r1, r1, #3
+		cmp	ip, #2
+		ldr	r3, [r1, #0]
+		beq	17f
+		blt	18f
+
+
+		.macro	backward_copy_shift push pull
+
+		subs	r2, r2, #28
+		blt	14f
+
+	CALGN(	ands	ip, r1, #31		)
+	CALGN(	rsb	ip, ip, #32		)
+	CALGN(	sbcnes	r4, ip, r2		)  @ C is always set here
+	CALGN(	subcc	r2, r2, ip		)
+	CALGN(	bcc	15f			)
+
+11:		stmfd	sp!, {r5 - r9}
+		cfi_adjust_cfa_offset (20)
+		cfi_rel_offset (r5, 0)
+		cfi_rel_offset (r6, 4)
+		cfi_rel_offset (r7, 8)
+		cfi_rel_offset (r8, 12)
+		cfi_rel_offset (r9, 16)
+
+	PLD(	pld	[r1, #-4]		)
+	PLD(	subs	r2, r2, #96		)
+	PLD(	pld	[r1, #-32]		)
+	PLD(	blt	13f			)
+	PLD(	pld	[r1, #-64]		)
+	PLD(	pld	[r1, #-96]		)
+
+12:	PLD(	pld	[r1, #-128]		)
+13:		ldmdb   r1!, {r7, r8, r9, ip}
+		mov     lr, r3, push #\push
+		subs    r2, r2, #32
+		ldmdb   r1!, {r3, r4, r5, r6}
+		orr     lr, lr, ip, pull #\pull
+		mov     ip, ip, push #\push
+		orr     ip, ip, r9, pull #\pull
+		mov     r9, r9, push #\push
+		orr     r9, r9, r8, pull #\pull
+		mov     r8, r8, push #\push
+		orr     r8, r8, r7, pull #\pull
+		mov     r7, r7, push #\push
+		orr     r7, r7, r6, pull #\pull
+		mov     r6, r6, push #\push
+		orr     r6, r6, r5, pull #\pull
+		mov     r5, r5, push #\push
+		orr     r5, r5, r4, pull #\pull
+		mov     r4, r4, push #\push
+		orr     r4, r4, r3, pull #\pull
+		stmdb   r0!, {r4 - r9, ip, lr}
+		bge	12b
+	PLD(	cmn	r2, #96			)
+	PLD(	bge	13b			)
+
+		ldmfd	sp!, {r5 - r9}
+		cfi_adjust_cfa_offset (-20)
+		cfi_restore (r5)
+		cfi_restore (r6)
+		cfi_restore (r7)
+		cfi_restore (r8)
+		cfi_restore (r9)
+
+14:		ands	ip, r2, #28
+		beq	16f
+
+15:		mov     lr, r3, push #\push
+		ldr	r3, [r1, #-4]!
+		subs	ip, ip, #4
+		orr	lr, lr, r3, pull #\pull
+		str	lr, [r0, #-4]!
+		bgt	15b
+	CALGN(	cmp	r2, #0			)
+	CALGN(	bge	11b			)
+
+16:		add	r1, r1, #(\pull / 8)
+		b	8b
+
+		.endm
+
+
+		backward_copy_shift	push=8	pull=24
+
+17:		backward_copy_shift	push=16	pull=16
+
+18:		backward_copy_shift	push=24	pull=8
+
+
+END(memmove)
+libc_hidden_builtin_def (memmove)
diff --git a/ports/sysdeps/arm/memset.S b/ports/sysdeps/arm/memset.S
new file mode 100644
index 0000000000..a29031c266
--- /dev/null
+++ b/ports/sysdeps/arm/memset.S
@@ -0,0 +1,64 @@
+/* Copyright (C) 1998, 2003 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Philip Blundell <philb@gnu.org>
+
+   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>
+
+/* void *memset (dstpp, c, len) */
+
+ENTRY(memset)
+	mov	r3, r0
+	cmp	r2, #8
+	bcc	2f		@ less than 8 bytes to move
+
+1:
+	tst	r3, #3		@ aligned yet?
+	strneb	r1, [r3], #1
+	subne	r2, r2, #1
+	bne	1b
+
+	and	r1, r1, #255	@ clear any sign bits
+	orr	r1, r1, r1, lsl $8
+	orr	r1, r1, r1, lsl $16
+	mov	ip, r1
+
+1:
+	subs	r2, r2, #8
+	stmcsia	r3!, {r1, ip}	@ store up to 32 bytes per loop iteration
+	subcss	r2, r2, #8
+	stmcsia	r3!, {r1, ip}
+	subcss	r2, r2, #8
+	stmcsia	r3!, {r1, ip}
+	subcss	r2, r2, #8
+	stmcsia	r3!, {r1, ip}
+	bcs	1b
+
+	and	r2, r2, #7
+2:
+	subs	r2, r2, #1	@ store up to 4 bytes per loop iteration
+	strcsb	r1, [r3], #1
+	subcss	r2, r2, #1
+	strcsb	r1, [r3], #1
+	subcss	r2, r2, #1
+	strcsb	r1, [r3], #1
+	subcss	r2, r2, #1
+	strcsb	r1, [r3], #1
+	bcs	2b
+	
+	DO_RET(lr)
+END(memset)
+libc_hidden_builtin_def (memset)
diff --git a/ports/sysdeps/arm/memusage.h b/ports/sysdeps/arm/memusage.h
new file mode 100644
index 0000000000..08a25425b9
--- /dev/null
+++ b/ports/sysdeps/arm/memusage.h
@@ -0,0 +1,20 @@
+/* Copyright (C) 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, see
+   <http://www.gnu.org/licenses/>.  */
+
+#define GETSP() ({ register uintptr_t stack_ptr asm ("sp"); stack_ptr; })
+
+#include <sysdeps/generic/memusage.h>
diff --git a/ports/sysdeps/arm/nptl/Makefile b/ports/sysdeps/arm/nptl/Makefile
new file mode 100644
index 0000000000..e2497397cb
--- /dev/null
+++ b/ports/sysdeps/arm/nptl/Makefile
@@ -0,0 +1,20 @@
+# 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, see
+# <http://www.gnu.org/licenses/>.
+
+ifeq ($(subdir),csu)
+gen-as-const-headers += tcb-offsets.sym
+endif
diff --git a/ports/sysdeps/arm/nptl/pthread_spin_lock.c b/ports/sysdeps/arm/nptl/pthread_spin_lock.c
new file mode 100644
index 0000000000..3a23bd31a5
--- /dev/null
+++ b/ports/sysdeps/arm/nptl/pthread_spin_lock.c
@@ -0,0 +1,29 @@
+/* Copyright (C) 2008 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <atomic.h>
+#include "pthreadP.h"
+
+int
+pthread_spin_lock (pthread_spinlock_t *lock)
+{
+  while (atomic_compare_and_exchange_val_acq (lock, 1, 0) != 0)
+   while (*lock != 0)
+    ;
+
+  return 0;
+}
diff --git a/ports/sysdeps/arm/nptl/pthread_spin_trylock.c b/ports/sysdeps/arm/nptl/pthread_spin_trylock.c
new file mode 100644
index 0000000000..7d3118071e
--- /dev/null
+++ b/ports/sysdeps/arm/nptl/pthread_spin_trylock.c
@@ -0,0 +1,26 @@
+/* Copyright (C) 2008 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <errno.h>
+#include <atomic.h>
+#include "pthreadP.h"
+
+int
+pthread_spin_trylock (pthread_spinlock_t *lock)
+{
+  return atomic_compare_and_exchange_val_acq (lock, 1, 0) ? EBUSY : 0;
+}
diff --git a/ports/sysdeps/arm/nptl/pthreaddef.h b/ports/sysdeps/arm/nptl/pthreaddef.h
new file mode 100644
index 0000000000..5385b24167
--- /dev/null
+++ b/ports/sysdeps/arm/nptl/pthreaddef.h
@@ -0,0 +1,46 @@
+/* Copyright (C) 2002, 2003, 2005 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   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/>.  */
+
+/* Default stack size.  */
+#define ARCH_STACK_DEFAULT_SIZE	(2 * 1024 * 1024)
+
+/* Required stack pointer alignment at beginning.  SSE requires 16
+   bytes.  */
+#define STACK_ALIGN		16
+
+/* 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.
+
+   __builtin_frame_address (0) returns the value of the hard frame
+   pointer, which will point at the location of the saved PC on the
+   stack.  Below this in memory is the remainder of the linkage info,
+   occupying 12 bytes.  Therefore in order to address from
+   CURRENT_STACK_FRAME using "struct layout", we need to have the macro
+   return the hard FP minus 12.  Of course, this makes no sense
+   without the obsolete APCS stack layout...  */
+#define CURRENT_STACK_FRAME	(__builtin_frame_address (0) - 12)
+
+
+/* XXX Until we have a better place keep the definitions here.  */
+#define __exit_thread_inline(val) \
+  INLINE_SYSCALL (exit, 1, (val))
diff --git a/ports/sysdeps/arm/nptl/tcb-offsets.sym b/ports/sysdeps/arm/nptl/tcb-offsets.sym
new file mode 100644
index 0000000000..92cc441d3d
--- /dev/null
+++ b/ports/sysdeps/arm/nptl/tcb-offsets.sym
@@ -0,0 +1,11 @@
+#include <sysdep.h>
+#include <tls.h>
+
+--
+
+-- Derive offsets relative to the thread register.
+#define thread_offsetof(mem)	(long)(offsetof(struct pthread, mem) - sizeof(struct pthread))
+
+MULTIPLE_THREADS_OFFSET		thread_offsetof (header.multiple_threads)
+PID_OFFSET			thread_offsetof (pid)
+TID_OFFSET			thread_offsetof (tid)
diff --git a/ports/sysdeps/arm/nptl/tls.h b/ports/sysdeps/arm/nptl/tls.h
new file mode 100644
index 0000000000..52f695e58b
--- /dev/null
+++ b/ports/sysdeps/arm/nptl/tls.h
@@ -0,0 +1,151 @@
+/* Definition for thread-local data handling.  NPTL/ARM version.
+   Copyright (C) 2005, 2007, 2011 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef _TLS_H
+#define _TLS_H	1
+
+#include <dl-sysdep.h>
+
+#ifndef __ASSEMBLER__
+# include <stdbool.h>
+# include <stddef.h>
+# include <stdint.h>
+
+/* Type for the dtv.  */
+typedef union dtv
+{
+  size_t counter;
+  struct
+  {
+    void *val;
+    bool is_static;
+  } pointer;
+} dtv_t;
+
+#else /* __ASSEMBLER__ */
+# include <tcb-offsets.h>
+#endif /* __ASSEMBLER__ */
+
+
+#ifndef __ASSEMBLER__
+
+/* Get system call information.  */
+# include <sysdep.h>
+
+/* The TP points to the start of the thread blocks.  */
+# define TLS_DTV_AT_TP	1
+
+/* Get the thread descriptor definition.  */
+# include <nptl/descr.h>
+
+typedef struct
+{
+  dtv_t *dtv;
+  void *private;
+} tcbhead_t;
+
+/* This is the size of the initial TCB.  */
+# define TLS_INIT_TCB_SIZE	sizeof (tcbhead_t)
+
+/* Alignment requirements for the initial TCB.  */
+# define TLS_INIT_TCB_ALIGN	16
+
+/* This is the size of the TCB.  */
+# define TLS_TCB_SIZE		sizeof (tcbhead_t)
+
+/* This is the size we need before TCB.  */
+# define TLS_PRE_TCB_SIZE	sizeof (struct pthread)
+
+/* Alignment requirements for the TCB.  */
+# define TLS_TCB_ALIGN		16
+
+/* Install the dtv pointer.  The pointer passed is to the element with
+   index -1 which contain the length.  */
+# define INSTALL_DTV(tcbp, dtvp) \
+  (((tcbhead_t *) (tcbp))->dtv = (dtvp) + 1)
+
+/* Install new dtv for current thread.  */
+# define INSTALL_NEW_DTV(dtv) \
+  (THREAD_DTV() = (dtv))
+
+/* Return dtv of given thread descriptor.  */
+# define GET_DTV(tcbp) \
+  (((tcbhead_t *) (tcbp))->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(tcbp, secondcall) \
+  ({ INTERNAL_SYSCALL_DECL (err);					\
+     long result_var;							\
+     result_var = INTERNAL_SYSCALL_ARM (set_tls, err, 1, (tcbp));	\
+     INTERNAL_SYSCALL_ERROR_P (result_var, err)				\
+       ? "unknown error" : NULL; })
+
+/* Return the address of the dtv for the current thread.  */
+# define THREAD_DTV() \
+  (((tcbhead_t *) __builtin_thread_pointer ())->dtv)
+
+/* Return the thread descriptor for the current thread.  */
+# define THREAD_SELF \
+ ((struct pthread *)__builtin_thread_pointer () - 1)
+
+/* Magic for libthread_db to know how to do THREAD_SELF.  */
+# define DB_THREAD_SELF \
+  CONST_THREAD_AREA (32, sizeof (struct pthread))
+
+/* 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)
+
+/* Initializing the thread pointer will generate a SIGILL if the syscall
+   is not available.  */
+#define TLS_INIT_TP_EXPENSIVE 1
+
+/* 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/ports/sysdeps/arm/preconfigure b/ports/sysdeps/arm/preconfigure
new file mode 100644
index 0000000000..d98c167a95
--- /dev/null
+++ b/ports/sysdeps/arm/preconfigure
@@ -0,0 +1,50 @@
+case "$machine" in
+arm*)
+	base_machine=arm
+	case $config_os in
+	linux-gnueabi*)
+		# Lets ask the compiler which ARM family we've got
+		# Unfortunately it doesn't define any flags for implementations
+		# that you might pass to -mcpu or -mtune
+		# Note if you add patterns here you must ensure that
+		# an appropriate directory exists in sysdeps/arm
+		archcppflag=`echo "" |
+		$CC $CFLAGS $CPPFLAGS -E -dM - |
+		  grep __ARM_ARCH |
+		  sed -e 's/^#define //' -e 's/ .*//'`
+
+		case x$archcppflag in
+		x__ARM_ARCH_[89]*__)
+		  machine=armv7
+		  echo "Found compiler is configured for something newer than v7 - using v7"
+		  ;;
+
+		x__ARM_ARCH_7A__)
+		  machine=armv7
+		  echo "Found compiler is configured for $machine"
+		  ;;
+
+		x__ARM_ARCH_6T2__)
+		  machine=armv6t2
+		  echo "Found compiler is configured for $machine"
+		  ;;
+
+		*)
+		  machine=arm
+		  echo 2>&1 "arm/preconfigure: Did not find ARM architecture type; using default"
+		  ;;
+		esac
+
+		machine=arm/$machine
+		if [ "${CFLAGS+set}" != "set" ]; then
+		  CFLAGS="-g -O2"
+		fi
+		CFLAGS="$CFLAGS -fno-unwind-tables"
+		;;
+	*)
+		echo "Old ABI no longer supported" 2>&1
+		exit 1
+		;;
+	esac
+	;;
+esac
diff --git a/ports/sysdeps/arm/rtld-global-offsets.sym b/ports/sysdeps/arm/rtld-global-offsets.sym
new file mode 100644
index 0000000000..ff4e97f2a6
--- /dev/null
+++ b/ports/sysdeps/arm/rtld-global-offsets.sym
@@ -0,0 +1,7 @@
+#define SHARED 1
+
+#include <ldsodefs.h>
+
+#define rtld_global_ro_offsetof(mem) offsetof (struct rtld_global_ro, mem)
+
+RTLD_GLOBAL_RO_DL_HWCAP_OFFSET	rtld_global_ro_offsetof (_dl_hwcap)
diff --git a/ports/sysdeps/arm/setfpucw.c b/ports/sysdeps/arm/setfpucw.c
new file mode 100644
index 0000000000..d0cea32b9d
--- /dev/null
+++ b/ports/sysdeps/arm/setfpucw.c
@@ -0,0 +1,46 @@
+/* Set the FPU control word.
+   Copyright (C) 1996, 1997, 1999, 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, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <math.h>
+#include <fpu_control.h>
+
+#include <unistd.h>
+#include <ldsodefs.h>
+#include <dl-procinfo.h>
+#include <sysdep.h>
+
+void
+__setfpucw (fpu_control_t set)
+{
+  if (GLRO (dl_hwcap) & HWCAP_ARM_VFP)
+    {
+      fpu_control_t cw;
+
+      /* Fetch the current control word.  */
+      _FPU_GETCW (cw);
+
+      /* Preserve the reserved bits, and set the rest as the user
+	 specified (or the default, if the user gave zero).  */
+      cw &= _FPU_RESERVED;
+      cw |= set & ~_FPU_RESERVED;
+
+      _FPU_SETCW (cw);
+    }
+
+  /* Do nothing if a VFP unit isn't present.  */
+}
diff --git a/ports/sysdeps/arm/setjmp.S b/ports/sysdeps/arm/setjmp.S
new file mode 100644
index 0000000000..5e3f39cc75
--- /dev/null
+++ b/ports/sysdeps/arm/setjmp.S
@@ -0,0 +1,98 @@
+/* setjmp for ARM.
+   Copyright (C) 1997, 1998, 2005, 2006, 2008 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <sysdep.h>
+#define _SETJMP_H
+#define _ASM
+#include <bits/setjmp.h>
+#include <rtld-global-offsets.h>
+
+ENTRY (__sigsetjmp)
+	mov	ip, r0
+
+	/* Save registers */
+	stmia	ip!, {v1-v6, sl, fp, sp, lr}
+
+	/* Check if we have a VFP unit.  */
+#ifdef IS_IN_rtld
+	ldr	a3, 1f
+	ldr	a4, Lrtld_local_ro
+0:	add	a3, pc, a3
+	add	a3, a3, a4
+	ldr	a3, [a3, #RTLD_GLOBAL_RO_DL_HWCAP_OFFSET]
+#else
+#ifdef PIC
+	ldr	a3, 1f
+	ldr	a4, Lrtld_global_ro
+0:	add	a3, pc, a3
+	ldr	a3, [a3, a4]
+	ldr	a3, [a3, #RTLD_GLOBAL_RO_DL_HWCAP_OFFSET]
+#else
+	ldr	a3, Lhwcap
+	ldr	a3, [a3, #0]
+#endif
+#endif
+
+	tst	a3, #HWCAP_ARM_VFP
+	beq	Lno_vfp
+
+	/* Store the VFP registers.
+	   Don't use VFP instructions directly because this code
+	   is used in non-VFP multilibs.  */
+	/* Following instruction is vstmia ip!, {d8-d15}.  */
+	stc	p11, cr8, [ip], #64
+	/* Store the floating-point status register.  */
+	/* Following instruction is vmrs a4, fpscr.  */
+	mrc	p10, 7, a4, cr1, cr0, 0
+	str	a4, [ip], #4
+Lno_vfp:
+
+	tst	a3, #HWCAP_ARM_IWMMXT
+	beq	Lno_iwmmxt
+
+	/* Save the call-preserved iWMMXt registers.  */
+	/* Following instructions are wstrd wr10, [ip], #8 (etc.)  */
+	stcl	p1, cr10, [r12], #8
+	stcl	p1, cr11, [r12], #8
+	stcl	p1, cr12, [r12], #8
+	stcl	p1, cr13, [r12], #8
+	stcl	p1, cr14, [r12], #8
+	stcl	p1, cr15, [r12], #8
+Lno_iwmmxt:
+
+	/* Make a tail call to __sigjmp_save; it takes the same args.  */
+	B	PLTJMP(C_SYMBOL_NAME(__sigjmp_save))
+
+#ifdef IS_IN_rtld
+1:	.long	_GLOBAL_OFFSET_TABLE_ - 0b - 8
+Lrtld_local_ro:
+	.long	C_SYMBOL_NAME(_rtld_local_ro)(GOTOFF)
+#else
+#ifdef PIC
+1:	.long	_GLOBAL_OFFSET_TABLE_ - 0b - 8
+Lrtld_global_ro:
+	.long	C_SYMBOL_NAME(_rtld_global_ro)(GOT)
+#else
+Lhwcap:
+	.long	C_SYMBOL_NAME(_dl_hwcap)
+#endif
+#endif
+
+END (__sigsetjmp)
+
+hidden_def (__sigsetjmp)
diff --git a/ports/sysdeps/arm/shlib-versions b/ports/sysdeps/arm/shlib-versions
new file mode 100644
index 0000000000..1ac597abbb
--- /dev/null
+++ b/ports/sysdeps/arm/shlib-versions
@@ -0,0 +1,9 @@
+arm.*-.*-linux-gnueabi.*	DEFAULT			GLIBC_2.4
+
+%ifdef HAVE_ARM_PCS_VFP
+# The EABI-derived hard-float ABI uses a new dynamic linker.
+arm.*-.*-linux-gnueabi.*       ld=ld-linux-armhf.so.3
+%else
+# The EABI-derived soft-float ABI continues to use ld-linux.so.3.
+arm.*-.*-linux-gnueabi.*       ld=ld-linux.so.3
+%endif
diff --git a/ports/sysdeps/arm/stackinfo.h b/ports/sysdeps/arm/stackinfo.h
new file mode 100644
index 0000000000..ea706bb2cb
--- /dev/null
+++ b/ports/sysdeps/arm/stackinfo.h
@@ -0,0 +1,33 @@
+/* Copyright (C) 2001, 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, see
+   <http://www.gnu.org/licenses/>.  */
+
+/* This file contains a bit of information about the stack allocation
+   of the processor.  */
+
+#ifndef _STACKINFO_H
+#define _STACKINFO_H	1
+
+#include <elf.h>
+
+/* On Arm 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/ports/sysdeps/arm/start.S b/ports/sysdeps/arm/start.S
new file mode 100644
index 0000000000..245d7aa571
--- /dev/null
+++ b/ports/sysdeps/arm/start.S
@@ -0,0 +1,148 @@
+/* Startup code for ARM & ELF
+   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/>.  */
+
+/* This is the canonical entry point, usually the first thing in the text
+   segment.
+
+	Note that the code in the .init section has already been run.
+	This includes _init and _libc_init
+
+
+	At this entry point, most registers' values are unspecified, except:
+
+   a1		Contains a function pointer to be registered with `atexit'.
+		This is how the dynamic linker arranges to have DT_FINI
+		functions called for shared libraries that have been loaded
+		before this code runs.
+
+   sp		The stack contains the arguments and environment:
+		0(sp)			argc
+		4(sp)			argv[0]
+		...
+		(4*argc)(sp)		NULL
+		(4*(argc+1))(sp)	envp[0]
+		...
+					NULL
+*/
+
+/* Tag_ABI_align8_preserved: This code preserves 8-byte
+   alignment in any callee.  */
+	.eabi_attribute 25, 1
+/* Tag_ABI_align8_needed: This code may require 8-byte alignment from
+   the caller.  */
+	.eabi_attribute 24, 1
+
+#if defined(__thumb2__)
+	.thumb
+	.syntax unified
+#endif
+
+	.text
+	.globl _start
+	.type _start,#function
+_start:
+       /* Protect against unhandled exceptions.  */
+       .fnstart
+	/* Clear the frame pointer and link register since this is the outermost frame. */
+	mov fp, #0
+	mov lr, #0
+
+	/* Pop argc off the stack and save a pointer to argv */
+	ldr a2, [sp], #4
+	mov a3, sp
+
+	/* Push stack limit */
+	str a3, [sp, #-4]!
+
+	/* Push rtld_fini */
+	str a1, [sp, #-4]!
+
+#ifdef SHARED
+	ldr sl, .L_GOT
+	adr a4, .L_GOT
+	add sl, sl, a4
+
+	ldr ip, .L_GOT+4	/* __libc_csu_fini */
+	ldr ip, [sl, ip]
+
+	str ip, [sp, #-4]!	/* Push __libc_csu_fini */
+
+	ldr a4, .L_GOT+8	/* __libc_csu_init */
+	ldr a4, [sl, a4]
+
+	ldr a1, .L_GOT+12	/* main */
+	ldr a1, [sl, a1]
+
+	/* __libc_start_main (main, argc, argv, init, fini, rtld_fini, stack_end) */
+	/* Let the libc call main and exit with its return code.  */
+	bl __libc_start_main(PLT)
+#else
+	/* Fetch address of __libc_csu_fini */
+	ldr ip, =__libc_csu_fini
+
+	/* Push __libc_csu_fini */
+	str ip, [sp, #-4]!
+
+	/* Set up the other arguments in registers */
+	ldr a1, =main
+	ldr a4, =__libc_csu_init
+
+	/* __libc_start_main (main, argc, argv, init, fini, rtld_fini, stack_end) */
+	/* Let the libc call main and exit with its return code.  */
+	bl __libc_start_main
+#endif
+
+	/* should never get here....*/
+	bl abort
+
+#ifdef SHARED
+	.align 2
+.L_GOT:
+	.word _GLOBAL_OFFSET_TABLE_ - .L_GOT
+	.word __libc_csu_fini(GOT)
+	.word __libc_csu_init(GOT)
+	.word main(GOT)
+#endif
+
+       .cantunwind
+       .fnend
+
+/* 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
diff --git a/ports/sysdeps/arm/strlen.S b/ports/sysdeps/arm/strlen.S
new file mode 100644
index 0000000000..0f18647ef4
--- /dev/null
+++ b/ports/sysdeps/arm/strlen.S
@@ -0,0 +1,72 @@
+/* Copyright (C) 1998, 2003 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Code contributed by Matthew Wilcox <willy@odie.barnet.ac.uk>
+
+   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>
+
+/* size_t strlen(const char *S)
+ * entry: r0 -> string
+ * exit: r0 = len
+ */
+
+ENTRY(strlen)
+	bic     r1, r0, $3              @ addr of word containing first byte
+	ldr     r2, [r1], $4            @ get the first word
+	ands    r3, r0, $3              @ how many bytes are duff?
+	rsb     r0, r3, $0              @ get - that number into counter.
+	beq     Laligned                @ skip into main check routine if no
+					@ more
+#ifdef __ARMEB__
+	orr     r2, r2, $0xff000000     @ set this byte to non-zero
+	subs    r3, r3, $1              @ any more to do?
+	orrgt   r2, r2, $0x00ff0000     @ if so, set this byte
+	subs    r3, r3, $1              @ more?
+	orrgt   r2, r2, $0x0000ff00     @ then set.
+#else
+	orr     r2, r2, $0x000000ff     @ set this byte to non-zero
+	subs    r3, r3, $1              @ any more to do?
+	orrgt   r2, r2, $0x0000ff00     @ if so, set this byte
+	subs    r3, r3, $1              @ more?
+	orrgt   r2, r2, $0x00ff0000     @ then set.
+#endif
+Laligned:				@ here, we have a word in r2.  Does it
+	tst     r2, $0x000000ff         @ contain any zeroes?
+	tstne   r2, $0x0000ff00         @
+	tstne   r2, $0x00ff0000         @
+	tstne   r2, $0xff000000         @
+	addne   r0, r0, $4              @ if not, the string is 4 bytes longer
+	ldrne   r2, [r1], $4            @ and we continue to the next word
+	bne     Laligned                @
+Llastword:				@ drop through to here once we find a
+#ifdef __ARMEB__
+	tst     r2, $0xff000000         @ word that has a zero byte in it
+	addne   r0, r0, $1              @
+	tstne   r2, $0x00ff0000         @ and add up to 3 bytes on to it
+	addne   r0, r0, $1              @
+	tstne   r2, $0x0000ff00         @ (if first three all non-zero, 4th
+	addne   r0, r0, $1              @  must be zero)
+#else
+	tst     r2, $0x000000ff         @ word that has a zero byte in it
+	addne   r0, r0, $1              @
+	tstne   r2, $0x0000ff00         @ and add up to 3 bytes on to it
+	addne   r0, r0, $1              @
+	tstne   r2, $0x00ff0000         @ (if first three all non-zero, 4th
+	addne   r0, r0, $1              @  must be zero)
+#endif
+	DO_RET(lr)
+END(strlen)
+libc_hidden_builtin_def (strlen)
diff --git a/ports/sysdeps/arm/sys/ucontext.h b/ports/sysdeps/arm/sys/ucontext.h
new file mode 100644
index 0000000000..e1d7c074dd
--- /dev/null
+++ b/ports/sysdeps/arm/sys/ucontext.h
@@ -0,0 +1,94 @@
+/* Copyright (C) 1998, 1999 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+/* System V/ARM ABI compliant context switching support.  */
+
+#ifndef _SYS_UCONTEXT_H
+#define _SYS_UCONTEXT_H	1
+
+#include <features.h>
+#include <signal.h>
+
+typedef int greg_t;
+
+/* Number of general registers.  */
+#define NGREG	16
+
+/* Container for all general registers.  */
+typedef greg_t gregset_t[NGREG];
+
+/* Number of each register is the `gregset_t' array.  */
+enum
+{
+  R0 = 0,
+#define R0	R0
+  R1 = 1,
+#define R1	R1
+  R2 = 2,
+#define R2	R2
+  R3 = 3,
+#define R3	R3
+  R4 = 4,
+#define R4	R4
+  R5 = 5,
+#define R5	R5
+  R6 = 6,
+#define R6	R6
+  R7 = 7,
+#define R7	R7
+  R8 = 8,
+#define R8	R8
+  R9 = 9,
+#define R9	R9
+  R10 = 10,
+#define R10	R10
+  R11 = 11,
+#define R11	R11
+  R12 = 12,
+#define R12	R12
+  R13 = 13,
+#define R13	R13
+  R14 = 14,
+#define R14	R14
+  R15 = 15,
+#define R15	R15
+};
+
+/* Structure to describe FPU registers.  */
+typedef struct fpregset
+  {
+  } fpregset_t;
+
+/* Context to describe whole processor state.  */
+typedef struct
+  {
+    gregset_t gregs;
+    fpregset_t fpregs;
+  } mcontext_t;
+
+/* Userlevel context.  */
+typedef struct ucontext
+  {
+    unsigned long int uc_flags;
+    struct ucontext *uc_link;
+    __sigset_t uc_sigmask;
+    stack_t uc_stack;
+    mcontext_t uc_mcontext;
+    long int uc_filler[5];
+  } ucontext_t;
+
+#endif /* sys/ucontext.h */
diff --git a/ports/sysdeps/arm/sysdep.h b/ports/sysdeps/arm/sysdep.h
new file mode 100644
index 0000000000..7800456f64
--- /dev/null
+++ b/ports/sysdeps/arm/sysdep.h
@@ -0,0 +1,120 @@
+/* Assembler macros for ARM.
+   Copyright (C) 1997, 1998, 2003, 2009, 2010, 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.
+
+   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 <sysdeps/generic/sysdep.h>
+#include <features.h>
+
+#if (!defined (__ARM_ARCH_2__) && !defined (__ARM_ARCH_3__) \
+     && !defined (__ARM_ARCH_3M__) && !defined (__ARM_ARCH_4__))
+# define __USE_BX__
+#endif
+
+#ifdef	__ASSEMBLER__
+
+/* Syntactic details of assembler.  */
+
+#define ALIGNARG(log2) log2
+/* 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
+
+#define PLTJMP(_x)	_x##(PLT)
+
+/* APCS-32 doesn't preserve the condition codes across function call. */
+#ifdef __APCS_32__
+#define LOADREGS(cond, base, reglist...)\
+	ldm##cond	base,reglist
+#ifdef __USE_BX__
+#define RETINSTR(cond, reg)	\
+	bx##cond	reg
+#define DO_RET(_reg)		\
+	bx _reg
+#else
+#define RETINSTR(cond, reg)	\
+	mov##cond	pc, reg
+#define DO_RET(_reg)		\
+	mov pc, _reg
+#endif
+#else  /* APCS-26 */
+#define LOADREGS(cond, base, reglist...)\
+	ldm##cond	base,reglist^
+#define RETINSTR(cond, reg)	\
+	mov##cond##s	pc, reg
+#define DO_RET(_reg)		\
+	movs pc, _reg
+#endif
+
+/* Define an entry point visible from C.  */
+#define	ENTRY(name)							      \
+  ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(name);				      \
+  ASM_TYPE_DIRECTIVE (C_SYMBOL_NAME(name),function)			      \
+  .align ALIGNARG(4);							      \
+  C_LABEL(name)								      \
+  .cfi_sections .debug_frame;						      \
+  cfi_startproc;							      \
+  CALL_MCOUNT
+
+#undef	END
+#define END(name)							      \
+  cfi_endproc;								      \
+  ASM_SIZE_DIRECTIVE(name)
+
+/* If compiled for profiling, call `mcount' at the start of each function.  */
+#ifdef	PROF
+/* Call __gnu_mcount_nc if GCC >= 4.4.  */
+#if __GNUC_PREREQ(4,4)
+#define CALL_MCOUNT \
+  str	lr,[sp, #-4]!; \
+  cfi_adjust_cfa_offset (4); \
+  cfi_rel_offset (lr, 0); \
+  bl PLTJMP(mcount); \
+  cfi_adjust_cfa_offset (-4); \
+  cfi_restore (lr)
+#else /* else call _mcount */
+#define CALL_MCOUNT \
+  str	lr,[sp, #-4]!; \
+  cfi_adjust_cfa_offset (4); \
+  cfi_rel_offset (lr, 0); \
+  bl PLTJMP(mcount); \
+  ldr lr, [sp], #4; \
+  cfi_adjust_cfa_offset (-4); \
+  cfi_restore (lr)
+#endif
+#else
+#define CALL_MCOUNT		/* Do nothing.  */
+#endif
+
+/* 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
+#if __GNUC_PREREQ(4,4)
+#define mcount		__gnu_mcount_nc
+#else
+#define mcount		_mcount
+#endif
+
+/* Tag_ABI_align8_preserved: This code preserves 8-byte
+   alignment in any callee.  */
+	.eabi_attribute 25, 1
+/* Tag_ABI_align8_needed: This code may require 8-byte alignment from
+   the caller.  */
+	.eabi_attribute 24, 1
+
+#endif	/* __ASSEMBLER__ */
diff --git a/ports/sysdeps/arm/tls-macros.h b/ports/sysdeps/arm/tls-macros.h
new file mode 100644
index 0000000000..e41d3bc5aa
--- /dev/null
+++ b/ports/sysdeps/arm/tls-macros.h
@@ -0,0 +1,78 @@
+#ifdef __thumb2__
+#define ARM_PC_OFFSET "4"
+#else
+#define ARM_PC_OFFSET "8"
+#endif
+
+#define TLS_LE(x)					\
+  ({ int *__result;					\
+     void *tp = __builtin_thread_pointer ();		\
+     asm ("ldr %0, 1f; "				\
+	  "add %0, %1, %0; "				\
+	  "b 2f; "					\
+	  ".align 2; "					\
+	  "1: .word " #x "(tpoff); "			\
+	  "2: "						\
+	  : "=&r" (__result) : "r" (tp));		\
+     __result; })
+
+#ifdef __thumb2__
+#define TLS_IE(x)					\
+  ({ int *__result;					\
+     void *tp = __builtin_thread_pointer ();		\
+     asm ("ldr %0, 1f; "				\
+	  "3: add %0, pc, %0;"				\
+	  "ldr %0, [%0];"				\
+	  "add %0, %1, %0; "				\
+	  "b 2f; "					\
+	  ".align 2; "					\
+	  "1: .word " #x "(gottpoff) + (. - 3b - 4); "	\
+	  "2: "						\
+	  : "=&r" (__result) : "r" (tp));		\
+     __result; })
+#else
+#define TLS_IE(x)					\
+  ({ int *__result;					\
+     void *tp = __builtin_thread_pointer ();		\
+     asm ("ldr %0, 1f; "				\
+	  "3: ldr %0, [pc, %0];"			\
+	  "add %0, %1, %0; "				\
+	  "b 2f; "					\
+	  ".align 2; "					\
+	  "1: .word " #x "(gottpoff) + (. - 3b - 8); "	\
+	  "2: "						\
+	  : "=&r" (__result) : "r" (tp));		\
+     __result; })
+#endif
+
+#define TLS_LD(x)					\
+  ({ char *__result;					\
+     int __offset;					\
+     extern void *__tls_get_addr (void *);		\
+     asm ("ldr %0, 2f; "				\
+	  "1: add %0, pc, %0; "				\
+	  "b 3f; "					\
+	  ".align 2; "					\
+	  "2: .word " #x "(tlsldm) + (. - 1b - "ARM_PC_OFFSET"); "	\
+	  "3: "						\
+	  : "=r" (__result));				\
+     __result = (char *)__tls_get_addr (__result);	\
+     asm ("ldr %0, 1f; "				\
+	  "b 2f; "					\
+	  ".align 2; "					\
+	  "1: .word " #x "(tlsldo); "			\
+	  "2: "						\
+	  : "=r" (__offset));				\
+     (int *) (__result + __offset); })
+
+#define TLS_GD(x)					\
+  ({ int *__result;					\
+     extern void *__tls_get_addr (void *);		\
+     asm ("ldr %0, 2f; "				\
+	  "1: add %0, pc, %0; "				\
+	  "b 3f; "					\
+	  ".align 2; "					\
+	  "2: .word " #x "(tlsgd) + (. - 1b - "ARM_PC_OFFSET"); "	\
+	  "3: "						\
+	  : "=r" (__result));				\
+     (int *)__tls_get_addr (__result); })
diff --git a/ports/sysdeps/arm/tlsdesc.c b/ports/sysdeps/arm/tlsdesc.c
new file mode 100644
index 0000000000..c5e69a8755
--- /dev/null
+++ b/ports/sysdeps/arm/tlsdesc.c
@@ -0,0 +1,160 @@
+/* Manage TLS descriptors.  ARM version.
+   Copyright (C) 2005, 2010, 2011 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <link.h>
+#include <ldsodefs.h>
+#include <elf/dynamic-link.h>
+#include <tls.h>
+#include <dl-tlsdesc.h>
+#include <tlsdeschtab.h>
+
+/* This function is used to lazily resolve TLS_DESC REL relocations
+   Besides the TLS descriptor itself, we get the module's got address
+   as the second parameter. */
+
+void
+attribute_hidden
+_dl_tlsdesc_lazy_resolver_fixup (struct tlsdesc volatile *td,
+				 Elf32_Addr *got)
+{
+  struct link_map *l = (struct link_map *)got[1];
+  lookup_t result;
+  unsigned long value;
+
+  if (_dl_tlsdesc_resolve_early_return_p
+      (td, (void*)(D_PTR (l, l_info[ADDRIDX (DT_TLSDESC_PLT)]) + l->l_addr)))
+    return;
+
+  if (td->argument.value & 0x80000000)
+    {
+      /* A global symbol, this is the symbol index.  */
+      /* The code below was borrowed from _dl_fixup().  */
+      const Elf_Symndx symndx = td->argument.value ^ 0x80000000;
+      const ElfW(Sym) *const symtab
+	= (const void *) D_PTR (l, l_info[DT_SYMTAB]);
+      const char *strtab = (const void *) D_PTR (l, l_info[DT_STRTAB]);
+      const ElfW(Sym) *sym = &symtab[symndx];
+
+      /* Look up the target symbol.  If the normal lookup rules are not
+	 used don't look in the global scope.  */
+      if (ELFW(ST_BIND) (sym->st_info) != STB_LOCAL
+	  && __builtin_expect (ELFW(ST_VISIBILITY) (sym->st_other), 0) == 0)
+	{
+	  const struct r_found_version *version = NULL;
+
+	  if (l->l_info[VERSYMIDX (DT_VERSYM)] != NULL)
+	    {
+	      const ElfW(Half) *vernum =
+		(const void *) D_PTR (l, l_info[VERSYMIDX (DT_VERSYM)]);
+	      ElfW(Half) ndx = vernum[symndx] & 0x7fff;
+	      version = &l->l_versions[ndx];
+	      if (version->hash == 0)
+		version = NULL;
+	    }
+
+	  result = _dl_lookup_symbol_x
+	    (strtab + sym->st_name, l, &sym,
+	     l->l_scope, version, ELF_RTYPE_CLASS_PLT,
+	     DL_LOOKUP_ADD_DEPENDENCY, NULL);
+	  if (sym)
+	    value = sym->st_value;
+	  else
+	    {
+	      td->entry = _dl_tlsdesc_undefweak;
+	      goto done;
+	    }
+	}
+      else
+	{
+	  /* We already found the symbol.  The module (and therefore its load
+	     address) is also known.  */
+	  result = l;
+	  value = sym->st_value;
+	}
+    }
+  else
+    {
+      /* A local symbol, this is the offset within our tls section.
+	 */
+      value = td->argument.value;
+      result = l;
+    }
+
+#ifndef SHARED
+  CHECK_STATIC_TLS (l, result);
+#else
+  if (!TRY_STATIC_TLS (l, result))
+    {
+      td->argument.pointer = _dl_make_tlsdesc_dynamic (result, value);
+      td->entry = _dl_tlsdesc_dynamic;
+    }
+  else
+#endif
+    {
+      td->argument.value = value + result->l_tls_offset;
+      td->entry = _dl_tlsdesc_return;
+    }
+
+ done:
+  _dl_tlsdesc_wake_up_held_fixups ();
+}
+
+/* This function is used to avoid busy waiting for other threads to
+   complete the lazy relocation.  Once another thread wins the race to
+   relocate a TLS descriptor, it sets the descriptor up such that this
+   function is called to wait until the resolver releases the
+   lock.  */
+
+void
+attribute_hidden
+_dl_tlsdesc_resolve_hold_fixup (struct tlsdesc volatile *td,
+				void *caller)
+{
+  /* Maybe we're lucky and can return early.  */
+  if (caller != td->entry)
+    return;
+
+  /* Locking here will stop execution until the running resolver runs
+     _dl_tlsdesc_wake_up_held_fixups(), releasing the lock.
+
+     FIXME: We'd be better off waiting on a condition variable, such
+     that we didn't have to hold the lock throughout the relocation
+     processing.  */
+  __rtld_lock_lock_recursive (GL(dl_load_lock));
+  __rtld_lock_unlock_recursive (GL(dl_load_lock));
+}
+
+/* Unmap the dynamic object, but also release its TLS descriptor table
+   if there is one.  */
+
+void
+internal_function
+_dl_unmap (struct link_map *map)
+{
+  __munmap ((void *) (map)->l_map_start,
+	    (map)->l_map_end - (map)->l_map_start);
+
+#if SHARED
+  /* _dl_unmap is only called for dlopen()ed libraries, for which
+     calling free() is safe, or before we've completed the initial
+     relocation, in which case calling free() is probably pointless,
+     but still safe.  */
+  if (map->l_mach.tlsdesc_table)
+    htab_delete (map->l_mach.tlsdesc_table);
+#endif
+}
diff --git a/ports/sysdeps/arm/tlsdesc.sym b/ports/sysdeps/arm/tlsdesc.sym
new file mode 100644
index 0000000000..3f3a13e2c4
--- /dev/null
+++ b/ports/sysdeps/arm/tlsdesc.sym
@@ -0,0 +1,15 @@
+#include <stddef.h>
+#include <sysdep.h>
+#include <tls.h>
+#include <link.h>
+#include <dl-tlsdesc.h>
+
+--
+
+-- Abuse tls.h macros to derive offsets relative to the thread register.
+
+TLSDESC_ARG			offsetof(struct tlsdesc, argument.pointer)
+
+TLSDESC_GEN_COUNT		offsetof(struct tlsdesc_dynamic_arg, gen_count)
+TLSDESC_MODID			offsetof(struct tlsdesc_dynamic_arg, tlsinfo.ti_module)
+TLSDESC_MODOFF			offsetof(struct tlsdesc_dynamic_arg, tlsinfo.ti_offset)
diff --git a/ports/sysdeps/arm/tst-audit.h b/ports/sysdeps/arm/tst-audit.h
new file mode 100644
index 0000000000..0a755a2ebd
--- /dev/null
+++ b/ports/sysdeps/arm/tst-audit.h
@@ -0,0 +1,25 @@
+/* Definitions for testing PLT entry/exit auditing.  ARM 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, see
+   <http://www.gnu.org/licenses/>.  */
+
+#define pltenter la_arm_gnu_pltenter
+#define pltexit la_arm_gnu_pltexit
+#define La_regs La_arm_regs
+#define La_retval La_arm_retval
+#define int_retval lrv_reg[0]
diff --git a/ports/sysdeps/arm/unwind-dw2-fde-glibc.c b/ports/sysdeps/arm/unwind-dw2-fde-glibc.c
new file mode 100644
index 0000000000..a94189b7e8
--- /dev/null
+++ b/ports/sysdeps/arm/unwind-dw2-fde-glibc.c
@@ -0,0 +1,79 @@
+/* Dummy exception handling and frame unwind runtime interface routines.
+   Copyright (C) 2004 Free Software Foundation, Inc.
+
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+/* ARM uses setjmp-longjmp exceptions.  However, previous versions of
+   GNU libc exported some DWARF-2 exception handling support routines.
+   They are not necessary, but older (or broken) configurations of GCC
+   will do so.  Even though all references to these are weak, because
+   they refer to versioned symbols, they must be provided.  */
+
+#include <stdlib.h>
+#include <unwind.h>
+#include <unwind-dw2-fde.h>
+
+/* These may be called from startup code, but don't need to do
+   anything.  */
+
+void __register_frame_info_bases (void *a1, struct object *a2,
+				  void *a3, void *a4)
+{
+}
+
+void __register_frame_info (void *a1, struct object *a2)
+{
+}
+
+void __register_frame (void *a1)
+{
+}
+
+void __register_frame_info_table_bases (void *a1, struct object *a2,
+					void *a3, void *a4)
+{
+}
+
+void __register_frame_info_table (void *a1, struct object *a2)
+{
+}
+
+void __register_frame_table (void *a1)
+{
+}
+
+void *__deregister_frame_info (void *a1)
+{
+  return NULL;
+}
+
+void *__deregister_frame_info_bases (void *a1)
+{
+  return NULL;
+}
+
+void __deregister_frame (void *a1)
+{
+}
+
+/* This should not be called.  */
+
+fde *
+_Unwind_Find_FDE (void *a1, struct dwarf_eh_bases *a2)
+{
+  abort ();
+}
diff --git a/ports/sysdeps/arm/unwind-pe.c b/ports/sysdeps/arm/unwind-pe.c
new file mode 100644
index 0000000000..710cecca97
--- /dev/null
+++ b/ports/sysdeps/arm/unwind-pe.c
@@ -0,0 +1 @@
+/* Empty */