summaryrefslogtreecommitdiff
path: root/libc/ports/sysdeps
diff options
context:
space:
mode:
Diffstat (limited to 'libc/ports/sysdeps')
-rw-r--r--libc/ports/sysdeps/arm/__longjmp.S32
-rw-r--r--libc/ports/sysdeps/arm/add_n.S99
-rw-r--r--libc/ports/sysdeps/arm/addmul_1.S73
-rw-r--r--libc/ports/sysdeps/arm/arm-features.h17
-rw-r--r--libc/ports/sysdeps/arm/arm-mcount.S13
-rw-r--r--libc/ports/sysdeps/arm/armv6/rawmemchr.S109
-rw-r--r--libc/ports/sysdeps/arm/armv6/stpcpy.S1
-rw-r--r--libc/ports/sysdeps/arm/armv6/strchr.S147
-rw-r--r--libc/ports/sysdeps/arm/armv6/strcpy.S231
-rw-r--r--libc/ports/sysdeps/arm/armv6/strlen.S103
-rw-r--r--libc/ports/sysdeps/arm/armv6/strrchr.S131
-rw-r--r--libc/ports/sysdeps/arm/armv6t2/Implies2
-rw-r--r--libc/ports/sysdeps/arm/armv6t2/ffs.S (renamed from libc/ports/sysdeps/arm/jmpbuf-offsets.h)22
-rw-r--r--libc/ports/sysdeps/arm/armv6t2/ffsll.S50
-rw-r--r--libc/ports/sysdeps/arm/armv6t2/memchr.S62
-rw-r--r--libc/ports/sysdeps/arm/bits/setjmp.h2
-rw-r--r--libc/ports/sysdeps/arm/crti.S4
-rw-r--r--libc/ports/sysdeps/arm/crtn.S8
-rw-r--r--libc/ports/sysdeps/arm/dl-machine.h2
-rw-r--r--libc/ports/sysdeps/arm/dl-tlsdesc.S42
-rw-r--r--libc/ports/sysdeps/arm/dl-trampoline.S13
-rw-r--r--libc/ports/sysdeps/arm/include/bits/setjmp.h34
-rw-r--r--libc/ports/sysdeps/arm/jmpbuf-unwind.h1
-rw-r--r--libc/ports/sysdeps/arm/memcpy.S247
-rw-r--r--libc/ports/sysdeps/arm/memmove.S247
-rw-r--r--libc/ports/sysdeps/arm/memset.S44
-rw-r--r--libc/ports/sysdeps/arm/preconfigure102
-rw-r--r--libc/ports/sysdeps/arm/preconfigure.in58
-rw-r--r--libc/ports/sysdeps/arm/setjmp.S29
-rw-r--r--libc/ports/sysdeps/arm/start.S10
-rw-r--r--libc/ports/sysdeps/arm/strlen.S9
-rw-r--r--libc/ports/sysdeps/arm/sub_n.S2
-rw-r--r--libc/ports/sysdeps/arm/submul_1.S74
-rw-r--r--libc/ports/sysdeps/arm/sysdep.h197
-rw-r--r--libc/ports/sysdeps/ia64/dl-fptr.h10
-rw-r--r--libc/ports/sysdeps/ia64/dl-machine.h4
-rw-r--r--libc/ports/sysdeps/ia64/entry.h5
-rw-r--r--libc/ports/sysdeps/ia64/fpu/libm_error.c115
-rw-r--r--libc/ports/sysdeps/mips/bits/nan.h16
-rw-r--r--libc/ports/sysdeps/unix/arm/sysdep.S32
-rw-r--r--libc/ports/sysdeps/unix/sysv/linux/aarch64/bits/mman.h76
-rw-r--r--libc/ports/sysdeps/unix/sysv/linux/aarch64/configure13
-rw-r--r--libc/ports/sysdeps/unix/sysv/linux/aarch64/configure.in12
-rw-r--r--libc/ports/sysdeps/unix/sysv/linux/aarch64/nptl/libpthread.abilist1
-rw-r--r--libc/ports/sysdeps/unix/sysv/linux/alpha/bits/mman.h3
-rw-r--r--libc/ports/sysdeps/unix/sysv/linux/alpha/bits/msq.h1
-rw-r--r--libc/ports/sysdeps/unix/sysv/linux/am33/bits/mman.h63
-rw-r--r--libc/ports/sysdeps/unix/sysv/linux/arm/____longjmp_chk.S4
-rw-r--r--libc/ports/sysdeps/unix/sysv/linux/arm/aeabi_read_tp.S9
-rw-r--r--libc/ports/sysdeps/unix/sysv/linux/arm/bits/mman.h76
-rw-r--r--libc/ports/sysdeps/unix/sysv/linux/arm/clone.S13
-rw-r--r--libc/ports/sysdeps/unix/sysv/linux/arm/configure1
-rw-r--r--libc/ports/sysdeps/unix/sysv/linux/arm/configure.in1
-rw-r--r--libc/ports/sysdeps/unix/sysv/linux/arm/mmap.S8
-rw-r--r--libc/ports/sysdeps/unix/sysv/linux/arm/mmap64.S8
-rw-r--r--libc/ports/sysdeps/unix/sysv/linux/arm/nptl/libpthread.abilist1
-rw-r--r--libc/ports/sysdeps/unix/sysv/linux/arm/nptl/pt-vfork.S21
-rw-r--r--libc/ports/sysdeps/unix/sysv/linux/arm/nptl/sysdep-cancel.h47
-rw-r--r--libc/ports/sysdeps/unix/sysv/linux/arm/nptl/unwind-forcedunwind.c4
-rw-r--r--libc/ports/sysdeps/unix/sysv/linux/arm/nptl/unwind-resume.c4
-rw-r--r--libc/ports/sysdeps/unix/sysv/linux/arm/nptl/vfork.S24
-rw-r--r--libc/ports/sysdeps/unix/sysv/linux/arm/syscall.S4
-rw-r--r--libc/ports/sysdeps/unix/sysv/linux/arm/sysdep.h69
-rw-r--r--libc/ports/sysdeps/unix/sysv/linux/arm/vfork.S2
-rw-r--r--libc/ports/sysdeps/unix/sysv/linux/generic/bits/msq.h1
-rw-r--r--libc/ports/sysdeps/unix/sysv/linux/hppa/bits/mman.h3
-rw-r--r--libc/ports/sysdeps/unix/sysv/linux/hppa/bits/msq.h1
-rw-r--r--libc/ports/sysdeps/unix/sysv/linux/ia64/bits/mman.h76
-rw-r--r--libc/ports/sysdeps/unix/sysv/linux/ia64/bits/msq.h6
-rw-r--r--libc/ports/sysdeps/unix/sysv/linux/ia64/makecontext.c20
-rw-r--r--libc/ports/sysdeps/unix/sysv/linux/ia64/nptl/dl-sysdep.h27
-rw-r--r--libc/ports/sysdeps/unix/sysv/linux/ia64/sysdep.h7
-rw-r--r--libc/ports/sysdeps/unix/sysv/linux/m68k/bits/mman.h76
-rw-r--r--libc/ports/sysdeps/unix/sysv/linux/m68k/coldfire/nptl/libpthread.abilist1
-rw-r--r--libc/ports/sysdeps/unix/sysv/linux/mips/bits/mman.h78
-rw-r--r--libc/ports/sysdeps/unix/sysv/linux/mips/bits/msq.h1
-rw-r--r--libc/ports/sysdeps/unix/sysv/linux/tile/bits/mman.h76
-rw-r--r--libc/ports/sysdeps/unix/sysv/linux/tile/tilegx/tilegx32/nptl/libpthread.abilist1
-rw-r--r--libc/ports/sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/nptl/libpthread.abilist1
-rw-r--r--libc/ports/sysdeps/unix/sysv/linux/tile/tilepro/nptl/libpthread.abilist1
80 files changed, 2144 insertions, 1096 deletions
diff --git a/libc/ports/sysdeps/arm/__longjmp.S b/libc/ports/sysdeps/arm/__longjmp.S
index a3a2a8aec..8de9fa1c7 100644
--- a/libc/ports/sysdeps/arm/__longjmp.S
+++ b/libc/ports/sysdeps/arm/__longjmp.S
@@ -19,8 +19,6 @@
/* ??? Needs more rearrangement for the LDM to handle thumb mode. */
#define NO_THUMB
#include <sysdep.h>
-#define _SETJMP_H
-#define _ASM
#include <bits/setjmp.h>
#include <rtld-global-offsets.h>
#include <arm-features.h>
@@ -33,11 +31,13 @@ ENTRY (__longjmp)
moveq r0, #1 /* can't let setjmp() return zero! */
#ifdef CHECK_SP
- ldr r4, [ip, #32] /* jmpbuf's sp */
+ sfi_breg ip, \
+ ldr r4, [\B, #32] /* jmpbuf's sp */
cfi_undefined (r4)
CHECK_SP (r4)
#endif
- LOADREGS(ia, ip!, {v1-v6, sl, fp, sp, lr})
+ sfi_sp sfi_breg ip, \
+ ldmia \B!, JMP_BUF_REGLIST
cfi_restore (v1)
cfi_restore (v2)
cfi_restore (v3)
@@ -81,9 +81,11 @@ ENTRY (__longjmp)
/* Restore the VFP registers. */
/* Following instruction is vldmia ip!, {d8-d15}. */
- ldc p11, cr8, [r12], #64
+ sfi_breg r12, \
+ ldc p11, cr8, [\B], #64
/* Restore the floating-point status register. */
- ldr a3, [ip], #4
+ sfi_breg ip, \
+ ldr a3, [\B], #4
/* Following instruction is fmxr fpscr, a3. */
mcr p10, 7, a3, cr1, cr0, 0
.Lno_vfp:
@@ -94,12 +96,18 @@ ENTRY (__longjmp)
/* 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
+ sfi_breg r12, \
+ ldcl p1, cr10, [\B], #8
+ sfi_breg r12, \
+ ldcl p1, cr11, [\B], #8
+ sfi_breg r12, \
+ ldcl p1, cr12, [\B], #8
+ sfi_breg r12, \
+ ldcl p1, cr13, [\B], #8
+ sfi_breg r12, \
+ ldcl p1, cr14, [\B], #8
+ sfi_breg r12, \
+ ldcl p1, cr15, [\B], #8
.Lno_iwmmxt:
#endif
diff --git a/libc/ports/sysdeps/arm/add_n.S b/libc/ports/sysdeps/arm/add_n.S
new file mode 100644
index 000000000..c6b014797
--- /dev/null
+++ b/libc/ports/sysdeps/arm/add_n.S
@@ -0,0 +1,99 @@
+/* mpn_add_n -- add (or subtract) bignums.
+ Copyright (C) 2013 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library. If not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <sysdep.h>
+#include <arm-features.h>
+
+ .syntax unified
+ .text
+
+#ifdef USE_AS_SUB_N
+# define INITC cmp r0, r0
+# define OPC sbcs
+# define RETC sbc r0, r0, r0; neg r0, r0
+# define FUNC __mpn_sub_n
+#else
+# define INITC cmn r0, #0
+# define OPC adcs
+# define RETC mov r0, #0; adc r0, r0, r0
+# define FUNC __mpn_add_n
+#endif
+
+/* mp_limb_t mpn_add_n(res_ptr, src1_ptr, src2_ptr, size) */
+
+ENTRY (FUNC)
+ push { r4, r5, r6, r7, r8, r10, lr }
+ cfi_adjust_cfa_offset (28)
+ cfi_rel_offset (r4, 0)
+ cfi_rel_offset (r5, 4)
+ cfi_rel_offset (r6, 8)
+ cfi_rel_offset (r7, 12)
+ cfi_rel_offset (r8, 16)
+ cfi_rel_offset (r10, 20)
+ cfi_rel_offset (lr, 24)
+
+ INITC /* initialize carry flag */
+ tst r3, #1 /* count & 1 == 1? */
+ add lr, r1, r3, lsl #2 /* compute end src1 */
+ beq 1f
+
+ sfi_breg r1, \
+ ldr r4, [\B], #4 /* do one to make count even */
+ sfi_breg r2, \
+ ldr r5, [\B], #4
+ OPC r4, r4, r5
+ teq r1, lr /* end of count? (preserve carry) */
+ sfi_breg r0, \
+ str r4, [\B], #4
+ beq 9f
+1:
+ tst r3, #2 /* count & 2 == 2? */
+ beq 2f
+ sfi_breg r1, \
+ ldm \B!, { r4, r5 } /* do two to make count 0 mod 4 */
+ sfi_breg r2, \
+ ldm \B!, { r6, r7 }
+ OPC r4, r4, r6
+ OPC r5, r5, r7
+ teq r1, lr /* end of count? */
+ sfi_breg r0, \
+ stm \B!, { r4, r5 }
+ beq 9f
+2:
+ sfi_breg r1, \
+ ldm \B!, { r3, r5, r7, r10 } /* do four each loop */
+ sfi_breg r2, \
+ ldm \B!, { r4, r6, r8, ip }
+ OPC r3, r3, r4
+ OPC r5, r5, r6
+ OPC r7, r7, r8
+ OPC r10, r10, ip
+ teq r1, lr
+ sfi_breg r0, \
+ stm \B!, { r3, r5, r7, r10 }
+ bne 2b
+
+9:
+ RETC /* copy carry out */
+#ifndef ARM_ALWAYS_BX
+ pop { r4, r5, r6, r7, r8, r10, pc }
+#else
+ pop { r4, r5, r6, r7, r8, r10, lr }
+ bx lr
+#endif
+END (FUNC)
diff --git a/libc/ports/sysdeps/arm/addmul_1.S b/libc/ports/sysdeps/arm/addmul_1.S
new file mode 100644
index 000000000..d204c887e
--- /dev/null
+++ b/libc/ports/sysdeps/arm/addmul_1.S
@@ -0,0 +1,73 @@
+/* mpn_addmul_1 -- multiply and accumulate bignums.
+ Copyright (C) 2013 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library. If not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <sysdep.h>
+
+ .syntax unified
+ .text
+
+@ cycles/limb
+@ StrongArm ?
+@ Cortex-A8 ?
+@ Cortex-A9 ?
+@ Cortex-A15 4
+
+/* mp_limb_t mpn_addmul_1(res_ptr, src1_ptr, size, s2_limb) */
+
+ENTRY (__mpn_addmul_1)
+ 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)
+
+ sfi_breg r1, \
+ ldr r6, [\B], #4
+ sfi_breg r0, \
+ ldr r5, [\B]
+ mov r4, #0 /* init carry in */
+ b 1f
+0:
+ sfi_breg r1, \
+ ldr r6, [\B], #4 /* load next ul */
+ adds r7, r4, r5 /* (out, c) = cl + lpl */
+ sfi_breg r0, \
+ ldr r5, [\B, #4] /* load next rl */
+ adc r4, ip, #0 /* cl = hpl + c */
+ sfi_breg r0, \
+ str r7, [\B], #4
+1:
+ mov ip, #0 /* zero-extend rl */
+ umlal r5, ip, r6, r3 /* (hpl, lpl) = ul * vl + rl */
+ subs r2, r2, #1
+ bne 0b
+
+ adds r4, r4, r5 /* (out, c) = cl + llpl */
+ sfi_breg r0, \
+ str r4, [\B]
+ adc r0, ip, #0 /* return hpl + c */
+
+ pop { r4, r5, r6, r7 }
+ cfi_adjust_cfa_offset (-16)
+ cfi_restore (r4)
+ cfi_restore (r5)
+ cfi_restore (r6)
+ cfi_restore (r7)
+ DO_RET (lr)
+END (__mpn_addmul_1)
diff --git a/libc/ports/sysdeps/arm/arm-features.h b/libc/ports/sysdeps/arm/arm-features.h
index 31801cf40..5104ba332 100644
--- a/libc/ports/sysdeps/arm/arm-features.h
+++ b/libc/ports/sysdeps/arm/arm-features.h
@@ -36,4 +36,21 @@
at runtime (or that we never care about its state) and so need not
be checked for. */
+/* A more-specific arm-features.h file may define ARM_ALWAYS_BX to indicate
+ that instructions using pc as a destination register must never be used,
+ so a "bx" (or "blx") instruction is always required. */
+
+/* The log2 of the minimum alignment required for an address that
+ is the target of a computed branch (i.e. a "bx" instruction).
+ A more-specific arm-features.h file may define this to set a more
+ stringent requirement.
+
+ Using this only makes sense for code in ARM mode (where instructions
+ always have a fixed size of four bytes), or for Thumb-mode code that is
+ specifically aligning all the related branch targets to match (since
+ Thumb instructions might be either two or four bytes). */
+#ifndef ARM_BX_ALIGN_LOG2
+# define ARM_BX_ALIGN_LOG2 2
+#endif
+
#endif /* arm-features.h */
diff --git a/libc/ports/sysdeps/arm/arm-mcount.S b/libc/ports/sysdeps/arm/arm-mcount.S
index 679d042ba..f61e978f5 100644
--- a/libc/ports/sysdeps/arm/arm-mcount.S
+++ b/libc/ports/sysdeps/arm/arm-mcount.S
@@ -69,7 +69,7 @@ END(__gnu_mcount_nc)
code be compiled with APCS frame pointers. */
ENTRY(_mcount)
- stmdb sp!, {r0, r1, r2, r3, fp, lr}
+ push {r0, r1, r2, r3, fp, lr}
cfi_adjust_cfa_offset (24)
cfi_rel_offset (r0, 0)
cfi_rel_offset (r1, 4)
@@ -79,13 +79,12 @@ ENTRY(_mcount)
cfi_rel_offset (lr, 20)
movs r0, fp
ittt ne
- ldrne r0, [r0, #-4]
+ sfi_breg r0, \
+ ldrne r0, [\B, #-4]
movsne r1, lr
blne __mcount_internal
-#ifdef __thumb2__
- ldmia sp!, {r0, r1, r2, r3, fp, pc}
-#else
- ldmia sp!, {r0, r1, r2, r3, fp, lr}
+#if defined (__ARM_ARCH_4T__) && defined (__THUMB_INTERWORK__)
+ pop {r0, r1, r2, r3, fp, lr}
cfi_adjust_cfa_offset (-24)
cfi_restore (r0)
cfi_restore (r1)
@@ -94,6 +93,8 @@ ENTRY(_mcount)
cfi_restore (fp)
cfi_restore (lr)
bx lr
+#else
+ pop {r0, r1, r2, r3, fp, pc}
#endif
END(_mcount)
diff --git a/libc/ports/sysdeps/arm/armv6/rawmemchr.S b/libc/ports/sysdeps/arm/armv6/rawmemchr.S
new file mode 100644
index 000000000..b5e4a16f0
--- /dev/null
+++ b/libc/ports/sysdeps/arm/armv6/rawmemchr.S
@@ -0,0 +1,109 @@
+/* rawmemchr -- find a byte within an unsized memory block.
+ Copyright (C) 2013 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library. If not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <sysdep.h>
+
+ .syntax unified
+ .text
+
+ENTRY (__rawmemchr)
+ @ r0 = start of string
+ @ r1 = character to match
+ @ returns a pointer to the match, which must be present.
+ sfi_breg r0, \
+ ldrb r2, [\B] @ load first byte asap
+
+ @ To cater to long strings, we want to search through a few
+ @ characters until we reach an aligned pointer. To cater to
+ @ small strings, we don't want to start doing word operations
+ @ immediately. The compromise is a maximum of 16 bytes less
+ @ whatever is required to end with an aligned pointer.
+ @ r3 = number of characters to search in alignment loop
+ and r3, r0, #7
+ uxtb r1, r1
+ rsb r3, r3, #15 @ 16 - 1 peeled loop iteration
+ cmp r2, r1
+ it eq
+ bxeq lr
+
+ @ Loop until we find ...
+1: sfi_breg r0, \
+ ldrb r2, [\B, #1]!
+ subs r3, r3, #1 @ ... the alignment point
+ it ne
+ cmpne r2, r1 @ ... or C
+ bne 1b
+
+ @ Disambiguate the exit possibilites above
+ cmp r2, r1 @ Found C
+ it eq
+ bxeq lr
+ add r0, r0, #1
+
+ @ So now we're aligned.
+ sfi_breg r0, \
+ ldrd r2, r3, [\B], #8
+ orr r1, r1, r1, lsl #8 @ Replicate C to all bytes
+#ifdef ARCH_HAS_T2
+ movw ip, #0x0101
+ sfi_pld r0, #64
+ movt ip, #0x0101
+#else
+ ldr ip, =0x01010101
+ sfi_pld r0, #64
+#endif
+ orr r1, r1, r1, lsl #16
+
+ @ Loop searching for C, 8 bytes at a time.
+ @ Subtracting (unsigned saturating) from 1 means result of 1 for
+ @ any byte that was originally zero and 0 otherwise. Therefore
+ @ we consider the lsb of each byte the "found" bit.
+2: eor r2, r2, r1 @ Convert C bytes to 0
+ eor r3, r3, r1
+ uqsub8 r2, ip, r2 @ Find C
+ uqsub8 r3, ip, r3
+ sfi_pld r0, #128
+ orrs r3, r3, r2 @ Test both words for found
+ it eq
+ sfi_breg r0, \
+ ldrdeq r2, r3, [\B], #8
+ beq 2b
+
+ @ Found something. Disambiguate between first and second words.
+ @ Adjust r0 to point to the word containing the match.
+ @ Adjust r2 to the found bits for the word containing the match.
+ cmp r2, #0
+ sub r0, r0, #4
+ ite eq
+ moveq r2, r3
+ subne r0, r0, #4
+
+ @ Find the bit-offset of the match within the word. Note that the
+ @ bit result from clz will be 7 higher than "true", but we'll
+ @ immediately discard those bits converting to a byte offset.
+#ifdef __ARMEL__
+ rev r2, r2 @ For LE, count from the little end
+#endif
+ clz r2, r2
+ add r0, r0, r2, lsr #3 @ Adjust the pointer to the found byte
+ bx lr
+
+END (__rawmemchr)
+
+weak_alias (__rawmemchr, rawmemchr)
+libc_hidden_def (__rawmemchr)
diff --git a/libc/ports/sysdeps/arm/armv6/stpcpy.S b/libc/ports/sysdeps/arm/armv6/stpcpy.S
new file mode 100644
index 000000000..21a4f385b
--- /dev/null
+++ b/libc/ports/sysdeps/arm/armv6/stpcpy.S
@@ -0,0 +1 @@
+/* Defined in strcpy.S. */
diff --git a/libc/ports/sysdeps/arm/armv6/strchr.S b/libc/ports/sysdeps/arm/armv6/strchr.S
new file mode 100644
index 000000000..936c2be66
--- /dev/null
+++ b/libc/ports/sysdeps/arm/armv6/strchr.S
@@ -0,0 +1,147 @@
+/* strchr -- find the first instance of C in a nul-terminated string.
+ Copyright (C) 2013 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library. If not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <sysdep.h>
+
+ .syntax unified
+ .text
+
+ENTRY (strchr)
+ @ r0 = start of string
+ @ r1 = character to match
+ @ returns NULL for no match, or a pointer to the match
+ sfi_breg r0, \
+ ldrb r2, [\B] @ load the first byte asap
+ uxtb r1, r1
+
+ @ To cater to long strings, we want to search through a few
+ @ characters until we reach an aligned pointer. To cater to
+ @ small strings, we don't want to start doing word operations
+ @ immediately. The compromise is a maximum of 16 bytes less
+ @ whatever is required to end with an aligned pointer.
+ @ r3 = number of characters to search in alignment loop
+ and r3, r0, #7
+ rsb r3, r3, #15 @ 16 - 1 peeled loop iteration
+ cmp r2, r1 @ Found C?
+ it ne
+ cmpne r2, #0 @ Found EOS?
+ beq 99f
+
+ @ Loop until we find ...
+1: sfi_breg r0, \
+ ldrb r2, [\B, #1]!
+ subs r3, r3, #1 @ ... the aligment point
+ it ne
+ cmpne r2, r1 @ ... or the character
+ it ne
+ cmpne r2, #0 @ ... or EOS
+ bne 1b
+
+ @ Disambiguate the exit possibilites above
+ cmp r2, r1 @ Found the character
+ it ne
+ cmpne r2, #0 @ Found EOS
+ beq 99f
+ add r0, r0, #1
+
+ @ So now we're aligned. Now we actually need a stack frame.
+ push { r4, r5, r6, r7 }
+ cfi_adjust_cfa_offset (16)
+ cfi_rel_offset (r4, 0)
+ cfi_rel_offset (r5, 4)
+ cfi_rel_offset (r6, 8)
+ cfi_rel_offset (r7, 12)
+
+ sfi_breg r0, \
+ ldrd r2, r3, [\B], #8
+ orr r1, r1, r1, lsl #8 @ Replicate C to all bytes
+#ifdef ARCH_HAS_T2
+ movw ip, #0x0101
+ sfi_pld r0, #64
+ movt ip, #0x0101
+#else
+ ldr ip, =0x01010101
+ sfi_pld r0, #64
+#endif
+ orr r1, r1, r1, lsl #16
+
+ @ Loop searching for EOS or C, 8 bytes at a time.
+2:
+ @ Subtracting (unsigned saturating) from 1 means result of 1 for
+ @ any byte that was originally zero and 0 otherwise. Therefore
+ @ we consider the lsb of each byte the "found" bit.
+ uqsub8 r4, ip, r2 @ Find EOS
+ eor r6, r2, r1 @ Convert C bytes to 0
+ uqsub8 r5, ip, r3
+ eor r7, r3, r1
+ uqsub8 r6, ip, r6 @ Find C
+ sfi_pld r0, #128 @ Prefetch 2 lines ahead
+ uqsub8 r7, ip, r7
+ orr r4, r4, r6 @ Combine found for EOS and C
+ orr r5, r5, r7
+ orrs r6, r4, r5 @ Combine the two words
+ it eq
+ sfi_breg r0, \
+ ldrdeq r2, r3, [\B], #8
+ beq 2b
+
+ @ Found something. Disambiguate between first and second words.
+ @ Adjust r0 to point to the word containing the match.
+ @ Adjust r2 to the contents of the word containing the match.
+ @ Adjust r4 to the found bits for the word containing the match.
+ cmp r4, #0
+ sub r0, r0, #4
+ itte eq
+ moveq r4, r5
+ moveq r2, r3
+ subne r0, r0, #4
+
+ @ Find the bit-offset of the match within the word.
+#if defined(__ARMEL__)
+ @ For LE, swap the found word so clz searches from the little end.
+ rev r4, r4
+#else
+ @ For BE, byte swap the word to make it easier to extract the byte.
+ rev r2, r2
+#endif
+ @ We're counting 0x01 (not 0x80), so the bit offset is 7 too high.
+ clz r3, r4
+ sub r3, r3, #7
+ lsr r2, r2, r3 @ Shift down found byte
+ uxtb r1, r1 @ Undo replication of C
+ uxtb r2, r2 @ Extract found byte
+ add r0, r0, r3, lsr #3 @ Adjust the pointer to the found byte
+
+ pop { r4, r5, r6, r7 }
+ cfi_adjust_cfa_offset (-16)
+ cfi_restore (r4)
+ cfi_restore (r5)
+ cfi_restore (r6)
+ cfi_restore (r7)
+
+ @ Disambiguate between EOS and C.
+99:
+ cmp r2, r1
+ it ne
+ movne r0, #0 @ Found EOS, return NULL
+ bx lr
+
+END (strchr)
+
+weak_alias (strchr, index)
+libc_hidden_builtin_def (strchr)
diff --git a/libc/ports/sysdeps/arm/armv6/strcpy.S b/libc/ports/sysdeps/arm/armv6/strcpy.S
new file mode 100644
index 000000000..cd13ff7ec
--- /dev/null
+++ b/libc/ports/sysdeps/arm/armv6/strcpy.S
@@ -0,0 +1,231 @@
+/* strcpy -- copy a nul-terminated string.
+ Copyright (C) 2013 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library. If not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <sysdep.h>
+
+/* Endian independent macros for shifting bytes within registers. */
+#ifdef __ARMEB__
+#define lsh_gt lsr
+#define lsh_ls lsl
+#else
+#define lsh_gt lsl
+#define lsh_ls lsr
+#endif
+
+ .syntax unified
+ .text
+
+ENTRY (__stpcpy)
+ @ Signal stpcpy with NULL in IP.
+ mov ip, #0
+ b 0f
+END (__stpcpy)
+
+weak_alias (__stpcpy, stpcpy)
+libc_hidden_def (__stpcpy)
+libc_hidden_builtin_def (stpcpy)
+
+ENTRY (strcpy)
+ @ Signal strcpy with DEST in IP.
+ mov ip, r0
+0:
+ sfi_pld r0
+ sfi_pld r1
+
+ @ To cater to long strings, we want 8 byte alignment in the source.
+ @ To cater to small strings, we don't want to start that right away.
+ @ Loop up to 16 times, less whatever it takes to reach alignment.
+ and r3, r1, #7
+ rsb r3, r3, #16
+
+ @ Loop until we find ...
+1: sfi_breg r1, \
+ ldrb r2, [\B], #1
+ subs r3, r3, #1 @ ... the alignment point
+ sfi_breg r0, \
+ strb r2, [\B], #1
+ it ne
+ cmpne r2, #0 @ ... or EOS
+ bne 1b
+
+ @ Disambiguate the exit possibilites above
+ cmp r2, #0 @ Found EOS
+ beq .Lreturn
+
+ @ Load the next two words asap
+ sfi_breg r1, \
+ ldrd r2, r3, [\B], #8
+ sfi_pld r0, #64
+ sfi_pld r1, #64
+
+ @ For longer strings, we actaully need a stack frame.
+ push { r4, r5, r6, r7 }
+ cfi_adjust_cfa_offset (16)
+ cfi_rel_offset (r4, 0)
+ cfi_rel_offset (r5, 4)
+ cfi_rel_offset (r6, 8)
+ cfi_rel_offset (r7, 12)
+
+ @ Subtracting (unsigned saturating) from 1 for any byte means result
+ @ of 1 for any byte that was originally zero and 0 otherwise.
+ @ Therefore we consider the lsb of each byte the "found" bit.
+#ifdef ARCH_HAS_T2
+ movw r7, #0x0101
+ tst r0, #3 @ Test alignment of DEST
+ movt r7, #0x0101
+#else
+ ldr ip, =0x01010101
+ tst r0, #3
+#endif
+ bne .Lunaligned
+
+ @ So now source (r1) is aligned to 8, and dest (r0) is aligned to 4.
+ @ Loop, reading 8 bytes at a time, searching for EOS.
+ .balign 16
+2: uqsub8 r4, r7, r2 @ Find EOS
+ uqsub8 r5, r7, r3
+ sfi_pld r1, #128
+ cmp r4, #0 @ EOS in first word?
+ sfi_pld r0, #128
+ bne 3f
+ sfi_breg r0, \
+ str r2, [\B], #4
+ cmp r5, #0 @ EOS in second word?
+ bne 4f
+ sfi_breg r0, \
+ str r3, [\B], #4
+ sfi_breg r1, \
+ ldrd r2, r3, [\B], #8
+ b 2b
+
+3: sub r1, r1, #4 @ backup to first word
+4: sub r1, r1, #4 @ backup to second word
+
+ @ ... then finish up any tail a byte at a time.
+ @ Note that we generally back up and re-read source bytes,
+ @ but we'll not re-write dest bytes.
+.Lbyte_loop:
+ sfi_breg r1, \
+ ldrb r2, [\B], #1
+ cmp r2, #0
+ sfi_breg r0, \
+ strb r2, [\B], #1
+ bne .Lbyte_loop
+
+ pop { r4, r5, r6, r7 }
+ cfi_remember_state
+ cfi_adjust_cfa_offset (-16)
+ cfi_restore (r4)
+ cfi_restore (r5)
+ cfi_restore (r6)
+ cfi_restore (r7)
+
+.Lreturn:
+ cmp ip, #0 @ Was this strcpy or stpcpy?
+ ite eq
+ subeq r0, r0, #1 @ stpcpy: undo post-inc from store
+ movne r0, ip @ strcpy: return original dest
+ bx lr
+
+.Lunaligned:
+ cfi_restore_state
+ @ Here, source is aligned to 8, but the destination is not word
+ @ aligned. Therefore we have to shift the data in order to be
+ @ able to perform aligned word stores.
+
+ @ Find out which misalignment we're dealing with.
+ tst r0, #1
+ beq .Lunaligned2
+ tst r0, #2
+ bne .Lunaligned3
+ @ Fallthru to .Lunaligned1.
+
+.macro unaligned_copy unalign
+ @ Prologue to unaligned loop. Seed shifted non-zero bytes.
+ uqsub8 r4, r7, r2 @ Find EOS
+ uqsub8 r5, r7, r3
+ mvns r4, r4 @ EOS in first word?
+ it ne
+ subne r1, r1, #8
+ bne .Lbyte_loop
+#ifdef __ARMEB__
+ rev r2, r2 @ Byte stores below need LE data
+#endif
+ @ Store a few bytes from the first word.
+ @ At the same time we align r0 and shift out bytes from r2.
+.rept 4-\unalign
+ sfi_breg r0, \
+ strb r2, [\B], #1
+ lsr r2, r2, #8
+.endr
+#ifdef __ARMEB__
+ rev r2, r2 @ Undo previous rev
+#endif
+ @ Rotated unaligned copy loop. The tail of the prologue is
+ @ shared with the loop itself.
+ .balign 8
+1: mvns r5, r5 @ EOS in second word?
+ bne 4f
+ @ Combine first and second words
+ orr r2, r2, r3, lsh_gt #(\unalign*8)
+ @ Save leftover bytes from the two words
+ lsh_ls r6, r3, #((4-\unalign)*8)
+ sfi_breg r0, \
+ str r2, [\B], #4
+ @ The "real" start of the unaligned copy loop.
+ sfi_breg r1, \
+ ldrd r2, r3, [\B], #8 @ Load 8 more bytes
+ uqsub8 r4, r7, r2 @ Find EOS
+ sfi_pld r1, #128
+ uqsub8 r5, r7, r3
+ sfi_pld r0, #128
+ mvns r4, r4 @ EOS in first word?
+ bne 3f
+ @ Combine the leftover and the first word
+ orr r6, r6, r2, lsh_gt #(\unalign*8)
+ @ Discard used bytes from the first word.
+ lsh_ls r2, r2, #((4-\unalign)*8)
+ sfi_breg r0, \
+ str r6, [\B], #4
+ b 1b
+ @ Found EOS in one of the words; adjust backward
+3: sub r1, r1, #4
+ mov r2, r6
+4: sub r1, r1, #4
+ @ And store the remaining bytes from the leftover
+#ifdef __ARMEB__
+ rev r2, r2
+#endif
+.rept \unalign
+ sfi_breg r0, \
+ strb r2, [\B], #1
+ lsr r2, r2, #8
+.endr
+ b .Lbyte_loop
+.endm
+
+.Lunaligned1:
+ unaligned_copy 1
+.Lunaligned2:
+ unaligned_copy 2
+.Lunaligned3:
+ unaligned_copy 3
+
+END (strcpy)
+
+libc_hidden_builtin_def (strcpy)
diff --git a/libc/ports/sysdeps/arm/armv6/strlen.S b/libc/ports/sysdeps/arm/armv6/strlen.S
new file mode 100644
index 000000000..59ff6b5d9
--- /dev/null
+++ b/libc/ports/sysdeps/arm/armv6/strlen.S
@@ -0,0 +1,103 @@
+/* strlen -- find the length of a nul-terminated string.
+ Copyright (C) 2013 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library. If not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <sysdep.h>
+
+ .syntax unified
+ .text
+
+ENTRY (strlen)
+ @ r0 = start of string
+ sfi_breg r0, \
+ ldrb r2, [\B] @ load the first byte asap
+
+ @ To cater to long strings, we want to search through a few
+ @ characters until we reach an aligned pointer. To cater to
+ @ small strings, we don't want to start doing word operations
+ @ immediately. The compromise is a maximum of 16 bytes less
+ @ whatever is required to end with an aligned pointer.
+ @ r3 = number of characters to search in alignment loop
+ and r3, r0, #7
+ mov r1, r0 @ Save the input pointer
+ rsb r3, r3, #15 @ 16 - 1 peeled loop iteration
+ cmp r2, #0
+ beq 99f
+
+ @ Loop until we find ...
+1: sfi_breg r0, \
+ ldrb r2, [\B, #1]!
+ subs r3, r3, #1 @ ... the aligment point
+ it ne
+ cmpne r2, #0 @ ... or EOS
+ bne 1b
+
+ @ Disambiguate the exit possibilites above
+ cmp r2, #0 @ Found EOS
+ beq 99f
+ add r0, r0, #1
+
+ @ So now we're aligned.
+ sfi_breg r0, \
+ ldrd r2, r3, [\B], #8
+#ifdef ARCH_HAS_T2
+ movw ip, #0x0101
+ sfi_pld r0, #64
+ movt ip, #0x0101
+#else
+ ldr ip, =0x01010101
+ sfi_pld r0, #64
+#endif
+
+ @ Loop searching for EOS, 8 bytes at a time.
+ @ Subtracting (unsigned saturating) from 1 for any byte means that
+ @ we get 1 for any byte that was originally zero and 0 otherwise.
+ @ Therefore we consider the lsb of each byte the "found" bit.
+ .balign 16
+2: uqsub8 r2, ip, r2 @ Find EOS
+ uqsub8 r3, ip, r3
+ sfi_pld r0, #128 @ Prefetch 2 lines ahead
+ orrs r3, r3, r2 @ Combine the two words
+ it eq
+ sfi_breg r0, \
+ ldrdeq r2, r3, [\B], #8
+ beq 2b
+
+ @ Found something. Disambiguate between first and second words.
+ @ Adjust r0 to point to the word containing the match.
+ @ Adjust r2 to the found bits for the word containing the match.
+ cmp r2, #0
+ sub r0, r0, #4
+ ite eq
+ moveq r2, r3
+ subne r0, r0, #4
+
+ @ Find the bit-offset of the match within the word. Note that the
+ @ bit result from clz will be 7 higher than "true", but we'll
+ @ immediately discard those bits converting to a byte offset.
+#ifdef __ARMEL__
+ rev r2, r2 @ For LE, count from the little end
+#endif
+ clz r2, r2
+ add r0, r0, r2, lsr #3 @ Adjust the pointer to the found byte
+99:
+ sub r0, r0, r1 @ Subtract input to compute length
+ bx lr
+
+END (strlen)
+
+libc_hidden_builtin_def (strlen)
diff --git a/libc/ports/sysdeps/arm/armv6/strrchr.S b/libc/ports/sysdeps/arm/armv6/strrchr.S
new file mode 100644
index 000000000..e40df90a7
--- /dev/null
+++ b/libc/ports/sysdeps/arm/armv6/strrchr.S
@@ -0,0 +1,131 @@
+/* strrchr -- find the last occurence of C in a nul-terminated string
+ Copyright (C) 2013 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library. If not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <sysdep.h>
+
+ .syntax unified
+ .text
+
+ENTRY (strrchr)
+ @ r0 = start of string
+ @ r1 = character to match
+ @ returns NULL for no match, or a pointer to the match
+
+ mov r3, r0
+ mov r0, #0
+ uxtb r1, r1
+
+ @ Loop a few times until we're aligned.
+ tst r3, #7
+ beq 2f
+1: sfi_breg r3, \
+ ldrb r2, [\B], #1
+ cmp r2, r1 @ Find the character
+ it eq
+ subeq r0, r3, #1
+ cmp r2, #0 @ Find EOS
+ it eq
+ bxeq lr
+ tst r3, #7 @ Find the aligment point
+ bne 1b
+
+ @ So now we're aligned. Now we actually need a stack frame.
+2: push { r4, r5, r6, r7 }
+ cfi_adjust_cfa_offset (16)
+ cfi_rel_offset (r4, 0)
+ cfi_rel_offset (r5, 4)
+ cfi_rel_offset (r6, 8)
+ cfi_rel_offset (r7, 12)
+
+ orr r1, r1, r1, lsl #8 @ Replicate C to all bytes
+#ifdef ARCH_HAS_T2
+ movw ip, #0x0101
+ movt ip, #0x0101
+#else
+ ldr ip, =0x01010101
+#endif
+ orr r1, r1, r1, lsl #16
+ mov r2, #0 @ No found bits yet
+
+ @ Loop searching for EOS and C, 8 bytes at a time.
+ @ Any time we find a match in a word, we copy the address of
+ @ the word to r0, and the found bits to r2.
+3: sfi_breg r3, \
+ ldrd r4, r5, [\B], #8
+ @ Subtracting (unsigned saturating) from 1 means result of 1 for
+ @ any byte that was originally zero and 0 otherwise. Therefore
+ @ we consider the lsb of each byte the "found" bit.
+ uqsub8 r6, ip, r4 @ Find EOS
+ uqsub8 r7, ip, r5
+ eor r4, r4, r1 @ Convert C bytes to 0
+ eor r5, r5, r1
+ uqsub8 r4, ip, r4 @ Find C
+ uqsub8 r5, ip, r5
+ cmp r6, #0 @ Found EOS, first word
+ bne 4f
+ cmp r4, #0 @ Handle C, first word
+ itt ne
+ subne r0, r3, #8
+ movne r2, r4
+ cmp r7, #0 @ Found EOS, second word
+ bne 5f
+ cmp r5, #0 @ Handle C, second word
+ itt ne
+ subne r0, r3, #4
+ movne r2, r5
+ b 3b
+
+ @ Found EOS in second word; fold to first word.
+5: add r3, r3, #4 @ Dec pointer to 2nd word, with below
+ mov r4, r5 @ Overwrite first word C found
+ mov r6, r7 @ Overwrite first word EOS found
+
+ @ Found EOS. Zap found C after EOS.
+4: sub r3, r3, #8 @ Decrement pointer to first word
+#ifdef __ARMEB__
+ @ Byte swap to be congruent with LE, which is easier from here on.
+ rev r6, r6 @ Byte swap found EOS,
+ rev r4, r4 @ ... this found C
+ rev r2, r2 @ ... prev found C
+#endif
+ sub r7, r6, #1 @ Toggle EOS lsb and below
+ eor r6, r6, r7 @ All bits below and including lsb
+ ands r4, r4, r6 @ Zap C above EOS
+ itt ne
+ movne r2, r4 @ Copy to result, if still non-zero
+ movne r0, r3
+
+ pop { r4, r5, r6, r7 }
+ cfi_adjust_cfa_offset (-16)
+ cfi_restore (r4)
+ cfi_restore (r5)
+ cfi_restore (r6)
+ cfi_restore (r7)
+
+ @ Adjust the result pointer if we found a word containing C.
+ cmp r2, #0
+ clz r2, r2 @ Find the bit offset of the last C
+ itt ne
+ rsbne r2, r2, #32 @ Convert to a count from the right
+ addne r0, r0, r2, lsr #3 @ Convert to byte offset and add.
+ bx lr
+
+END (strrchr)
+
+weak_alias (strrchr, rindex)
+libc_hidden_builtin_def (strrchr)
diff --git a/libc/ports/sysdeps/arm/armv6t2/Implies b/libc/ports/sysdeps/arm/armv6t2/Implies
new file mode 100644
index 000000000..20a87fc8a
--- /dev/null
+++ b/libc/ports/sysdeps/arm/armv6t2/Implies
@@ -0,0 +1,2 @@
+# We can do everything that 6 can
+arm/armv6
diff --git a/libc/ports/sysdeps/arm/jmpbuf-offsets.h b/libc/ports/sysdeps/arm/armv6t2/ffs.S
index beeccbb40..b2c88b946 100644
--- a/libc/ports/sysdeps/arm/jmpbuf-offsets.h
+++ b/libc/ports/sysdeps/arm/armv6t2/ffs.S
@@ -1,5 +1,5 @@
-/* Private macros for accessing __jmp_buf contents. ARM EABI version.
- Copyright (C) 2007-2013 Free Software Foundation, Inc.
+/* ffs -- find first set bit in an int, from least significant end.
+ Copyright (C) 2013 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -16,4 +16,20 @@
License along with the GNU C Library. If not, see
<http://www.gnu.org/licenses/>. */
-#define __JMP_BUF_SP 8
+#include <sysdep.h>
+
+ .syntax unified
+ .text
+
+ENTRY (__ffs)
+ cmp r0, #0
+ rbit r0, r0
+ itt ne
+ clzne r0, r0
+ addne r0, r0, #1
+ bx lr
+END (__ffs)
+
+weak_alias (__ffs, ffs)
+weak_alias (__ffs, ffsl)
+libc_hidden_builtin_def (ffs)
diff --git a/libc/ports/sysdeps/arm/armv6t2/ffsll.S b/libc/ports/sysdeps/arm/armv6t2/ffsll.S
new file mode 100644
index 000000000..e49c70fdf
--- /dev/null
+++ b/libc/ports/sysdeps/arm/armv6t2/ffsll.S
@@ -0,0 +1,50 @@
+/* ffsll -- find first set bit in a long long, from least significant end.
+ Copyright (C) 2013 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library. If not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <sysdep.h>
+
+ .syntax unified
+ .text
+
+ENTRY (ffsll)
+ @ If low part is 0, operate on the high part. Ensure that the
+ @ word on which we operate is in r0. Set r2 to the bit offset
+ @ of the word being considered. Set the flags for the word
+ @ being operated on.
+#ifdef __ARMEL__
+ cmp r0, #0
+ itee ne
+ movne r2, #0
+ moveq r2, #32
+ movseq r0, r1
+#else
+ cmp r1, #0
+ ittee ne
+ movne r2, #0
+ movne r0, r1
+ moveq r2, #32
+ cmpeq r0, #0
+#endif
+ @ Perform the ffs on r0.
+ rbit r0, r0
+ ittt ne
+ clzne r0, r0
+ addne r2, r2, #1
+ addne r0, r0, r2
+ bx lr
+END (ffsll)
diff --git a/libc/ports/sysdeps/arm/armv6t2/memchr.S b/libc/ports/sysdeps/arm/armv6t2/memchr.S
index 6d35f478b..f75897143 100644
--- a/libc/ports/sysdeps/arm/armv6t2/memchr.S
+++ b/libc/ports/sysdeps/arm/armv6t2/memchr.S
@@ -42,10 +42,12 @@
.syntax unified
.text
+#ifdef NO_THUMB
+ .arm
+#else
.thumb
-
-@ ---------------------------------------------------------------------------
.thumb_func
+#endif
.global memchr
.type memchr,%function
ENTRY(memchr)
@@ -63,7 +65,8 @@ ENTRY(memchr)
@ Work up to an aligned point
5:
- ldrb r3, [r0],#1
+ sfi_breg r0, \
+ ldrb r3, [\B],#1
subs r2, r2, #1
cmp r3, r1
beq 50f @ If it matches exit found
@@ -83,20 +86,29 @@ ENTRY(memchr)
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
+ bic r6, 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
+ sfi_breg r0, \
+ ldrd r4,r5, [\B],#8
+#ifndef NO_THUMB
+ subs r6, r6, #8
+#endif
+ eor r4,r4, r1 @ Get it so that r4,r5 have 00's where the bytes match the target
+ eor r5,r5, r1
+ uadd8 r4, r4, r7 @ Parallel add 0xff - sets the GE bits for anything that wasn't 0
+ sel r4, r3, r7 @ bytes are 00 for none-00 bytes, or ff for 00 bytes - NOTE INVERSION
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
+ sel r5, r4, r7 @ chained....bytes are 00 for none-00 bytes, or ff for 00 bytes - NOTE INVERSION
+#ifndef NO_THUMB
+ cbnz r5, 60f
+#else
+ cmp r5, #0
+ bne 60f
+ subs r6, r6, #8
+#endif
bne 15b @ (Flags from the subs above) If not run out of bytes then go around again
pop {r4,r5,r6,r7}
@@ -110,13 +122,25 @@ ENTRY(memchr)
and r2,r2,#7 @ Leave the count remaining as the number after the double words have been done
20:
+#ifndef NO_THUMB
cbz r2, 40f @ 0 length or hit the end already then not found
+#else
+ cmp r2, #0
+ beq 40f
+#endif
21: @ Post aligned section, or just a short call
- ldrb r3,[r0],#1
+ sfi_breg r0, \
+ ldrb r3,[\B],#1
+#ifndef NO_THUMB
subs r2,r2,#1
eor r3,r3,r1 @ r3 = 0 if match - doesn't break flags from sub
cbz r3, 50f
+#else
+ eors r3, r3, r1
+ beq 50f
+ subs r2, r2, #1
+#endif
bne 21b @ on r2 flags
40:
@@ -129,22 +153,22 @@ ENTRY(memchr)
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
+ @ r4 has the 00/ff pattern for the first word, r5 has the chained value
cfi_restore_state
- cmp r5, #0
+ cmp r4, #0
itte eq
- moveq r5, r6 @ the end is in the 2nd word
+ moveq r4, r5 @ 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
+ tst r4, # CHARTSTMASK(0) @ 1st character
bne 61f
adds r0,r0,#1
- tst r5, # CHARTSTMASK(1) @ 2nd character
+ tst r4, # CHARTSTMASK(1) @ 2nd character
ittt eq
addeq r0,r0,#1
- tsteq r5, # (3<<15) @ 2nd & 3rd character
+ tsteq r4, # (3<<15) @ 2nd & 3rd character
@ If not the 3rd must be the last one
addeq r0,r0,#1
diff --git a/libc/ports/sysdeps/arm/bits/setjmp.h b/libc/ports/sysdeps/arm/bits/setjmp.h
index 1f7ddd365..21bbf7f57 100644
--- a/libc/ports/sysdeps/arm/bits/setjmp.h
+++ b/libc/ports/sysdeps/arm/bits/setjmp.h
@@ -24,7 +24,7 @@
# error "Never include <bits/setjmp.h> directly; use <setjmp.h> instead."
#endif
-#ifndef _ASM
+#ifndef __ASSEMBLER__
/* 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
diff --git a/libc/ports/sysdeps/arm/crti.S b/libc/ports/sysdeps/arm/crti.S
index 1d55ae27a..be20a1199 100644
--- a/libc/ports/sysdeps/arm/crti.S
+++ b/libc/ports/sysdeps/arm/crti.S
@@ -80,7 +80,7 @@ call_weak_fn:
.globl _init
.type _init, %function
_init:
- stmfd sp!, {r3, lr}
+ push {r3, lr}
#if PREINIT_FUNCTION_WEAK
bl call_weak_fn
#else
@@ -92,4 +92,4 @@ _init:
.globl _fini
.type _fini, %function
_fini:
- stmfd sp!, {r3, lr}
+ push {r3, lr}
diff --git a/libc/ports/sysdeps/arm/crtn.S b/libc/ports/sysdeps/arm/crtn.S
index a01eb0139..ae7546c5e 100644
--- a/libc/ports/sysdeps/arm/crtn.S
+++ b/libc/ports/sysdeps/arm/crtn.S
@@ -42,16 +42,16 @@
.section .init,"ax",%progbits
#ifdef __ARM_ARCH_4T__
- ldmfd sp!, {r3, lr}
+ pop {r3, lr}
bx lr
#else
- ldmfd sp!, {r3, pc}
+ pop {r3, pc}
#endif
.section .fini,"ax",%progbits
#ifdef __ARM_ARCH_4T__
- ldmfd sp!, {r3, lr}
+ pop {r3, lr}
bx lr
#else
- ldmfd sp!, {r3, pc}
+ pop {r3, pc}
#endif
diff --git a/libc/ports/sysdeps/arm/dl-machine.h b/libc/ports/sysdeps/arm/dl-machine.h
index 30ad46c25..5a424f841 100644
--- a/libc/ports/sysdeps/arm/dl-machine.h
+++ b/libc/ports/sysdeps/arm/dl-machine.h
@@ -136,7 +136,7 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
return lazy;
}
-#if defined(__USE_BX__)
+#if defined(ARCH_HAS_BX)
#define BX(x) "bx\t" #x
#else
#define BX(x) "mov\tpc, " #x
diff --git a/libc/ports/sysdeps/arm/dl-tlsdesc.S b/libc/ports/sysdeps/arm/dl-tlsdesc.S
index 7b4c8dfcb..e810d0db3 100644
--- a/libc/ports/sysdeps/arm/dl-tlsdesc.S
+++ b/libc/ports/sysdeps/arm/dl-tlsdesc.S
@@ -20,12 +20,6 @@
#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
@@ -50,18 +44,9 @@ _dl_tlsdesc_return:
.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
+ GET_TLS (r1)
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
@@ -99,14 +84,14 @@ _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}
+ push {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
+ GET_TLS (lr)
mov r4, r0 /* r4 = tp */
ldr r0, [r0]
ldr r2, [r1, #8] /* gen_count */
@@ -124,13 +109,18 @@ _dl_tlsdesc_dynamic:
1: mov r0, r1
bl __tls_get_addr
rsb r0, r4, r0
-2: ldmia sp!, {r2,r3,r4, lr}
+2:
+#if defined (__ARM_ARCH_4T__) && defined (__THUMB_INTERWORK__)
+ pop {r2,r3,r4, lr}
cfi_adjust_cfa_offset (-16)
cfi_restore (lr)
cfi_restore (r4)
cfi_restore (r3)
cfi_restore (r2)
- BX (lr)
+ bx lr
+#else
+ pop {r2,r3,r4, pc}
+#endif
.fnend
cfi_endproc
.size _dl_tlsdesc_dynamic, .-_dl_tlsdesc_dynamic
@@ -155,7 +145,7 @@ _dl_tlsdesc_lazy_resolver:
cfi_adjust_cfa_offset (4)
cfi_rel_offset (r2, 0)
.save {r0,r1,r3,ip,lr}
- stmdb sp!, {r0, r1, r3, ip, lr}
+ push {r0, r1, r3, ip, lr}
cfi_adjust_cfa_offset (20)
cfi_rel_offset (r0, 0)
cfi_rel_offset (r1, 4)
@@ -163,14 +153,14 @@ _dl_tlsdesc_lazy_resolver:
cfi_rel_offset (ip, 12)
cfi_rel_offset (lr, 16)
bl _dl_tlsdesc_lazy_resolver_fixup
- ldmia sp!, {r0, r1, r3, ip, lr}
+ pop {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}
+ pop {r2}
cfi_adjust_cfa_offset (-4)
cfi_restore (r2)
ldr r1, [r0, #4]
@@ -193,7 +183,7 @@ _dl_tlsdesc_resolve_hold:
cfi_adjust_cfa_offset (4)
cfi_rel_offset (r2, 0)
.save {r0,r1,r3,ip,lr}
- stmdb sp!, {r0, r1, r3, ip, lr}
+ push {r0, r1, r3, ip, lr}
cfi_adjust_cfa_offset (20)
cfi_rel_offset (r0, 0)
cfi_rel_offset (r1, 4)
@@ -202,14 +192,14 @@ _dl_tlsdesc_resolve_hold:
cfi_rel_offset (lr, 16)
adr r2, _dl_tlsdesc_resolve_hold
bl _dl_tlsdesc_resolve_hold_fixup
- ldmia sp!, {r0, r1, r3, ip, lr}
+ pop {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}
+ pop {r2}
cfi_adjust_cfa_offset (-4)
cfi_restore (r2)
ldr r1, [r0, #4]
diff --git a/libc/ports/sysdeps/arm/dl-trampoline.S b/libc/ports/sysdeps/arm/dl-trampoline.S
index 561d8ae6f..936697676 100644
--- a/libc/ports/sysdeps/arm/dl-trampoline.S
+++ b/libc/ports/sysdeps/arm/dl-trampoline.S
@@ -21,12 +21,6 @@
#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
@@ -43,7 +37,7 @@ _dl_runtime_resolve:
@ lr points to &GOT[2]
@ Save arguments. We save r4 to realign the stack.
- stmdb sp!,{r0-r4}
+ push {r0-r4}
cfi_adjust_cfa_offset (20)
cfi_rel_offset (r0, 0)
cfi_rel_offset (r1, 4)
@@ -67,7 +61,7 @@ _dl_runtime_resolve:
@ get arguments and return address back. We restore r4
@ only to realign the stack.
- ldmia sp!, {r0-r4,lr}
+ pop {r0-r4,lr}
cfi_adjust_cfa_offset (-24)
@ jump to the newly found address
@@ -192,8 +186,7 @@ _dl_runtime_profile:
add ip, r7, #72
ldmia ip, {r0-r3}
ldr ip, [r7, #264]
- mov lr, pc
- BX(ip)
+ BLX(ip)
stmia r7, {r0-r3}
@ Call pltexit.
diff --git a/libc/ports/sysdeps/arm/include/bits/setjmp.h b/libc/ports/sysdeps/arm/include/bits/setjmp.h
new file mode 100644
index 000000000..23d8f75cf
--- /dev/null
+++ b/libc/ports/sysdeps/arm/include/bits/setjmp.h
@@ -0,0 +1,34 @@
+/* Private jmp_buf-related definitions. ARM EABI version.
+ Copyright (C) 2013 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library. If not, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef _INCLUDE_BITS_SETJMP_H
+#define _INCLUDE_BITS_SETJMP_H 1
+
+#ifndef __ASSEMBLER__
+/* Get the public declarations. */
+# include <sysdeps/arm/bits/setjmp.h>
+#endif
+
+/* Register list for a ldm/stm instruction to load/store
+ the general registers from a __jmp_buf. */
+#define JMP_BUF_REGLIST {v1-v6, sl, fp, sp, lr}
+
+/* Index of __jmp_buf where the sp register resides. */
+#define __JMP_BUF_SP 8
+
+#endif /* include/bits/setjmp.h */
diff --git a/libc/ports/sysdeps/arm/jmpbuf-unwind.h b/libc/ports/sysdeps/arm/jmpbuf-unwind.h
index 7f7770aea..0863540ce 100644
--- a/libc/ports/sysdeps/arm/jmpbuf-unwind.h
+++ b/libc/ports/sysdeps/arm/jmpbuf-unwind.h
@@ -16,7 +16,6 @@
<http://www.gnu.org/licenses/>. */
#include <setjmp.h>
-#include <jmpbuf-offsets.h>
#include <stdint.h>
#include <unwind.h>
diff --git a/libc/ports/sysdeps/arm/memcpy.S b/libc/ports/sysdeps/arm/memcpy.S
index 98b9b47e3..add82e2d1 100644
--- a/libc/ports/sysdeps/arm/memcpy.S
+++ b/libc/ports/sysdeps/arm/memcpy.S
@@ -20,6 +20,7 @@
/* Thumb requires excessive IT insns here. */
#define NO_THUMB
#include <sysdep.h>
+#include <arm-features.h>
/*
* Data preload for architectures that support it (ARM V5TE and above)
@@ -45,20 +46,21 @@
* Endian independent macros for shifting bytes within registers.
*/
#ifndef __ARMEB__
-#define pull lsr
-#define push lsl
+#define PULL lsr
+#define PUSH lsl
#else
-#define pull lsl
-#define push lsr
+#define PULL lsl
+#define PUSH lsr
#endif
.text
+ .syntax unified
/* Prototype: void *memcpy(void *dest, const void *src, size_t n); */
ENTRY(memcpy)
- stmfd sp!, {r0, r4, lr}
+ push {r0, r4, lr}
cfi_adjust_cfa_offset (12)
cfi_rel_offset (r4, 4)
cfi_rel_offset (lr, 8)
@@ -68,13 +70,13 @@ ENTRY(memcpy)
subs r2, r2, #4
blt 8f
ands ip, r0, #3
- PLD( pld [r1, #0] )
+ PLD( sfi_pld r1, #0 )
bne 9f
ands ip, r1, #3
bne 10f
1: subs r2, r2, #(28)
- stmfd sp!, {r5 - r8}
+ push {r5 - r8}
cfi_adjust_cfa_offset (16)
cfi_rel_offset (r5, 0)
cfi_rel_offset (r6, 4)
@@ -84,54 +86,112 @@ ENTRY(memcpy)
CALGN( ands ip, r1, #31 )
CALGN( rsb r3, ip, #32 )
- CALGN( sbcnes r4, r3, r2 ) @ C is always set here
+ CALGN( sbcsne 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 )
+#ifndef ARM_ALWAYS_BX
+ CALGN( add pc, r4, ip, lsl #(ARM_BX_ALIGN_LOG2 - 2))
+#else
+ CALGN( add r4, r4, ip, lsl #(ARM_BX_ALIGN_LOG2 - 2))
+ CALGN( bx r4 )
+#endif
- PLD( pld [r1, #0] )
+ PLD( sfi_pld r1, #0 )
2: PLD( subs r2, r2, #96 )
- PLD( pld [r1, #28] )
+ PLD( sfi_pld r1, #28 )
PLD( blt 4f )
- PLD( pld [r1, #60] )
- PLD( pld [r1, #92] )
+ PLD( sfi_pld r1, #60 )
+ PLD( sfi_pld r1, #92 )
-3: PLD( pld [r1, #124] )
-4: ldmia r1!, {r3, r4, r5, r6, r7, r8, ip, lr}
+3: PLD( sfi_pld r1, #124 )
+4: sfi_breg r1, \
+ ldmia \B!, {r3, r4, r5, r6, r7, r8, ip, lr}
subs r2, r2, #32
- stmia r0!, {r3, r4, r5, r6, r7, r8, ip, lr}
+ sfi_breg r0, \
+ stmia \B!, {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
+#ifndef ARM_ALWAYS_BX
+ /* C is always clear here. */
+ addne pc, pc, ip, lsl #(ARM_BX_ALIGN_LOG2 - 2)
b 7f
+#else
+ beq 7f
+ push {r10}
+ cfi_adjust_cfa_offset (4)
+ cfi_rel_offset (r10, 0)
+ add r10, pc, ip, lsl #(ARM_BX_ALIGN_LOG2 - 2)
+ bx r10
+#endif
+ .p2align ARM_BX_ALIGN_LOG2
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
+ .p2align ARM_BX_ALIGN_LOG2
+ sfi_breg r1, \
+ ldr r3, [\B], #4
+ .p2align ARM_BX_ALIGN_LOG2
+ sfi_breg r1, \
+ ldr r4, [\B], #4
+ .p2align ARM_BX_ALIGN_LOG2
+ sfi_breg r1, \
+ ldr r5, [\B], #4
+ .p2align ARM_BX_ALIGN_LOG2
+ sfi_breg r1, \
+ ldr r6, [\B], #4
+ .p2align ARM_BX_ALIGN_LOG2
+ sfi_breg r1, \
+ ldr r7, [\B], #4
+ .p2align ARM_BX_ALIGN_LOG2
+ sfi_breg r1, \
+ ldr r8, [\B], #4
+ .p2align ARM_BX_ALIGN_LOG2
+ sfi_breg r1, \
+ ldr lr, [\B], #4
+
+#ifndef ARM_ALWAYS_BX
+ add pc, pc, ip, lsl #(ARM_BX_ALIGN_LOG2 - 2)
nop
+#else
+ add r10, pc, ip, lsl #(ARM_BX_ALIGN_LOG2 - 2)
+ bx r10
+#endif
+ .p2align ARM_BX_ALIGN_LOG2
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
+ .p2align ARM_BX_ALIGN_LOG2
+ sfi_breg r0, \
+ str r3, [\B], #4
+ .p2align ARM_BX_ALIGN_LOG2
+ sfi_breg r0, \
+ str r4, [\B], #4
+ .p2align ARM_BX_ALIGN_LOG2
+ sfi_breg r0, \
+ str r5, [\B], #4
+ .p2align ARM_BX_ALIGN_LOG2
+ sfi_breg r0, \
+ str r6, [\B], #4
+ .p2align ARM_BX_ALIGN_LOG2
+ sfi_breg r0, \
+ str r7, [\B], #4
+ .p2align ARM_BX_ALIGN_LOG2
+ sfi_breg r0, \
+ str r8, [\B], #4
+ .p2align ARM_BX_ALIGN_LOG2
+ sfi_breg r0, \
+ str lr, [\B], #4
+
+#ifdef ARM_ALWAYS_BX
+ pop {r10}
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (r10)
+#endif
CALGN( bcs 2b )
-7: ldmfd sp!, {r5 - r8}
+7: pop {r5 - r8}
cfi_adjust_cfa_offset (-16)
cfi_restore (r5)
cfi_restore (r6)
@@ -139,41 +199,55 @@ ENTRY(memcpy)
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}
+ sfi_breg r1, \
+ ldrbne r3, [\B], #1
+ sfi_breg r1, \
+ ldrbcs r4, [\B], #1
+ sfi_breg r1, \
+ ldrbcs ip, [\B]
+ sfi_breg r0, \
+ strbne r3, [\B], #1
+ sfi_breg r0, \
+ strbcs r4, [\B], #1
+ sfi_breg r0, \
+ strbcs ip, [\B]
+
+#if ((defined (__ARM_ARCH_4T__) && defined(__THUMB_INTERWORK__)) \
+ || defined (ARM_ALWAYS_BX))
+ pop {r0, r4, lr}
cfi_adjust_cfa_offset (-12)
cfi_restore (r4)
cfi_restore (lr)
bx lr
#else
- ldmfd sp!, {r0, r4, pc}
+ pop {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
+ sfi_breg r1, \
+ ldrbgt r3, [\B], #1
+ sfi_breg r1, \
+ ldrbge r4, [\B], #1
+ sfi_breg r1, \
+ ldrb lr, [\B], #1
+ sfi_breg r0, \
+ strbgt r3, [\B], #1
+ sfi_breg r0, \
+ strbge r4, [\B], #1
subs r2, r2, ip
- strb lr, [r0], #1
+ sfi_breg r0, \
+ strb lr, [\B], #1
blt 8b
ands ip, r1, #3
beq 1b
10: bic r1, r1, #3
cmp ip, #2
- ldr lr, [r1], #4
+ sfi_breg r1, \
+ ldr lr, [\B], #4
beq 17f
bgt 18f
@@ -185,66 +259,71 @@ ENTRY(memcpy)
CALGN( ands ip, r1, #31 )
CALGN( rsb ip, ip, #32 )
- CALGN( sbcnes r4, ip, r2 ) @ C is always set here
+ CALGN( sbcsne r4, ip, r2 ) @ C is always set here
CALGN( subcc r2, r2, ip )
CALGN( bcc 15f )
-11: stmfd sp!, {r5 - r9}
+11: push {r5 - r8, r10}
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)
+ cfi_rel_offset (r10, 16)
- PLD( pld [r1, #0] )
+ PLD( sfi_pld r1, #0 )
PLD( subs r2, r2, #96 )
- PLD( pld [r1, #28] )
+ PLD( sfi_pld r1, #28 )
PLD( blt 13f )
- PLD( pld [r1, #60] )
- PLD( pld [r1, #92] )
+ PLD( sfi_pld r1, #60 )
+ PLD( sfi_pld r1, #92 )
-12: PLD( pld [r1, #124] )
-13: ldmia r1!, {r4, r5, r6, r7}
- mov r3, lr, pull #\pull
+12: PLD( sfi_pld r1, #124 )
+13: sfi_breg r1, \
+ ldmia \B!, {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}
+ sfi_breg r1, \
+ ldmia \B!, {r8, r10, 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, r10, PUSH #\push
+ mov r10, r10, PULL #\pull
+ orr r10, r10, ip, PUSH #\push
+ mov ip, ip, PULL #\pull
+ orr ip, ip, lr, PUSH #\push
+ sfi_breg r0, \
+ stmia \B!, {r3, r4, r5, r6, r7, r8, r10, ip}
bge 12b
PLD( cmn r2, #96 )
PLD( bge 13b )
- ldmfd sp!, {r5 - r9}
+ pop {r5 - r8, r10}
cfi_adjust_cfa_offset (-20)
cfi_restore (r5)
cfi_restore (r6)
cfi_restore (r7)
cfi_restore (r8)
- cfi_restore (r9)
+ cfi_restore (r10)
14: ands ip, r2, #28
beq 16f
-15: mov r3, lr, pull #\pull
- ldr lr, [r1], #4
+15: mov r3, lr, PULL #\pull
+ sfi_breg r1, \
+ ldr lr, [\B], #4
subs ip, ip, #4
- orr r3, r3, lr, push #\push
- str r3, [r0], #4
+ orr r3, r3, lr, PUSH #\push
+ sfi_breg r0, \
+ str r3, [\B], #4
bgt 15b
CALGN( cmp r2, #0 )
CALGN( bge 11b )
diff --git a/libc/ports/sysdeps/arm/memmove.S b/libc/ports/sysdeps/arm/memmove.S
index 059ca7ac3..9d4d5b099 100644
--- a/libc/ports/sysdeps/arm/memmove.S
+++ b/libc/ports/sysdeps/arm/memmove.S
@@ -20,6 +20,7 @@
/* Thumb requires excessive IT insns here. */
#define NO_THUMB
#include <sysdep.h>
+#include <arm-features.h>
/*
* Data preload for architectures that support it (ARM V5TE and above)
@@ -45,14 +46,15 @@
* Endian independent macros for shifting bytes within registers.
*/
#ifndef __ARMEB__
-#define pull lsr
-#define push lsl
+#define PULL lsr
+#define PUSH lsl
#else
-#define pull lsl
-#define push lsr
+#define PULL lsl
+#define PUSH lsr
#endif
.text
+ .syntax unified
/*
* Prototype: void *memmove(void *dest, const void *src, size_t n);
@@ -73,7 +75,7 @@ ENTRY(memmove)
bls HIDDEN_JUMPTARGET(memcpy)
#endif
- stmfd sp!, {r0, r4, lr}
+ push {r0, r4, lr}
cfi_adjust_cfa_offset (12)
cfi_rel_offset (r4, 4)
cfi_rel_offset (lr, 8)
@@ -85,13 +87,13 @@ ENTRY(memmove)
subs r2, r2, #4
blt 8f
ands ip, r0, #3
- PLD( pld [r1, #-4] )
+ PLD( sfi_pld r1, #-4 )
bne 9f
ands ip, r1, #3
bne 10f
1: subs r2, r2, #(28)
- stmfd sp!, {r5 - r8}
+ push {r5 - r8}
cfi_adjust_cfa_offset (16)
cfi_rel_offset (r5, 0)
cfi_rel_offset (r6, 4)
@@ -100,54 +102,112 @@ ENTRY(memmove)
blt 5f
CALGN( ands ip, r1, #31 )
- CALGN( sbcnes r4, ip, r2 ) @ C is always set here
+ CALGN( sbcsne 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 )
+#ifndef ARM_ALWAYS_BX
+ CALGN( add pc, r4, ip, lsl #(ARM_BX_ALIGN_LOG2 - 2))
+#else
+ CALGN( add r4, r4, ip, lsl #(ARM_BX_ALIGN_LOG2 - 2))
+ CALGN( bx r4 )
+#endif
- PLD( pld [r1, #-4] )
+ PLD( sfi_pld r1, #-4 )
2: PLD( subs r2, r2, #96 )
- PLD( pld [r1, #-32] )
+ PLD( sfi_pld r1, #-32 )
PLD( blt 4f )
- PLD( pld [r1, #-64] )
- PLD( pld [r1, #-96] )
+ PLD( sfi_pld r1, #-64 )
+ PLD( sfi_pld r1, #-96 )
-3: PLD( pld [r1, #-128] )
-4: ldmdb r1!, {r3, r4, r5, r6, r7, r8, ip, lr}
+3: PLD( sfi_pld r1, #-128 )
+4: sfi_breg r1, \
+ ldmdb \B!, {r3, r4, r5, r6, r7, r8, ip, lr}
subs r2, r2, #32
- stmdb r0!, {r3, r4, r5, r6, r7, r8, ip, lr}
+ sfi_breg r0, \
+ stmdb \B!, {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
+#ifndef ARM_ALWAYS_BX
+ /* C is always clear here. */
+ addne pc, pc, ip, lsl #(ARM_BX_ALIGN_LOG2 - 2)
b 7f
+#else
+ beq 7f
+ push {r10}
+ cfi_adjust_cfa_offset (4)
+ cfi_rel_offset (r10, 0)
+ add r10, pc, ip, lsl #(ARM_BX_ALIGN_LOG2 - 2)
+ bx r10
+#endif
+ .p2align ARM_BX_ALIGN_LOG2
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
+ .p2align ARM_BX_ALIGN_LOG2
+ sfi_breg r1, \
+ ldr r3, [\B, #-4]!
+ .p2align ARM_BX_ALIGN_LOG2
+ sfi_breg r1, \
+ ldr r4, [\B, #-4]!
+ .p2align ARM_BX_ALIGN_LOG2
+ sfi_breg r1, \
+ ldr r5, [\B, #-4]!
+ .p2align ARM_BX_ALIGN_LOG2
+ sfi_breg r1, \
+ ldr r6, [\B, #-4]!
+ .p2align ARM_BX_ALIGN_LOG2
+ sfi_breg r1, \
+ ldr r7, [\B, #-4]!
+ .p2align ARM_BX_ALIGN_LOG2
+ sfi_breg r1, \
+ ldr r8, [\B, #-4]!
+ .p2align ARM_BX_ALIGN_LOG2
+ sfi_breg r1, \
+ ldr lr, [\B, #-4]!
+
+#ifndef ARM_ALWAYS_BX
+ add pc, pc, ip, lsl #(ARM_BX_ALIGN_LOG2 - 2)
nop
+#else
+ add r10, pc, ip, lsl #(ARM_BX_ALIGN_LOG2 - 2)
+ bx r10
+#endif
+ .p2align ARM_BX_ALIGN_LOG2
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]!
+ .p2align ARM_BX_ALIGN_LOG2
+ sfi_breg r0, \
+ str r3, [\B, #-4]!
+ .p2align ARM_BX_ALIGN_LOG2
+ sfi_breg r0, \
+ str r4, [\B, #-4]!
+ .p2align ARM_BX_ALIGN_LOG2
+ sfi_breg r0, \
+ str r5, [\B, #-4]!
+ .p2align ARM_BX_ALIGN_LOG2
+ sfi_breg r0, \
+ str r6, [\B, #-4]!
+ .p2align ARM_BX_ALIGN_LOG2
+ sfi_breg r0, \
+ str r7, [\B, #-4]!
+ .p2align ARM_BX_ALIGN_LOG2
+ sfi_breg r0, \
+ str r8, [\B, #-4]!
+ .p2align ARM_BX_ALIGN_LOG2
+ sfi_breg r0, \
+ str lr, [\B, #-4]!
+
+#ifdef ARM_ALWAYS_BX
+ pop {r10}
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (r10)
+#endif
CALGN( bcs 2b )
-7: ldmfd sp!, {r5 - r8}
+7: pop {r5 - r8}
cfi_adjust_cfa_offset (-16)
cfi_restore (r5)
cfi_restore (r6)
@@ -155,40 +215,54 @@ ENTRY(memmove)
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}
+ sfi_breg r1, \
+ ldrbne r3, [\B, #-1]!
+ sfi_breg r1, \
+ ldrbcs r4, [\B, #-1]!
+ sfi_breg r1, \
+ ldrbcs ip, [\B, #-1]
+ sfi_breg r0, \
+ strbne r3, [\B, #-1]!
+ sfi_breg r0, \
+ strbcs r4, [\B, #-1]!
+ sfi_breg r0, \
+ strbcs ip, [\B, #-1]
+
+#if ((defined (__ARM_ARCH_4T__) && defined (__THUMB_INTERWORK__)) \
+ || defined (ARM_ALWAYS_BX))
+ pop {r0, r4, lr}
cfi_adjust_cfa_offset (-12)
cfi_restore (r4)
cfi_restore (lr)
bx lr
#else
- ldmfd sp!, {r0, r4, pc}
+ pop {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]!
+ sfi_breg r1, \
+ ldrbgt r3, [\B, #-1]!
+ sfi_breg r1, \
+ ldrbge r4, [\B, #-1]!
+ sfi_breg r1, \
+ ldrb lr, [\B, #-1]!
+ sfi_breg r0, \
+ strbgt r3, [\B, #-1]!
+ sfi_breg r0, \
+ strbge r4, [\B, #-1]!
subs r2, r2, ip
- strb lr, [r0, #-1]!
+ sfi_breg r0, \
+ strb lr, [\B, #-1]!
blt 8b
ands ip, r1, #3
beq 1b
10: bic r1, r1, #3
cmp ip, #2
- ldr r3, [r1, #0]
+ sfi_breg r1, \
+ ldr r3, [\B, #0]
beq 17f
blt 18f
@@ -200,66 +274,71 @@ ENTRY(memmove)
CALGN( ands ip, r1, #31 )
CALGN( rsb ip, ip, #32 )
- CALGN( sbcnes r4, ip, r2 ) @ C is always set here
+ CALGN( sbcsne r4, ip, r2 ) @ C is always set here
CALGN( subcc r2, r2, ip )
CALGN( bcc 15f )
-11: stmfd sp!, {r5 - r9}
+11: push {r5 - r8, r10}
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)
+ cfi_rel_offset (r10, 16)
- PLD( pld [r1, #-4] )
+ PLD( sfi_pld r1, #-4 )
PLD( subs r2, r2, #96 )
- PLD( pld [r1, #-32] )
+ PLD( sfi_pld r1, #-32 )
PLD( blt 13f )
- PLD( pld [r1, #-64] )
- PLD( pld [r1, #-96] )
+ PLD( sfi_pld r1, #-64 )
+ PLD( sfi_pld r1, #-96 )
-12: PLD( pld [r1, #-128] )
-13: ldmdb r1!, {r7, r8, r9, ip}
- mov lr, r3, push #\push
+12: PLD( sfi_pld r1, #-128 )
+13: sfi_breg r1, \
+ ldmdb \B!, {r7, r8, r10, 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}
+ sfi_breg r1, \
+ ldmdb \B!, {r3, r4, r5, r6}
+ orr lr, lr, ip, PULL #\pull
+ mov ip, ip, PUSH #\push
+ orr ip, ip, r10, PULL #\pull
+ mov r10, r10, PUSH #\push
+ orr r10, r10, 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
+ sfi_breg r0, \
+ stmdb \B!, {r4 - r8, r10, ip, lr}
bge 12b
PLD( cmn r2, #96 )
PLD( bge 13b )
- ldmfd sp!, {r5 - r9}
+ pop {r5 - r8, r10}
cfi_adjust_cfa_offset (-20)
cfi_restore (r5)
cfi_restore (r6)
cfi_restore (r7)
cfi_restore (r8)
- cfi_restore (r9)
+ cfi_restore (r10)
14: ands ip, r2, #28
beq 16f
-15: mov lr, r3, push #\push
- ldr r3, [r1, #-4]!
+15: mov lr, r3, PUSH #\push
+ sfi_breg r1, \
+ ldr r3, [\B, #-4]!
subs ip, ip, #4
- orr lr, lr, r3, pull #\pull
- str lr, [r0, #-4]!
+ orr lr, lr, r3, PULL #\pull
+ sfi_breg r0, \
+ str lr, [\B, #-4]!
bgt 15b
CALGN( cmp r2, #0 )
CALGN( bge 11b )
diff --git a/libc/ports/sysdeps/arm/memset.S b/libc/ports/sysdeps/arm/memset.S
index 9924cb911..a28cdc620 100644
--- a/libc/ports/sysdeps/arm/memset.S
+++ b/libc/ports/sysdeps/arm/memset.S
@@ -20,6 +20,9 @@
#define NO_THUMB
#include <sysdep.h>
+ .text
+ .syntax unified
+
/* void *memset (dstpp, c, len) */
ENTRY(memset)
@@ -29,7 +32,8 @@ ENTRY(memset)
1:
tst r3, #3 @ aligned yet?
- strneb r1, [r3], #1
+ sfi_breg r3, \
+ strbne r1, [\B], #1
subne r2, r2, #1
bne 1b
@@ -40,27 +44,35 @@ ENTRY(memset)
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}
+ sfi_breg r3, \
+ stmiacs \B!, {r1, ip} @ store up to 32 bytes per loop iteration
+ subscs r2, r2, #8
+ sfi_breg r3, \
+ stmiacs \B!, {r1, ip}
+ subscs r2, r2, #8
+ sfi_breg r3, \
+ stmiacs \B!, {r1, ip}
+ subscs r2, r2, #8
+ sfi_breg r3, \
+ stmiacs \B!, {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
+ sfi_breg r3, \
+ strbcs r1, [\B], #1
+ subscs r2, r2, #1
+ sfi_breg r3, \
+ strbcs r1, [\B], #1
+ subscs r2, r2, #1
+ sfi_breg r3, \
+ strbcs r1, [\B], #1
+ subscs r2, r2, #1
+ sfi_breg r3, \
+ strbcs r1, [\B], #1
bcs 2b
-
+
DO_RET(lr)
END(memset)
libc_hidden_builtin_def (memset)
diff --git a/libc/ports/sysdeps/arm/preconfigure b/libc/ports/sysdeps/arm/preconfigure
index 6d61b1428..7ba17492e 100644
--- a/libc/ports/sysdeps/arm/preconfigure
+++ b/libc/ports/sysdeps/arm/preconfigure
@@ -1,53 +1,63 @@
+# This file is generated from configure.in by Autoconf. DO NOT EDIT!
+ # Local preconfigure fragment for sysdeps/arm
+
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_[0-9].*__' |
- sed -e 's/^#define //' -e 's/ .*//'`
+ case $config_os in
+ linux-gnueabi*)
+ # If the compiler enables unwind tables by default, this causes
+ # problems with undefined symbols in -nostdlib link tests. To
+ # avoid this, add -fno-unwind-tables here and remove it in
+ # sysdeps/unix/sysv/linux/arm/configure.in after those tests have
+ # been run.
+ if "${CFLAGS+set}" != "set" ; then
+ CFLAGS="-g -O2"
+ fi
+ CFLAGS="$CFLAGS -fno-unwind-tables"
+ ;;
+ linux*)
+ as_fn_error $? "Old ABI no longer supported" "$LINENO" 5
+ ;;
+ esac
+
+ base_machine=arm
+ # 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=`$CC $CFLAGS $CPPFLAGS -E -dM -xc /dev/null |
+ sed -n 's/^#define \(__ARM_ARCH_[0-9].*__\) .*$/\1/p'`
- case x$archcppflag in
- x__ARM_ARCH_[89]*__)
- machine=armv7
- echo "Found compiler is configured for something newer than v7 - using v7"
- ;;
+ case "x$archcppflag" in
+ x__ARM_ARCH_89*__)
+ machine=armv7
+ { $as_echo "$as_me:${as_lineno-$LINENO}: Found compiler is configured for something newer than v7 - using v7" >&5
+$as_echo "$as_me: Found compiler is configured for something newer than v7 - using v7" >&6;}
+ ;;
- x__ARM_ARCH_7A__)
- machine=armv7
- echo "Found compiler is configured for $machine"
- ;;
+ x__ARM_ARCH_7A__)
+ machine=armv7
+ { $as_echo "$as_me:${as_lineno-$LINENO}: Found compiler is configured for $machine" >&5
+$as_echo "$as_me: Found compiler is configured for $machine" >&6;}
+ ;;
- x__ARM_ARCH_6T2__)
- machine=armv6t2
- echo "Found compiler is configured for $machine"
- ;;
- x__ARM_ARCH_6*__)
- machine=armv6
- echo "Found compiler is configured for $machine"
- ;;
- *)
- machine=arm
- echo 2>&1 "arm/preconfigure: Did not find ARM architecture type; using default"
- ;;
- esac
+ x__ARM_ARCH_6T2__)
+ machine=armv6t2
+ { $as_echo "$as_me:${as_lineno-$LINENO}: Found compiler is configured for $machine" >&5
+$as_echo "$as_me: Found compiler is configured for $machine" >&6;}
+ ;;
+ x__ARM_ARCH_6*__)
+ machine=armv6
+ { $as_echo "$as_me:${as_lineno-$LINENO}: Found compiler is configured for $machine" >&5
+$as_echo "$as_me: Found compiler is configured for $machine" >&6;}
+ ;;
+ *)
+ machine=arm
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: arm/preconfigure: Did not find ARM architecture type; using default" >&5
+$as_echo "$as_me: WARNING: arm/preconfigure: Did not find ARM architecture type; using default" >&2;}
+ ;;
+ esac
- machine=arm/$machine
- if [ "${CFLAGS+set}" != "set" ]; then
- CFLAGS="-g -O2"
- fi
- CFLAGS="$CFLAGS -fno-unwind-tables"
- ;;
- linux*)
- echo "Old ABI no longer supported" 2>&1
- exit 1
- ;;
- esac
- ;;
+ machine=arm/$machine
esac
diff --git a/libc/ports/sysdeps/arm/preconfigure.in b/libc/ports/sysdeps/arm/preconfigure.in
new file mode 100644
index 000000000..99f21282f
--- /dev/null
+++ b/libc/ports/sysdeps/arm/preconfigure.in
@@ -0,0 +1,58 @@
+GLIBC_PROVIDES dnl See aclocal.m4 in the top level source directory.
+# Local preconfigure fragment for sysdeps/arm
+
+case "$machine" in
+arm*)
+ case $config_os in
+ linux-gnueabi*)
+ # If the compiler enables unwind tables by default, this causes
+ # problems with undefined symbols in -nostdlib link tests. To
+ # avoid this, add -fno-unwind-tables here and remove it in
+ # sysdeps/unix/sysv/linux/arm/configure.in after those tests have
+ # been run.
+ if [ "${CFLAGS+set}" != "set" ]; then
+ CFLAGS="-g -O2"
+ fi
+ CFLAGS="$CFLAGS -fno-unwind-tables"
+ ;;
+ linux*)
+ AC_MSG_ERROR([Old ABI no longer supported])
+ ;;
+ esac
+
+ base_machine=arm
+ # 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=`$CC $CFLAGS $CPPFLAGS -E -dM -xc /dev/null |
+ sed -n 's/^#define \(__ARM_ARCH_[0-9].*__\) .*$/\1/p'`
+
+ case "x$archcppflag" in
+ x__ARM_ARCH_[89]*__)
+ machine=armv7
+ AC_MSG_NOTICE([Found compiler is configured for something newer than v7 - using v7])
+ ;;
+
+ x__ARM_ARCH_7A__)
+ machine=armv7
+ AC_MSG_NOTICE([Found compiler is configured for $machine])
+ ;;
+
+ x__ARM_ARCH_6T2__)
+ machine=armv6t2
+ AC_MSG_NOTICE([Found compiler is configured for $machine])
+ ;;
+ x__ARM_ARCH_6*__)
+ machine=armv6
+ AC_MSG_NOTICE([Found compiler is configured for $machine])
+ ;;
+ *)
+ machine=arm
+ AC_MSG_WARN([arm/preconfigure: Did not find ARM architecture type; using default])
+ ;;
+ esac
+
+ machine=arm/$machine
+esac
diff --git a/libc/ports/sysdeps/arm/setjmp.S b/libc/ports/sysdeps/arm/setjmp.S
index 6776cab38..f75047065 100644
--- a/libc/ports/sysdeps/arm/setjmp.S
+++ b/libc/ports/sysdeps/arm/setjmp.S
@@ -19,8 +19,6 @@
/* ??? Needs more rearrangement for the STM to handle thumb mode. */
#define NO_THUMB
#include <sysdep.h>
-#define _SETJMP_H
-#define _ASM
#include <bits/setjmp.h>
#include <rtld-global-offsets.h>
#include <arm-features.h>
@@ -29,7 +27,8 @@ ENTRY (__sigsetjmp)
mov ip, r0
/* Save registers */
- stmia ip!, {v1-v6, sl, fp, sp, lr}
+ sfi_breg ip, \
+ stmia \B!, JMP_BUF_REGLIST
#if !defined ARM_ASSUME_NO_IWMMXT || defined __SOFTFP__
# define NEED_HWCAP 1
@@ -66,11 +65,13 @@ ENTRY (__sigsetjmp)
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
+ sfi_breg ip, \
+ stc p11, cr8, [\B], #64
/* Store the floating-point status register. */
/* Following instruction is vmrs a4, fpscr. */
mrc p10, 7, a4, cr1, cr0, 0
- str a4, [ip], #4
+ sfi_breg ip, \
+ str a4, [\B], #4
.Lno_vfp:
#ifndef ARM_ASSUME_NO_IWMMXT
@@ -79,12 +80,18 @@ ENTRY (__sigsetjmp)
/* 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
+ sfi_breg r12, \
+ stcl p1, cr10, [\B], #8
+ sfi_breg r12, \
+ stcl p1, cr11, [\B], #8
+ sfi_breg r12, \
+ stcl p1, cr12, [\B], #8
+ sfi_breg r12, \
+ stcl p1, cr13, [\B], #8
+ sfi_breg r12, \
+ stcl p1, cr14, [\B], #8
+ sfi_breg r12, \
+ stcl p1, cr15, [\B], #8
.Lno_iwmmxt:
#endif
diff --git a/libc/ports/sysdeps/arm/start.S b/libc/ports/sysdeps/arm/start.S
index a1d15b810..0a57b0bec 100644
--- a/libc/ports/sysdeps/arm/start.S
+++ b/libc/ports/sysdeps/arm/start.S
@@ -80,14 +80,14 @@ _start:
mov lr, #0
/* Pop argc off the stack and save a pointer to argv */
- ldr a2, [sp], #4
+ pop { a2 }
mov a3, sp
/* Push stack limit */
- str a3, [sp, #-4]!
+ push { a3 }
/* Push rtld_fini */
- str a1, [sp, #-4]!
+ push { a1 }
#ifdef SHARED
ldr sl, .L_GOT
@@ -97,7 +97,7 @@ _start:
ldr ip, .L_GOT+4 /* __libc_csu_fini */
ldr ip, [sl, ip]
- str ip, [sp, #-4]! /* Push __libc_csu_fini */
+ push { ip } /* Push __libc_csu_fini */
ldr a4, .L_GOT+8 /* __libc_csu_init */
ldr a4, [sl, a4]
@@ -113,7 +113,7 @@ _start:
ldr ip, =__libc_csu_fini
/* Push __libc_csu_fini */
- str ip, [sp, #-4]!
+ push { ip }
/* Set up the other arguments in registers */
ldr a1, =main
diff --git a/libc/ports/sysdeps/arm/strlen.S b/libc/ports/sysdeps/arm/strlen.S
index 2b947e240..7d358a724 100644
--- a/libc/ports/sysdeps/arm/strlen.S
+++ b/libc/ports/sysdeps/arm/strlen.S
@@ -25,9 +25,13 @@
* exit: r0 = len
*/
+ .syntax unified
+ .text
+
ENTRY(strlen)
bic r1, r0, $3 @ addr of word containing first byte
- ldr r2, [r1], $4 @ get the first word
+ sfi_breg r1, \
+ ldr r2, [\B], $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
@@ -51,7 +55,8 @@ Laligned: @ here, we have a word in r2. Does it
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
+ sfi_breg r1, \
+ ldrne r2, [\B], $4 @ and we continue to the next word
bne Laligned @
Llastword: @ drop through to here once we find a
#ifdef __ARMEB__
diff --git a/libc/ports/sysdeps/arm/sub_n.S b/libc/ports/sysdeps/arm/sub_n.S
new file mode 100644
index 000000000..8eafa41e6
--- /dev/null
+++ b/libc/ports/sysdeps/arm/sub_n.S
@@ -0,0 +1,2 @@
+#define USE_AS_SUB_N
+#include "add_n.S"
diff --git a/libc/ports/sysdeps/arm/submul_1.S b/libc/ports/sysdeps/arm/submul_1.S
new file mode 100644
index 000000000..2d17490d8
--- /dev/null
+++ b/libc/ports/sysdeps/arm/submul_1.S
@@ -0,0 +1,74 @@
+/* mpn_submul_1 -- multiply and subtract bignums.
+ Copyright (C) 2013 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library. If not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <sysdep.h>
+
+ .syntax unified
+ .text
+
+@ cycles/limb
+@ StrongArm ?
+@ Cortex-A8 ?
+@ Cortex-A9 ?
+@ Cortex-A15 4
+
+/* mp_limb_t mpn_submul_1(res_ptr, src1_ptr, size, s2_limb) */
+
+ENTRY (__mpn_submul_1)
+ 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)
+
+ sfi_breg r1, \
+ ldr r6, [\B], #4
+ sfi_breg r0, \
+ ldr r7, [\B]
+ mov r4, #0 /* init carry in */
+ b 1f
+0:
+ sfi_breg r1, \
+ ldr r6, [\B], #4 /* load next ul */
+ adds r5, r5, r4 /* (lpl, c) = lpl + cl */
+ adc r4, ip, #0 /* cl = hpl + c */
+ subs r5, r7, r5 /* (lpl, !c) = rl - lpl */
+ sfi_breg r0, \
+ ldr r7, [\B, #4] /* load next rl */
+ it cc
+ addcc r4, r4, #1 /* cl += !c */
+ sfi_breg r0, \
+ str r5, [\B], #4
+1:
+ umull r5, ip, r6, r3 /* (hpl, lpl) = ul * vl */
+ subs r2, r2, #1
+ bne 0b
+
+ adds r5, r5, r4 /* (lpl, c) = lpl + cl */
+ adc r4, ip, #0 /* cl = hpl + c */
+ subs r5, r7, r5 /* (lpl, !c) = rl - lpl */
+ sfi_breg r0, \
+ str r5, [\B], #4
+ it cc
+ addcc r4, r4, #1 /* cl += !c */
+ mov r0, r4 /* return carry */
+
+ pop { r4, r5, r6, r7 }
+ DO_RET (lr)
+END (__mpn_submul_1)
diff --git a/libc/ports/sysdeps/arm/sysdep.h b/libc/ports/sysdeps/arm/sysdep.h
index 4af7429ac..83df7ebc3 100644
--- a/libc/ports/sysdeps/arm/sysdep.h
+++ b/libc/ports/sysdeps/arm/sysdep.h
@@ -19,9 +19,42 @@
#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__
+/* The __ARM_ARCH define is provided by gcc 4.8. Construct it otherwise. */
+#ifndef __ARM_ARCH
+# ifdef __ARM_ARCH_2__
+# define __ARM_ARCH 2
+# elif defined (__ARM_ARCH_3__) || defined (__ARM_ARCH_3M__)
+# define __ARM_ARCH 3
+# elif defined (__ARM_ARCH_4__) || defined (__ARM_ARCH_4T__)
+# define __ARM_ARCH 4
+# elif defined (__ARM_ARCH_5__) || defined (__ARM_ARCH_5E__) \
+ || defined(__ARM_ARCH_5T__) || defined(__ARM_ARCH_5TE__) \
+ || defined(__ARM_ARCH_5TEJ__)
+# define __ARM_ARCH 5
+# elif defined (__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) \
+ || defined (__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__) \
+ || defined (__ARM_ARCH_6K__) || defined(__ARM_ARCH_6T2__)
+# define __ARM_ARCH 6
+# elif defined (__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) \
+ || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) \
+ || defined(__ARM_ARCH_7EM__)
+# define __ARM_ARCH 7
+# else
+# error unknown arm architecture
+# endif
+#endif
+
+#if __ARM_ARCH > 4 || defined (__ARM_ARCH_4T__)
+# define ARCH_HAS_BX
+#endif
+#if __ARM_ARCH > 4
+# define ARCH_HAS_BLX
+#endif
+#if __ARM_ARCH > 6 || defined (__ARM_ARCH_6K__) || defined (__ARM_ARCH_6ZK__)
+# define ARCH_HAS_HARD_TP
+#endif
+#if __ARM_ARCH > 6 || defined (__ARM_ARCH_6T2__)
+# define ARCH_HAS_T2
#endif
#ifdef __ASSEMBLER__
@@ -33,30 +66,23 @@
#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
+#ifdef ARCH_HAS_BX
+# define BX(R) bx R
+# define BXC(C, R) bx##C R
+# ifdef ARCH_HAS_BLX
+# define BLX(R) blx R
+# else
+# define BLX(R) mov lr, pc; bx R
+# endif
#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
+# define BX(R) mov pc, R
+# define BXC(C, R) mov##C pc, R
+# define BLX(R) mov lr, pc; mov pc, R
#endif
+#define DO_RET(R) BX(R)
+#define RETINSTR(C, R) BXC(C, R)
+
/* Define an entry point visible from C. */
#define ENTRY(name) \
.globl C_SYMBOL_NAME(name); \
@@ -80,7 +106,7 @@
/* Call __gnu_mcount_nc if GCC >= 4.4. */
#if __GNUC_PREREQ(4,4)
#define CALL_MCOUNT \
- str lr,[sp, #-4]!; \
+ push {lr}; \
cfi_adjust_cfa_offset (4); \
cfi_rel_offset (lr, 0); \
bl PLTJMP(mcount); \
@@ -88,11 +114,11 @@
cfi_restore (lr)
#else /* else call _mcount */
#define CALL_MCOUNT \
- str lr,[sp, #-4]!; \
+ push {lr}; \
cfi_adjust_cfa_offset (4); \
cfi_rel_offset (lr, 0); \
bl PLTJMP(mcount); \
- ldr lr, [sp], #4; \
+ pops {lr}; \
cfi_adjust_cfa_offset (-4); \
cfi_restore (lr)
#endif
@@ -117,11 +143,124 @@
the caller. */
.eabi_attribute 24, 1
+/* The thumb2 encoding is reasonably complete. Unless suppressed, use it. */
+ .syntax unified
+# if defined(__thumb2__) && !defined(NO_THUMB)
+ .thumb
+#else
+# undef __thumb__
+# undef __thumb2__
+ .arm
+# endif
+
+/* Load or store to/from a pc-relative EXPR into/from R, using T. */
+# ifdef __thumb2__
+# define LDST_PCREL(OP, R, T, EXPR) \
+ ldr T, 98f; \
+ .subsection 2; \
+98: .word EXPR - 99f - PC_OFS; \
+ .previous; \
+99: add T, T, pc; \
+ OP R, [T]
+# else
+# define LDST_PCREL(OP, R, T, EXPR) \
+ ldr T, 98f; \
+ .subsection 2; \
+98: .word EXPR - 99f - PC_OFS; \
+ .previous; \
+99: OP R, [pc, T]
+# endif
+
+/* Cope with negative memory offsets, which thumb can't encode.
+ Use NEGOFF_ADJ_BASE to (conditionally) alter the base register,
+ and then NEGOFF_OFF1 to use 0 for thumb and the offset for arm,
+ or NEGOFF_OFF2 to use A-B for thumb and A for arm. */
+# ifdef __thumb2__
+# define NEGOFF_ADJ_BASE(R, OFF) add R, R, $OFF
+# define NEGOFF_ADJ_BASE2(D, S, OFF) add D, S, $OFF
+# define NEGOFF_OFF1(R, OFF) [R]
+# define NEGOFF_OFF2(R, OFFA, OFFB) [R, $((OFFA) - (OFFB))]
+# else
+# define NEGOFF_ADJ_BASE(R, OFF)
+# define NEGOFF_ADJ_BASE2(D, S, OFF) mov D, S
+# define NEGOFF_OFF1(R, OFF) [R, $OFF]
+# define NEGOFF_OFF2(R, OFFA, OFFB) [R, $OFFA]
+# endif
+
+/* Helper to get the TLS base pointer. The interface is that TMP is a
+ register that may be used to hold the LR, if necessary. TMP may be
+ LR itself to indicate that LR need not be saved. The base pointer
+ is returned in R0. Only R0 and TMP are modified. */
+
+# ifdef ARCH_HAS_HARD_TP
+/* If the cpu has cp15 available, use it. */
+# define GET_TLS(TMP) mrc p15, 0, r0, c13, c0, 3
+# else
+/* At this generic level we have no tricks to pull. Call the ABI routine. */
+# define GET_TLS(TMP) \
+ push { r1, r2, r3, lr }; \
+ cfi_remember_state; \
+ cfi_adjust_cfa_offset (16); \
+ cfi_rel_offset (r1, 0); \
+ cfi_rel_offset (r2, 4); \
+ cfi_rel_offset (r3, 8); \
+ cfi_rel_offset (lr, 12); \
+ bl __aeabi_read_tp; \
+ pop { r1, r2, r3, lr }; \
+ cfi_restore_state
+# endif /* ARCH_HAS_HARD_TP */
+
+# ifndef ARM_SFI_MACROS
+# define ARM_SFI_MACROS 1
+/* This assembly macro is prepended to any load/store instruction,
+ pulling the base register out of the addressing mode syntax and
+ making it the first operand of the macro. For example:
+ ldr r0, [r1]
+ becomes:
+ sfi_breg r1, ldr r0, [\B]
+ The \B stands in for the base register that is the first operand
+ to the macro, so we can avoid error-prone repetition of the base
+ register in two places on the line.
+
+ This is used for all memory access through a base register other
+ than PC or SP. It's intended to support SFI schemes such as
+ Native Client, where the OS will enforce that all load/store
+ instructions use a special form. In any such configuration,
+ another sysdep.h file will have defined ARM_SFI_MACROS and
+ provided its own assembly macros with the same interface. */
+
+ .macro sfi_breg basereg, insn, operands:vararg
+ .macro _sfi_breg_doit B
+ \insn \operands
+ .endm
+ _sfi_breg_doit \basereg
+ .purgem _sfi_breg_doit
+ .endm
+
+/* This assembly macro replaces the "pld" instruction.
+ The syntax:
+ sfi_pld REGISTER, #OFFSET
+ is exactly equivalent to:
+ sfi_breg REGISTER, pld [\B, #OFFSET]
+ (and ", #OFFSET" is optional). We have a separate macro
+ only to work around a bug in GAS versions prior to 2.23.2,
+ that misparses the sfi_breg macro expansion in this case. */
+
+ .macro sfi_pld basereg, offset=#0
+ pld [\basereg, \offset]
+ .endm
+
+/* This macro precedes any instruction that directly changes the SP.
+ It's not needed for push/pop or for any kind of load or store that
+ implicitly changes the SP via the ! syntax. */
+# define sfi_sp /* Nothing to do. */
+
+# endif
+
#endif /* __ASSEMBLER__ */
/* This number is the offset from the pc at the current location. */
-/* ??? At the moment we're not turning on thumb mode in assembly. */
-#if defined(__thumb__) && !defined(__ASSEMBLER__)
+#ifdef __thumb__
# define PC_OFS 4
#else
# define PC_OFS 8
diff --git a/libc/ports/sysdeps/ia64/dl-fptr.h b/libc/ports/sysdeps/ia64/dl-fptr.h
index c2bef6c28..447c098af 100644
--- a/libc/ports/sysdeps/ia64/dl-fptr.h
+++ b/libc/ports/sysdeps/ia64/dl-fptr.h
@@ -32,4 +32,14 @@
#define ELF_MACHINE_LOAD_ADDRESS(var, symbol) \
asm ("movl %0 = @gprel (" #symbol ");; add %0 = %0, gp" : "=&r" (var));
+/* We don't have a gcc helper to extract the plabel info. */
+#define ELF_PTR_TO_FDESC(ptr) \
+ ({ union { \
+ void *_ptr; \
+ struct fdesc *_fdesc; \
+ } _u; \
+ _u._ptr = ptr; \
+ _u._fdesc; \
+ })
+
#endif /* !dl_ia64_fptr_h */
diff --git a/libc/ports/sysdeps/ia64/dl-machine.h b/libc/ports/sysdeps/ia64/dl-machine.h
index 2eb80d752..dd469d7a7 100644
--- a/libc/ports/sysdeps/ia64/dl-machine.h
+++ b/libc/ports/sysdeps/ia64/dl-machine.h
@@ -119,7 +119,7 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
/* This function will be called to perform the relocation. */
if (!profile)
- doit = (Elf64_Addr) ((struct fdesc *) &_dl_runtime_resolve)->ip;
+ doit = (Elf64_Addr) ELF_PTR_TO_FDESC (&_dl_runtime_resolve)->ip;
else
{
if (GLRO(dl_profile) != NULL
@@ -129,7 +129,7 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
want profiling and the timers are started. */
GL(dl_profile_map) = l;
}
- doit = (Elf64_Addr) ((struct fdesc *) &_dl_runtime_profile)->ip;
+ doit = (Elf64_Addr) ELF_PTR_TO_FDESC (&_dl_runtime_profile)->ip;
}
reserve[1] = doit;
diff --git a/libc/ports/sysdeps/ia64/entry.h b/libc/ports/sysdeps/ia64/entry.h
index b93e1b6a5..e11b49fc5 100644
--- a/libc/ports/sysdeps/ia64/entry.h
+++ b/libc/ports/sysdeps/ia64/entry.h
@@ -1,10 +1,13 @@
+#include <link.h>
+#include <dl-fptr.h>
+
#ifndef __ASSEMBLY__
extern void _start (void);
#endif
/* The function's entry point is stored in the first word of the
function descriptor (plabel) of _start(). */
-#define ENTRY_POINT (((long int *) _start)[0])
+#define ENTRY_POINT ELF_PTR_TO_FDESC (_start)->ip
/* We have to provide a special declaration. */
#define ENTRY_POINT_DECL(class) class void _start (void);
diff --git a/libc/ports/sysdeps/ia64/fpu/libm_error.c b/libc/ports/sysdeps/ia64/fpu/libm_error.c
index 8ef4bb5a7..a9307dd4b 100644
--- a/libc/ports/sysdeps/ia64/fpu/libm_error.c
+++ b/libc/ports/sysdeps/ia64/fpu/libm_error.c
@@ -162,80 +162,79 @@ struct exceptionl excl;
# endif
-#define STATIC static
+#define _DECL_NUM(type, prefix, var, bytes...) \
+ ALIGNIT static const union { \
+ const char _bytes[sizeof (type)]; \
+ const type num; \
+ } prefix ## var = { \
+ ._bytes = bytes, \
+ }
+
+#define DECL_FLOAT(var, bytes...) \
+ _DECL_NUM (float, float_, var, ##bytes)
+
+DECL_FLOAT(inf, {0x00,0x00,0x80,0x7F});
+DECL_FLOAT(huge, {0xFF,0xFF,0x7F,0x7F});
+DECL_FLOAT(zero, {0x00,0x00,0x00,0x00});
+DECL_FLOAT(neg_inf, {0x00,0x00,0x80,0xFF});
+DECL_FLOAT(neg_huge, {0xFF,0xFF,0x7F,0xFF});
+DECL_FLOAT(neg_zero, {0x00,0x00,0x00,0x80});
-ALIGNIT
-STATIC const char float_inf[4] = {0x00,0x00,0x80,0x7F};
-ALIGNIT
-STATIC const char float_huge[4] = {0xFF,0xFF,0x7F,0x7F};
-ALIGNIT
-STATIC const char float_zero[4] = {0x00,0x00,0x00,0x00};
-ALIGNIT
-STATIC const char float_neg_inf[4] = {0x00,0x00,0x80,0xFF};
-ALIGNIT
-STATIC const char float_neg_huge[4] = {0xFF,0xFF,0x7F,0xFF};
-ALIGNIT
-STATIC const char float_neg_zero[4] = {0x00,0x00,0x00,0x80};
-ALIGNIT
-STATIC const char double_inf[8] = {0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0x7F};
+#define DECL_DOUBLE(var, bytes...) \
+ _DECL_NUM (double, double_, var, ##bytes)
+
+DECL_DOUBLE(inf, {0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0x7F});
#ifndef _LIBC
-ALIGNIT
-STATIC const char double_huge[8] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xEF,0x7F};
+DECL_DOUBLE(huge, {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xEF,0x7F});
#endif
-ALIGNIT
-STATIC const char double_zero[8] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
-ALIGNIT
-STATIC const char double_neg_inf[8] = {0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0xFF};
+DECL_DOUBLE(zero, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00});
+DECL_DOUBLE(neg_inf, {0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0xFF});
#ifndef _LIBC
-ALIGNIT
-STATIC const char double_neg_huge[8] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xEF,0xFF};
+DECL_DOUBLE(neg_huge, {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xEF,0xFF});
#endif
-ALIGNIT
-STATIC const char double_neg_zero[8] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80};
-ALIGNIT
-STATIC const char long_double_inf[16] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xFF,0x7F,0x00,0x00,0x00,0x00,0x00,0x00};
-ALIGNIT
+DECL_DOUBLE(neg_zero, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80});
+
+#define DECL_LONG_DOUBLE(var, bytes...) \
+ _DECL_NUM (long double, long_double_, var, ##bytes)
+
+DECL_LONG_DOUBLE(inf, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xFF,0x7F,0x00,0x00,0x00,0x00,0x00,0x00});
#ifndef _LIBC
-STATIC const char long_double_huge[16] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0x7F,0x00,0x00,0x00,0x00,0x00,0x00};
+DECL_LONG_DOUBLE(huge, {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0x7F,0x00,0x00,0x00,0x00,0x00,0x00});
#endif
-ALIGNIT
-STATIC const char long_double_zero[16] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
-ALIGNIT
-STATIC const char long_double_neg_inf[16] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00};
-ALIGNIT
+DECL_LONG_DOUBLE(zero, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00});
+DECL_LONG_DOUBLE(neg_inf, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00});
#ifndef _LIBC
-STATIC const char long_double_neg_huge[16] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0x00,0x00,0x00,0x00,0x00,0x00};
+DECL_LONG_DOUBLE(neg_huge, {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0x00,0x00,0x00,0x00,0x00,0x00});
#endif
-ALIGNIT
-STATIC const char long_double_neg_zero[16] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00};
+DECL_LONG_DOUBLE(neg_zero, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00});
-#define RETVAL_HUGE_VALL *(long double *)retval = *(long double *)long_double_inf
-#define RETVAL_NEG_HUGE_VALL *(long double *)retval = *(long double *)long_double_neg_inf
-#define RETVAL_HUGEL *(long double *)retval = (long double)*(float *)float_huge
-#define RETVAL_NEG_HUGEL *(long double *)retval =(long double)*(float*)float_neg_huge
+#define RETVAL_HUGE_VALL *(long double *)retval = long_double_inf.num
+#define RETVAL_NEG_HUGE_VALL *(long double *)retval = long_double_neg_inf.num
+#define RETVAL_HUGEL *(long double *)retval = (long double)float_huge.num
+#define RETVAL_NEG_HUGEL *(long double *)retval = (long double)float_neg_huge.num
-#define RETVAL_HUGE_VALD *(double *)retval = *(double *) double_inf
-#define RETVAL_NEG_HUGE_VALD *(double *)retval = *(double *) double_neg_inf
-#define RETVAL_HUGED *(double *)retval = (double) *(float *)float_huge
-#define RETVAL_NEG_HUGED *(double *)retval = (double) *(float *) float_neg_huge
+#define RETVAL_HUGE_VALD *(double *)retval = double_inf.num
+#define RETVAL_NEG_HUGE_VALD *(double *)retval = double_neg_inf.num
+#define RETVAL_HUGED *(double *)retval = (double)float_huge.num
+#define RETVAL_NEG_HUGED *(double *)retval = (double)float_neg_huge.num
-#define RETVAL_HUGE_VALF *(float *)retval = *(float *) float_inf
-#define RETVAL_NEG_HUGE_VALF *(float *)retval = *(float *) float_neg_inf
-#define RETVAL_HUGEF *(float *)retval = *(float *) float_huge
-#define RETVAL_NEG_HUGEF *(float *)retval = *(float *) float_neg_huge
+#define RETVAL_HUGE_VALF *(float *)retval = float_inf.num
+#define RETVAL_NEG_HUGE_VALF *(float *)retval = float_neg_inf.num
+#define RETVAL_HUGEF *(float *)retval = float_huge.num
+#define RETVAL_NEG_HUGEF *(float *)retval = float_neg_huge.num
-#define ZEROL_VALUE *(long double *)long_double_zero
-#define ZEROD_VALUE *(double *)double_zero
-#define ZEROF_VALUE *(float *)float_zero
+#define ZEROL_VALUE long_double_zero.num
+#define ZEROD_VALUE double_zero.num
+#define ZEROF_VALUE float_zero.num
-#define RETVAL_ZEROL *(long double *)retval = *(long double *)long_double_zero
-#define RETVAL_ZEROD *(double *)retval = *(double *)double_zero
-#define RETVAL_ZEROF *(float *)retval = *(float *)float_zero
+#define RETVAL_ZEROL *(long double *)retval = long_double_zero.num
+#define RETVAL_ZEROD *(double *)retval = double_zero.num
+#define RETVAL_ZEROF *(float *)retval = float_zero.num
-#define RETVAL_NEG_ZEROL *(long double *)retval = *(long double *)long_double_neg_zero
-#define RETVAL_NEG_ZEROD *(double *)retval = *(double *)double_neg_zero
-#define RETVAL_NEG_ZEROF *(float *)retval = *(float *)float_neg_zero
+#define RETVAL_NEG_ZEROL *(long double *)retval = long_double_neg_zero.num
+#define RETVAL_NEG_ZEROD *(double *)retval = double_neg_zero.num
+#define RETVAL_NEG_ZEROF *(float *)retval = float_neg_zero.num
#define RETVAL_ONEL *(long double *)retval = (long double) 1.0
#define RETVAL_ONED *(double *)retval = 1.0
diff --git a/libc/ports/sysdeps/mips/bits/nan.h b/libc/ports/sysdeps/mips/bits/nan.h
index 7aa157b1d..80f7866a9 100644
--- a/libc/ports/sysdeps/mips/bits/nan.h
+++ b/libc/ports/sysdeps/mips/bits/nan.h
@@ -22,10 +22,10 @@
/* IEEE Not A Number. */
-/* Note that MIPS has the QNaN and SNaN patterns reversed compared to most
- other architectures. The IEEE spec left the definition of this open to
+/* Note that MIPS has the qNaN and sNaN patterns reversed compared to most
+ other architectures. IEEE 754-1985 left the definition of this open to
implementations, and for MIPS the top bit of the mantissa must be SET to
- indicate a SNaN. */
+ indicate a sNaN. */
#if __GNUC_PREREQ(3,3)
@@ -43,14 +43,14 @@
# include <endian.h>
# if __BYTE_ORDER == __BIG_ENDIAN
-# define __nan_bytes { 0x7f, 0xbf, 0xff, 0xff }
+# define __qnan_bytes { 0x7f, 0xbf, 0xff, 0xff }
# endif
# if __BYTE_ORDER == __LITTLE_ENDIAN
-# define __nan_bytes { 0xff, 0xff, 0xbf, 0x7f }
+# define __qnan_bytes { 0xff, 0xff, 0xbf, 0x7f }
# endif
-static union { unsigned char __c[4]; float __d; } __nan_union
- __attribute__ ((__unused__)) = { __nan_bytes };
-# define NAN (__nan_union.__d)
+static union { unsigned char __c[4]; float __d; } __qnan_union
+ __attribute__ ((__unused__)) = { __qnan_bytes };
+# define NAN (__qnan_union.__d)
#endif /* GCC. */
diff --git a/libc/ports/sysdeps/unix/arm/sysdep.S b/libc/ports/sysdeps/unix/arm/sysdep.S
index 40e4d80ec..d82ad258a 100644
--- a/libc/ports/sysdeps/unix/arm/sysdep.S
+++ b/libc/ports/sysdeps/unix/arm/sysdep.S
@@ -37,28 +37,24 @@ __syscall_error:
#endif
#ifndef IS_IN_rtld
- mov ip, lr
- cfi_register (lr, ip)
- mov r1, r0
-
- mov r0, #0xffff0fff
- mov lr, pc
- sub pc, r0, #31
-
- ldr r2, 1f
-2: ldr r2, [pc, r2]
- str r1, [r0, r2]
- mvn r0, #0
- RETINSTR (, ip)
+ mov r1, r0
+ GET_TLS (r2)
+ ldr r2, 1f
+#ifdef __thumb__
+2: add r2, r2, pc
+ ldr r2, [r2]
+#else
+2: ldr r2, [pc, r2]
+#endif
+ str r1, [r0, r2]
+ mvn r0, #0
+ DO_RET(lr)
1: .word errno(gottpoff) + (. - 2b - PC_OFS)
#elif RTLD_PRIVATE_ERRNO
- ldr r1, 1f
-0: str r0, [pc, r1]
- mvn r0, $0
+ LDST_PCREL(str, r0, r1, C_SYMBOL_NAME(rtld_errno))
+ mvn r0, #0
DO_RET(r14)
-
-1: .word C_SYMBOL_NAME(rtld_errno) - 0b - PC_OFS
#else
#error "Unsupported non-TLS case"
#endif
diff --git a/libc/ports/sysdeps/unix/sysv/linux/aarch64/bits/mman.h b/libc/ports/sysdeps/unix/sysv/linux/aarch64/bits/mman.h
index 67c563ce2..770607b83 100644
--- a/libc/ports/sysdeps/unix/sysv/linux/aarch64/bits/mman.h
+++ b/libc/ports/sysdeps/unix/sysv/linux/aarch64/bits/mman.h
@@ -25,38 +25,8 @@
/* The following definitions basically come from the kernel headers.
But the kernel header is not namespace clean. */
-
-/* Protections are chosen from these bits, OR'd together. The
- implementation does not necessarily support PROT_EXEC or PROT_WRITE
- without PROT_READ. The only guarantees are that no writing will be
- allowed without PROT_WRITE and no access will be allowed for PROT_NONE. */
-
-#define PROT_READ 0x1 /* Page can be read. */
-#define PROT_WRITE 0x2 /* Page can be written. */
-#define PROT_EXEC 0x4 /* Page can be executed. */
-#define PROT_NONE 0x0 /* Page can not be accessed. */
-#define PROT_GROWSDOWN 0x01000000 /* Extend change to start of
- growsdown vma (mprotect only). */
-#define PROT_GROWSUP 0x02000000 /* Extend change to start of
- growsup vma (mprotect only). */
-
-/* Sharing types (must choose one and only one of these). */
-#define MAP_SHARED 0x01 /* Share changes. */
-#define MAP_PRIVATE 0x02 /* Changes are private. */
-#ifdef __USE_MISC
-# define MAP_TYPE 0x0f /* Mask for type of mapping. */
-#endif
-
-/* Other flags. */
-#define MAP_FIXED 0x10 /* Interpret addr exactly. */
-#ifdef __USE_MISC
-# define MAP_FILE 0
-# define MAP_ANONYMOUS 0x20 /* Don't use a file. */
-# define MAP_ANON MAP_ANONYMOUS
-#endif
-
-#ifdef __USE_MISC
/* These are Linux-specific. */
+#ifdef __USE_MISC
# define MAP_GROWSDOWN 0x00100 /* Stack-like segment. */
# define MAP_DENYWRITE 0x00800 /* ETXTBSY */
# define MAP_EXECUTABLE 0x01000 /* Mark it as an executable. */
@@ -68,47 +38,7 @@
# define MAP_HUGETLB 0x40000 /* Create huge page mapping. */
#endif
-/* Flags to `msync'. */
-#define MS_ASYNC 1 /* Sync memory asynchronously. */
-#define MS_SYNC 4 /* Synchronous memory sync. */
-#define MS_INVALIDATE 2 /* Invalidate the caches. */
-
-/* Flags for `mlockall'. */
-#define MCL_CURRENT 1 /* Lock all currently mapped pages. */
-#define MCL_FUTURE 2 /* Lock all additions to address
- space. */
-/* Flags for `mremap'. */
-#ifdef __USE_GNU
-# define MREMAP_MAYMOVE 1
-# define MREMAP_FIXED 2
-#endif
-
-/* Advice to `madvise'. */
-#ifdef __USE_BSD
-# define MADV_NORMAL 0 /* No further special treatment. */
-# define MADV_RANDOM 1 /* Expect random page references. */
-# define MADV_SEQUENTIAL 2 /* Expect sequential page references. */
-# define MADV_WILLNEED 3 /* Will need these pages. */
-# define MADV_DONTNEED 4 /* Don't need these pages. */
-# define MADV_REMOVE 9 /* Remove these pages and resources. */
-# define MADV_DONTFORK 10 /* Do not inherit across fork. */
-# define MADV_DOFORK 11 /* Do inherit across fork. */
-# define MADV_MERGEABLE 12 /* KSM may merge identical pages. */
-# define MADV_UNMERGEABLE 13 /* KSM may not merge identical pages. */
-# define MADV_HUGEPAGE 14 /* Worth backing with hugepages. */
-# define MADV_NOHUGEPAGE 15 /* Not worth backing with hugepages. */
-# define MADV_DONTDUMP 16 /* Explicity exclude from the core dump,
- overrides the coredump filter bits. */
-# define MADV_DODUMP 17 /* Clear the MADV_DONTDUMP flag. */
-# define MADV_HWPOISON 100 /* Poison a page for testing. */
-#endif
-/* The POSIX people had to invent similar names for the same things. */
-#ifdef __USE_XOPEN2K
-# define POSIX_MADV_NORMAL 0 /* No further special treatment. */
-# define POSIX_MADV_RANDOM 1 /* Expect random page references. */
-# define POSIX_MADV_SEQUENTIAL 2 /* Expect sequential page references. */
-# define POSIX_MADV_WILLNEED 3 /* Will need these pages. */
-# define POSIX_MADV_DONTNEED 4 /* Don't need these pages. */
-#endif
+/* Include generic Linux declarations. */
+#include <bits/mman-linux.h>
diff --git a/libc/ports/sysdeps/unix/sysv/linux/aarch64/configure b/libc/ports/sysdeps/unix/sysv/linux/aarch64/configure
index 5a22126fe..04b6c81b6 100644
--- a/libc/ports/sysdeps/unix/sysv/linux/aarch64/configure
+++ b/libc/ports/sysdeps/unix/sysv/linux/aarch64/configure
@@ -1,3 +1,16 @@
# This file is generated from configure.in by Autoconf. DO NOT EDIT!
+ # Local configure fragment for sysdeps/unix/sysv/linux/aarch64.
arch_minimum_kernel=3.7.0
+
+test -n "$libc_cv_slibdir" ||
+case "$prefix" in
+ /usr | /usr/)
+ libc_cv_slibdir="/lib64"
+ if test "$libdir" = '${exec_prefix}/lib'; then
+ libdir='${exec_prefix}/lib64';
+ # Locale data can be shared between 32bit and 64bit libraries
+ libc_cv_localedir='${exec_prefix}/lib/locale'
+ fi
+ ;;
+esac
diff --git a/libc/ports/sysdeps/unix/sysv/linux/aarch64/configure.in b/libc/ports/sysdeps/unix/sysv/linux/aarch64/configure.in
index d1995d486..6596a1511 100644
--- a/libc/ports/sysdeps/unix/sysv/linux/aarch64/configure.in
+++ b/libc/ports/sysdeps/unix/sysv/linux/aarch64/configure.in
@@ -2,3 +2,15 @@ GLIBC_PROVIDES dnl See aclocal.m4 in the top level source directory.
# Local configure fragment for sysdeps/unix/sysv/linux/aarch64.
arch_minimum_kernel=3.7.0
+
+test -n "$libc_cv_slibdir" ||
+case "$prefix" in
+ /usr | /usr/)
+ libc_cv_slibdir="/lib64"
+ if test "$libdir" = '${exec_prefix}/lib'; then
+ libdir='${exec_prefix}/lib64';
+ # Locale data can be shared between 32bit and 64bit libraries
+ libc_cv_localedir='${exec_prefix}/lib/locale'
+ fi
+ ;;
+esac
diff --git a/libc/ports/sysdeps/unix/sysv/linux/aarch64/nptl/libpthread.abilist b/libc/ports/sysdeps/unix/sysv/linux/aarch64/nptl/libpthread.abilist
index 031c70e8a..696158aef 100644
--- a/libc/ports/sysdeps/unix/sysv/linux/aarch64/nptl/libpthread.abilist
+++ b/libc/ports/sysdeps/unix/sysv/linux/aarch64/nptl/libpthread.abilist
@@ -73,7 +73,6 @@ GLIBC_2.17
pause F
pread F
pread64 F
- pthread_atfork F
pthread_attr_destroy F
pthread_attr_getaffinity_np F
pthread_attr_getdetachstate F
diff --git a/libc/ports/sysdeps/unix/sysv/linux/alpha/bits/mman.h b/libc/ports/sysdeps/unix/sysv/linux/alpha/bits/mman.h
index 2238c2c72..c51b05d37 100644
--- a/libc/ports/sysdeps/unix/sysv/linux/alpha/bits/mman.h
+++ b/libc/ports/sysdeps/unix/sysv/linux/alpha/bits/mman.h
@@ -51,6 +51,9 @@
# define MAP_FILE 0
# define MAP_ANONYMOUS 0x10 /* Don't use a file. */
# define MAP_ANON MAP_ANONYMOUS
+/* When MAP_HUGETLB is set bits [26:31] encode the log2 of the huge page size. */
+# define MAP_HUGE_SHIFT 26
+# define MAP_HUGE_MASK 0x3f
#endif
/* Not used by Linux, but here to make sure we don't clash with
diff --git a/libc/ports/sysdeps/unix/sysv/linux/alpha/bits/msq.h b/libc/ports/sysdeps/unix/sysv/linux/alpha/bits/msq.h
index 1b07465d4..8bb057b4e 100644
--- a/libc/ports/sysdeps/unix/sysv/linux/alpha/bits/msq.h
+++ b/libc/ports/sysdeps/unix/sysv/linux/alpha/bits/msq.h
@@ -25,6 +25,7 @@
#define MSG_NOERROR 010000 /* no error if message is too big */
#ifdef __USE_GNU
# define MSG_EXCEPT 020000 /* recv any msg except of specified type */
+# define MSG_COPY 040000 /* copy (not remove) all queue messages */
#endif
/* Types used in the structure definition. */
diff --git a/libc/ports/sysdeps/unix/sysv/linux/am33/bits/mman.h b/libc/ports/sysdeps/unix/sysv/linux/am33/bits/mman.h
index 5dd8ae13f..a6e85f99d 100644
--- a/libc/ports/sysdeps/unix/sysv/linux/am33/bits/mman.h
+++ b/libc/ports/sysdeps/unix/sysv/linux/am33/bits/mman.h
@@ -24,35 +24,6 @@
But the kernel header is not namespace clean. */
-/* Protections are chosen from these bits, OR'd together. The
- implementation does not necessarily support PROT_EXEC or PROT_WRITE
- without PROT_READ. The only guarantees are that no writing will be
- allowed without PROT_WRITE and no access will be allowed for PROT_NONE. */
-
-#define PROT_READ 0x1 /* Page can be read. */
-#define PROT_WRITE 0x2 /* Page can be written. */
-#define PROT_EXEC 0x4 /* Page can be executed. */
-#define PROT_NONE 0x0 /* Page can not be accessed. */
-#define PROT_GROWSDOWN 0x01000000 /* Extend change to start of
- growsdown vma (mprotect only). */
-#define PROT_GROWSUP 0x02000000 /* Extend change to start of
- growsup vma (mprotect only). */
-
-/* Sharing types (must choose one and only one of these). */
-#define MAP_SHARED 0x01 /* Share changes. */
-#define MAP_PRIVATE 0x02 /* Changes are private. */
-#ifdef __USE_MISC
-# define MAP_TYPE 0x0f /* Mask for type of mapping. */
-#endif
-
-/* Other flags. */
-#define MAP_FIXED 0x10 /* Interpret addr exactly. */
-#ifdef __USE_MISC
-# define MAP_FILE 0
-# define MAP_ANONYMOUS 0x20 /* Don't use a file. */
-# define MAP_ANON MAP_ANONYMOUS
-#endif
-
/* These are Linux-specific. */
#ifdef __USE_MISC
# define MAP_GROWSDOWN 0x0100 /* Stack-like segment. */
@@ -62,35 +33,5 @@
# define MAP_NORESERVE 0x4000 /* Don't check for reservations. */
#endif
-/* Flags to `msync'. */
-#define MS_ASYNC 1 /* Sync memory asynchronously. */
-#define MS_SYNC 4 /* Synchronous memory sync. */
-#define MS_INVALIDATE 2 /* Invalidate the caches. */
-
-/* Flags for `mlockall'. */
-#define MCL_CURRENT 1 /* Lock all currently mapped pages. */
-#define MCL_FUTURE 2 /* Lock all additions to address
- space. */
-
-/* Flags for `mremap'. */
-#ifdef __USE_GNU
-# define MREMAP_MAYMOVE 1
-#endif
-
-/* Advice to `madvise'. */
-#ifdef __USE_BSD
-# define MADV_NORMAL 0 /* No further special treatment. */
-# define MADV_RANDOM 1 /* Expect random page references. */
-# define MADV_SEQUENTIAL 2 /* Expect sequential page references. */
-# define MADV_WILLNEED 3 /* Will need these pages. */
-# define MADV_DONTNEED 4 /* Don't need these pages. */
-#endif
-
-/* The POSIX people had to invent similar names for the same things. */
-#ifdef __USE_XOPEN2K
-# define POSIX_MADV_NORMAL 0 /* No further special treatment. */
-# define POSIX_MADV_RANDOM 1 /* Expect random page references. */
-# define POSIX_MADV_SEQUENTIAL 2 /* Expect sequential page references. */
-# define POSIX_MADV_WILLNEED 3 /* Will need these pages. */
-# define POSIX_MADV_DONTNEED 4 /* Don't need these pages. */
-#endif
+/* Include generic Linux declarations. */
+#include <bits/mman-linux.h>
diff --git a/libc/ports/sysdeps/unix/sysv/linux/arm/____longjmp_chk.S b/libc/ports/sysdeps/unix/sysv/linux/arm/____longjmp_chk.S
index 29edec69d..6ee7a1aeb 100644
--- a/libc/ports/sysdeps/unix/sysv/linux/arm/____longjmp_chk.S
+++ b/libc/ports/sysdeps/unix/sysv/linux/arm/____longjmp_chk.S
@@ -53,7 +53,7 @@ longjmp_msg:
cfi_remember_state; \
cmp sp, reg; \
bls .Lok; \
- str r7, [sp, #-4]!; \
+ push { r7 }; \
cfi_adjust_cfa_offset (4); \
cfi_rel_offset (r7, 0); \
mov r5, r0; \
@@ -79,7 +79,7 @@ longjmp_msg:
.Lfail: \
add sp, sp, #12; \
cfi_adjust_cfa_offset (-12); \
- ldr r7, [sp], #4; \
+ pop { r7 }; \
cfi_adjust_cfa_offset (-4); \
cfi_restore (r7); \
CALL_FAIL \
diff --git a/libc/ports/sysdeps/unix/sysv/linux/arm/aeabi_read_tp.S b/libc/ports/sysdeps/unix/sysv/linux/arm/aeabi_read_tp.S
index c4ddbc69f..21e322986 100644
--- a/libc/ports/sysdeps/unix/sysv/linux/arm/aeabi_read_tp.S
+++ b/libc/ports/sysdeps/unix/sysv/linux/arm/aeabi_read_tp.S
@@ -41,6 +41,15 @@
.hidden __aeabi_read_tp
ENTRY (__aeabi_read_tp)
+#ifdef ARCH_HAS_HARD_TP
+ mrc p15, 0, r0, c13, c0, 3
+ bx lr
+#elif defined(__thumb2__)
+ movw r0, #0x0fe0
+ movt r0, #0xffff
+ bx r0
+#else
mov r0, #0xffff0fff
sub pc, r0, #31
+#endif
END (__aeabi_read_tp)
diff --git a/libc/ports/sysdeps/unix/sysv/linux/arm/bits/mman.h b/libc/ports/sysdeps/unix/sysv/linux/arm/bits/mman.h
index f5ca3c9b6..11ecbca03 100644
--- a/libc/ports/sysdeps/unix/sysv/linux/arm/bits/mman.h
+++ b/libc/ports/sysdeps/unix/sysv/linux/arm/bits/mman.h
@@ -23,36 +23,6 @@
/* The following definitions basically come from the kernel headers.
But the kernel header is not namespace clean. */
-
-/* Protections are chosen from these bits, OR'd together. The
- implementation does not necessarily support PROT_EXEC or PROT_WRITE
- without PROT_READ. The only guarantees are that no writing will be
- allowed without PROT_WRITE and no access will be allowed for PROT_NONE. */
-
-#define PROT_READ 0x1 /* Page can be read. */
-#define PROT_WRITE 0x2 /* Page can be written. */
-#define PROT_EXEC 0x4 /* Page can be executed. */
-#define PROT_NONE 0x0 /* Page can not be accessed. */
-#define PROT_GROWSDOWN 0x01000000 /* Extend change to start of
- growsdown vma (mprotect only). */
-#define PROT_GROWSUP 0x02000000 /* Extend change to start of
- growsup vma (mprotect only). */
-
-/* Sharing types (must choose one and only one of these). */
-#define MAP_SHARED 0x01 /* Share changes. */
-#define MAP_PRIVATE 0x02 /* Changes are private. */
-#ifdef __USE_MISC
-# define MAP_TYPE 0x0f /* Mask for type of mapping. */
-#endif
-
-/* Other flags. */
-#define MAP_FIXED 0x10 /* Interpret addr exactly. */
-#ifdef __USE_MISC
-# define MAP_FILE 0
-# define MAP_ANONYMOUS 0x20 /* Don't use a file. */
-# define MAP_ANON MAP_ANONYMOUS
-#endif
-
/* These are Linux-specific. */
#ifdef __USE_MISC
# define MAP_GROWSDOWN 0x00100 /* Stack-like segment. */
@@ -66,47 +36,5 @@
# define MAP_HUGETLB 0x40000 /* Create huge page mapping. */
#endif
-/* Flags to `msync'. */
-#define MS_ASYNC 1 /* Sync memory asynchronously. */
-#define MS_SYNC 4 /* Synchronous memory sync. */
-#define MS_INVALIDATE 2 /* Invalidate the caches. */
-
-/* Flags for `mlockall'. */
-#define MCL_CURRENT 1 /* Lock all currently mapped pages. */
-#define MCL_FUTURE 2 /* Lock all additions to address
- space. */
-
-/* Flags for `mremap'. */
-#ifdef __USE_GNU
-# define MREMAP_MAYMOVE 1
-# define MREMAP_FIXED 2
-#endif
-
-/* Advice to `madvise'. */
-#ifdef __USE_BSD
-# define MADV_NORMAL 0 /* No further special treatment. */
-# define MADV_RANDOM 1 /* Expect random page references. */
-# define MADV_SEQUENTIAL 2 /* Expect sequential page references. */
-# define MADV_WILLNEED 3 /* Will need these pages. */
-# define MADV_DONTNEED 4 /* Don't need these pages. */
-# define MADV_REMOVE 9 /* Remove these pages and resources. */
-# define MADV_DONTFORK 10 /* Do not inherit across fork. */
-# define MADV_DOFORK 11 /* Do inherit across fork. */
-# define MADV_MERGEABLE 12 /* KSM may merge identical pages. */
-# define MADV_UNMERGEABLE 13 /* KSM may not merge identical pages. */
-# define MADV_HUGEPAGE 14 /* Worth backing with hugepages. */
-# define MADV_NOHUGEPAGE 15 /* Not worth backing with hugepages. */
-# define MADV_DONTDUMP 16 /* Explicity exclude from the core dump,
- overrides the coredump filter bits. */
-# define MADV_DODUMP 17 /* Clear the MADV_DONTDUMP flag. */
-# define MADV_HWPOISON 100 /* Poison a page for testing. */
-#endif
-
-/* The POSIX people had to invent similar names for the same things. */
-#ifdef __USE_XOPEN2K
-# define POSIX_MADV_NORMAL 0 /* No further special treatment. */
-# define POSIX_MADV_RANDOM 1 /* Expect random page references. */
-# define POSIX_MADV_SEQUENTIAL 2 /* Expect sequential page references. */
-# define POSIX_MADV_WILLNEED 3 /* Will need these pages. */
-# define POSIX_MADV_DONTNEED 4 /* Don't need these pages. */
-#endif
+/* Include generic Linux declarations. */
+#include <bits/mman-linux.h>
diff --git a/libc/ports/sysdeps/unix/sysv/linux/arm/clone.S b/libc/ports/sysdeps/unix/sysv/linux/arm/clone.S
index 732a3ffd0..ce9c2a5ba 100644
--- a/libc/ports/sysdeps/unix/sysv/linux/arm/clone.S
+++ b/libc/ports/sysdeps/unix/sysv/linux/arm/clone.S
@@ -49,7 +49,7 @@ ENTRY(__clone)
mov ip, r2
#endif
@ new sp is already in r1
- stmfd sp!, {r4, r7}
+ push {r4, r7}
cfi_adjust_cfa_offset (8)
cfi_rel_offset (r4, 0)
cfi_rel_offset (r7, 4)
@@ -61,7 +61,7 @@ ENTRY(__clone)
cfi_endproc
cmp r0, #0
beq 1f
- ldmfd sp!, {r4, r7}
+ pop {r4, r7}
blt PLTJMP(C_SYMBOL_NAME(__syscall_error))
RETINSTR(, lr)
@@ -74,17 +74,16 @@ PSEUDO_END (__clone)
#ifdef RESET_PID
tst ip, #CLONE_THREAD
bne 3f
- mov r0, #0xffff0fff
- mov lr, pc
- sub pc, r0, #31
+ GET_TLS (lr)
mov r1, r0
tst ip, #CLONE_VM
ldr r7, =SYS_ify(getpid)
ite ne
movne r0, #-1
swieq 0x0
- str r0, [r1, #PID_OFFSET]
- str r0, [r1, #TID_OFFSET]
+ NEGOFF_ADJ_BASE (r1, TID_OFFSET)
+ str r0, NEGOFF_OFF1 (r1, TID_OFFSET)
+ str r0, NEGOFF_OFF2 (r1, PID_OFFSET, TID_OFFSET)
3:
#endif
@ pick the function arg and call address off the stack and execute
diff --git a/libc/ports/sysdeps/unix/sysv/linux/arm/configure b/libc/ports/sysdeps/unix/sysv/linux/arm/configure
index cb94cc5eb..f66b15828 100644
--- a/libc/ports/sysdeps/unix/sysv/linux/arm/configure
+++ b/libc/ports/sysdeps/unix/sysv/linux/arm/configure
@@ -2,4 +2,5 @@
# Local configure fragment for sysdeps/unix/sysv/linux/arm.
libc_cv_gcc_unwind_find_fde=no
+# Remove -fno-unwind-tables that was added in sysdeps/arm/preconfigure.in.
CFLAGS=${CFLAGS% -fno-unwind-tables}
diff --git a/libc/ports/sysdeps/unix/sysv/linux/arm/configure.in b/libc/ports/sysdeps/unix/sysv/linux/arm/configure.in
index 3e67dee42..8fffe9405 100644
--- a/libc/ports/sysdeps/unix/sysv/linux/arm/configure.in
+++ b/libc/ports/sysdeps/unix/sysv/linux/arm/configure.in
@@ -2,4 +2,5 @@ GLIBC_PROVIDES dnl See aclocal.m4 in the top level source directory.
# Local configure fragment for sysdeps/unix/sysv/linux/arm.
libc_cv_gcc_unwind_find_fde=no
+# Remove -fno-unwind-tables that was added in sysdeps/arm/preconfigure.in.
CFLAGS=${CFLAGS% -fno-unwind-tables}
diff --git a/libc/ports/sysdeps/unix/sysv/linux/arm/mmap.S b/libc/ports/sysdeps/unix/sysv/linux/arm/mmap.S
index 68560b065..06b737eeb 100644
--- a/libc/ports/sysdeps/unix/sysv/linux/arm/mmap.S
+++ b/libc/ports/sysdeps/unix/sysv/linux/arm/mmap.S
@@ -23,11 +23,11 @@
ENTRY (__mmap)
/* shuffle args */
- str r5, [sp, #-4]!
+ push { r5 }
cfi_adjust_cfa_offset (4)
cfi_rel_offset (r5, 0)
ldr r5, [sp, #8]
- str r4, [sp, #-4]!
+ push { r4 }
cfi_adjust_cfa_offset (4)
cfi_rel_offset (r4, 0)
cfi_remember_state
@@ -43,10 +43,10 @@ ENTRY (__mmap)
/* restore registers */
2:
- ldr r4, [sp], #4
+ pop { r4 }
cfi_adjust_cfa_offset (-4)
cfi_restore (r4)
- ldr r5, [sp], #4
+ pop { r5 }
cfi_adjust_cfa_offset (-4)
cfi_restore (r5)
diff --git a/libc/ports/sysdeps/unix/sysv/linux/arm/mmap64.S b/libc/ports/sysdeps/unix/sysv/linux/arm/mmap64.S
index dcbab3aed..d039129b2 100644
--- a/libc/ports/sysdeps/unix/sysv/linux/arm/mmap64.S
+++ b/libc/ports/sysdeps/unix/sysv/linux/arm/mmap64.S
@@ -34,11 +34,11 @@
.text
ENTRY (__mmap64)
ldr ip, [sp, $LOW_OFFSET]
- str r5, [sp, #-4]!
+ push { r5 }
cfi_adjust_cfa_offset (4)
cfi_rel_offset (r5, 0)
ldr r5, [sp, $HIGH_OFFSET]
- str r4, [sp, #-4]!
+ push { r4 }
cfi_adjust_cfa_offset (4)
cfi_rel_offset (r4, 0)
cfi_remember_state
@@ -51,7 +51,7 @@ ENTRY (__mmap64)
orr r5, ip, r5, lsl $20 @ compose page offset
DO_CALL (mmap2, 0)
cmn r0, $4096
- ldmfd sp!, {r4, r5}
+ pop {r4, r5}
cfi_adjust_cfa_offset (-8)
cfi_restore (r4)
cfi_restore (r5)
@@ -62,7 +62,7 @@ ENTRY (__mmap64)
cfi_restore_state
.Linval:
mov r0, $-EINVAL
- ldmfd sp!, {r4, r5}
+ pop {r4, r5}
cfi_adjust_cfa_offset (-8)
cfi_restore (r4)
cfi_restore (r5)
diff --git a/libc/ports/sysdeps/unix/sysv/linux/arm/nptl/libpthread.abilist b/libc/ports/sysdeps/unix/sysv/linux/arm/nptl/libpthread.abilist
index 6c0bbde67..de8095a60 100644
--- a/libc/ports/sysdeps/unix/sysv/linux/arm/nptl/libpthread.abilist
+++ b/libc/ports/sysdeps/unix/sysv/linux/arm/nptl/libpthread.abilist
@@ -83,7 +83,6 @@ GLIBC_2.4
pause F
pread F
pread64 F
- pthread_atfork F
pthread_attr_destroy F
pthread_attr_getaffinity_np F
pthread_attr_getdetachstate F
diff --git a/libc/ports/sysdeps/unix/sysv/linux/arm/nptl/pt-vfork.S b/libc/ports/sysdeps/unix/sysv/linux/arm/nptl/pt-vfork.S
index a38d56419..ca5045707 100644
--- a/libc/ports/sysdeps/unix/sysv/linux/arm/nptl/pt-vfork.S
+++ b/libc/ports/sysdeps/unix/sysv/linux/arm/nptl/pt-vfork.S
@@ -19,23 +19,16 @@
/* Save the PID value. */
#define SAVE_PID \
- str lr, [sp, #-4]!; /* Save LR. */ \
- cfi_adjust_cfa_offset (4); \
- cfi_rel_offset (lr, 0); \
- mov r0, #0xffff0fff; /* Point to the high page. */ \
- mov lr, pc; /* Save our return address. */ \
- sub pc, r0, #31; /* Jump to the TLS entry. */ \
- ldr lr, [sp], #4; /* Restore LR. */ \
- cfi_adjust_cfa_offset (-4); \
- cfi_restore (lr); \
- mov r2, r0; /* Save the TLS addr in r2. */ \
- ldr r3, [r2, #PID_OFFSET]; /* Load the saved PID. */ \
- rsb r0, r3, #0; /* Negate it. */ \
- str r0, [r2, #PID_OFFSET] /* Store the temporary PID. */
+ GET_TLS (r2); \
+ NEGOFF_ADJ_BASE2 (r2, r0, PID_OFFSET); /* Save the TLS addr in r2. */ \
+ ldr r3, NEGOFF_OFF1 (r2, PID_OFFSET); /* Load the saved PID. */ \
+ rsb r0, r3, #0; /* Negate it. */ \
+ str r0, NEGOFF_OFF1 (r2, PID_OFFSET); /* Store the temp PID. */
/* Restore the old PID value in the parent. */
#define RESTORE_PID \
cmp r0, #0; /* If we are the parent... */ \
- strne r3, [r2, #PID_OFFSET] /* ... restore the saved PID. */
+ it ne; \
+ strne r3, NEGOFF_OFF1 (r2, PID_OFFSET); /* restore the saved PID. */
#include "../vfork.S"
diff --git a/libc/ports/sysdeps/unix/sysv/linux/arm/nptl/sysdep-cancel.h b/libc/ports/sysdeps/unix/sysv/linux/arm/nptl/sysdep-cancel.h
index df85d5199..59b826ded 100644
--- a/libc/ports/sysdeps/unix/sysv/linux/arm/nptl/sysdep-cancel.h
+++ b/libc/ports/sysdeps/unix/sysv/linux/arm/nptl/sysdep-cancel.h
@@ -31,7 +31,6 @@
# undef PSEUDO
# define PSEUDO(name, syscall_name, args) \
.text; \
- PSEUDO_PROLOGUE; \
ENTRY (__##syscall_name##_nocancel); \
CFI_SECTIONS; \
DO_CALL (syscall_name, args); \
@@ -77,19 +76,19 @@
# define DOCARGS_0 \
.save {r7}; \
- str lr, [sp, #-4]!; \
+ push {lr}; \
cfi_adjust_cfa_offset (4); \
cfi_rel_offset (lr, 0); \
.save {lr}
# define UNDOCARGS_0
# define RESTORE_LR_0 \
- ldr lr, [sp], #4; \
+ pop {lr}; \
cfi_adjust_cfa_offset (-4); \
cfi_restore (lr)
# define DOCARGS_1 \
.save {r7}; \
- stmfd sp!, {r0, r1, lr}; \
+ push {r0, r1, lr}; \
cfi_adjust_cfa_offset (12); \
cfi_rel_offset (lr, 8); \
.save {lr}; \
@@ -103,13 +102,13 @@
# define DOCARGS_2 \
.save {r7}; \
- stmfd sp!, {r0, r1, lr}; \
+ push {r0, r1, lr}; \
cfi_adjust_cfa_offset (12); \
cfi_rel_offset (lr, 8); \
.save {lr}; \
.pad #8
# define UNDOCARGS_2 \
- ldmfd sp!, {r0, r1}; \
+ pop {r0, r1}; \
cfi_adjust_cfa_offset (-8); \
RESTART_UNWIND
# define RESTORE_LR_2 \
@@ -117,13 +116,13 @@
# define DOCARGS_3 \
.save {r7}; \
- stmfd sp!, {r0, r1, r2, r3, lr}; \
+ push {r0, r1, r2, r3, lr}; \
cfi_adjust_cfa_offset (20); \
cfi_rel_offset (lr, 16); \
.save {lr}; \
.pad #16
# define UNDOCARGS_3 \
- ldmfd sp!, {r0, r1, r2, r3}; \
+ pop {r0, r1, r2, r3}; \
cfi_adjust_cfa_offset (-16); \
RESTART_UNWIND
# define RESTORE_LR_3 \
@@ -131,13 +130,13 @@
# define DOCARGS_4 \
.save {r7}; \
- stmfd sp!, {r0, r1, r2, r3, lr}; \
+ push {r0, r1, r2, r3, lr}; \
cfi_adjust_cfa_offset (20); \
cfi_rel_offset (lr, 16); \
.save {lr}; \
.pad #16
# define UNDOCARGS_4 \
- ldmfd sp!, {r0, r1, r2, r3}; \
+ pop {r0, r1, r2, r3}; \
cfi_adjust_cfa_offset (-16); \
RESTART_UNWIND
# define RESTORE_LR_4 \
@@ -146,13 +145,13 @@
/* r4 is only stmfd'ed for correct stack alignment. */
# define DOCARGS_5 \
.save {r4, r7}; \
- stmfd sp!, {r0, r1, r2, r3, r4, lr}; \
+ push {r0, r1, r2, r3, r4, lr}; \
cfi_adjust_cfa_offset (24); \
cfi_rel_offset (lr, 20); \
.save {lr}; \
.pad #20
# define UNDOCARGS_5 \
- ldmfd sp!, {r0, r1, r2, r3}; \
+ pop {r0, r1, r2, r3}; \
cfi_adjust_cfa_offset (-16); \
.fnend; \
.fnstart; \
@@ -160,20 +159,20 @@
.save {lr}; \
.pad #4
# define RESTORE_LR_5 \
- ldmfd sp!, {r4, lr}; \
+ pop {r4, lr}; \
cfi_adjust_cfa_offset (-8); \
/* r4 will be marked as restored later. */ \
cfi_restore (lr)
# define DOCARGS_6 \
.save {r4, r5, r7}; \
- stmfd sp!, {r0, r1, r2, r3, lr}; \
+ push {r0, r1, r2, r3, lr}; \
cfi_adjust_cfa_offset (20); \
cfi_rel_offset (lr, 16); \
.save {lr}; \
.pad #16
# define UNDOCARGS_6 \
- ldmfd sp!, {r0, r1, r2, r3}; \
+ pop {r0, r1, r2, r3}; \
cfi_adjust_cfa_offset (-16); \
.fnend; \
.fnstart; \
@@ -203,12 +202,8 @@ extern int __local_multiple_threads attribute_hidden;
# define SINGLE_THREAD_P __builtin_expect (__local_multiple_threads == 0, 1)
# else
# define SINGLE_THREAD_P \
- ldr ip, 1b; \
- 2: \
- ldr ip, [pc, ip]; \
- teq ip, #0;
-# define PSEUDO_PROLOGUE \
- 1: .word __local_multiple_threads - 2f - PC_OFS;
+ LDST_PCREL(ldr, ip, ip, __local_multiple_threads); \
+ teq ip, #0
# endif
# else
/* There is no __local_multiple_threads for librt, so use the TCB. */
@@ -217,14 +212,14 @@ extern int __local_multiple_threads attribute_hidden;
__builtin_expect (THREAD_GETMEM (THREAD_SELF, \
header.multiple_threads) == 0, 1)
# else
-# define PSEUDO_PROLOGUE
# define SINGLE_THREAD_P \
- stmfd sp!, {r0, lr}; \
+ push {r0, lr}; \
cfi_adjust_cfa_offset (8); \
cfi_rel_offset (lr, 4); \
- bl __aeabi_read_tp; \
- ldr ip, [r0, #MULTIPLE_THREADS_OFFSET]; \
- ldmfd sp!, {r0, lr}; \
+ GET_TLS (lr); \
+ NEGOFF_ADJ_BASE (r0, MULTIPLE_THREADS_OFFSET); \
+ ldr ip, NEGOFF_OFF1 (r0, MULTIPLE_THREADS_OFFSET); \
+ pop {r0, lr}; \
cfi_adjust_cfa_offset (-8); \
cfi_restore (lr); \
teq ip, #0
diff --git a/libc/ports/sysdeps/unix/sysv/linux/arm/nptl/unwind-forcedunwind.c b/libc/ports/sysdeps/unix/sysv/linux/arm/nptl/unwind-forcedunwind.c
index caa6a2626..108924d8b 100644
--- a/libc/ports/sysdeps/unix/sysv/linux/arm/nptl/unwind-forcedunwind.c
+++ b/libc/ports/sysdeps/unix/sysv/linux/arm/nptl/unwind-forcedunwind.c
@@ -93,7 +93,7 @@ asm (
"_Unwind_Resume:\n"
" .cfi_sections .debug_frame\n"
" " CFI_STARTPROC "\n"
-" stmfd sp!, {r4, r5, r6, lr}\n"
+" push {r4, r5, r6, lr}\n"
" " CFI_ADJUST_CFA_OFFSET (16)" \n"
" " CFI_REL_OFFSET (r4, 0) "\n"
" " CFI_REL_OFFSET (r5, 4) "\n"
@@ -108,7 +108,7 @@ asm (
" cmp r3, #0\n"
" beq 4f\n"
"5: mov r0, r6\n"
-" ldmfd sp!, {r4, r5, r6, lr}\n"
+" pop {r4, r5, r6, lr}\n"
" " CFI_ADJUST_CFA_OFFSET (-16) "\n"
" " CFI_RESTORE (r4) "\n"
" " CFI_RESTORE (r5) "\n"
diff --git a/libc/ports/sysdeps/unix/sysv/linux/arm/nptl/unwind-resume.c b/libc/ports/sysdeps/unix/sysv/linux/arm/nptl/unwind-resume.c
index 121159913..d155ea7dc 100644
--- a/libc/ports/sysdeps/unix/sysv/linux/arm/nptl/unwind-resume.c
+++ b/libc/ports/sysdeps/unix/sysv/linux/arm/nptl/unwind-resume.c
@@ -56,7 +56,7 @@ asm (
"_Unwind_Resume:\n"
" .cfi_sections .debug_frame\n"
" " CFI_STARTPROC "\n"
-" stmfd sp!, {r4, r5, r6, lr}\n"
+" push {r4, r5, r6, lr}\n"
" " CFI_ADJUST_CFA_OFFSET (16)" \n"
" " CFI_REL_OFFSET (r4, 0) "\n"
" " CFI_REL_OFFSET (r5, 4) "\n"
@@ -71,7 +71,7 @@ asm (
" cmp r3, #0\n"
" beq 4f\n"
"5: mov r0, r6\n"
-" ldmfd sp!, {r4, r5, r6, lr}\n"
+" pop {r4, r5, r6, lr}\n"
" " CFI_ADJUST_CFA_OFFSET (-16) "\n"
" " CFI_RESTORE (r4) "\n"
" " CFI_RESTORE (r5) "\n"
diff --git a/libc/ports/sysdeps/unix/sysv/linux/arm/nptl/vfork.S b/libc/ports/sysdeps/unix/sysv/linux/arm/nptl/vfork.S
index 3fce2d1af..216fb2d2e 100644
--- a/libc/ports/sysdeps/unix/sysv/linux/arm/nptl/vfork.S
+++ b/libc/ports/sysdeps/unix/sysv/linux/arm/nptl/vfork.S
@@ -19,24 +19,18 @@
/* Save the PID value. */
#define SAVE_PID \
- str lr, [sp, #-4]!; /* Save LR. */ \
- cfi_adjust_cfa_offset (4); \
- cfi_rel_offset (lr, 0); \
- mov r0, #0xffff0fff; /* Point to the high page. */ \
- mov lr, pc; /* Save our return address. */ \
- sub pc, r0, #31; /* Jump to the TLS entry. */ \
- ldr lr, [sp], #4; /* Restore LR. */ \
- cfi_adjust_cfa_offset (-4); \
- cfi_restore (lr); \
- mov r2, r0; /* Save the TLS addr in r2. */ \
- ldr r3, [r2, #PID_OFFSET]; /* Load the saved PID. */ \
- rsbs r0, r3, #0; /* Negate it. */ \
- moveq r0, #0x80000000; /* Use 0x80000000 if it was 0. */ \
- str r0, [r2, #PID_OFFSET] /* Store the temporary PID. */
+ GET_TLS (r2); \
+ NEGOFF_ADJ_BASE2 (r2, r0, PID_OFFSET); /* Save the TLS addr in r2. */ \
+ ldr r3, NEGOFF_OFF1 (r2, PID_OFFSET); /* Load the saved PID. */ \
+ rsbs r0, r3, #0; /* Negate it. */ \
+ it eq; \
+ moveq r0, #0x80000000; /* Use 0x80000000 if it was 0. */ \
+ str r0, NEGOFF_OFF1 (r2, PID_OFFSET); /* Store the temp PID. */
/* Restore the old PID value in the parent. */
#define RESTORE_PID \
cmp r0, #0; /* If we are the parent... */ \
- strne r3, [r2, #PID_OFFSET] /* ... restore the saved PID. */
+ it ne; \
+ strne r3, NEGOFF_OFF1 (r2, PID_OFFSET); /* restore the saved PID. */
#include "../vfork.S"
diff --git a/libc/ports/sysdeps/unix/sysv/linux/arm/syscall.S b/libc/ports/sysdeps/unix/sysv/linux/arm/syscall.S
index 665ecb4de..bdd5a52be 100644
--- a/libc/ports/sysdeps/unix/sysv/linux/arm/syscall.S
+++ b/libc/ports/sysdeps/unix/sysv/linux/arm/syscall.S
@@ -23,7 +23,7 @@
ENTRY (syscall)
mov ip, sp
- stmfd sp!, {r4, r5, r6, r7}
+ push {r4, r5, r6, r7}
cfi_adjust_cfa_offset (16)
cfi_rel_offset (r4, 0)
cfi_rel_offset (r5, 4)
@@ -35,7 +35,7 @@ ENTRY (syscall)
mov r2, r3
ldmfd ip, {r3, r4, r5, r6}
swi 0x0
- ldmfd sp!, {r4, r5, r6, r7}
+ pop {r4, r5, r6, r7}
cfi_adjust_cfa_offset (-16)
cfi_restore (r4)
cfi_restore (r5)
diff --git a/libc/ports/sysdeps/unix/sysv/linux/arm/sysdep.h b/libc/ports/sysdeps/unix/sysv/linux/arm/sysdep.h
index f40cb95e8..b195d8ea1 100644
--- a/libc/ports/sysdeps/unix/sysv/linux/arm/sysdep.h
+++ b/libc/ports/sysdeps/unix/sysv/linux/arm/sysdep.h
@@ -45,6 +45,38 @@
#ifdef __ASSEMBLER__
+#ifndef ARCH_HAS_HARD_TP
+/* Internal macro calling the linux kernel kuser_get_tls helper.
+ Note that in thumb mode, a constant pool break is often out of range, so
+ we always expand the constant inline. */
+# ifdef __thumb2__
+# define GET_TLS_BODY \
+ movw r0, #0x0fe0; \
+ movt r0, #0xffff; \
+ blx r0
+# else
+# define GET_TLS_BODY \
+ mov r0, #0xffff0fff; /* Point to the high page. */ \
+ mov lr, pc; /* Save our return address. */ \
+ sub pc, r0, #31 /* Jump to the TLS entry. */
+# endif
+
+/* Helper to get the TLS base pointer. Save LR in TMP, return in R0,
+ and no other registers clobbered. TMP may be LR itself to indicate
+ that no save is necessary. */
+# undef GET_TLS
+# define GET_TLS(TMP) \
+ .ifnc TMP, lr; \
+ mov TMP, lr; \
+ cfi_register (lr, TMP); \
+ GET_TLS_BODY; \
+ mov lr, TMP; \
+ cfi_restore (lr); \
+ .else; \
+ GET_TLS_BODY; \
+ .endif
+#endif /* ARCH_HAS_HARD_TP */
+
/* Linux uses a negative return value to indicate syscall errors,
unlike most Unices, which use the condition codes' carry flag.
@@ -110,32 +142,29 @@
# if RTLD_PRIVATE_ERRNO
# define SYSCALL_ERROR_HANDLER \
__local_syscall_error: \
- ldr r1, 1f; \
- rsb r0, r0, #0; \
-0: str r0, [pc, r1]; \
- mvn r0, #0; \
- DO_RET(lr); \
-1: .word C_SYMBOL_NAME(rtld_errno) - 0b - PC_OFS;
+ rsb r0, r0, #0; \
+ LDST_PCREL(str, r0, r1, C_SYMBOL_NAME(rtld_errno)); \
+ mvn r0, #0; \
+ DO_RET(lr)
# else
# if defined(__ARM_ARCH_4T__) && defined(__THUMB_INTERWORK__)
# define POP_PC \
- ldr lr, [sp], #4; \
+ pop { lr }; \
cfi_adjust_cfa_offset (-4); \
cfi_restore (lr); \
bx lr
# else
-# define POP_PC \
- ldr pc, [sp], #4
+# define POP_PC pop { pc }
# endif
# define SYSCALL_ERROR_HANDLER \
__local_syscall_error: \
- str lr, [sp, #-4]!; \
+ push { lr }; \
cfi_adjust_cfa_offset (4); \
cfi_rel_offset (lr, 0); \
- str r0, [sp, #-4]!; \
+ push { r0 }; \
cfi_adjust_cfa_offset (4); \
bl PLTJMP(C_SYMBOL_NAME(__errno_location)); \
- ldr r1, [sp], #4; \
+ pop { r1 }; \
cfi_adjust_cfa_offset (-4); \
rsb r1, r1, #0; \
str r1, [r0]; \
@@ -202,7 +231,7 @@ __local_syscall_error: \
#undef DOARGS_0
#define DOARGS_0 \
.fnstart; \
- str r7, [sp, #-4]!; \
+ push { r7 }; \
cfi_adjust_cfa_offset (4); \
cfi_rel_offset (r7, 0); \
.save { r7 }
@@ -217,7 +246,7 @@ __local_syscall_error: \
#undef DOARGS_5
#define DOARGS_5 \
.fnstart; \
- stmfd sp!, {r4, r7}; \
+ push {r4, r7}; \
cfi_adjust_cfa_offset (8); \
cfi_rel_offset (r4, 0); \
cfi_rel_offset (r7, 4); \
@@ -227,7 +256,7 @@ __local_syscall_error: \
#define DOARGS_6 \
.fnstart; \
mov ip, sp; \
- stmfd sp!, {r4, r5, r7}; \
+ push {r4, r5, r7}; \
cfi_adjust_cfa_offset (12); \
cfi_rel_offset (r4, 0); \
cfi_rel_offset (r5, 4); \
@@ -238,7 +267,7 @@ __local_syscall_error: \
#define DOARGS_7 \
.fnstart; \
mov ip, sp; \
- stmfd sp!, {r4, r5, r6, r7}; \
+ push {r4, r5, r6, r7}; \
cfi_adjust_cfa_offset (16); \
cfi_rel_offset (r4, 0); \
cfi_rel_offset (r5, 4); \
@@ -249,7 +278,7 @@ __local_syscall_error: \
#undef UNDOARGS_0
#define UNDOARGS_0 \
- ldr r7, [sp], #4; \
+ pop {r7}; \
cfi_adjust_cfa_offset (-4); \
cfi_restore (r7); \
.fnend
@@ -263,14 +292,14 @@ __local_syscall_error: \
#define UNDOARGS_4 UNDOARGS_0
#undef UNDOARGS_5
#define UNDOARGS_5 \
- ldmfd sp!, {r4, r7}; \
+ pop {r4, r7}; \
cfi_adjust_cfa_offset (-8); \
cfi_restore (r4); \
cfi_restore (r7); \
.fnend
#undef UNDOARGS_6
#define UNDOARGS_6 \
- ldmfd sp!, {r4, r5, r7}; \
+ pop {r4, r5, r7}; \
cfi_adjust_cfa_offset (-12); \
cfi_restore (r4); \
cfi_restore (r5); \
@@ -278,7 +307,7 @@ __local_syscall_error: \
.fnend
#undef UNDOARGS_7
#define UNDOARGS_7 \
- ldmfd sp!, {r4, r5, r6, r7}; \
+ pop {r4, r5, r6, r7}; \
cfi_adjust_cfa_offset (-16); \
cfi_restore (r4); \
cfi_restore (r5); \
diff --git a/libc/ports/sysdeps/unix/sysv/linux/arm/vfork.S b/libc/ports/sysdeps/unix/sysv/linux/arm/vfork.S
index ae931f79c..128a6402b 100644
--- a/libc/ports/sysdeps/unix/sysv/linux/arm/vfork.S
+++ b/libc/ports/sysdeps/unix/sysv/linux/arm/vfork.S
@@ -37,7 +37,7 @@ ENTRY (__vfork)
mov ip, r7
cfi_register (r7, ip)
.fnstart
- str r7, [sp, #-4]!
+ push { r7 }
cfi_adjust_cfa_offset (4)
.save { r7 }
ldr r7, =SYS_ify (vfork)
diff --git a/libc/ports/sysdeps/unix/sysv/linux/generic/bits/msq.h b/libc/ports/sysdeps/unix/sysv/linux/generic/bits/msq.h
index 87f37b4d6..49cbf0611 100644
--- a/libc/ports/sysdeps/unix/sysv/linux/generic/bits/msq.h
+++ b/libc/ports/sysdeps/unix/sysv/linux/generic/bits/msq.h
@@ -27,6 +27,7 @@
#define MSG_NOERROR 010000 /* no error if message is too big */
#ifdef __USE_GNU
# define MSG_EXCEPT 020000 /* recv any msg except of specified type */
+# define MSG_COPY 040000 /* copy (not remove) all queue messages */
#endif
/* Types used in the structure definition. */
diff --git a/libc/ports/sysdeps/unix/sysv/linux/hppa/bits/mman.h b/libc/ports/sysdeps/unix/sysv/linux/hppa/bits/mman.h
index c216ddb1f..2835b0ff0 100644
--- a/libc/ports/sysdeps/unix/sysv/linux/hppa/bits/mman.h
+++ b/libc/ports/sysdeps/unix/sysv/linux/hppa/bits/mman.h
@@ -44,6 +44,9 @@
# define MAP_ANONYMOUS 0x10 /* Don't use a file */
# define MAP_ANON MAP_ANONYMOUS
# define MAP_VARIABLE 0
+/* When MAP_HUGETLB is set bits [26:31] encode the log2 of the huge page size. */
+# define MAP_HUGE_SHIFT 26
+# define MAP_HUGE_MASK 0x3f
#endif
/* These are Linux-specific. */
diff --git a/libc/ports/sysdeps/unix/sysv/linux/hppa/bits/msq.h b/libc/ports/sysdeps/unix/sysv/linux/hppa/bits/msq.h
index e56286b28..ac35f510b 100644
--- a/libc/ports/sysdeps/unix/sysv/linux/hppa/bits/msq.h
+++ b/libc/ports/sysdeps/unix/sysv/linux/hppa/bits/msq.h
@@ -26,6 +26,7 @@
#define MSG_NOERROR 010000 /* no error if message is too big */
#ifdef __USE_GNU
# define MSG_EXCEPT 020000 /* recv any msg except of specified type */
+# define MSG_COPY 040000 /* copy (not remove) all queue messages */
#endif
/* Types used in the structure definition. */
diff --git a/libc/ports/sysdeps/unix/sysv/linux/ia64/bits/mman.h b/libc/ports/sysdeps/unix/sysv/linux/ia64/bits/mman.h
index fba16db47..c3b1caf9d 100644
--- a/libc/ports/sysdeps/unix/sysv/linux/ia64/bits/mman.h
+++ b/libc/ports/sysdeps/unix/sysv/linux/ia64/bits/mman.h
@@ -23,36 +23,6 @@
/* The following definitions basically come from the kernel headers.
But the kernel header is not namespace clean. */
-
-/* Protections are chosen from these bits, OR'd together. The
- implementation does not necessarily support PROT_EXEC or PROT_WRITE
- without PROT_READ. The only guarantees are that no writing will be
- allowed without PROT_WRITE and no access will be allowed for PROT_NONE. */
-
-#define PROT_READ 0x1 /* Page can be read. */
-#define PROT_WRITE 0x2 /* Page can be written. */
-#define PROT_EXEC 0x4 /* Page can be executed. */
-#define PROT_NONE 0x0 /* Page can not be accessed. */
-#define PROT_GROWSDOWN 0x01000000 /* Extend change to start of
- growsdown vma (mprotect only). */
-#define PROT_GROWSUP 0x02000000 /* Extend change to start of
- growsup vma (mprotect only). */
-
-/* Sharing types (must choose one and only one of these). */
-#define MAP_SHARED 0x01 /* Share changes. */
-#define MAP_PRIVATE 0x02 /* Changes are private. */
-#ifdef __USE_MISC
-# define MAP_TYPE 0x0f /* Mask for type of mapping. */
-#endif
-
-/* Other flags. */
-#define MAP_FIXED 0x10 /* Interpret addr exactly. */
-#ifdef __USE_MISC
-# define MAP_FILE 0
-# define MAP_ANONYMOUS 0x20 /* Don't use a file. */
-# define MAP_ANON MAP_ANONYMOUS
-#endif
-
/* These are Linux-specific. */
#ifdef __USE_MISC
# define MAP_GROWSDOWN 0x00100 /* Stack-like segment. */
@@ -67,47 +37,5 @@
# define MAP_HUGETLB 0x40000 /* Create huge page mapping. */
#endif
-/* Flags to `msync'. */
-#define MS_ASYNC 0x1 /* Sync memory asynchronously. */
-#define MS_INVALIDATE 0x2 /* Invalidate the caches. */
-#define MS_SYNC 0x4 /* Synchronous memory sync. */
-
-/* Flags for `mlockall'. */
-#define MCL_CURRENT 0x1 /* Lock all currently mapped pages. */
-#define MCL_FUTURE 0x2 /* Lock all additions to address
- space. */
-
-/* Flags for `mremap'. */
-#ifdef __USE_GNU
-# define MREMAP_MAYMOVE 1
-# define MREMAP_FIXED 2
-#endif
-
-/* Advice to `madvise'. */
-#ifdef __USE_BSD
-# define MADV_NORMAL 0 /* No further special treatment. */
-# define MADV_RANDOM 1 /* Expect random page references. */
-# define MADV_SEQUENTIAL 2 /* Expect sequential page references. */
-# define MADV_WILLNEED 3 /* Will need these pages. */
-# define MADV_DONTNEED 4 /* Don't need these pages. */
-# define MADV_REMOVE 9 /* Remove these pages and resources. */
-# define MADV_DONTFORK 10 /* Do not inherit across fork. */
-# define MADV_DOFORK 11 /* Do inherit across fork. */
-# define MADV_MERGEABLE 12 /* KSM may merge identical pages. */
-# define MADV_UNMERGEABLE 13 /* KSM may not merge identical pages. */
-# define MADV_HUGEPAGE 14 /* Worth backing with hugepages. */
-# define MADV_NOHUGEPAGE 15 /* Not worth backing with hugepages. */
-# define MADV_DONTDUMP 16 /* Explicity exclude from the core dump,
- overrides the coredump filter bits. */
-# define MADV_DODUMP 17 /* Clear the MADV_DONTDUMP flag. */
-# define MADV_HWPOISON 100 /* Poison a page for testing. */
-#endif
-
-/* The POSIX people had to invent similar names for the same things. */
-#ifdef __USE_XOPEN2K
-# define POSIX_MADV_NORMAL 0 /* No further special treatment. */
-# define POSIX_MADV_RANDOM 1 /* Expect random page references. */
-# define POSIX_MADV_SEQUENTIAL 2 /* Expect sequential page references. */
-# define POSIX_MADV_WILLNEED 3 /* Will need these pages. */
-# define POSIX_MADV_DONTNEED 4 /* Don't need these pages. */
-#endif
+/* Include generic Linux declarations. */
+#include <bits/mman-linux.h>
diff --git a/libc/ports/sysdeps/unix/sysv/linux/ia64/bits/msq.h b/libc/ports/sysdeps/unix/sysv/linux/ia64/bits/msq.h
index 68d3ed792..8519390c4 100644
--- a/libc/ports/sysdeps/unix/sysv/linux/ia64/bits/msq.h
+++ b/libc/ports/sysdeps/unix/sysv/linux/ia64/bits/msq.h
@@ -24,8 +24,10 @@
/* Define options for message queue functions. */
#define MSG_NOERROR 010000 /* no error if message is too big */
-#define MSG_EXCEPT 020000 /* recv any msg except of specified type */
-
+#ifdef __USE_GNU
+# define MSG_EXCEPT 020000 /* recv any msg except of specified type */
+# define MSG_COPY 040000 /* copy (not remove) all queue messages */
+#endif
/* Structure of record for one message inside the kernel.
The type `struct __msg' is opaque. */
diff --git a/libc/ports/sysdeps/unix/sysv/linux/ia64/makecontext.c b/libc/ports/sysdeps/unix/sysv/linux/ia64/makecontext.c
index 79fa05af6..c3bb5de19 100644
--- a/libc/ports/sysdeps/unix/sysv/linux/ia64/makecontext.c
+++ b/libc/ports/sysdeps/unix/sysv/linux/ia64/makecontext.c
@@ -22,14 +22,10 @@
#include <stdlib.h>
#include <ucontext.h>
#include <sys/rse.h>
+#include <link.h>
+#include <dl-fptr.h>
-struct fdesc
- {
- unsigned long ip;
- unsigned long gp;
- };
-
#define PUSH(val) \
do { \
if (ia64_rse_is_rnat_slot (rbs)) \
@@ -48,7 +44,7 @@ __makecontext (ucontext_t *ucp, void (*func) (void), int argc, ...)
extern void __start_context (ucontext_t *link, long gp, ...);
unsigned long stack_start, stack_end;
va_list ap;
- long *rbs;
+ unsigned long *rbs;
int i;
stack_start = (long) sc->sc_stack.ss_sp;
@@ -65,16 +61,16 @@ makecontext: does not know how to handle more than 8 arguments\n"));
}
/* set the entry point and global pointer: */
- sc->sc_br[0] = ((struct fdesc *) &__start_context)->ip;
- sc->sc_br[1] = ((struct fdesc *) func)->ip;
- sc->sc_gr[1] = ((struct fdesc *) func)->gp;
+ sc->sc_br[0] = ELF_PTR_TO_FDESC (&__start_context)->ip;
+ sc->sc_br[1] = ELF_PTR_TO_FDESC (func)->ip;
+ sc->sc_gr[1] = ELF_PTR_TO_FDESC (func)->gp;
/* set up the call frame: */
sc->sc_ar_pfs = ((sc->sc_ar_pfs & ~0x3fffffffffUL)
| (argc + 2) | ((argc + 2) << 7));
- rbs = (long *) stack_start;
+ rbs = (unsigned long *) stack_start;
PUSH((long) ucp->uc_link);
- PUSH(((struct fdesc *) &__start_context)->gp);
+ PUSH(ELF_PTR_TO_FDESC (&__start_context)->gp);
va_start (ap, argc);
for (i = 0; i < argc; ++i)
PUSH(va_arg (ap, long));
diff --git a/libc/ports/sysdeps/unix/sysv/linux/ia64/nptl/dl-sysdep.h b/libc/ports/sysdeps/unix/sysv/linux/ia64/nptl/dl-sysdep.h
index e87b0fe69..886a4f0e5 100644
--- a/libc/ports/sysdeps/unix/sysv/linux/ia64/nptl/dl-sysdep.h
+++ b/libc/ports/sysdeps/unix/sysv/linux/ia64/nptl/dl-sysdep.h
@@ -16,22 +16,10 @@
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
-#ifndef _DL_SYSDEP_H
-#define _DL_SYSDEP_H 1
+#ifndef _LINUX_IA64_DL_SYSDEP_H
+#define _LINUX_IA64_DL_SYSDEP_H 1
-/* This macro must be defined to either 0 or 1.
-
- If 1, then an errno global variable hidden in ld.so will work right with
- all the errno-using libc code compiled for ld.so, and there is never a
- need to share the errno location with libc. This is appropriate only if
- all the libc functions that ld.so uses are called without PLT and always
- get the versions linked into ld.so rather than the libc ones. */
-
-#ifdef IS_IN_rtld
-# define RTLD_PRIVATE_ERRNO 1
-#else
-# define RTLD_PRIVATE_ERRNO 0
-#endif
+#include_next <dl-sysdep.h>
/* Traditionally system calls have been made using break 0x100000. A
second method was introduced which, if possible, will use the EPC
@@ -41,7 +29,7 @@
#define NEED_DL_SYSINFO 1
#define USE_DL_SYSINFO 1
-#if defined NEED_DL_SYSINFO && !defined __ASSEMBLER__
+#ifndef __ASSEMBLER__
/* Don't declare this as a function---we want it's entry-point, not
it's function descriptor... */
extern int _dl_sysinfo_break attribute_hidden;
@@ -64,11 +52,4 @@ extern int _dl_sysinfo_break attribute_hidden;
might write into it after _dl_start returns. */
#define DL_ARGV_NOT_RELRO 1
-
-#ifndef __ASSEMBLER__
-/* Get version of the OS. */
-extern int _dl_discover_osversion (void) attribute_hidden;
-# define HAVE_DL_DISCOVER_OSVERSION 1
-#endif
-
#endif /* dl-sysdep.h */
diff --git a/libc/ports/sysdeps/unix/sysv/linux/ia64/sysdep.h b/libc/ports/sysdeps/unix/sysv/linux/ia64/sysdep.h
index c6fce1313..96f6a4e8a 100644
--- a/libc/ports/sysdeps/unix/sysv/linux/ia64/sysdep.h
+++ b/libc/ports/sysdeps/unix/sysv/linux/ia64/sysdep.h
@@ -252,7 +252,7 @@
_retval; })
#undef INTERNAL_SYSCALL_DECL
-#define INTERNAL_SYSCALL_DECL(err) long int err
+#define INTERNAL_SYSCALL_DECL(err) long int err __attribute__ ((unused))
#undef INTERNAL_SYSCALL
#define INTERNAL_SYSCALL_NCS(name, err, nr, args...) \
@@ -264,7 +264,10 @@
INTERNAL_SYSCALL_NCS (__NR_##name, err, nr, ##args)
#undef INTERNAL_SYSCALL_ERROR_P
-#define INTERNAL_SYSCALL_ERROR_P(val, err) (err == -1)
+#define INTERNAL_SYSCALL_ERROR_P(val, err) \
+ ({ (void) (val); \
+ (err == -1); \
+ })
#undef INTERNAL_SYSCALL_ERRNO
#define INTERNAL_SYSCALL_ERRNO(val, err) (val)
diff --git a/libc/ports/sysdeps/unix/sysv/linux/m68k/bits/mman.h b/libc/ports/sysdeps/unix/sysv/linux/m68k/bits/mman.h
index d2fb69d83..b89011aee 100644
--- a/libc/ports/sysdeps/unix/sysv/linux/m68k/bits/mman.h
+++ b/libc/ports/sysdeps/unix/sysv/linux/m68k/bits/mman.h
@@ -23,36 +23,6 @@
/* The following definitions basically come from the kernel headers.
But the kernel header is not namespace clean. */
-
-/* Protections are chosen from these bits, OR'd together. The
- implementation does not necessarily support PROT_EXEC or PROT_WRITE
- without PROT_READ. The only guarantees are that no writing will be
- allowed without PROT_WRITE and no access will be allowed for PROT_NONE. */
-
-#define PROT_READ 0x1 /* Page can be read. */
-#define PROT_WRITE 0x2 /* Page can be written. */
-#define PROT_EXEC 0x4 /* Page can be executed. */
-#define PROT_NONE 0x0 /* Page can not be accessed. */
-#define PROT_GROWSDOWN 0x01000000 /* Extend change to start of
- growsdown vma (mprotect only). */
-#define PROT_GROWSUP 0x02000000 /* Extend change to start of
- growsup vma (mprotect only). */
-
-/* Sharing types (must choose one and only one of these). */
-#define MAP_SHARED 0x01 /* Share changes. */
-#define MAP_PRIVATE 0x02 /* Changes are private. */
-#ifdef __USE_MISC
-# define MAP_TYPE 0x0f /* Mask for type of mapping. */
-#endif
-
-/* Other flags. */
-#define MAP_FIXED 0x10 /* Interpret addr exactly. */
-#ifdef __USE_MISC
-# define MAP_FILE 0
-# define MAP_ANONYMOUS 0x20 /* Don't use a file. */
-# define MAP_ANON MAP_ANONYMOUS
-#endif
-
/* These are Linux-specific. */
#ifdef __USE_MISC
# define MAP_GROWSDOWN 0x00100 /* Stack-like segment. */
@@ -66,47 +36,5 @@
# define MAP_HUGETLB 0x40000 /* Create huge page mapping. */
#endif
-/* Flags to `msync'. */
-#define MS_ASYNC 1 /* Sync memory asynchronously. */
-#define MS_SYNC 4 /* Synchronous memory sync. */
-#define MS_INVALIDATE 2 /* Invalidate the caches. */
-
-/* Flags for `mlockall'. */
-#define MCL_CURRENT 1 /* Lock all currently mapped pages. */
-#define MCL_FUTURE 2 /* Lock all additions to address
- space. */
-
-/* Flags for `mremap'. */
-#ifdef __USE_GNU
-# define MREMAP_MAYMOVE 1
-# define MREMAP_FIXED 2
-#endif
-
-/* Advice to `madvise'. */
-#ifdef __USE_BSD
-# define MADV_NORMAL 0 /* No further special treatment. */
-# define MADV_RANDOM 1 /* Expect random page references. */
-# define MADV_SEQUENTIAL 2 /* Expect sequential page references. */
-# define MADV_WILLNEED 3 /* Will need these pages. */
-# define MADV_DONTNEED 4 /* Don't need these pages. */
-# define MADV_REMOVE 9 /* Remove these pages and resources. */
-# define MADV_DONTFORK 10 /* Do not inherit across fork. */
-# define MADV_DOFORK 11 /* Do inherit across fork. */
-# define MADV_MERGEABLE 12 /* KSM may merge identical pages. */
-# define MADV_UNMERGEABLE 13 /* KSM may not merge identical pages. */
-# define MADV_HUGEPAGE 14 /* Worth backing with hugepages. */
-# define MADV_NOHUGEPAGE 15 /* Not worth backing with hugepages. */
-# define MADV_DONTDUMP 16 /* Explicity exclude from the core dump,
- overrides the coredump filter bits. */
-# define MADV_DODUMP 17 /* Clear the MADV_DONTDUMP flag. */
-# define MADV_HWPOISON 100 /* Poison a page for testing. */
-#endif
-
-/* The POSIX people had to invent similar names for the same things. */
-#ifdef __USE_XOPEN2K
-# define POSIX_MADV_NORMAL 0 /* No further special treatment. */
-# define POSIX_MADV_RANDOM 1 /* Expect random page references. */
-# define POSIX_MADV_SEQUENTIAL 2 /* Expect sequential page references. */
-# define POSIX_MADV_WILLNEED 3 /* Will need these pages. */
-# define POSIX_MADV_DONTNEED 4 /* Don't need these pages. */
-#endif
+/* Include generic Linux declarations. */
+#include <bits/mman-linux.h>
diff --git a/libc/ports/sysdeps/unix/sysv/linux/m68k/coldfire/nptl/libpthread.abilist b/libc/ports/sysdeps/unix/sysv/linux/m68k/coldfire/nptl/libpthread.abilist
index 6c0bbde67..de8095a60 100644
--- a/libc/ports/sysdeps/unix/sysv/linux/m68k/coldfire/nptl/libpthread.abilist
+++ b/libc/ports/sysdeps/unix/sysv/linux/m68k/coldfire/nptl/libpthread.abilist
@@ -83,7 +83,6 @@ GLIBC_2.4
pause F
pread F
pread64 F
- pthread_atfork F
pthread_attr_destroy F
pthread_attr_getaffinity_np F
pthread_attr_getdetachstate F
diff --git a/libc/ports/sysdeps/unix/sysv/linux/mips/bits/mman.h b/libc/ports/sysdeps/unix/sysv/linux/mips/bits/mman.h
index a13a90096..b327795f8 100644
--- a/libc/ports/sysdeps/unix/sysv/linux/mips/bits/mman.h
+++ b/libc/ports/sysdeps/unix/sysv/linux/mips/bits/mman.h
@@ -23,41 +23,9 @@
/* The following definitions basically come from the kernel headers.
But the kernel header is not namespace clean. */
-
-/* Protections are chosen from these bits, OR'd together. The
- implementation does not necessarily support PROT_EXEC or PROT_WRITE
- without PROT_READ. The only guarantees are that no writing will be
- allowed without PROT_WRITE and no access will be allowed for PROT_NONE. */
-
-#define PROT_READ 0x1 /* Page can be read. */
-#define PROT_WRITE 0x2 /* Page can be written. */
-#define PROT_EXEC 0x4 /* Page can be executed. */
-#define PROT_NONE 0x0 /* Page can not be accessed. */
-#define PROT_GROWSDOWN 0x01000000 /* Extend change to start of
- growsdown vma (mprotect only). */
-#define PROT_GROWSUP 0x02000000 /* Extend change to start of
- growsup vma (mprotect only). */
-
-/* Sharing types (must choose one and only one of these). */
-#define MAP_SHARED 0x01 /* Share changes. */
-#define MAP_PRIVATE 0x02 /* Changes are private. */
-#ifdef __USE_MISC
-# define MAP_TYPE 0x0f /* Mask for type of mapping. */
-#endif
-
-/* Other flags. */
-#define MAP_FIXED 0x10 /* Interpret addr exactly. */
-#ifdef __USE_MISC
-# define MAP_FILE 0
-# define MAP_ANONYMOUS 0x0800 /* Don't use a file. */
-# define MAP_ANON MAP_ANONYMOUS
-# define MAP_RENAME MAP_ANONYMOUS
-#endif
-
/* These are Linux-specific. */
#ifdef __USE_MISC
# define MAP_NORESERVE 0x0400 /* don't check for reservations */
-# define MAP_ANONYMOUS 0x0800 /* don't use a file */
# define MAP_GROWSDOWN 0x1000 /* stack-like segment */
# define MAP_DENYWRITE 0x2000 /* ETXTBSY */
# define MAP_EXECUTABLE 0x4000 /* mark it as an executable */
@@ -68,47 +36,11 @@
# define MAP_HUGETLB 0x80000 /* Create huge page mapping. */
#endif
-/* Flags to `msync'. */
-#define MS_ASYNC 1 /* Sync memory asynchronously. */
-#define MS_SYNC 4 /* Synchronous memory sync. */
-#define MS_INVALIDATE 2 /* Invalidate the caches. */
-
-/* Flags for `mlockall'. */
-#define MCL_CURRENT 1 /* Lock all currently mapped pages. */
-#define MCL_FUTURE 2 /* Lock all additions to address
- space. */
-
-/* Flags for `mremap'. */
-#ifdef __USE_GNU
-# define MREMAP_MAYMOVE 1
-# define MREMAP_FIXED 2
-#endif
+#define __MAP_ANONYMOUS 0x0800
-/* Advice to `madvise'. */
-#ifdef __USE_BSD
-# define MADV_NORMAL 0 /* No further special treatment. */
-# define MADV_RANDOM 1 /* Expect random page references. */
-# define MADV_SEQUENTIAL 2 /* Expect sequential page references. */
-# define MADV_WILLNEED 3 /* Will need these pages. */
-# define MADV_DONTNEED 4 /* Don't need these pages. */
-# define MADV_REMOVE 9 /* Remove these pages and resources. */
-# define MADV_DONTFORK 10 /* Do not inherit across fork. */
-# define MADV_DOFORK 11 /* Do inherit across fork. */
-# define MADV_MERGEABLE 12 /* KSM may merge identical pages. */
-# define MADV_UNMERGEABLE 13 /* KSM may not merge identical pages. */
-# define MADV_HUGEPAGE 14 /* Worth backing with hugepages. */
-# define MADV_NOHUGEPAGE 15 /* Not worth backing with hugepages. */
-# define MADV_DONTDUMP 16 /* Explicity exclude from the core dump,
- overrides the coredump filter bits. */
-# define MADV_DODUMP 17 /* Clear the MADV_DONTDUMP flag. */
-# define MADV_HWPOISON 100 /* Poison a page for testing. */
-#endif
+/* Include generic Linux declarations. */
+#include <bits/mman-linux.h>
-/* The POSIX people had to invent similar names for the same things. */
-#ifdef __USE_XOPEN2K
-# define POSIX_MADV_NORMAL 0 /* No further special treatment. */
-# define POSIX_MADV_RANDOM 1 /* Expect random page references. */
-# define POSIX_MADV_SEQUENTIAL 2 /* Expect sequential page references. */
-# define POSIX_MADV_WILLNEED 3 /* Will need these pages. */
-# define POSIX_MADV_DONTNEED 4 /* Don't need these pages. */
+#ifdef __USE_MISC
+# define MAP_RENAME MAP_ANONYMOUS
#endif
diff --git a/libc/ports/sysdeps/unix/sysv/linux/mips/bits/msq.h b/libc/ports/sysdeps/unix/sysv/linux/mips/bits/msq.h
index 8439069cd..e814bc722 100644
--- a/libc/ports/sysdeps/unix/sysv/linux/mips/bits/msq.h
+++ b/libc/ports/sysdeps/unix/sysv/linux/mips/bits/msq.h
@@ -25,6 +25,7 @@
#define MSG_NOERROR 010000 /* no error if message is too big */
#ifdef __USE_GNU
# define MSG_EXCEPT 020000 /* recv any msg except of specified type */
+# define MSG_COPY 040000 /* copy (not remove) all queue messages */
#endif
/* Types used in the structure definition. */
diff --git a/libc/ports/sysdeps/unix/sysv/linux/tile/bits/mman.h b/libc/ports/sysdeps/unix/sysv/linux/tile/bits/mman.h
index 7494ee5e5..02fddecc1 100644
--- a/libc/ports/sysdeps/unix/sysv/linux/tile/bits/mman.h
+++ b/libc/ports/sysdeps/unix/sysv/linux/tile/bits/mman.h
@@ -23,36 +23,6 @@
/* The following definitions basically come from the kernel headers.
But the kernel header is not namespace clean. */
-
-/* Protections are chosen from these bits, OR'd together. The
- implementation does not necessarily support PROT_EXEC or PROT_WRITE
- without PROT_READ. The only guarantees are that no writing will be
- allowed without PROT_WRITE and no access will be allowed for PROT_NONE. */
-
-#define PROT_READ 0x1 /* Page can be read. */
-#define PROT_WRITE 0x2 /* Page can be written. */
-#define PROT_EXEC 0x4 /* Page can be executed. */
-#define PROT_NONE 0x0 /* Page can not be accessed. */
-#define PROT_GROWSDOWN 0x01000000 /* Extend change to start of
- growsdown vma (mprotect only). */
-#define PROT_GROWSUP 0x02000000 /* Extend change to start of
- growsup vma (mprotect only). */
-
-/* Sharing types (must choose one and only one of these). */
-#define MAP_SHARED 0x01 /* Share changes. */
-#define MAP_PRIVATE 0x02 /* Changes are private. */
-#ifdef __USE_MISC
-# define MAP_TYPE 0x0f /* Mask for type of mapping. */
-#endif
-
-/* Other flags. */
-#define MAP_FIXED 0x10 /* Interpret addr exactly. */
-#ifdef __USE_MISC
-# define MAP_FILE 0
-# define MAP_ANONYMOUS 0x20 /* Don't use a file. */
-# define MAP_ANON MAP_ANONYMOUS
-#endif
-
#ifdef __USE_MISC
/* These are Linux-specific. */
# define MAP_NONBLOCK 0x00080 /* Do not block on IO. */
@@ -66,47 +36,5 @@
# define MAP_HUGETLB 0x04000 /* Create huge page mapping. */
#endif
-/* Flags to `msync'. */
-#define MS_ASYNC 1 /* Sync memory asynchronously. */
-#define MS_SYNC 4 /* Synchronous memory sync. */
-#define MS_INVALIDATE 2 /* Invalidate the caches. */
-
-/* Flags for `mlockall'. */
-#define MCL_CURRENT 1 /* Lock all currently mapped pages. */
-#define MCL_FUTURE 2 /* Lock all additions to address
- space. */
-
-/* Flags for `mremap'. */
-#ifdef __USE_GNU
-# define MREMAP_MAYMOVE 1
-# define MREMAP_FIXED 2
-#endif
-
-/* Advice to `madvise'. */
-#ifdef __USE_BSD
-# define MADV_NORMAL 0 /* No further special treatment. */
-# define MADV_RANDOM 1 /* Expect random page references. */
-# define MADV_SEQUENTIAL 2 /* Expect sequential page references. */
-# define MADV_WILLNEED 3 /* Will need these pages. */
-# define MADV_DONTNEED 4 /* Don't need these pages. */
-# define MADV_REMOVE 9 /* Remove these pages and resources. */
-# define MADV_DONTFORK 10 /* Do not inherit across fork. */
-# define MADV_DOFORK 11 /* Do inherit across fork. */
-# define MADV_MERGEABLE 12 /* KSM may merge identical pages. */
-# define MADV_UNMERGEABLE 13 /* KSM may not merge identical pages. */
-# define MADV_HUGEPAGE 14 /* Worth backing with hugepages. */
-# define MADV_NOHUGEPAGE 15 /* Not worth backing with hugepages. */
-# define MADV_DONTDUMP 16 /* Explicity exclude from the core dump,
- overrides the coredump filter bits. */
-# define MADV_DODUMP 17 /* Clear the MADV_DONTDUMP flag. */
-# define MADV_HWPOISON 100 /* Poison a page for testing. */
-#endif
-
-/* The POSIX people had to invent similar names for the same things. */
-#ifdef __USE_XOPEN2K
-# define POSIX_MADV_NORMAL 0 /* No further special treatment. */
-# define POSIX_MADV_RANDOM 1 /* Expect random page references. */
-# define POSIX_MADV_SEQUENTIAL 2 /* Expect sequential page references. */
-# define POSIX_MADV_WILLNEED 3 /* Will need these pages. */
-# define POSIX_MADV_DONTNEED 4 /* Don't need these pages. */
-#endif
+/* Include generic Linux declarations. */
+#include <bits/mman-linux.h>
diff --git a/libc/ports/sysdeps/unix/sysv/linux/tile/tilegx/tilegx32/nptl/libpthread.abilist b/libc/ports/sysdeps/unix/sysv/linux/tile/tilegx/tilegx32/nptl/libpthread.abilist
index 3ab004605..658c4bf99 100644
--- a/libc/ports/sysdeps/unix/sysv/linux/tile/tilegx/tilegx32/nptl/libpthread.abilist
+++ b/libc/ports/sysdeps/unix/sysv/linux/tile/tilegx/tilegx32/nptl/libpthread.abilist
@@ -73,7 +73,6 @@ GLIBC_2.12
pause F
pread F
pread64 F
- pthread_atfork F
pthread_attr_destroy F
pthread_attr_getaffinity_np F
pthread_attr_getdetachstate F
diff --git a/libc/ports/sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/nptl/libpthread.abilist b/libc/ports/sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/nptl/libpthread.abilist
index 3ab004605..658c4bf99 100644
--- a/libc/ports/sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/nptl/libpthread.abilist
+++ b/libc/ports/sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/nptl/libpthread.abilist
@@ -73,7 +73,6 @@ GLIBC_2.12
pause F
pread F
pread64 F
- pthread_atfork F
pthread_attr_destroy F
pthread_attr_getaffinity_np F
pthread_attr_getdetachstate F
diff --git a/libc/ports/sysdeps/unix/sysv/linux/tile/tilepro/nptl/libpthread.abilist b/libc/ports/sysdeps/unix/sysv/linux/tile/tilepro/nptl/libpthread.abilist
index 3ab004605..658c4bf99 100644
--- a/libc/ports/sysdeps/unix/sysv/linux/tile/tilepro/nptl/libpthread.abilist
+++ b/libc/ports/sysdeps/unix/sysv/linux/tile/tilepro/nptl/libpthread.abilist
@@ -73,7 +73,6 @@ GLIBC_2.12
pause F
pread F
pread64 F
- pthread_atfork F
pthread_attr_destroy F
pthread_attr_getaffinity_np F
pthread_attr_getdetachstate F