Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0-only */
0002 /*
0003  * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com)
0004  */
0005 
0006 /* ARC700 has a relatively long pipeline and branch prediction, so we want
0007    to avoid branches that are hard to predict.  On the other hand, the
0008    presence of the norm instruction makes it easier to operate on whole
0009    words branch-free.  */
0010 
0011 #include <linux/linkage.h>
0012 
0013 ENTRY_CFI(strchr)
0014     extb_s  r1,r1
0015     asl r5,r1,8
0016     bmsk    r2,r0,1
0017     or  r5,r5,r1
0018     mov_s   r3,0x01010101
0019     breq.d  r2,r0,.Laligned
0020     asl r4,r5,16
0021     sub_s   r0,r0,r2
0022     asl r7,r2,3
0023     ld_s    r2,[r0]
0024 #ifdef __LITTLE_ENDIAN__
0025     asl r7,r3,r7
0026 #else
0027     lsr r7,r3,r7
0028 #endif
0029     or  r5,r5,r4
0030     ror r4,r3
0031     sub r12,r2,r7
0032     bic_s   r12,r12,r2
0033     and r12,r12,r4
0034     brne.d  r12,0,.Lfound0_ua
0035     xor r6,r2,r5
0036     ld.a    r2,[r0,4]
0037     sub r12,r6,r7
0038     bic r12,r12,r6
0039 #ifdef __LITTLE_ENDIAN__
0040     and r7,r12,r4
0041     breq    r7,0,.Loop ; For speed, we want this branch to be unaligned.
0042     b   .Lfound_char ; Likewise this one.
0043 #else
0044     and r12,r12,r4
0045     breq    r12,0,.Loop ; For speed, we want this branch to be unaligned.
0046     lsr_s   r12,r12,7
0047     bic     r2,r7,r6
0048     b.d .Lfound_char_b
0049     and_s   r2,r2,r12
0050 #endif
0051 ; /* We require this code address to be unaligned for speed...  */
0052 .Laligned:
0053     ld_s    r2,[r0]
0054     or  r5,r5,r4
0055     ror r4,r3
0056 ; /* ... so that this code address is aligned, for itself and ...  */
0057 .Loop:
0058     sub r12,r2,r3
0059     bic_s   r12,r12,r2
0060     and r12,r12,r4
0061     brne.d  r12,0,.Lfound0
0062     xor r6,r2,r5
0063     ld.a    r2,[r0,4]
0064     sub r12,r6,r3
0065     bic r12,r12,r6
0066     and r7,r12,r4
0067     breq    r7,0,.Loop /* ... so that this branch is unaligned.  */
0068     ; Found searched-for character.  r0 has already advanced to next word.
0069 #ifdef __LITTLE_ENDIAN__
0070 /* We only need the information about the first matching byte
0071    (i.e. the least significant matching byte) to be exact,
0072    hence there is no problem with carry effects.  */
0073 .Lfound_char:
0074     sub r3,r7,1
0075     bic r3,r3,r7
0076     norm    r2,r3
0077     sub_s   r0,r0,1
0078     asr_s   r2,r2,3
0079     j.d [blink]
0080     sub_s   r0,r0,r2
0081 
0082     .balign 4
0083 .Lfound0_ua:
0084     mov r3,r7
0085 .Lfound0:
0086     sub r3,r6,r3
0087     bic r3,r3,r6
0088     and r2,r3,r4
0089     or_s    r12,r12,r2
0090     sub_s   r3,r12,1
0091     bic_s   r3,r3,r12
0092     norm    r3,r3
0093     add_s   r0,r0,3
0094     asr_s   r12,r3,3
0095     asl.f   0,r2,r3
0096     sub_s   r0,r0,r12
0097     j_s.d   [blink]
0098     mov.pl  r0,0
0099 #else /* BIG ENDIAN */
0100 .Lfound_char:
0101     lsr r7,r7,7
0102 
0103     bic r2,r7,r6
0104 .Lfound_char_b:
0105     norm    r2,r2
0106     sub_s   r0,r0,4
0107     asr_s   r2,r2,3
0108     j.d [blink]
0109     add_s   r0,r0,r2
0110 
0111 .Lfound0_ua:
0112     mov_s   r3,r7
0113 .Lfound0:
0114     asl_s   r2,r2,7
0115     or  r7,r6,r4
0116     bic_s   r12,r12,r2
0117     sub r2,r7,r3
0118     or  r2,r2,r6
0119     bic r12,r2,r12
0120     bic.f   r3,r4,r12
0121     norm    r3,r3
0122 
0123     add.pl  r3,r3,1
0124     asr_s   r12,r3,3
0125     asl.f   0,r2,r3
0126     add_s   r0,r0,r12
0127     j_s.d   [blink]
0128     mov.mi  r0,0
0129 #endif /* ENDIAN */
0130 END_CFI(strchr)