xref: /kernel/linux/linux-6.6/arch/arc/lib/strlen.S (revision 62306a36)
162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com)
462306a36Sopenharmony_ci */
562306a36Sopenharmony_ci
662306a36Sopenharmony_ci#include <linux/linkage.h>
762306a36Sopenharmony_ci
862306a36Sopenharmony_ciENTRY_CFI(strlen)
962306a36Sopenharmony_ci	or	r3,r0,7
1062306a36Sopenharmony_ci	ld	r2,[r3,-7]
1162306a36Sopenharmony_ci	ld.a	r6,[r3,-3]
1262306a36Sopenharmony_ci	mov	r4,0x01010101
1362306a36Sopenharmony_ci	; uses long immediate
1462306a36Sopenharmony_ci#ifdef __LITTLE_ENDIAN__
1562306a36Sopenharmony_ci	asl_s	r1,r0,3
1662306a36Sopenharmony_ci	btst_s	r0,2
1762306a36Sopenharmony_ci	asl	r7,r4,r1
1862306a36Sopenharmony_ci	ror	r5,r4
1962306a36Sopenharmony_ci	sub	r1,r2,r7
2062306a36Sopenharmony_ci	bic_s	r1,r1,r2
2162306a36Sopenharmony_ci	mov.eq	r7,r4
2262306a36Sopenharmony_ci	sub	r12,r6,r7
2362306a36Sopenharmony_ci	bic	r12,r12,r6
2462306a36Sopenharmony_ci	or.eq	r12,r12,r1
2562306a36Sopenharmony_ci	and	r12,r12,r5
2662306a36Sopenharmony_ci	brne	r12,0,.Learly_end
2762306a36Sopenharmony_ci#else /* BIG ENDIAN */
2862306a36Sopenharmony_ci	ror	r5,r4
2962306a36Sopenharmony_ci	btst_s	r0,2
3062306a36Sopenharmony_ci	mov_s	r1,31
3162306a36Sopenharmony_ci	sub3	r7,r1,r0
3262306a36Sopenharmony_ci	sub	r1,r2,r4
3362306a36Sopenharmony_ci	bic_s	r1,r1,r2
3462306a36Sopenharmony_ci	bmsk	r1,r1,r7
3562306a36Sopenharmony_ci	sub	r12,r6,r4
3662306a36Sopenharmony_ci	bic	r12,r12,r6
3762306a36Sopenharmony_ci	bmsk.ne	r12,r12,r7
3862306a36Sopenharmony_ci	or.eq	r12,r12,r1
3962306a36Sopenharmony_ci	and	r12,r12,r5
4062306a36Sopenharmony_ci	brne	r12,0,.Learly_end
4162306a36Sopenharmony_ci#endif /* ENDIAN */
4262306a36Sopenharmony_ci
4362306a36Sopenharmony_ci.Loop:
4462306a36Sopenharmony_ci	ld_s	r2,[r3,4]
4562306a36Sopenharmony_ci	ld.a	r6,[r3,8]
4662306a36Sopenharmony_ci	; stall for load result
4762306a36Sopenharmony_ci	sub	r1,r2,r4
4862306a36Sopenharmony_ci	bic_s	r1,r1,r2
4962306a36Sopenharmony_ci	sub	r12,r6,r4
5062306a36Sopenharmony_ci	bic	r12,r12,r6
5162306a36Sopenharmony_ci	or	r12,r12,r1
5262306a36Sopenharmony_ci	and	r12,r12,r5
5362306a36Sopenharmony_ci	breq r12,0,.Loop
5462306a36Sopenharmony_ci.Lend:
5562306a36Sopenharmony_ci	and.f	r1,r1,r5
5662306a36Sopenharmony_ci	sub.ne	r3,r3,4
5762306a36Sopenharmony_ci	mov.eq	r1,r12
5862306a36Sopenharmony_ci#ifdef __LITTLE_ENDIAN__
5962306a36Sopenharmony_ci	sub_s	r2,r1,1
6062306a36Sopenharmony_ci	bic_s	r2,r2,r1
6162306a36Sopenharmony_ci	norm	r1,r2
6262306a36Sopenharmony_ci	sub_s	r0,r0,3
6362306a36Sopenharmony_ci	lsr_s	r1,r1,3
6462306a36Sopenharmony_ci	sub	    r0,r3,r0
6562306a36Sopenharmony_ci	j_s.d	[blink]
6662306a36Sopenharmony_ci	sub	    r0,r0,r1
6762306a36Sopenharmony_ci#else /* BIG ENDIAN */
6862306a36Sopenharmony_ci	lsr_s	r1,r1,7
6962306a36Sopenharmony_ci	mov.eq	r2,r6
7062306a36Sopenharmony_ci	bic_s	r1,r1,r2
7162306a36Sopenharmony_ci	norm	r1,r1
7262306a36Sopenharmony_ci	sub	    r0,r3,r0
7362306a36Sopenharmony_ci	lsr_s	r1,r1,3
7462306a36Sopenharmony_ci	j_s.d	[blink]
7562306a36Sopenharmony_ci	add	    r0,r0,r1
7662306a36Sopenharmony_ci#endif /* ENDIAN */
7762306a36Sopenharmony_ci.Learly_end:
7862306a36Sopenharmony_ci	b.d	.Lend
7962306a36Sopenharmony_ci	sub_s.ne r1,r1,r1
8062306a36Sopenharmony_ciEND_CFI(strlen)
81