]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/l4re-core/uclibc/lib/contrib/uclibc/libc/string/metag/strchr.S
Update
[l4.git] / l4 / pkg / l4re-core / uclibc / lib / contrib / uclibc / libc / string / metag / strchr.S
1 !    Copyright (C) 2013 Imagination Technologies Ltd.
2
3 !    Licensed under LGPL v2.1 or later, see the file COPYING.LIB in this tarball.
4
5
6 #include <features.h>
7
8         .text
9         .global _strchr
10         .type   _strchr, function
11 ! D1Ar1 src
12 ! D0Ar2 c
13 _strchr:
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
17         CMP     D1Ar5, #0
18         BZ      $Laligned64bit                              ! Jump to 64 bit aligned strchr
19 $Lalign64bit:
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
36 $Lcheck8bytes:
37         GETL    D0Re0, D1Re0, [D1Ar1++]                     ! grab 16 bytes
38         MOV     A0.3, D0Re0                                 ! save for later use
39                                                             ! first word
40                                                             ! check for \0
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)
44         XOR     D0Ar2, D0Ar2, #-1
45         AND     D0Re0, D0Re0, D0Ar2
46         ANDMT   D0Re0, D0Re0, #HI(0x80808080)
47         ANDMB   D0Re0, D0Re0, #LO(0x80808080)
48         CMP     D0Re0, #0
49         BNZ     $Lnullinword1                               ! found \0 (or c if c==\0)
50
51                                                             ! Check for c
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)
57         XOR     D0Ar2, D0Ar2, #-1
58         AND     D0Re0, D0Re0, D0Ar2
59         ANDMT   D0Re0, D0Re0, #HI(0x80808080)
60         ANDMB   D0Re0, D0Re0, #LO(0x80808080)
61         CMP     D0Re0, #0
62         BNZ     $Lcharinword1                               ! found c
63
64                                                             ! second word
65                                                             ! check for \0
66         MOV     A0.3, D1Re0                                 ! save for later use
67         MOV     D1Ar3, D1Re0
68         ADDT    D1Re0, D1Re0, #HI(0xfefefeff)               ! Do 4 1-byte compares
69         ADD     D1Re0, D1Re0, #LO(0xfefefeff)
70         XOR     D1Ar3, D1Ar3, #-1
71         AND     D1Re0, D1Re0, D1Ar3
72         ANDMT   D1Re0, D1Re0, #HI(0x80808080)
73         ANDMB   D1Re0, D1Re0, #LO(0x80808080)
74         CMP     D1Re0, #0
75         BNZ     $Lnullinword2                               ! Found \0 (or c if c==\0)
76
77         MOV     D0.4, A0.3                                  ! restore the second word
78         XOR     D1Re0, D0.4, D0Ar4                          ! test c
79
80         MOV     D1Ar3, D1Re0
81         ADDT    D1Re0, D1Re0, #HI(0xfefefeff)               ! Do 4 1-byte compares
82         ADD     D1Re0, D1Re0, #LO(0xfefefeff)
83         XOR     D1Ar3, D1Ar3, #-1
84         AND     D1Re0, D1Re0, D1Ar3
85         ANDMT   D1Re0, D1Re0, #HI(0x80808080)
86         ANDMB   D1Re0, D1Re0, #LO(0x80808080)
87         CMP     D1Re0, #0
88         BNZ     $Lcharinword2                               ! found c
89
90         B       $Lcheck8bytes                               ! Keep checking
91
92 $Lnullinword1:                                              ! found \0 somewhere, check for c too
93         SUB     D1Ar1, D1Ar1, #4
94 $Lnullinword2:
95         SUB     D1Ar1, D1Ar1, #4
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
100         CMP     D0Re0, D0Ar2
101         BZ      $Lcharatcurrent                             ! found c
102         CMP     D0Re0, #0!
103         BZ      $Lnotfound                                  ! found \0
104
105         ADD     D1Ar1, D1Ar1, #1
106         LSR     D0.4, D0.4, #8
107         MOV     D0Re0, D0.4
108         AND     D0Re0, D0Re0, #0xff                         ! take second byte of word
109         CMP     D0Re0, D0Ar2
110         BZ      $Lcharatcurrent                             ! found c
111         CMP     D0Re0, #0
112         BZ      $Lnotfound                                  ! found \0
113
114         ADD     D1Ar1, D1Ar1, #1
115         LSR     D0.4, D0.4, #8
116         MOV     D0Re0, D0.4
117         AND     D0Re0, D0Re0, #0xff                         ! take third byte of word
118         CMP     D0Re0, D0Ar2
119         BZ      $Lcharatcurrent                             ! found c
120         CMP     D0Re0, #0
121         BZ      $Lnotfound                                  ! found \0
122
123         ADD     D1Ar1, D1Ar1, #1                            ! move to 4th byte
124         CMP     D0Ar2, #0                                   ! If c was \0
125         BZ      $Lcharatcurrent                             ! c has been found!
126
127 $Lnotfound:
128         MOV     D0Re0,          #0                          ! End of string c not found
129         B       $Lend
130
131 $Lcharinword1:                                              ! found c in first word
132         MOV     D1Re0, D0Re0
133         SUB     D1Ar1, D1Ar1, #4
134 $Lcharinword2:                                              ! found c in second word
135         SUB     D1Ar1, D1Ar1, #4
136
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)
140         BNE     $Lcharatcurrent
141         ADD     D1Ar1, D1Ar1, #1
142
143         LSR     D1Re0, D1Re0, #8
144         AND     D0Re0, D1Re0, #0xff                         ! Second byte
145         CMP     D0Re0, #0                                   ! Test c (indicated by zero)
146         BNE     $Lcharatcurrent
147         ADD     D1Ar1, D1Ar1, #1
148
149         LSR     D1Re0, D1Re0, #8
150         AND     D0Re0, D1Re0, #0xff                         ! Third byte
151         CMP     D0Re0, #0                                   ! Test c (indicated by zero)
152         BNE     $Lcharatcurrent
153         ADD     D1Ar1, D1Ar1, #1                            ! Must be the fourth byte
154         B       $Lcharatcurrent
155
156 $Lcharatprevious:
157         SUB     D1Ar1, D1Ar1, #1                            ! Fix-up pointer
158 $Lcharatcurrent:
159         MOV     D0Re0, D1Ar1                                ! Return the string pointer
160 $Lend:
161         MOV     PC, D1RtP
162         .size _strchr,.-_strchr
163
164 libc_hidden_def(strchr)
165 #ifdef __UCLIBC_SUSV3_LEGACY__
166 strong_alias(strchr,index)
167 #endif