Cygwin: access: Fix X_OK behaviour for backup operators and admins
[newlib-cygwin.git] / newlib / libc / machine / arc / memcmp-bs-norm.S
blobb136fdc3355c633c5207295eeced7fe458dcd401
1 /*
2    Copyright (c) 2015-2024, Synopsys, Inc. All rights reserved.
4    Redistribution and use in source and binary forms, with or without
5    modification, are permitted provided that the following conditions are met:
7    1) Redistributions of source code must retain the above copyright notice,
8    this list of conditions and the following disclaimer.
10    2) Redistributions in binary form must reproduce the above copyright notice,
11    this list of conditions and the following disclaimer in the documentation
12    and/or other materials provided with the distribution.
14    3) Neither the name of the Synopsys, Inc., nor the names of its contributors
15    may be used to endorse or promote products derived from this software
16    without specific prior written permission.
18    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21    ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
22    LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23    CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24    SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25    INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26    CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27    ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28    POSSIBILITY OF SUCH DAMAGE.
31 /* This implementation is optimized for performance.  For code size a generic
32    implementation of this function from newlib/libc/string/memcmp.c will be
33    used.  */
34 #if !defined (__OPTIMIZE_SIZE__) && !defined (PREFER_SIZE_OVER_SPEED) \
35     && !defined (__ARC_RF16__)
37 #include "asm.h"
39 #if !defined (__ARC601__) && defined (__ARC_NORM__) \
40     && defined (__ARC_BARREL_SHIFTER__)
42 #ifdef __LITTLE_ENDIAN__
43 #define WORD2 r2
44 #define SHIFT r3
45 #else /* BIG ENDIAN */
46 #define WORD2 r3
47 #define SHIFT r2
48 #endif
50 ENTRY (memcmp)
51         or      r12,r0,r1
52         asl_s   r12,r12,30
53 #if defined (__ARC700__) || defined (__ARCEM__) || defined (__ARCHS__)
54         sub_l   r3,r2,1
55         brls    r2,r12,.Lbytewise
56 #else
57         brls.d  r2,r12,.Lbytewise
58         sub_s   r3,r2,1
59 #endif
60         ld      r4,[r0,0]
61         ld      r5,[r1,0]
62         lsr.f   lp_count,r3,3
63 #ifdef __ARCEM__
64         /* A branch can't be the last instruction in a zero overhead loop.
65            So we move the branch to the start of the loop, duplicate it
66            after the end, and set up r12 so that the branch isn't taken
67            initially.  */
68         mov_s   r12,WORD2
69         lpne    .Loop_end
70         brne    WORD2,r12,.Lodd
71         ld      WORD2,[r0,4]
72 #else
73         lpne    .Loop_end
74         ld_s    WORD2,[r0,4]
75 #endif
76         ld_s    r12,[r1,4]
77         brne    r4,r5,.Leven
78         ld.a    r4,[r0,8]
79         ld.a    r5,[r1,8]
80 #ifdef __ARCEM__
81 .Loop_end:
82         brne    WORD2,r12,.Lodd
83 #else
84         brne    WORD2,r12,.Lodd
85 #ifdef __ARCHS__
86         nop
87 #endif
88 .Loop_end:
89 #endif
90         asl_s   SHIFT,SHIFT,3
91         bcc_s   .Last_cmp
92         brne    r4,r5,.Leven
93         ld      r4,[r0,4]
94         ld      r5,[r1,4]
95 #ifdef __LITTLE_ENDIAN__
96 #if defined (__ARC700__) || defined (__ARCEM__) || defined (__ARCHS__)
97         nop_s
98         ; one more load latency cycle
99 .Last_cmp:
100         xor     r0,r4,r5
101         bset    r0,r0,SHIFT
102         sub_s   r1,r0,1
103         bic_s   r1,r1,r0
104         norm    r1,r1
105         b.d     .Leven_cmp
106         and     r1,r1,24
107 .Leven:
108         xor     r0,r4,r5
109         sub_s   r1,r0,1
110         bic_s   r1,r1,r0
111         norm    r1,r1
112         ; slow track insn
113         and     r1,r1,24
114 .Leven_cmp:
115         asl     r2,r4,r1
116         asl     r12,r5,r1
117         lsr_s   r2,r2,1
118         lsr_s   r12,r12,1
119         j_s.d   [blink]
120         sub     r0,r2,r12
121         .balign 4
122 .Lodd:
123         xor     r0,WORD2,r12
124         sub_s   r1,r0,1
125         bic_s   r1,r1,r0
126         norm    r1,r1
127         ; slow track insn
128         and     r1,r1,24
129         asl_s   r2,r2,r1
130         asl_s   r12,r12,r1
131         lsr_s   r2,r2,1
132         lsr_s   r12,r12,1
133         j_s.d   [blink]
134         sub     r0,r2,r12
135 #else /* !__ARC700__ */
136         .balign 4
137 .Last_cmp:
138         xor     r0,r4,r5
139         b.d     .Leven_cmp
140         bset    r0,r0,SHIFT
141 .Lodd:
142         mov_s   r4,WORD2
143         mov_s   r5,r12
144 .Leven:
145         xor     r0,r4,r5
146 .Leven_cmp:
147         mov_s   r1,0x80808080
148         ; uses long immediate
149         sub_s   r12,r0,1
150         bic_s   r0,r0,r12
151         sub     r0,r1,r0
152         xor_s   r0,r0,r1
153         and     r1,r5,r0
154         and     r0,r4,r0
155         xor.f   0,r0,r1
156         sub_s   r0,r0,r1
157         j_s.d   [blink]
158         mov.mi  r0,r1
159 #endif /* !__ARC700__ */
160 #else /* BIG ENDIAN */
161 .Last_cmp:
162         neg_s   SHIFT,SHIFT
163         lsr     r4,r4,SHIFT
164         lsr     r5,r5,SHIFT
165         ; slow track insn
166 .Leven:
167         sub.f   r0,r4,r5
168         mov.ne  r0,1
169         j_s.d   [blink]
170         bset.cs r0,r0,31
171 .Lodd:
172         cmp_s   WORD2,r12
173 #if defined (__ARC700__) || defined (__ARCEM__) || defined (__ARCHS__)
174         mov_s   r0,1
175         j_s.d   [blink]
176         bset.cs r0,r0,31
177 #else
178         j_s.d   [blink]
179         rrc     r0,2
180 #endif /* __ARC700__ || __ARCEM__ || __ARCHS__ */
181 #endif /* ENDIAN */
182         .balign 4
183 .Lbytewise:
184         breq    r2,0,.Lnil
185         ldb     r4,[r0,0]
186         ldb     r5,[r1,0]
187         lsr.f   lp_count,r3
188 #ifdef __ARCEM__
189         mov     r12,r3
190         lpne    .Lbyte_end
191         brne    r3,r12,.Lbyte_odd
192 #else
193         lpne    .Lbyte_end
194 #endif
195         ldb_s   r3,[r0,1]
196         ldb_l   r12,[r1,1]
197         brne    r4,r5,.Lbyte_even
198         ldb.a   r4,[r0,2]
199         ldb.a   r5,[r1,2]
200 #ifdef __ARCEM__
201 .Lbyte_end:
202         brne    r3,r12,.Lbyte_odd
203 #else
204         brne    r3,r12,.Lbyte_odd
205 #ifdef __ARCHS__
206         nop
207 #endif
208 .Lbyte_end:
209 #endif
210         bcc_l   .Lbyte_even
211         brne    r4,r5,.Lbyte_even
212         ldb_s   r3,[r0,1]
213         ldb_s   r12,[r1,1]
214 .Lbyte_odd:
215         j_s.d   [blink]
216         sub     r0,r3,r12
217 .Lbyte_even:
218         j_s.d   [blink]
219         sub     r0,r4,r5
220 .Lnil:
221         j_s.d   [blink]
222         mov_l   r0,0
223 ENDFUNC (memcmp)
224 #endif /* !__ARC601__ && __ARC_NORM__ && __ARC_BARREL_SHIFTER__ */
226 #endif /* !__OPTIMIZE_SIZE__ && !PREFER_SIZE_OVER_SPEED */