1 ! Copyright (C) 2013 Imagination Technologies Ltd.
3 ! Licensed under LGPL v2.1 or later, see the file COPYING.LIB in this tarball.
10 .type _strchr, function
14 AND D0Ar2,D0Ar2,#0xff ! Drop all but 8 bits of c
15 MOV D1Ar5, D1Ar1 ! Copy src to D1Ar5
16 AND D1Ar5, D1Ar5, #7 ! Check 64 bit alignment
18 BZ $Laligned64bit ! Jump to 64 bit aligned strchr
20 GETB D0Re0, [D1Ar1++] ! Get the next character
21 ADD D1Ar5, D1Ar5, #1 ! Increment alignment counter
22 CMP D0Re0, D0Ar2 ! Is the char c
23 BZ $Lcharatprevious ! If so exit returning position
24 CMP D0Re0, #0 ! End of string?
25 BZ $Lnotfound ! If so exit
26 CMP D1Ar5, #8 ! Are we aligned 64bit yet?
27 BNZ $Lalign64bit ! If not keep aligning
28 $Laligned64bit: ! src is 64bit aligned
29 MOV D0Ar4, D0Ar2 ! put c into D0Ar4
30 LSL D0Ar4, D0Ar4, #8 ! Shift it up
31 ADD D0Ar4, D0Ar4, D0Ar2 ! another c
32 LSL D0Ar4, D0Ar4, #8 ! shift
33 ADD D0Ar4, D0Ar4, D0Ar2 ! another c
34 LSL D0Ar4, D0Ar4, #8 ! shift
35 ADD D0Ar4, D0Ar4, D0Ar2 ! 4 copies of c
37 GETL D0Re0, D1Re0, [D1Ar1++] ! grab 16 bytes
38 MOV A0.3, D0Re0 ! save for later use
41 MOV D0Ar2, D0Re0 ! D0Ar2 is a scratch now
42 ADDT D0Re0, D0Re0, #HI(0xfefefeff) ! Do 4 1-byte compares
43 ADD D0Re0, D0Re0, #LO(0xfefefeff)
45 AND D0Re0, D0Re0, D0Ar2
46 ANDMT D0Re0, D0Re0, #HI(0x80808080)
47 ANDMB D0Re0, D0Re0, #LO(0x80808080)
49 BNZ $Lnullinword1 ! found \0 (or c if c==\0)
52 MOV D0Re0, A0.3 ! restore the first word
53 XOR D0Re0, D0Re0, D0Ar4
54 MOV D0Ar2, D0Re0 ! DO 4 1-byte compares
55 ADDT D0Re0, D0Re0, #HI(0xfefefeff)
56 ADD D0Re0, D0Re0, #LO(0xfefefeff)
58 AND D0Re0, D0Re0, D0Ar2
59 ANDMT D0Re0, D0Re0, #HI(0x80808080)
60 ANDMB D0Re0, D0Re0, #LO(0x80808080)
62 BNZ $Lcharinword1 ! found c
66 MOV A0.3, D1Re0 ! save for later use
68 ADDT D1Re0, D1Re0, #HI(0xfefefeff) ! Do 4 1-byte compares
69 ADD D1Re0, D1Re0, #LO(0xfefefeff)
71 AND D1Re0, D1Re0, D1Ar3
72 ANDMT D1Re0, D1Re0, #HI(0x80808080)
73 ANDMB D1Re0, D1Re0, #LO(0x80808080)
75 BNZ $Lnullinword2 ! Found \0 (or c if c==\0)
77 MOV D0.4, A0.3 ! restore the second word
78 XOR D1Re0, D0.4, D0Ar4 ! test c
81 ADDT D1Re0, D1Re0, #HI(0xfefefeff) ! Do 4 1-byte compares
82 ADD D1Re0, D1Re0, #LO(0xfefefeff)
84 AND D1Re0, D1Re0, D1Ar3
85 ANDMT D1Re0, D1Re0, #HI(0x80808080)
86 ANDMB D1Re0, D1Re0, #LO(0x80808080)
88 BNZ $Lcharinword2 ! found c
90 B $Lcheck8bytes ! Keep checking
92 $Lnullinword1: ! found \0 somewhere, check for c too
96 AND D0Ar2, D0Ar4, #0xff ! restore c
97 MOV D0Re0, A0.3 ! restore the word
98 MOV D0.4, D0Re0 ! for shifting later
99 AND D0Re0, D0Re0, #0xff ! take first byte of word
101 BZ $Lcharatcurrent ! found c
103 BZ $Lnotfound ! found \0
108 AND D0Re0, D0Re0, #0xff ! take second byte of word
110 BZ $Lcharatcurrent ! found c
112 BZ $Lnotfound ! found \0
117 AND D0Re0, D0Re0, #0xff ! take third byte of word
119 BZ $Lcharatcurrent ! found c
121 BZ $Lnotfound ! found \0
123 ADD D1Ar1, D1Ar1, #1 ! move to 4th byte
124 CMP D0Ar2, #0 ! If c was \0
125 BZ $Lcharatcurrent ! c has been found!
128 MOV D0Re0, #0 ! End of string c not found
131 $Lcharinword1: ! found c in first word
134 $Lcharinword2: ! found c in second word
137 AND D0Re0, D1Re0, #0xff ! First byte
138 CMP D0Re0, #0 ! Test c (zero indicates c due
139 ! to the 4 1-byte compare code)
144 AND D0Re0, D1Re0, #0xff ! Second byte
145 CMP D0Re0, #0 ! Test c (indicated by zero)
150 AND D0Re0, D1Re0, #0xff ! Third byte
151 CMP D0Re0, #0 ! Test c (indicated by zero)
153 ADD D1Ar1, D1Ar1, #1 ! Must be the fourth byte
157 SUB D1Ar1, D1Ar1, #1 ! Fix-up pointer
159 MOV D0Re0, D1Ar1 ! Return the string pointer
162 .size _strchr,.-_strchr
164 libc_hidden_def(strchr)
165 #ifdef __UCLIBC_SUSV3_LEGACY__
166 strong_alias(strchr,index)