about summary refs log tree commit diff
path: root/REORG.TODO/sysdeps/arm/armv6t2
diff options
context:
space:
mode:
Diffstat (limited to 'REORG.TODO/sysdeps/arm/armv6t2')
-rw-r--r--REORG.TODO/sysdeps/arm/armv6t2/Implies2
-rw-r--r--REORG.TODO/sysdeps/arm/armv6t2/ffs.S36
-rw-r--r--REORG.TODO/sysdeps/arm/armv6t2/ffsll.S50
-rw-r--r--REORG.TODO/sysdeps/arm/armv6t2/memchr.S184
-rw-r--r--REORG.TODO/sysdeps/arm/armv6t2/strlen.S164
5 files changed, 436 insertions, 0 deletions
diff --git a/REORG.TODO/sysdeps/arm/armv6t2/Implies b/REORG.TODO/sysdeps/arm/armv6t2/Implies
new file mode 100644
index 0000000000..20a87fc8a5
--- /dev/null
+++ b/REORG.TODO/sysdeps/arm/armv6t2/Implies
@@ -0,0 +1,2 @@
+# We can do everything that 6 can
+arm/armv6
diff --git a/REORG.TODO/sysdeps/arm/armv6t2/ffs.S b/REORG.TODO/sysdeps/arm/armv6t2/ffs.S
new file mode 100644
index 0000000000..ed13cd97ba
--- /dev/null
+++ b/REORG.TODO/sysdeps/arm/armv6t2/ffs.S
@@ -0,0 +1,36 @@
+/* ffs -- find first set bit in an int, from least significant end.
+   Copyright (C) 2013-2017 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 (__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_def (__ffs)
+libc_hidden_builtin_def (ffs)
diff --git a/REORG.TODO/sysdeps/arm/armv6t2/ffsll.S b/REORG.TODO/sysdeps/arm/armv6t2/ffsll.S
new file mode 100644
index 0000000000..2754cc70aa
--- /dev/null
+++ b/REORG.TODO/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-2017 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/REORG.TODO/sysdeps/arm/armv6t2/memchr.S b/REORG.TODO/sysdeps/arm/armv6t2/memchr.S
new file mode 100644
index 0000000000..fb4dc8efa3
--- /dev/null
+++ b/REORG.TODO/sysdeps/arm/armv6t2/memchr.S
@@ -0,0 +1,184 @@
+/* Copyright (C) 2011-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Code contributed by Dave Gilbert <david.gilbert@linaro.org>
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <sysdep.h>
+
+@ This memchr routine is optimised on a Cortex-A9 and should work on all ARMv7
+@ and ARMv6T2 processors.  It has a fast path for short sizes, and has an
+@ optimised path for large data sets; the worst case is finding the match early
+@ in a large data set.
+@ Note: The use of cbz/cbnz means it's Thumb only
+
+@ 2011-07-15 david.gilbert@linaro.org
+@    Copy from Cortex strings release 21 and change license
+@ http://bazaar.launchpad.net/~linaro-toolchain-dev/cortex-strings/trunk/view/head:/src/linaro-a9/memchr.S
+@    Change function declarations/entry/exit
+@ 2011-12-01 david.gilbert@linaro.org
+@    Add some fixes from comments received (including use of ldrd instead ldm)
+@ 2011-12-07 david.gilbert@linaro.org
+@    Removed cbz from align loop - can't be taken
+
+@ this lets us check a flag in a 00/ff byte easily in either endianness
+#ifdef __ARMEB__
+#define CHARTSTMASK(c) 1<<(31-(c*8))
+#else
+#define CHARTSTMASK(c) 1<<(c*8)
+#endif
+	.syntax unified
+
+	.text
+#ifdef NO_THUMB
+	.arm
+#else
+	.thumb
+	.thumb_func
+#endif
+	.global memchr
+	.type memchr,%function
+ENTRY(memchr)
+	@ r0 = start of memory to scan
+	@ r1 = character to look for
+	@ r2 = length
+	@ returns r0 = pointer to character or NULL if not found
+	and	r1,r1,#0xff	@ Don't think we can trust the caller to actually pass a char
+
+	cmp	r2,#16		@ If it's short don't bother with anything clever
+	blt	20f
+
+	tst	r0, #7		@ If it's already aligned skip the next bit
+	beq	10f
+
+	@ Work up to an aligned point
+5:
+	ldrb	r3, [r0],#1
+	subs	r2, r2, #1
+	cmp	r3, r1
+	beq	50f		@ If it matches exit found
+	tst	r0, #7
+	bne	5b		@ If not aligned yet then do next byte
+
+10:
+	@ At this point, we are aligned, we know we have at least 8 bytes to work with
+	push	{r4,r5,r6,r7}
+	cfi_adjust_cfa_offset (16)
+	cfi_rel_offset (r4, 0)
+	cfi_rel_offset (r5, 4)
+	cfi_rel_offset (r6, 8)
+	cfi_rel_offset (r7, 12)
+
+	cfi_remember_state
+
+	orr	r1, r1, r1, lsl #8	@ expand the match word across to all bytes
+	orr	r1, r1, r1, lsl #16
+	bic	r6, r2, #7	@ Number of double words to work with * 8
+	mvns	r7, #0		@ all F's
+	movs	r3, #0
+
+15:
+	ldrd 	r4,r5, [r0],#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, 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}
+	cfi_adjust_cfa_offset (-16)
+	cfi_restore (r4)
+	cfi_restore (r5)
+	cfi_restore (r6)
+	cfi_restore (r7)
+
+	and	r1,r1,#0xff	@ Get r1 back to a single character from the expansion above
+	and	r2,r2,#7	@ Leave the count remaining as the number after the double words have been done
+
+20:
+#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
+#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:
+	movs	r0,#0		@ not found
+	DO_RET(lr)
+
+50:
+	subs	r0,r0,#1	@ found
+	DO_RET(lr)
+
+60:  @ We're here because the fast path found a hit - now we have to track down exactly which word it was
+     @ r0 points to the start of the double word after the one that was tested
+     @ r4 has the 00/ff pattern for the first word, r5 has the chained value
+	cfi_restore_state
+	cmp	r4, #0
+	itte	eq
+	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	r4, # CHARTSTMASK(0)	@ 1st character
+	bne	61f
+	adds	r0,r0,#1
+	tst	r4, # CHARTSTMASK(1)	@ 2nd character
+	ittt	eq
+	addeq	r0,r0,#1
+	tsteq	r4, # (3<<15)		@ 2nd & 3rd character
+	@ If not the 3rd must be the last one
+	addeq	r0,r0,#1
+
+61:
+	pop	{r4,r5,r6,r7}
+	cfi_adjust_cfa_offset (-16)
+	cfi_restore (r4)
+	cfi_restore (r5)
+	cfi_restore (r6)
+	cfi_restore (r7)
+
+	subs	r0,r0,#1
+	DO_RET(lr)
+
+END(memchr)
+libc_hidden_builtin_def (memchr)
diff --git a/REORG.TODO/sysdeps/arm/armv6t2/strlen.S b/REORG.TODO/sysdeps/arm/armv6t2/strlen.S
new file mode 100644
index 0000000000..c72a1e73be
--- /dev/null
+++ b/REORG.TODO/sysdeps/arm/armv6t2/strlen.S
@@ -0,0 +1,164 @@
+/* Copyright (C) 2010-2017 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/>.  */
+
+/*
+   Assumes:
+   ARMv6T2, AArch32
+
+ */
+
+#include <arm-features.h>               /* This might #define NO_THUMB.  */
+#include <sysdep.h>
+
+#ifdef __ARMEB__
+#define S2LO		lsl
+#define S2HI		lsr
+#else
+#define S2LO		lsr
+#define S2HI		lsl
+#endif
+
+#ifndef NO_THUMB
+/* This code is best on Thumb.  */
+	.thumb
+#else
+/* Using bne.w explicitly is desirable in Thumb mode because it helps
+   align the following label without a nop.  In ARM mode there is no
+   such difference.  */
+.macro bne.w label
+	bne \label
+.endm
+
+/* This clobbers the condition codes, which the real Thumb cbnz instruction
+   does not do.  But it doesn't matter for any of the uses here.  */
+.macro cbnz reg, label
+	cmp \reg, #0
+	bne \label
+.endm
+#endif
+
+/* Parameters and result.  */
+#define srcin		r0
+#define result		r0
+
+/* Internal variables.  */
+#define src		r1
+#define data1a		r2
+#define data1b		r3
+#define const_m1	r12
+#define const_0		r4
+#define tmp1		r4		/* Overlaps const_0  */
+#define tmp2		r5
+
+	.text
+	.p2align 6
+ENTRY(strlen)
+	pld	[srcin, #0]
+	strd	r4, r5, [sp, #-8]!
+	cfi_adjust_cfa_offset (8)
+	cfi_rel_offset (r4, 0)
+	cfi_rel_offset (r5, 4)
+	cfi_remember_state
+	bic	src, srcin, #7
+	mvn	const_m1, #0
+	ands	tmp1, srcin, #7		/* (8 - bytes) to alignment.  */
+	pld	[src, #32]
+	bne.w	.Lmisaligned8
+	mov	const_0, #0
+	mov	result, #-8
+.Lloop_aligned:
+	/* Bytes 0-7.  */
+	ldrd	data1a, data1b, [src]
+	pld	[src, #64]
+	add	result, result, #8
+.Lstart_realigned:
+	uadd8	data1a, data1a, const_m1	/* Saturating GE<0:3> set.  */
+	sel	data1a, const_0, const_m1	/* Select based on GE<0:3>.  */
+	uadd8	data1b, data1b, const_m1
+	sel	data1b, data1a, const_m1	/* Only used if d1a == 0.  */
+	cbnz	data1b, .Lnull_found
+
+	/* Bytes 8-15.  */
+	ldrd	data1a, data1b, [src, #8]
+	uadd8	data1a, data1a, const_m1	/* Saturating GE<0:3> set.  */
+	add	result, result, #8
+	sel	data1a, const_0, const_m1	/* Select based on GE<0:3>.  */
+	uadd8	data1b, data1b, const_m1
+	sel	data1b, data1a, const_m1	/* Only used if d1a == 0.  */
+	cbnz	data1b, .Lnull_found
+
+	/* Bytes 16-23.  */
+	ldrd	data1a, data1b, [src, #16]
+	uadd8	data1a, data1a, const_m1	/* Saturating GE<0:3> set.  */
+	add	result, result, #8
+	sel	data1a, const_0, const_m1	/* Select based on GE<0:3>.  */
+	uadd8	data1b, data1b, const_m1
+	sel	data1b, data1a, const_m1	/* Only used if d1a == 0.  */
+	cbnz	data1b, .Lnull_found
+
+	/* Bytes 24-31.  */
+	ldrd	data1a, data1b, [src, #24]
+	add	src, src, #32
+	uadd8	data1a, data1a, const_m1	/* Saturating GE<0:3> set.  */
+	add	result, result, #8
+	sel	data1a, const_0, const_m1	/* Select based on GE<0:3>.  */
+	uadd8	data1b, data1b, const_m1
+	sel	data1b, data1a, const_m1	/* Only used if d1a == 0.  */
+	cmp	data1b, #0
+	beq	.Lloop_aligned
+
+.Lnull_found:
+	cmp	data1a, #0
+	itt	eq
+	addeq	result, result, #4
+	moveq	data1a, data1b
+#ifndef __ARMEB__
+	rev	data1a, data1a
+#endif
+	clz	data1a, data1a
+	ldrd	r4, r5, [sp], #8
+	cfi_adjust_cfa_offset (-8)
+	cfi_restore (r4)
+	cfi_restore (r5)
+	add	result, result, data1a, lsr #3	/* Bits -> Bytes.  */
+	DO_RET(lr)
+
+.Lmisaligned8:
+	cfi_restore_state
+	ldrd	data1a, data1b, [src]
+	and	tmp2, tmp1, #3
+	rsb	result, tmp1, #0
+	lsl	tmp2, tmp2, #3			/* Bytes -> bits.  */
+	tst	tmp1, #4
+	pld	[src, #64]
+	S2HI	tmp2, const_m1, tmp2
+#ifdef NO_THUMB
+	mvn	tmp1, tmp2
+	orr	data1a, data1a, tmp1
+	itt	ne
+	orrne	data1b, data1b, tmp1
+#else
+	orn	data1a, data1a, tmp2
+	itt	ne
+	ornne	data1b, data1b, tmp2
+#endif
+	movne	data1a, const_m1
+	mov	const_0, #0
+	b	.Lstart_realigned
+
+END(strlen)
+libc_hidden_builtin_def (strlen)