diff options
Diffstat (limited to 'arch/arc/lib/strlen.S')
| -rw-r--r-- | arch/arc/lib/strlen.S | 83 | 
1 files changed, 83 insertions, 0 deletions
diff --git a/arch/arc/lib/strlen.S b/arch/arc/lib/strlen.S new file mode 100644 index 00000000000..39759e09969 --- /dev/null +++ b/arch/arc/lib/strlen.S @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <asm/linkage.h> + +ARC_ENTRY strlen +	or	r3,r0,7 +	ld	r2,[r3,-7] +	ld.a	r6,[r3,-3] +	mov	r4,0x01010101 +	; uses long immediate +#ifdef __LITTLE_ENDIAN__ +	asl_s	r1,r0,3 +	btst_s	r0,2 +	asl	r7,r4,r1 +	ror	r5,r4 +	sub	r1,r2,r7 +	bic_s	r1,r1,r2 +	mov.eq	r7,r4 +	sub	r12,r6,r7 +	bic	r12,r12,r6 +	or.eq	r12,r12,r1 +	and	r12,r12,r5 +	brne	r12,0,.Learly_end +#else /* BIG ENDIAN */ +	ror	r5,r4 +	btst_s	r0,2 +	mov_s	r1,31 +	sub3	r7,r1,r0 +	sub	r1,r2,r4 +	bic_s	r1,r1,r2 +	bmsk	r1,r1,r7 +	sub	r12,r6,r4 +	bic	r12,r12,r6 +	bmsk.ne	r12,r12,r7 +	or.eq	r12,r12,r1 +	and	r12,r12,r5 +	brne	r12,0,.Learly_end +#endif /* ENDIAN */ + +.Loop: +	ld_s	r2,[r3,4] +	ld.a	r6,[r3,8] +	; stall for load result +	sub	r1,r2,r4 +	bic_s	r1,r1,r2 +	sub	r12,r6,r4 +	bic	r12,r12,r6 +	or	r12,r12,r1 +	and	r12,r12,r5 +	breq r12,0,.Loop +.Lend: +	and.f	r1,r1,r5 +	sub.ne	r3,r3,4 +	mov.eq	r1,r12 +#ifdef __LITTLE_ENDIAN__ +	sub_s	r2,r1,1 +	bic_s	r2,r2,r1 +	norm	r1,r2 +	sub_s	r0,r0,3 +	lsr_s	r1,r1,3 +	sub	    r0,r3,r0 +	j_s.d	[blink] +	sub	    r0,r0,r1 +#else /* BIG ENDIAN */ +	lsr_s	r1,r1,7 +	mov.eq	r2,r6 +	bic_s	r1,r1,r2 +	norm	r1,r1 +	sub	    r0,r3,r0 +	lsr_s	r1,r1,3 +	j_s.d	[blink] +	add	    r0,r0,r1 +#endif /* ENDIAN */ +.Learly_end: +	b.d	.Lend +	sub_s.ne r1,r1,r1 +ARC_EXIT strlen  |