xref: /openbmc/linux/arch/arc/lib/strchr-700.S (revision ec7ac6afd07b2d958aab9dfc0a686300b856922a)
15210d1e6SVineet Gupta/*
25210d1e6SVineet Gupta * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com)
35210d1e6SVineet Gupta *
45210d1e6SVineet Gupta * This program is free software; you can redistribute it and/or modify
55210d1e6SVineet Gupta * it under the terms of the GNU General Public License version 2 as
65210d1e6SVineet Gupta * published by the Free Software Foundation.
75210d1e6SVineet Gupta */
85210d1e6SVineet Gupta
95210d1e6SVineet Gupta/* ARC700 has a relatively long pipeline and branch prediction, so we want
105210d1e6SVineet Gupta   to avoid branches that are hard to predict.  On the other hand, the
115210d1e6SVineet Gupta   presence of the norm instruction makes it easier to operate on whole
125210d1e6SVineet Gupta   words branch-free.  */
135210d1e6SVineet Gupta
14*ec7ac6afSVineet Gupta#include <linux/linkage.h>
155210d1e6SVineet Gupta
16*ec7ac6afSVineet GuptaENTRY(strchr)
175210d1e6SVineet Gupta	extb_s	r1,r1
185210d1e6SVineet Gupta	asl	r5,r1,8
195210d1e6SVineet Gupta	bmsk	r2,r0,1
205210d1e6SVineet Gupta	or	r5,r5,r1
215210d1e6SVineet Gupta	mov_s	r3,0x01010101
225210d1e6SVineet Gupta	breq.d	r2,r0,.Laligned
235210d1e6SVineet Gupta	asl	r4,r5,16
245210d1e6SVineet Gupta	sub_s	r0,r0,r2
255210d1e6SVineet Gupta	asl	r7,r2,3
265210d1e6SVineet Gupta	ld_s	r2,[r0]
275210d1e6SVineet Gupta#ifdef __LITTLE_ENDIAN__
285210d1e6SVineet Gupta	asl	r7,r3,r7
295210d1e6SVineet Gupta#else
305210d1e6SVineet Gupta	lsr	r7,r3,r7
315210d1e6SVineet Gupta#endif
325210d1e6SVineet Gupta	or	r5,r5,r4
335210d1e6SVineet Gupta	ror	r4,r3
345210d1e6SVineet Gupta	sub	r12,r2,r7
355210d1e6SVineet Gupta	bic_s	r12,r12,r2
365210d1e6SVineet Gupta	and	r12,r12,r4
375210d1e6SVineet Gupta	brne.d	r12,0,.Lfound0_ua
385210d1e6SVineet Gupta	xor	r6,r2,r5
395210d1e6SVineet Gupta	ld.a	r2,[r0,4]
405210d1e6SVineet Gupta	sub	r12,r6,r7
415210d1e6SVineet Gupta	bic	r12,r12,r6
42b0f55f2aSJoern Rennecke#ifdef __LITTLE_ENDIAN__
435210d1e6SVineet Gupta	and	r7,r12,r4
445210d1e6SVineet Gupta	breq	r7,0,.Loop ; For speed, we want this branch to be unaligned.
455210d1e6SVineet Gupta	b	.Lfound_char ; Likewise this one.
46b0f55f2aSJoern Rennecke#else
47b0f55f2aSJoern Rennecke	and	r12,r12,r4
48b0f55f2aSJoern Rennecke	breq	r12,0,.Loop ; For speed, we want this branch to be unaligned.
49b0f55f2aSJoern Rennecke	lsr_s	r12,r12,7
50b0f55f2aSJoern Rennecke	bic 	r2,r7,r6
51b0f55f2aSJoern Rennecke	b.d	.Lfound_char_b
52b0f55f2aSJoern Rennecke	and_s	r2,r2,r12
53b0f55f2aSJoern Rennecke#endif
545210d1e6SVineet Gupta; /* We require this code address to be unaligned for speed...  */
555210d1e6SVineet Gupta.Laligned:
565210d1e6SVineet Gupta	ld_s	r2,[r0]
575210d1e6SVineet Gupta	or	r5,r5,r4
585210d1e6SVineet Gupta	ror	r4,r3
595210d1e6SVineet Gupta; /* ... so that this code address is aligned, for itself and ...  */
605210d1e6SVineet Gupta.Loop:
615210d1e6SVineet Gupta	sub	r12,r2,r3
625210d1e6SVineet Gupta	bic_s	r12,r12,r2
635210d1e6SVineet Gupta	and	r12,r12,r4
645210d1e6SVineet Gupta	brne.d	r12,0,.Lfound0
655210d1e6SVineet Gupta	xor	r6,r2,r5
665210d1e6SVineet Gupta	ld.a	r2,[r0,4]
675210d1e6SVineet Gupta	sub	r12,r6,r3
685210d1e6SVineet Gupta	bic	r12,r12,r6
695210d1e6SVineet Gupta	and	r7,r12,r4
705210d1e6SVineet Gupta	breq	r7,0,.Loop /* ... so that this branch is unaligned.  */
715210d1e6SVineet Gupta	; Found searched-for character.  r0 has already advanced to next word.
725210d1e6SVineet Gupta#ifdef __LITTLE_ENDIAN__
735210d1e6SVineet Gupta/* We only need the information about the first matching byte
745210d1e6SVineet Gupta   (i.e. the least significant matching byte) to be exact,
755210d1e6SVineet Gupta   hence there is no problem with carry effects.  */
765210d1e6SVineet Gupta.Lfound_char:
775210d1e6SVineet Gupta	sub	r3,r7,1
785210d1e6SVineet Gupta	bic	r3,r3,r7
795210d1e6SVineet Gupta	norm	r2,r3
805210d1e6SVineet Gupta	sub_s	r0,r0,1
815210d1e6SVineet Gupta	asr_s	r2,r2,3
825210d1e6SVineet Gupta	j.d	[blink]
835210d1e6SVineet Gupta	sub_s	r0,r0,r2
845210d1e6SVineet Gupta
855210d1e6SVineet Gupta	.balign	4
865210d1e6SVineet Gupta.Lfound0_ua:
875210d1e6SVineet Gupta	mov	r3,r7
885210d1e6SVineet Gupta.Lfound0:
895210d1e6SVineet Gupta	sub	r3,r6,r3
905210d1e6SVineet Gupta	bic	r3,r3,r6
915210d1e6SVineet Gupta	and	r2,r3,r4
925210d1e6SVineet Gupta	or_s	r12,r12,r2
935210d1e6SVineet Gupta	sub_s	r3,r12,1
945210d1e6SVineet Gupta	bic_s	r3,r3,r12
955210d1e6SVineet Gupta	norm	r3,r3
965210d1e6SVineet Gupta	add_s	r0,r0,3
975210d1e6SVineet Gupta	asr_s	r12,r3,3
985210d1e6SVineet Gupta	asl.f	0,r2,r3
995210d1e6SVineet Gupta	sub_s	r0,r0,r12
1005210d1e6SVineet Gupta	j_s.d	[blink]
1015210d1e6SVineet Gupta	mov.pl	r0,0
1025210d1e6SVineet Gupta#else /* BIG ENDIAN */
1035210d1e6SVineet Gupta.Lfound_char:
1045210d1e6SVineet Gupta	lsr	r7,r7,7
1055210d1e6SVineet Gupta
1065210d1e6SVineet Gupta	bic	r2,r7,r6
107b0f55f2aSJoern Rennecke.Lfound_char_b:
1085210d1e6SVineet Gupta	norm	r2,r2
1095210d1e6SVineet Gupta	sub_s	r0,r0,4
1105210d1e6SVineet Gupta	asr_s	r2,r2,3
1115210d1e6SVineet Gupta	j.d	[blink]
1125210d1e6SVineet Gupta	add_s	r0,r0,r2
1135210d1e6SVineet Gupta
1145210d1e6SVineet Gupta.Lfound0_ua:
1155210d1e6SVineet Gupta	mov_s	r3,r7
1165210d1e6SVineet Gupta.Lfound0:
1175210d1e6SVineet Gupta	asl_s	r2,r2,7
1185210d1e6SVineet Gupta	or	r7,r6,r4
1195210d1e6SVineet Gupta	bic_s	r12,r12,r2
1205210d1e6SVineet Gupta	sub	r2,r7,r3
1215210d1e6SVineet Gupta	or	r2,r2,r6
1225210d1e6SVineet Gupta	bic	r12,r2,r12
1235210d1e6SVineet Gupta	bic.f	r3,r4,r12
1245210d1e6SVineet Gupta	norm	r3,r3
1255210d1e6SVineet Gupta
1265210d1e6SVineet Gupta	add.pl	r3,r3,1
1275210d1e6SVineet Gupta	asr_s	r12,r3,3
1285210d1e6SVineet Gupta	asl.f	0,r2,r3
1295210d1e6SVineet Gupta	add_s	r0,r0,r12
1305210d1e6SVineet Gupta	j_s.d	[blink]
1315210d1e6SVineet Gupta	mov.mi	r0,0
1325210d1e6SVineet Gupta#endif /* ENDIAN */
133*ec7ac6afSVineet GuptaEND(strchr)
134