diff options
| author | Eric Andersen <andersen@codepoet.org> | 2003-11-20 15:23:03 +0000 | 
|---|---|---|
| committer | Eric Andersen <andersen@codepoet.org> | 2003-11-20 15:23:03 +0000 | 
| commit | ee4435bcd6f94b7463cbd7e960e84ddf03965272 (patch) | |
| tree | 4d8ab5b8d85897e3b0844ad26b804300e90a2d81 | |
| parent | 72a8f4125ba443d28f9398a45ec5c4c9504c3e8f (diff) | |
| download | uClibc-alpine-ee4435bcd6f94b7463cbd7e960e84ddf03965272.tar.bz2 uClibc-alpine-ee4435bcd6f94b7463cbd7e960e84ddf03965272.tar.xz | |
Add an initial set of arm optimized string functions.  These
do seem to make noticable speed improvement...
 -Erik
| -rw-r--r-- | libc/string/Makefile | 2 | ||||
| -rw-r--r-- | libc/string/arm/Makefile | 39 | ||||
| -rw-r--r-- | libc/string/arm/_memcpy.S | 583 | ||||
| -rw-r--r-- | libc/string/arm/bcopy.S | 52 | ||||
| -rw-r--r-- | libc/string/arm/bzero.S | 48 | ||||
| -rw-r--r-- | libc/string/arm/memcmp.S | 53 | ||||
| -rw-r--r-- | libc/string/arm/memcpy.S | 48 | ||||
| -rw-r--r-- | libc/string/arm/memmove.S | 48 | ||||
| -rw-r--r-- | libc/string/arm/memset.S | 72 | ||||
| -rw-r--r-- | libc/string/arm/strcmp.S | 49 | ||||
| -rw-r--r-- | libc/string/arm/strlen.S | 71 | ||||
| -rw-r--r-- | libc/string/arm/strncmp.S | 53 | 
12 files changed, 1117 insertions, 1 deletions
| diff --git a/libc/string/Makefile b/libc/string/Makefile index 30637fa74..464a07e74 100644 --- a/libc/string/Makefile +++ b/libc/string/Makefile @@ -23,7 +23,7 @@ DIRS=  ifeq ($(TARGET_ARCH),$(wildcard $(TARGET_ARCH)))  DIRS = $(TARGET_ARCH)  endif -ALL_SUBDIRS = i386 +ALL_SUBDIRS = i386 arm  MSRC= wstring.c  MOBJ=  basename.o bcopy.o bzero.o dirname.o ffs.o memccpy.o memchr.o memcmp.o \ diff --git a/libc/string/arm/Makefile b/libc/string/arm/Makefile new file mode 100644 index 000000000..25adea975 --- /dev/null +++ b/libc/string/arm/Makefile @@ -0,0 +1,39 @@ +# Makefile for uClibc +# +# Copyright (C) 2000-2003 Erik Andersen <andersen@uclibc.org> +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of the GNU Library General Public License as published by the Free +# Software Foundation; either version 2 of the License, or (at your option) any +# later version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more +# details. +# +# You should have received a copy of the GNU Library General Public License +# along with this program; if not, write to the Free Software Foundation, Inc., +# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +TOPDIR=../../../ +include $(TOPDIR)Rules.mak + +SSRC= _memcpy.S bcopy.S bzero.S memcmp.S memcpy.S memmove.S memset.S \ +	strcmp.S strlen.S strncmp.S +SOBJS=$(patsubst %.S,%.o, $(SSRC)) + +all: $(SOBJS) $(LIBC) + +$(LIBC): ar-target + +ar-target: $(SOBJS) +	$(AR) $(ARFLAGS) $(LIBC) $(SOBJS) + +$(SOBJS): %.o : %.S +	$(CC) $(CFLAGS) -c $< -o $@ +	$(STRIPTOOL) -x -R .note -R .comment $*.o + +clean: +	$(RM) *.[oa] *~ core + diff --git a/libc/string/arm/_memcpy.S b/libc/string/arm/_memcpy.S new file mode 100644 index 000000000..5a5ba7c59 --- /dev/null +++ b/libc/string/arm/_memcpy.S @@ -0,0 +1,583 @@ +/*- + * Copyright (c) 1997 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Neil A. Carson and Mark Brinicombe + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + *    notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + *    notice, this list of conditions and the following disclaimer in the + *    documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + *    must display the following acknowledgement: + *        This product includes software developed by the NetBSD + *        Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation nor the names of its + *    contributors may be used to endorse or promote products derived + *    from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * Adapted for uClibc from NetBSD _memcpy.S,v 1.6 2003/10/09 + * by Erik Andersen <andersen@codepoet.org> + */ + + +#include <endian.h> + +/* + * This is one fun bit of code ... + * Some easy listening music is suggested while trying to understand this + * code e.g. Iron Maiden + * + * For anyone attempting to understand it : + * + * The core code is implemented here with simple stubs for memcpy() + * memmove() and bcopy(). + * + * All local labels are prefixed with Lmemcpy_ + * Following the prefix a label starting f is used in the forward copy code + * while a label using b is used in the backwards copy code + * The source and destination addresses determine whether a forward or + * backward copy is performed. + * Separate bits of code are used to deal with the following situations + * for both the forward and backwards copy. + * unaligned source address + * unaligned destination address + * Separate copy routines are used to produce an optimised result for each + * of these cases. + * The copy code will use LDM/STM instructions to copy up to 32 bytes at + * a time where possible. + * + * Note: r12 (aka ip) can be trashed during the function along with + * r0-r3 although r0-r2 have defined uses i.e. src, dest, len through out. + * Additional registers are preserved prior to use i.e. r4, r5 & lr + * + * Apologies for the state of the comments ;-) + */ + +		.text +		.global _memcpy; +		.type _memcpy,%function +		.align 4;                                                               \ + +_memcpy: +	/* Determine copy direction */ +	cmp	r1, r0 +	bcc	.Lmemcpy_backwards + +	moveq	r0, #0			/* Quick abort for len=0 */ +	moveq	pc, lr + +	stmdb	sp!, {r0, lr}		/* memcpy() returns dest addr */ +	subs	r2, r2, #4 +	blt	.Lmemcpy_fl4		/* less than 4 bytes */ +	ands	r12, r0, #3 +	bne	.Lmemcpy_fdestul	/* oh unaligned destination addr */ +	ands	r12, r1, #3 +	bne	.Lmemcpy_fsrcul		/* oh unaligned source addr */ + +.Lmemcpy_ft8: +	/* We have aligned source and destination */ +	subs	r2, r2, #8 +	blt	.Lmemcpy_fl12		/* less than 12 bytes (4 from above) */ +	subs	r2, r2, #0x14          +	blt	.Lmemcpy_fl32		/* less than 32 bytes (12 from above) */ +	stmdb	sp!, {r4}		/* borrow r4 */ + +	/* blat 32 bytes at a time */ +	/* XXX for really big copies perhaps we should use more registers */ +.Lmemcpy_floop32:	 +	ldmia	r1!, {r3, r4, r12, lr} +	stmia	r0!, {r3, r4, r12, lr} +	ldmia	r1!, {r3, r4, r12, lr} +	stmia	r0!, {r3, r4, r12, lr} +	subs	r2, r2, #0x20          +	bge	.Lmemcpy_floop32 + +	cmn	r2, #0x10 +	ldmgeia	r1!, {r3, r4, r12, lr}	/* blat a remaining 16 bytes */ +	stmgeia	r0!, {r3, r4, r12, lr} +	subge	r2, r2, #0x10          +	ldmia	sp!, {r4}		/* return r4 */ + +.Lmemcpy_fl32: +	adds	r2, r2, #0x14          + +	/* blat 12 bytes at a time */ +.Lmemcpy_floop12: +	ldmgeia	r1!, {r3, r12, lr} +	stmgeia	r0!, {r3, r12, lr} +	subges	r2, r2, #0x0c          +	bge	.Lmemcpy_floop12 + +.Lmemcpy_fl12: +	adds	r2, r2, #8 +	blt	.Lmemcpy_fl4 + +	subs	r2, r2, #4 +	ldrlt	r3, [r1], #4 +	strlt	r3, [r0], #4 +	ldmgeia	r1!, {r3, r12} +	stmgeia	r0!, {r3, r12} +	subge	r2, r2, #4 + +.Lmemcpy_fl4: +	/* less than 4 bytes to go */ +	adds	r2, r2, #4 +	ldmeqia	sp!, {r0, pc}		/* done */ + +	/* copy the crud byte at a time */ +	cmp	r2, #2 +	ldrb	r3, [r1], #1 +	strb	r3, [r0], #1 +	ldrgeb	r3, [r1], #1 +	strgeb	r3, [r0], #1 +	ldrgtb	r3, [r1], #1 +	strgtb	r3, [r0], #1 +	ldmia	sp!, {r0, pc} + +	/* erg - unaligned destination */ +.Lmemcpy_fdestul: +	rsb	r12, r12, #4 +	cmp	r12, #2 + +	/* align destination with byte copies */ +	ldrb	r3, [r1], #1 +	strb	r3, [r0], #1 +	ldrgeb	r3, [r1], #1 +	strgeb	r3, [r0], #1 +	ldrgtb	r3, [r1], #1 +	strgtb	r3, [r0], #1 +	subs	r2, r2, r12 +	blt	.Lmemcpy_fl4		/* less the 4 bytes */ + +	ands	r12, r1, #3 +	beq	.Lmemcpy_ft8		/* we have an aligned source */ + +	/* erg - unaligned source */ +	/* This is where it gets nasty ... */ +.Lmemcpy_fsrcul: +	bic	r1, r1, #3 +	ldr	lr, [r1], #4 +	cmp	r12, #2 +	bgt	.Lmemcpy_fsrcul3 +	beq	.Lmemcpy_fsrcul2 +	cmp	r2, #0x0c             +	blt	.Lmemcpy_fsrcul1loop4 +	sub	r2, r2, #0x0c          +	stmdb	sp!, {r4, r5} + +.Lmemcpy_fsrcul1loop16: +#if BYTE_ORDER == BIG_ENDIAN +	mov	r3, lr, lsl #8 +	ldmia	r1!, {r4, r5, r12, lr} +	orr	r3, r3, r4, lsr #24 +	mov	r4, r4, lsl #8 +	orr	r4, r4, r5, lsr #24 +	mov	r5, r5, lsl #8 +	orr	r5, r5, r12, lsr #24 +	mov	r12, r12, lsl #8 +	orr	r12, r12, lr, lsr #24 +#else +	mov	r3, lr, lsr #8 +	ldmia	r1!, {r4, r5, r12, lr} +	orr	r3, r3, r4, lsl #24 +	mov	r4, r4, lsr #8 +	orr	r4, r4, r5, lsl #24 +	mov	r5, r5, lsr #8 +	orr	r5, r5, r12, lsl #24 +	mov	r12, r12, lsr #8 +	orr	r12, r12, lr, lsl #24 +#endif +	stmia	r0!, {r3-r5, r12} +	subs	r2, r2, #0x10          +	bge	.Lmemcpy_fsrcul1loop16 +	ldmia	sp!, {r4, r5} +	adds	r2, r2, #0x0c          +	blt	.Lmemcpy_fsrcul1l4 + +.Lmemcpy_fsrcul1loop4: +#if BYTE_ORDER == BIG_ENDIAN +	mov	r12, lr, lsl #8 +	ldr	lr, [r1], #4 +	orr	r12, r12, lr, lsr #24 +#else +	mov	r12, lr, lsr #8 +	ldr	lr, [r1], #4 +	orr	r12, r12, lr, lsl #24 +#endif +	str	r12, [r0], #4 +	subs	r2, r2, #4 +	bge	.Lmemcpy_fsrcul1loop4 + +.Lmemcpy_fsrcul1l4: +	sub	r1, r1, #3 +	b	.Lmemcpy_fl4 + +.Lmemcpy_fsrcul2: +	cmp	r2, #0x0c             +	blt	.Lmemcpy_fsrcul2loop4 +	sub	r2, r2, #0x0c          +	stmdb	sp!, {r4, r5} + +.Lmemcpy_fsrcul2loop16: +#if BYTE_ORDER == BIG_ENDIAN +	mov	r3, lr, lsl #16 +	ldmia	r1!, {r4, r5, r12, lr} +	orr	r3, r3, r4, lsr #16 +	mov	r4, r4, lsl #16 +	orr	r4, r4, r5, lsr #16 +	mov	r5, r5, lsl #16 +	orr	r5, r5, r12, lsr #16 +	mov	r12, r12, lsl #16 +	orr	r12, r12, lr, lsr #16 +#else +	mov	r3, lr, lsr #16 +	ldmia	r1!, {r4, r5, r12, lr} +	orr	r3, r3, r4, lsl #16 +	mov	r4, r4, lsr #16 +	orr	r4, r4, r5, lsl #16 +	mov	r5, r5, lsr #16 +	orr	r5, r5, r12, lsl #16 +	mov	r12, r12, lsr #16 +	orr	r12, r12, lr, lsl #16 +#endif +	stmia	r0!, {r3-r5, r12} +	subs	r2, r2, #0x10          +	bge	.Lmemcpy_fsrcul2loop16 +	ldmia	sp!, {r4, r5} +	adds	r2, r2, #0x0c          +	blt	.Lmemcpy_fsrcul2l4 + +.Lmemcpy_fsrcul2loop4: +#if BYTE_ORDER == BIG_ENDIAN +	mov	r12, lr, lsl #16 +	ldr	lr, [r1], #4 +	orr	r12, r12, lr, lsr #16 +#else +	mov	r12, lr, lsr #16 +	ldr	lr, [r1], #4 +	orr	r12, r12, lr, lsl #16 +#endif +	str	r12, [r0], #4 +	subs	r2, r2, #4 +	bge	.Lmemcpy_fsrcul2loop4 + +.Lmemcpy_fsrcul2l4: +	sub	r1, r1, #2 +	b	.Lmemcpy_fl4 + +.Lmemcpy_fsrcul3: +	cmp	r2, #0x0c             +	blt	.Lmemcpy_fsrcul3loop4 +	sub	r2, r2, #0x0c          +	stmdb	sp!, {r4, r5} + +.Lmemcpy_fsrcul3loop16: +#if BYTE_ORDER == BIG_ENDIAN +	mov	r3, lr, lsl #24 +	ldmia	r1!, {r4, r5, r12, lr} +	orr	r3, r3, r4, lsr #8 +	mov	r4, r4, lsl #24 +	orr	r4, r4, r5, lsr #8 +	mov	r5, r5, lsl #24 +	orr	r5, r5, r12, lsr #8 +	mov	r12, r12, lsl #24 +	orr	r12, r12, lr, lsr #8 +#else +	mov	r3, lr, lsr #24 +	ldmia	r1!, {r4, r5, r12, lr} +	orr	r3, r3, r4, lsl #8 +	mov	r4, r4, lsr #24 +	orr	r4, r4, r5, lsl #8 +	mov	r5, r5, lsr #24 +	orr	r5, r5, r12, lsl #8 +	mov	r12, r12, lsr #24 +	orr	r12, r12, lr, lsl #8 +#endif +	stmia	r0!, {r3-r5, r12} +	subs	r2, r2, #0x10          +	bge	.Lmemcpy_fsrcul3loop16 +	ldmia	sp!, {r4, r5} +	adds	r2, r2, #0x0c          +	blt	.Lmemcpy_fsrcul3l4 + +.Lmemcpy_fsrcul3loop4: +#if BYTE_ORDER == BIG_ENDIAN +	mov	r12, lr, lsl #24 +	ldr	lr, [r1], #4 +	orr	r12, r12, lr, lsr #8 +#else +	mov	r12, lr, lsr #24 +	ldr	lr, [r1], #4 +	orr	r12, r12, lr, lsl #8 +#endif +	str	r12, [r0], #4 +	subs	r2, r2, #4 +	bge	.Lmemcpy_fsrcul3loop4 + +.Lmemcpy_fsrcul3l4: +	sub	r1, r1, #1 +	b	.Lmemcpy_fl4 + +.Lmemcpy_backwards: +	add	r1, r1, r2 +	add	r0, r0, r2 +	subs	r2, r2, #4 +	blt	.Lmemcpy_bl4		/* less than 4 bytes */ +	ands	r12, r0, #3 +	bne	.Lmemcpy_bdestul	/* oh unaligned destination addr */ +	ands	r12, r1, #3 +	bne	.Lmemcpy_bsrcul		/* oh unaligned source addr */ + +.Lmemcpy_bt8: +	/* We have aligned source and destination */ +	subs	r2, r2, #8 +	blt	.Lmemcpy_bl12		/* less than 12 bytes (4 from above) */ +	stmdb	sp!, {r4, lr} +	subs	r2, r2, #0x14		/* less than 32 bytes (12 from above) */ +	blt	.Lmemcpy_bl32 + +	/* blat 32 bytes at a time */ +	/* XXX for really big copies perhaps we should use more registers */ +.Lmemcpy_bloop32: +	ldmdb	r1!, {r3, r4, r12, lr} +	stmdb	r0!, {r3, r4, r12, lr} +	ldmdb	r1!, {r3, r4, r12, lr} +	stmdb	r0!, {r3, r4, r12, lr} +	subs	r2, r2, #0x20          +	bge	.Lmemcpy_bloop32 + +.Lmemcpy_bl32: +	cmn	r2, #0x10             +	ldmgedb	r1!, {r3, r4, r12, lr}	/* blat a remaining 16 bytes */ +	stmgedb	r0!, {r3, r4, r12, lr} +	subge	r2, r2, #0x10          +	adds	r2, r2, #0x14          +	ldmgedb	r1!, {r3, r12, lr}	/* blat a remaining 12 bytes */ +	stmgedb	r0!, {r3, r12, lr} +	subge	r2, r2, #0x0c          +	ldmia	sp!, {r4, lr} + +.Lmemcpy_bl12: +	adds	r2, r2, #8 +	blt	.Lmemcpy_bl4 +	subs	r2, r2, #4 +	ldrlt	r3, [r1, #-4]! +	strlt	r3, [r0, #-4]! +	ldmgedb	r1!, {r3, r12} +	stmgedb	r0!, {r3, r12} +	subge	r2, r2, #4 + +.Lmemcpy_bl4: +	/* less than 4 bytes to go */ +	adds	r2, r2, #4 +	moveq	pc, lr			/* done */ + +	/* copy the crud byte at a time */ +	cmp	r2, #2 +	ldrb	r3, [r1, #-1]! +	strb	r3, [r0, #-1]! +	ldrgeb	r3, [r1, #-1]! +	strgeb	r3, [r0, #-1]! +	ldrgtb	r3, [r1, #-1]! +	strgtb	r3, [r0, #-1]! +	mov	pc, lr + +	/* erg - unaligned destination */ +.Lmemcpy_bdestul: +	cmp	r12, #2 + +	/* align destination with byte copies */ +	ldrb	r3, [r1, #-1]! +	strb	r3, [r0, #-1]! +	ldrgeb	r3, [r1, #-1]! +	strgeb	r3, [r0, #-1]! +	ldrgtb	r3, [r1, #-1]! +	strgtb	r3, [r0, #-1]! +	subs	r2, r2, r12 +	blt	.Lmemcpy_bl4		/* less than 4 bytes to go */ +	ands	r12, r1, #3 +	beq	.Lmemcpy_bt8		/* we have an aligned source */ + +	/* erg - unaligned source */ +	/* This is where it gets nasty ... */ +.Lmemcpy_bsrcul: +	bic	r1, r1, #3 +	ldr	r3, [r1, #0] +	cmp	r12, #2 +	blt	.Lmemcpy_bsrcul1 +	beq	.Lmemcpy_bsrcul2 +	cmp	r2, #0x0c             +	blt	.Lmemcpy_bsrcul3loop4 +	sub	r2, r2, #0x0c          +	stmdb	sp!, {r4, r5, lr} + +.Lmemcpy_bsrcul3loop16: +#if BYTE_ORDER == BIG_ENDIAN +	mov	lr, r3, lsr #8 +	ldmdb	r1!, {r3-r5, r12} +	orr	lr, lr, r12, lsl #24 +	mov	r12, r12, lsr #8 +	orr	r12, r12, r5, lsl #24 +	mov	r5, r5, lsr #8 +	orr	r5, r5, r4, lsl #24 +	mov	r4, r4, lsr #8 +	orr	r4, r4, r3, lsl #24 +#else +	mov	lr, r3, lsl #8 +	ldmdb	r1!, {r3-r5, r12} +	orr	lr, lr, r12, lsr #24 +	mov	r12, r12, lsl #8 +	orr	r12, r12, r5, lsr #24 +	mov	r5, r5, lsl #8 +	orr	r5, r5, r4, lsr #24 +	mov	r4, r4, lsl #8 +	orr	r4, r4, r3, lsr #24 +#endif +	stmdb	r0!, {r4, r5, r12, lr} +	subs	r2, r2, #0x10          +	bge	.Lmemcpy_bsrcul3loop16 +	ldmia	sp!, {r4, r5, lr} +	adds	r2, r2, #0x0c          +	blt	.Lmemcpy_bsrcul3l4 + +.Lmemcpy_bsrcul3loop4: +#if BYTE_ORDER == BIG_ENDIAN +	mov	r12, r3, lsr #8 +	ldr	r3, [r1, #-4]! +	orr	r12, r12, r3, lsl #24 +#else +	mov	r12, r3, lsl #8 +	ldr	r3, [r1, #-4]! +	orr	r12, r12, r3, lsr #24 +#endif +	str	r12, [r0, #-4]! +	subs	r2, r2, #4 +	bge	.Lmemcpy_bsrcul3loop4 + +.Lmemcpy_bsrcul3l4: +	add	r1, r1, #3 +	b	.Lmemcpy_bl4 + +.Lmemcpy_bsrcul2: +	cmp	r2, #0x0c             +	blt	.Lmemcpy_bsrcul2loop4 +	sub	r2, r2, #0x0c          +	stmdb	sp!, {r4, r5, lr} + +.Lmemcpy_bsrcul2loop16: +#if BYTE_ORDER == BIG_ENDIAN +	mov	lr, r3, lsr #16 +	ldmdb	r1!, {r3-r5, r12} +	orr	lr, lr, r12, lsl #16 +	mov	r12, r12, lsr #16 +	orr	r12, r12, r5, lsl #16 +	mov	r5, r5, lsr #16 +	orr	r5, r5, r4, lsl #16 +	mov	r4, r4, lsr #16 +	orr	r4, r4, r3, lsl #16 +#else +	mov	lr, r3, lsl #16 +	ldmdb	r1!, {r3-r5, r12} +	orr	lr, lr, r12, lsr #16 +	mov	r12, r12, lsl #16 +	orr	r12, r12, r5, lsr #16 +	mov	r5, r5, lsl #16 +	orr	r5, r5, r4, lsr #16 +	mov	r4, r4, lsl #16 +	orr	r4, r4, r3, lsr #16 +#endif +	stmdb	r0!, {r4, r5, r12, lr} +	subs	r2, r2, #0x10          +	bge	.Lmemcpy_bsrcul2loop16 +	ldmia	sp!, {r4, r5, lr} +	adds	r2, r2, #0x0c          +	blt	.Lmemcpy_bsrcul2l4 + +.Lmemcpy_bsrcul2loop4: +#if BYTE_ORDER == BIG_ENDIAN +	mov	r12, r3, lsr #16 +	ldr	r3, [r1, #-4]! +	orr	r12, r12, r3, lsl #16 +#else +	mov	r12, r3, lsl #16 +	ldr	r3, [r1, #-4]! +	orr	r12, r12, r3, lsr #16 +#endif +	str	r12, [r0, #-4]! +	subs	r2, r2, #4 +	bge	.Lmemcpy_bsrcul2loop4 + +.Lmemcpy_bsrcul2l4: +	add	r1, r1, #2 +	b	.Lmemcpy_bl4 + +.Lmemcpy_bsrcul1: +	cmp	r2, #0x0c             +	blt	.Lmemcpy_bsrcul1loop4 +	sub	r2, r2, #0x0c          +	stmdb	sp!, {r4, r5, lr} + +.Lmemcpy_bsrcul1loop32: +#if BYTE_ORDER == BIG_ENDIAN +	mov	lr, r3, lsr #24 +	ldmdb	r1!, {r3-r5, r12} +	orr	lr, lr, r12, lsl #8 +	mov	r12, r12, lsr #24 +	orr	r12, r12, r5, lsl #8 +	mov	r5, r5, lsr #24 +	orr	r5, r5, r4, lsl #8 +	mov	r4, r4, lsr #24 +	orr	r4, r4, r3, lsl #8 +#else +	mov	lr, r3, lsl #24 +	ldmdb	r1!, {r3-r5, r12} +	orr	lr, lr, r12, lsr #8 +	mov	r12, r12, lsl #24 +	orr	r12, r12, r5, lsr #8 +	mov	r5, r5, lsl #24 +	orr	r5, r5, r4, lsr #8 +	mov	r4, r4, lsl #24 +	orr	r4, r4, r3, lsr #8 +#endif +	stmdb	r0!, {r4, r5, r12, lr} +	subs	r2, r2, #0x10          +	bge	.Lmemcpy_bsrcul1loop32 +	ldmia	sp!, {r4, r5, lr} +	adds	r2, r2, #0x0c          +	blt	.Lmemcpy_bsrcul1l4 + +.Lmemcpy_bsrcul1loop4: +#if BYTE_ORDER == BIG_ENDIAN +	mov	r12, r3, lsr #24 +	ldr	r3, [r1, #-4]! +	orr	r12, r12, r3, lsl #8 +#else +	mov	r12, r3, lsl #24 +	ldr	r3, [r1, #-4]! +	orr	r12, r12, r3, lsr #8 +#endif +	str	r12, [r0, #-4]! +	subs	r2, r2, #4 +	bge	.Lmemcpy_bsrcul1loop4 + +.Lmemcpy_bsrcul1l4: +	add	r1, r1, #1 +	b	.Lmemcpy_bl4 diff --git a/libc/string/arm/bcopy.S b/libc/string/arm/bcopy.S new file mode 100644 index 000000000..c256df3f3 --- /dev/null +++ b/libc/string/arm/bcopy.S @@ -0,0 +1,52 @@ +/*- + * Copyright (c) 1997 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Neil A. Carson and Mark Brinicombe + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + *    notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + *    notice, this list of conditions and the following disclaimer in the + *    documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + *    must display the following acknowledgement: + *	This product includes software developed by the NetBSD + *	Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation nor the names of its + *    contributors may be used to endorse or promote products derived + *    from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * Adapted for uClibc from NetBSD bcopy.S,v 1.2 1997/10/09 + * by Erik Andersen <andersen@codepoet.org> + */ + +/* bcopy = memcpy/memmove with arguments reversed. */ + +		.text +		.global bcopy; +		.type bcopy,%function +		.align 4;                                                               \ + +bcopy: +	/* switch the source and destination registers */ +	eor     r0, r1, r0  +	eor     r1, r0, r1  +	eor     r0, r1, r0  +	b	_memcpy (PLT) diff --git a/libc/string/arm/bzero.S b/libc/string/arm/bzero.S new file mode 100644 index 000000000..52245a244 --- /dev/null +++ b/libc/string/arm/bzero.S @@ -0,0 +1,48 @@ +/*- + * Copyright (c) 1997 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Neil A. Carson and Mark Brinicombe + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + *    notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + *    notice, this list of conditions and the following disclaimer in the + *    documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + *    must display the following acknowledgement: + *	This product includes software developed by the NetBSD + *	Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation nor the names of its + *    contributors may be used to endorse or promote products derived + *    from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * Adapted for uClibc from NetBSD bzero.S,v 1.2 1997/10/09 + * by Erik Andersen <andersen@codepoet.org> + */ + +		.text +		.global bzero; +		.type bzero,%function +		.align 4;                                                               \ + +bzero: +	mov	r2, r1 +	mov	r1, #0 +	b	memset (PLT) diff --git a/libc/string/arm/memcmp.S b/libc/string/arm/memcmp.S new file mode 100644 index 000000000..8f3f137b0 --- /dev/null +++ b/libc/string/arm/memcmp.S @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2002 ARM Ltd + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + *    notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + *    notice, this list of conditions and the following disclaimer in the + *    documentation and/or other materials provided with the distribution. + * 3. The name of the company may not be used to endorse or promote + *    products derived from this software without specific prior written + *    permission. + * + * THIS SOFTWARE IS PROVIDED BY ARM LTD ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL ARM LTD BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Adapted for uClibc from NetBSD memcmp.S, version 1.2 2003/04/05 + * by Erik Andersen <andersen@codepoet.org> + */ + + +		.text +		.global memcmp; +		.type memcmp,%function +		.align 4;                                                               \ + +memcmp: +	/* if ((len - 1) < 0) return 0 */ +	subs	r2, r2, #1 +	movmi	r0, #0 +	movmi	pc, lr + +	/* ip == last src address to compare */ +	add	ip, r0, r2 +1: +	ldrb	r2, [r0], #1 +	ldrb	r3, [r1], #1 +	cmp	ip, r0 +	cmpcs	r2, r3 +	beq	1b +	sub	r0, r2, r3 +	mov	pc, lr diff --git a/libc/string/arm/memcpy.S b/libc/string/arm/memcpy.S new file mode 100644 index 000000000..cc9a43cb4 --- /dev/null +++ b/libc/string/arm/memcpy.S @@ -0,0 +1,48 @@ +/*- + * Copyright (c) 1997 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Neil A. Carson and Mark Brinicombe + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + *    notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + *    notice, this list of conditions and the following disclaimer in the + *    documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + *    must display the following acknowledgement: + *	This product includes software developed by the NetBSD + *	Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation nor the names of its + *    contributors may be used to endorse or promote products derived + *    from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * Adapted for uClibc from NetBSD memcpy.S,v 1.3 2003/04/05 + * by Erik Andersen <andersen@codepoet.org> + */ + +		.text +		.global memcpy; +		.type memcpy,%function +		.align 4;                                                               \ + +memcpy: +	stmfd	sp!, {r0, lr} +	bl	_memcpy (PLT) +	ldmfd	sp!, {r0, pc} diff --git a/libc/string/arm/memmove.S b/libc/string/arm/memmove.S new file mode 100644 index 000000000..84e3e518c --- /dev/null +++ b/libc/string/arm/memmove.S @@ -0,0 +1,48 @@ +/*- + * Copyright (c) 1997 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Neil A. Carson and Mark Brinicombe + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + *    notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + *    notice, this list of conditions and the following disclaimer in the + *    documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + *    must display the following acknowledgement: + *	This product includes software developed by the NetBSD + *	Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation nor the names of its + *    contributors may be used to endorse or promote products derived + *    from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * Adapted for uClibc from NetBSD memmove.S,v 1.3 2003/04/05 + * by Erik Andersen <andersen@codepoet.org> + */ + +		.text +		.global memmove; +		.type memmove,%function +		.align 4;                                                               \ + +memmove: +	stmfd	sp!, {r0, lr} +	bl	_memcpy (PLT) +	ldmfd	sp!, {r0, pc} diff --git a/libc/string/arm/memset.S b/libc/string/arm/memset.S new file mode 100644 index 000000000..07d3913f9 --- /dev/null +++ b/libc/string/arm/memset.S @@ -0,0 +1,72 @@ +/* Copyright (C) 1998 Free Software Foundation, Inc. +   This file is part of the GNU C Library. +   Contributed by Philip Blundell <philb@gnu.org> + +   The GNU C Library is free software; you can redistribute it and/or +   modify it under the terms of the GNU Lesser General Public +   License as published by the Free Software Foundation; either +   version 2.1 of the License, or (at your option) any later version. + +   The GNU C Library is distributed in the hope that it will be useful, +   but WITHOUT ANY WARRANTY; without even the implied warranty of +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +   Lesser General Public License for more details. + +   You should have received a copy of the GNU Lesser General Public +   License along with the GNU C Library; if not, write to the Free +   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +   02111-1307 USA.  */ + +#include <sys/syscall.h> + +		.text +		.global memset; +		.type memset,%function +		.align 4;                                                               \ + +memset: +	mov	a4, a1 +	cmp	a3, $8		@ at least 8 bytes to do? +	blt	2f +	orr	a2, a2, a2, lsl $8 +	orr	a2, a2, a2, lsl $16 +1: +	tst	a4, $3		@ aligned yet? +	strneb	a2, [a4], $1 +	subne	a3, a3, $1 +	bne	1b +	mov	ip, a2 +1: +	cmp	a3, $8		@ 8 bytes still to do? +	blt	2f +	stmia	a4!, {a2, ip} +	sub	a3, a3, $8 +	cmp	a3, $8		@ 8 bytes still to do? +	blt	2f +	stmia	a4!, {a2, ip} +	sub	a3, a3, $8 +	cmp	a3, $8		@ 8 bytes still to do? +	blt	2f +	stmia	a4!, {a2, ip} +	sub	a3, a3, $8 +	cmp	a3, $8		@ 8 bytes still to do? +	stmgeia	a4!, {a2, ip} +	subge	a3, a3, $8 +	bge	1b +2: +	movs	a3, a3		@ anything left? +	moveq	pc, lr		@ nope +	rsb	a3, a3, $7 +	add	pc, pc, a3, lsl $2 +	mov	r0, r0 +	strb	a2, [a4], $1 +	strb	a2, [a4], $1 +	strb	a2, [a4], $1 +	strb	a2, [a4], $1 +	strb	a2, [a4], $1 +	strb	a2, [a4], $1 +	strb	a2, [a4], $1 +	mov	pc, lr + +.size memset,.-memset; + diff --git a/libc/string/arm/strcmp.S b/libc/string/arm/strcmp.S new file mode 100644 index 000000000..b2f26d63a --- /dev/null +++ b/libc/string/arm/strcmp.S @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2002 ARM Ltd + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + *    notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + *    notice, this list of conditions and the following disclaimer in the + *    documentation and/or other materials provided with the distribution. + * 3. The name of the company may not be used to endorse or promote + *    products derived from this software without specific prior written + *    permission. + * + * THIS SOFTWARE IS PROVIDED BY ARM LTD ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL ARM LTD BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Adapted for uClibc from NetBSD strcmp.S, version 1.3 2003/04/05 + * by Erik Andersen <andersen@codepoet.org> + */ + +		.text +		.global strcmp; +		.type strcmp,%function +		.align 4;                                                               \ + +strcmp: +1: +	ldrb	r2, [r0], #1 +	ldrb	r3, [r1], #1 +	cmp	r2, #1 +	cmpcs	r2, r3 +	beq	1b +	sub	r0, r2, r3 +	mov	pc, lr + +.weak  strcoll; +    strcoll = strcmp + diff --git a/libc/string/arm/strlen.S b/libc/string/arm/strlen.S new file mode 100644 index 000000000..a84114c31 --- /dev/null +++ b/libc/string/arm/strlen.S @@ -0,0 +1,71 @@ +/* Copyright (C) 1998 Free Software Foundation, Inc. +   This file is part of the GNU C Library. +   Code contributed by Matthew Wilcox <willy@odie.barnet.ac.uk> + +   The GNU C Library is free software; you can redistribute it and/or +   modify it under the terms of the GNU Lesser General Public +   License as published by the Free Software Foundation; either +   version 2.1 of the License, or (at your option) any later version. + +   The GNU C Library is distributed in the hope that it will be useful, +   but WITHOUT ANY WARRANTY; without even the implied warranty of +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +   Lesser General Public License for more details. + +   You should have received a copy of the GNU Lesser General Public +   License along with the GNU C Library; if not, write to the Free +   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +   02111-1307 USA.  */ + +#include <endian.h> +#include <sys/syscall.h> + +/* size_t strlen(const char *S) + * entry: r0 -> string + * exit: r0 = len + */ + +		.text +		.global strlen; +		.type strlen,%function +		.align 4;                                                               \ + +strlen: +	bic     r1, r0, $3              @ addr of word containing first byte +	ldr     r2, [r1], $4            @ get the first word +	ands    r3, r0, $3              @ how many bytes are duff? +	rsb     r0, r3, $0              @ get - that number into counter. +	beq     Laligned                @ skip into main check routine if no +					@ more +#if __BYTE_ORDER == __BIG_ENDIAN +	orr     r2, r2, $0xff000000     @ set this byte to non-zero +	subs    r3, r3, $1              @ any more to do? +	orrgt   r2, r2, $0x00ff0000     @ if so, set this byte +	subs    r3, r3, $1              @ more? +	orrgt   r2, r2, $0x0000ff00     @ then set. +#else +	orr     r2, r2, $0x000000ff     @ set this byte to non-zero +	subs    r3, r3, $1              @ any more to do? +	orrgt   r2, r2, $0x0000ff00     @ if so, set this byte +	subs    r3, r3, $1              @ more? +	orrgt   r2, r2, $0x00ff0000     @ then set. +#endif +Laligned:				@ here, we have a word in r2.  Does it +	tst     r2, $0x000000ff         @ contain any zeroes? +	tstne   r2, $0x0000ff00         @ +	tstne   r2, $0x00ff0000         @ +	tstne   r2, $0xff000000         @ +	addne   r0, r0, $4              @ if not, the string is 4 bytes longer +	ldrne   r2, [r1], $4            @ and we continue to the next word +	bne     Laligned                @ +Llastword:				@ drop through to here once we find a +	tst     r2, $0x000000ff         @ word that has a zero byte in it +	addne   r0, r0, $1              @ +	tstne   r2, $0x0000ff00         @ and add up to 3 bytes on to it +	addne   r0, r0, $1              @ +	tstne   r2, $0x00ff0000         @ (if first three all non-zero, 4th +	addne   r0, r0, $1              @  must be zero) +	mov	pc,lr + +.size strlen,.-strlen; + diff --git a/libc/string/arm/strncmp.S b/libc/string/arm/strncmp.S new file mode 100644 index 000000000..6f478b5ed --- /dev/null +++ b/libc/string/arm/strncmp.S @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2002 ARM Ltd + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + *    notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + *    notice, this list of conditions and the following disclaimer in the + *    documentation and/or other materials provided with the distribution. + * 3. The name of the company may not be used to endorse or promote + *    products derived from this software without specific prior written + *    permission. + * + * THIS SOFTWARE IS PROVIDED BY ARM LTD ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL ARM LTD BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Adapted for uClibc from NetBSD strncmp.S, version 1.2 2003/04/05 + * by Erik Andersen <andersen@codepoet.org> + */ + +		.text +		.global strncmp; +		.type strncmp,%function +		.align 4;                                                               \ + +strncmp: +	/* if ((len - 1) < 0) return 0 */ +	subs	r2, r2, #1 +	movmi	r0, #0 +	movmi	pc, lr + +	/* ip == last src address to compare */ +	add	ip, r0, r2 +1: +	ldrb	r2, [r0], #1 +	ldrb	r3, [r1], #1 +	cmp	ip, r0 +	cmpcs	r2, #1 +	cmpcs	r2, r3 +	beq	1b +	sub	r0, r2, r3 +	mov	pc, lr | 
