| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167 | !    Copyright (C) 2013 Imagination Technologies Ltd.!    Licensed under LGPL v2.1 or later, see the file COPYING.LIB in this tarball.#include <features.h>	.text	.global	_strchr	.type	_strchr, function! D1Ar1 src! D0Ar2 c_strchr:	AND     D0Ar2,D0Ar2,#0xff                           ! Drop all but 8 bits of c	MOV 	D1Ar5, D1Ar1                                ! Copy src to D1Ar5	AND 	D1Ar5, D1Ar5, #7                            ! Check 64 bit alignment	CMP 	D1Ar5, #0	BZ 	$Laligned64bit                              ! Jump to 64 bit aligned strchr$Lalign64bit:	GETB 	D0Re0, [D1Ar1++]                            ! Get the next character	ADD 	D1Ar5, D1Ar5, #1                            ! Increment alignment counter	CMP 	D0Re0, D0Ar2                                ! Is the char c	BZ 	$Lcharatprevious                            ! If so exit returning position	CMP 	D0Re0, #0                                   ! End of string?	BZ 	$Lnotfound                                  ! If so exit	CMP 	D1Ar5, #8                                   ! Are we aligned 64bit yet?	BNZ 	$Lalign64bit                                ! If not keep aligning$Laligned64bit:                                             ! src is 64bit aligned	MOV 	D0Ar4, D0Ar2                                ! put c into D0Ar4	LSL 	D0Ar4, D0Ar4, #8                            ! Shift it up	ADD 	D0Ar4, D0Ar4, D0Ar2                         ! another c	LSL 	D0Ar4, D0Ar4, #8                            ! shift	ADD 	D0Ar4, D0Ar4, D0Ar2                         ! another c	LSL 	D0Ar4, D0Ar4, #8                            ! shift	ADD 	D0Ar4, D0Ar4, D0Ar2                         ! 4 copies of c$Lcheck8bytes:	GETL 	D0Re0, D1Re0, [D1Ar1++]                     ! grab 16 bytes	MOV 	A0.3, D0Re0                                 ! save for later use							    ! first word							    ! check for \0	MOV 	D0Ar2, D0Re0                                ! D0Ar2 is a scratch now	ADDT 	D0Re0, D0Re0, #HI(0xfefefeff)               ! Do 4 1-byte compares	ADD 	D0Re0, D0Re0, #LO(0xfefefeff)	XOR 	D0Ar2, D0Ar2, #-1	AND 	D0Re0, D0Re0, D0Ar2	ANDMT 	D0Re0, D0Re0, #HI(0x80808080)	ANDMB 	D0Re0, D0Re0, #LO(0x80808080)	CMP 	D0Re0, #0	BNZ 	$Lnullinword1                               ! found \0 (or c if c==\0)							    ! Check for c	MOV 	D0Re0, A0.3                                 ! restore the first word	XOR 	D0Re0, D0Re0, D0Ar4	MOV 	D0Ar2, D0Re0                                ! DO 4 1-byte compares	ADDT 	D0Re0, D0Re0, #HI(0xfefefeff)	ADD 	D0Re0, D0Re0, #LO(0xfefefeff)	XOR 	D0Ar2, D0Ar2, #-1	AND 	D0Re0, D0Re0, D0Ar2	ANDMT 	D0Re0, D0Re0, #HI(0x80808080)	ANDMB 	D0Re0, D0Re0, #LO(0x80808080)	CMP 	D0Re0, #0	BNZ 	$Lcharinword1                               ! found c							    ! second word							    ! check for \0	MOV 	A0.3, D1Re0                                 ! save for later use	MOV 	D1Ar3, D1Re0	ADDT 	D1Re0, D1Re0, #HI(0xfefefeff)               ! Do 4 1-byte compares	ADD 	D1Re0, D1Re0, #LO(0xfefefeff)	XOR 	D1Ar3, D1Ar3, #-1	AND 	D1Re0, D1Re0, D1Ar3	ANDMT 	D1Re0, D1Re0, #HI(0x80808080)	ANDMB 	D1Re0, D1Re0, #LO(0x80808080)	CMP 	D1Re0, #0	BNZ 	$Lnullinword2                               ! Found \0 (or c if c==\0)	MOV 	D0.4, A0.3                                  ! restore the second word	XOR 	D1Re0, D0.4, D0Ar4                          ! test c	MOV 	D1Ar3, D1Re0	ADDT 	D1Re0, D1Re0, #HI(0xfefefeff)               ! Do 4 1-byte compares	ADD 	D1Re0, D1Re0, #LO(0xfefefeff)	XOR 	D1Ar3, D1Ar3, #-1	AND 	D1Re0, D1Re0, D1Ar3	ANDMT 	D1Re0, D1Re0, #HI(0x80808080)	ANDMB 	D1Re0, D1Re0, #LO(0x80808080)	CMP 	D1Re0, #0	BNZ 	$Lcharinword2                               ! found c	B 	$Lcheck8bytes                               ! Keep checking$Lnullinword1:                                              ! found \0 somewhere, check for c too	SUB 	D1Ar1, D1Ar1, #4$Lnullinword2:	SUB 	D1Ar1, D1Ar1, #4	AND 	D0Ar2, D0Ar4, #0xff                         ! restore c	MOV 	D0Re0, A0.3                                 ! restore the word	MOV 	D0.4, D0Re0                                 ! for shifting later	AND 	D0Re0, D0Re0, #0xff                         ! take first byte of word	CMP 	D0Re0, D0Ar2	BZ 	$Lcharatcurrent                             ! found c	CMP 	D0Re0, #0!	BZ 	$Lnotfound                                  ! found \0	ADD 	D1Ar1, D1Ar1, #1	LSR 	D0.4, D0.4, #8	MOV 	D0Re0, D0.4	AND 	D0Re0, D0Re0, #0xff                         ! take second byte of word	CMP 	D0Re0, D0Ar2	BZ 	$Lcharatcurrent                             ! found c	CMP 	D0Re0, #0	BZ 	$Lnotfound                                  ! found \0	ADD 	D1Ar1, D1Ar1, #1	LSR 	D0.4, D0.4, #8	MOV 	D0Re0, D0.4	AND 	D0Re0, D0Re0, #0xff                         ! take third byte of word	CMP 	D0Re0, D0Ar2	BZ 	$Lcharatcurrent                             ! found c	CMP 	D0Re0, #0	BZ 	$Lnotfound                                  ! found \0	ADD 	D1Ar1, D1Ar1, #1                            ! move to 4th byte	CMP     D0Ar2, #0                                   ! If c was \0	BZ      $Lcharatcurrent                             ! c has been found!$Lnotfound:	MOV 	D0Re0,		#0                          ! End of string c not found	B 	$Lend$Lcharinword1: 						    ! found c in first word	MOV 	D1Re0, D0Re0	SUB 	D1Ar1, D1Ar1, #4$Lcharinword2:                                              ! found c in second word	SUB 	D1Ar1, D1Ar1, #4	AND 	D0Re0, D1Re0, #0xff                         ! First byte	CMP 	D0Re0, #0                                   ! Test c (zero indicates c due							    ! to the 4 1-byte compare code)	BNE 	$Lcharatcurrent	ADD 	D1Ar1, D1Ar1, #1	LSR 	D1Re0, D1Re0, #8	AND 	D0Re0, D1Re0, #0xff                         ! Second byte	CMP 	D0Re0, #0                                   ! Test c (indicated by zero)	BNE 	$Lcharatcurrent	ADD 	D1Ar1, D1Ar1, #1	LSR 	D1Re0, D1Re0, #8	AND 	D0Re0, D1Re0, #0xff                         ! Third byte	CMP 	D0Re0, #0                                   ! Test c (indicated by zero)	BNE 	$Lcharatcurrent	ADD 	D1Ar1, D1Ar1, #1                            ! Must be the fourth byte	B 	$Lcharatcurrent$Lcharatprevious:	SUB 	D1Ar1, D1Ar1, #1                            ! Fix-up pointer$Lcharatcurrent:	MOV 	D0Re0, D1Ar1                                ! Return the string pointer$Lend:	MOV 	PC, D1RtP	.size _strchr,.-_strchrlibc_hidden_def(strchr)#ifdef __UCLIBC_SUSV3_LEGACY__strong_alias(strchr,index)#endif
 |