1 | /* strcmp with SSE4.2 |
2 | Copyright (C) 2010-2024 Free Software Foundation, Inc. |
3 | This file is part of the GNU C Library. |
4 | |
5 | The GNU C Library is free software; you can redistribute it and/or |
6 | modify it under the terms of the GNU Lesser General Public |
7 | License as published by the Free Software Foundation; either |
8 | version 2.1 of the License, or (at your option) any later version. |
9 | |
10 | The GNU C Library is distributed in the hope that it will be useful, |
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
13 | Lesser General Public License for more details. |
14 | |
15 | You should have received a copy of the GNU Lesser General Public |
16 | License along with the GNU C Library; if not, see |
17 | <https://www.gnu.org/licenses/>. */ |
18 | |
19 | #if IS_IN (libc) |
20 | |
21 | #include <sysdep.h> |
22 | #include "asm-syntax.h" |
23 | |
24 | #define CFI_PUSH(REG) \ |
25 | cfi_adjust_cfa_offset (4); \ |
26 | cfi_rel_offset (REG, 0) |
27 | |
28 | #define CFI_POP(REG) \ |
29 | cfi_adjust_cfa_offset (-4); \ |
30 | cfi_restore (REG) |
31 | |
32 | #define PUSH(REG) pushl REG; CFI_PUSH (REG) |
33 | #define POP(REG) popl REG; CFI_POP (REG) |
34 | |
35 | #ifdef USE_AS_STRNCMP |
36 | # ifndef STRCMP |
37 | # define STRCMP __strncmp_sse4_2 |
38 | # endif |
39 | # define STR1 8 |
40 | # define STR2 STR1+4 |
41 | # define CNT STR2+4 |
42 | # define RETURN POP (REM); ret; .p2align 4; CFI_PUSH (REM) |
43 | # define REM %ebp |
44 | #elif defined USE_AS_STRCASECMP_L |
45 | # include "locale-defines.h" |
46 | # ifndef STRCMP |
47 | # define STRCMP __strcasecmp_l_sse4_2 |
48 | # endif |
49 | # ifdef PIC |
50 | # define STR1 12 |
51 | # else |
52 | # define STR1 8 |
53 | # endif |
54 | # define STR2 STR1+4 |
55 | # define LOCALE 12 /* Loaded before the adjustment. */ |
56 | # ifdef PIC |
57 | # define RETURN POP (%edi); POP (%ebx); ret; \ |
58 | .p2align 4; CFI_PUSH (%ebx); CFI_PUSH (%edi) |
59 | # else |
60 | # define RETURN POP (%edi); ret; .p2align 4; CFI_PUSH (%edi) |
61 | # endif |
62 | # define NONASCII __strcasecmp_nonascii |
63 | #elif defined USE_AS_STRNCASECMP_L |
64 | # include "locale-defines.h" |
65 | # ifndef STRCMP |
66 | # define STRCMP __strncasecmp_l_sse4_2 |
67 | # endif |
68 | # ifdef PIC |
69 | # define STR1 16 |
70 | # else |
71 | # define STR1 12 |
72 | # endif |
73 | # define STR2 STR1+4 |
74 | # define CNT STR2+4 |
75 | # define LOCALE 16 /* Loaded before the adjustment. */ |
76 | # ifdef PIC |
77 | # define RETURN POP (%edi); POP (REM); POP (%ebx); ret; \ |
78 | .p2align 4; \ |
79 | CFI_PUSH (%ebx); CFI_PUSH (REM); CFI_PUSH (%edi) |
80 | # else |
81 | # define RETURN POP (%edi); POP (REM); ret; \ |
82 | .p2align 4; CFI_PUSH (REM); CFI_PUSH (%edi) |
83 | # endif |
84 | # define REM %ebp |
85 | # define NONASCII __strncasecmp_nonascii |
86 | #else |
87 | # ifndef STRCMP |
88 | # define STRCMP __strcmp_sse4_2 |
89 | # endif |
90 | # define STR1 4 |
91 | # define STR2 STR1+4 |
92 | # define RETURN ret; .p2align 4 |
93 | #endif |
94 | |
95 | .section .text.sse4.2,"ax" ,@progbits |
96 | |
97 | #ifdef USE_AS_STRCASECMP_L |
98 | ENTRY (__strcasecmp_sse4_2) |
99 | # ifdef PIC |
100 | PUSH (%ebx) |
101 | LOAD_PIC_REG(bx) |
102 | movl __libc_tsd_LOCALE@GOTNTPOFF(%ebx), %eax |
103 | movl %gs:(%eax), %eax |
104 | # else |
105 | movl %gs:__libc_tsd_LOCALE@NTPOFF, %eax |
106 | # endif |
107 | # if LOCALE_T___LOCALES != 0 || LC_CTYPE != 0 |
108 | movl LOCALE_T___LOCALES+LC_CTYPE*4(%eax), %eax |
109 | # else |
110 | movl (%eax), %eax |
111 | # endif |
112 | testl $1, LOCALE_DATA_VALUES+_NL_CTYPE_NONASCII_CASE*SIZEOF_VALUES(%eax) |
113 | # ifdef PIC |
114 | je L(ascii) |
115 | POP (%ebx) |
116 | jmp __strcasecmp_nonascii |
117 | # else |
118 | jne __strcasecmp_nonascii |
119 | jmp L(ascii) |
120 | # endif |
121 | END (__strcasecmp_sse4_2) |
122 | #endif |
123 | |
124 | #ifdef USE_AS_STRNCASECMP_L |
125 | ENTRY (__strncasecmp_sse4_2) |
126 | # ifdef PIC |
127 | PUSH (%ebx) |
128 | LOAD_PIC_REG(bx) |
129 | movl __libc_tsd_LOCALE@GOTNTPOFF(%ebx), %eax |
130 | movl %gs:(%eax), %eax |
131 | # else |
132 | movl %gs:__libc_tsd_LOCALE@NTPOFF, %eax |
133 | # endif |
134 | # if LOCALE_T___LOCALES != 0 || LC_CTYPE != 0 |
135 | movl LOCALE_T___LOCALES+LC_CTYPE*4(%eax), %eax |
136 | # else |
137 | movl (%eax), %eax |
138 | # endif |
139 | testl $1, LOCALE_DATA_VALUES+_NL_CTYPE_NONASCII_CASE*SIZEOF_VALUES(%eax) |
140 | # ifdef PIC |
141 | je L(ascii) |
142 | POP (%ebx) |
143 | jmp __strncasecmp_nonascii |
144 | # else |
145 | jne __strncasecmp_nonascii |
146 | jmp L(ascii) |
147 | # endif |
148 | END (__strncasecmp_sse4_2) |
149 | #endif |
150 | |
151 | ENTRY (STRCMP) |
152 | #if defined USE_AS_STRCASECMP_L || defined USE_AS_STRNCASECMP_L |
153 | movl LOCALE(%esp), %eax |
154 | # if LOCALE_T___LOCALES != 0 || LC_CTYPE != 0 |
155 | movl LOCALE_T___LOCALES+LC_CTYPE*4(%eax), %eax |
156 | # else |
157 | movl (%eax), %eax |
158 | # endif |
159 | testl $1, LOCALE_DATA_VALUES+_NL_CTYPE_NONASCII_CASE*SIZEOF_VALUES(%eax) |
160 | jne NONASCII |
161 | |
162 | # ifdef PIC |
163 | PUSH (%ebx) |
164 | LOAD_PIC_REG(bx) |
165 | # endif |
166 | L(ascii): |
167 | .section .rodata.cst16,"aM" ,@progbits,16 |
168 | .align 16 |
169 | .Lbelowupper: |
170 | .quad 0x4040404040404040 |
171 | .quad 0x4040404040404040 |
172 | .Ltopupper: |
173 | .quad 0x5b5b5b5b5b5b5b5b |
174 | .quad 0x5b5b5b5b5b5b5b5b |
175 | .Ltouppermask: |
176 | .quad 0x2020202020202020 |
177 | .quad 0x2020202020202020 |
178 | .previous |
179 | |
180 | # ifdef PIC |
181 | # define UCLOW_reg .Lbelowupper@GOTOFF(%ebx) |
182 | # define UCHIGH_reg .Ltopupper@GOTOFF(%ebx) |
183 | # define LCQWORD_reg .Ltouppermask@GOTOFF(%ebx) |
184 | # else |
185 | # define UCLOW_reg .Lbelowupper |
186 | # define UCHIGH_reg .Ltopupper |
187 | # define LCQWORD_reg .Ltouppermask |
188 | # endif |
189 | #endif |
190 | |
191 | #if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L |
192 | PUSH (REM) |
193 | #endif |
194 | #if defined USE_AS_STRCASECMP_L || defined USE_AS_STRNCASECMP_L |
195 | PUSH (%edi) |
196 | #endif |
197 | mov STR1(%esp), %edx |
198 | mov STR2(%esp), %eax |
199 | #if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L |
200 | movl CNT(%esp), REM |
201 | test REM, REM |
202 | je L(eq) |
203 | #endif |
204 | mov %dx, %cx |
205 | and $0xfff, %cx |
206 | cmp $0xff0, %cx |
207 | ja L(first4bytes) |
208 | movdqu (%edx), %xmm2 |
209 | mov %eax, %ecx |
210 | and $0xfff, %ecx |
211 | cmp $0xff0, %ecx |
212 | ja L(first4bytes) |
213 | #if defined USE_AS_STRCASECMP_L || defined USE_AS_STRNCASECMP_L |
214 | # define TOLOWER(reg1, reg2) \ |
215 | movdqa reg1, %xmm3; \ |
216 | movdqa UCHIGH_reg, %xmm4; \ |
217 | movdqa reg2, %xmm5; \ |
218 | movdqa UCHIGH_reg, %xmm6; \ |
219 | pcmpgtb UCLOW_reg, %xmm3; \ |
220 | pcmpgtb reg1, %xmm4; \ |
221 | pcmpgtb UCLOW_reg, %xmm5; \ |
222 | pcmpgtb reg2, %xmm6; \ |
223 | pand %xmm4, %xmm3; \ |
224 | pand %xmm6, %xmm5; \ |
225 | pand LCQWORD_reg, %xmm3; \ |
226 | pand LCQWORD_reg, %xmm5; \ |
227 | por %xmm3, reg1; \ |
228 | por %xmm5, reg2 |
229 | |
230 | movdqu (%eax), %xmm1 |
231 | TOLOWER (%xmm2, %xmm1) |
232 | movd %xmm2, %ecx |
233 | movd %xmm1, %edi |
234 | movdqa %xmm2, %xmm3 |
235 | movdqa %xmm1, %xmm4 |
236 | cmpl %edi, %ecx |
237 | #else |
238 | # define TOLOWER(reg1, reg) |
239 | |
240 | movd %xmm2, %ecx |
241 | cmp (%eax), %ecx |
242 | #endif |
243 | jne L(less4bytes) |
244 | #if !defined USE_AS_STRCASECMP_L && !defined USE_AS_STRNCASECMP_L |
245 | movdqu (%eax), %xmm1 |
246 | #endif |
247 | pxor %xmm2, %xmm1 |
248 | pxor %xmm0, %xmm0 |
249 | ptest %xmm1, %xmm0 |
250 | jnc L(less16bytes) |
251 | pcmpeqb %xmm0, %xmm2 |
252 | ptest %xmm2, %xmm0 |
253 | jnc L(less16bytes) |
254 | |
255 | #if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L |
256 | sub $16, REM |
257 | jbe L(eq) |
258 | #endif |
259 | add $16, %edx |
260 | add $16, %eax |
261 | L(first4bytes): |
262 | movzbl (%eax), %ecx |
263 | #if defined USE_AS_STRCASECMP_L || defined USE_AS_STRNCASECMP_L |
264 | movzbl (%edx), %edi |
265 | # ifdef PIC |
266 | movl _nl_C_LC_CTYPE_tolower@GOTOFF+128*4(%ebx,%ecx,4), %ecx |
267 | movl _nl_C_LC_CTYPE_tolower@GOTOFF+128*4(%ebx,%edi,4), %edi |
268 | # else |
269 | movl _nl_C_LC_CTYPE_tolower+128*4(,%ecx,4), %ecx |
270 | movl _nl_C_LC_CTYPE_tolower+128*4(,%edi,4), %edi |
271 | # endif |
272 | cmpl %ecx, %edi |
273 | #else |
274 | cmpb %cl, (%edx) |
275 | #endif |
276 | jne L(neq) |
277 | cmpl $0, %ecx |
278 | je L(eq) |
279 | |
280 | #if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L |
281 | cmp $1, REM |
282 | je L(eq) |
283 | #endif |
284 | |
285 | movzbl 1(%eax), %ecx |
286 | #if defined USE_AS_STRCASECMP_L || defined USE_AS_STRNCASECMP_L |
287 | movzbl 1(%edx), %edi |
288 | # ifdef PIC |
289 | movl _nl_C_LC_CTYPE_tolower@GOTOFF+128*4(%ebx,%ecx,4), %ecx |
290 | movl _nl_C_LC_CTYPE_tolower@GOTOFF+128*4(%ebx,%edi,4), %edi |
291 | # else |
292 | movl _nl_C_LC_CTYPE_tolower+128*4(,%ecx,4), %ecx |
293 | movl _nl_C_LC_CTYPE_tolower+128*4(,%edi,4), %edi |
294 | # endif |
295 | cmpl %ecx, %edi |
296 | #else |
297 | cmpb %cl, 1(%edx) |
298 | #endif |
299 | jne L(neq) |
300 | cmpl $0, %ecx |
301 | je L(eq) |
302 | |
303 | #if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L |
304 | cmp $2, REM |
305 | je L(eq) |
306 | #endif |
307 | movzbl 2(%eax), %ecx |
308 | #if defined USE_AS_STRCASECMP_L || defined USE_AS_STRNCASECMP_L |
309 | movzbl 2(%edx), %edi |
310 | # ifdef PIC |
311 | movl _nl_C_LC_CTYPE_tolower@GOTOFF+128*4(%ebx,%ecx,4), %ecx |
312 | movl _nl_C_LC_CTYPE_tolower@GOTOFF+128*4(%ebx,%edi,4), %edi |
313 | # else |
314 | movl _nl_C_LC_CTYPE_tolower+128*4(,%ecx,4), %ecx |
315 | movl _nl_C_LC_CTYPE_tolower+128*4(,%edi,4), %edi |
316 | # endif |
317 | cmpl %ecx, %edi |
318 | #else |
319 | cmpb %cl, 2(%edx) |
320 | #endif |
321 | jne L(neq) |
322 | cmpl $0, %ecx |
323 | je L(eq) |
324 | |
325 | #if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L |
326 | cmp $3, REM |
327 | je L(eq) |
328 | #endif |
329 | movzbl 3(%eax), %ecx |
330 | #if defined USE_AS_STRCASECMP_L || defined USE_AS_STRNCASECMP_L |
331 | movzbl 3(%edx), %edi |
332 | # ifdef PIC |
333 | movl _nl_C_LC_CTYPE_tolower@GOTOFF+128*4(%ebx,%ecx,4), %ecx |
334 | movl _nl_C_LC_CTYPE_tolower@GOTOFF+128*4(%ebx,%edi,4), %edi |
335 | # else |
336 | movl _nl_C_LC_CTYPE_tolower+128*4(,%ecx,4), %ecx |
337 | movl _nl_C_LC_CTYPE_tolower+128*4(,%edi,4), %edi |
338 | # endif |
339 | cmpl %ecx, %edi |
340 | #else |
341 | cmpb %cl, 3(%edx) |
342 | #endif |
343 | jne L(neq) |
344 | cmpl $0, %ecx |
345 | je L(eq) |
346 | |
347 | #if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L |
348 | cmp $4, REM |
349 | je L(eq) |
350 | #endif |
351 | movzbl 4(%eax), %ecx |
352 | #if defined USE_AS_STRCASECMP_L || defined USE_AS_STRNCASECMP_L |
353 | movzbl 4(%edx), %edi |
354 | # ifdef PIC |
355 | movl _nl_C_LC_CTYPE_tolower@GOTOFF+128*4(%ebx,%ecx,4), %ecx |
356 | movl _nl_C_LC_CTYPE_tolower@GOTOFF+128*4(%ebx,%edi,4), %edi |
357 | # else |
358 | movl _nl_C_LC_CTYPE_tolower+128*4(,%ecx,4), %ecx |
359 | movl _nl_C_LC_CTYPE_tolower+128*4(,%edi,4), %edi |
360 | # endif |
361 | cmpl %ecx, %edi |
362 | #else |
363 | cmpb %cl, 4(%edx) |
364 | #endif |
365 | jne L(neq) |
366 | cmpl $0, %ecx |
367 | je L(eq) |
368 | |
369 | #if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L |
370 | cmp $5, REM |
371 | je L(eq) |
372 | #endif |
373 | movzbl 5(%eax), %ecx |
374 | #if defined USE_AS_STRCASECMP_L || defined USE_AS_STRNCASECMP_L |
375 | movzbl 5(%edx), %edi |
376 | # ifdef PIC |
377 | movl _nl_C_LC_CTYPE_tolower@GOTOFF+128*4(%ebx,%ecx,4), %ecx |
378 | movl _nl_C_LC_CTYPE_tolower@GOTOFF+128*4(%ebx,%edi,4), %edi |
379 | # else |
380 | movl _nl_C_LC_CTYPE_tolower+128*4(,%ecx,4), %ecx |
381 | movl _nl_C_LC_CTYPE_tolower+128*4(,%edi,4), %edi |
382 | # endif |
383 | cmpl %ecx, %edi |
384 | #else |
385 | cmpb %cl, 5(%edx) |
386 | #endif |
387 | jne L(neq) |
388 | cmpl $0, %ecx |
389 | je L(eq) |
390 | |
391 | #if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L |
392 | cmp $6, REM |
393 | je L(eq) |
394 | #endif |
395 | movzbl 6(%eax), %ecx |
396 | #if defined USE_AS_STRCASECMP_L || defined USE_AS_STRNCASECMP_L |
397 | movzbl 6(%edx), %edi |
398 | # ifdef PIC |
399 | movl _nl_C_LC_CTYPE_tolower@GOTOFF+128*4(%ebx,%ecx,4), %ecx |
400 | movl _nl_C_LC_CTYPE_tolower@GOTOFF+128*4(%ebx,%edi,4), %edi |
401 | # else |
402 | movl _nl_C_LC_CTYPE_tolower+128*4(,%ecx,4), %ecx |
403 | movl _nl_C_LC_CTYPE_tolower+128*4(,%edi,4), %edi |
404 | # endif |
405 | cmpl %ecx, %edi |
406 | #else |
407 | cmpb %cl, 6(%edx) |
408 | #endif |
409 | jne L(neq) |
410 | cmpl $0, %ecx |
411 | je L(eq) |
412 | |
413 | #if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L |
414 | cmp $7, REM |
415 | je L(eq) |
416 | #endif |
417 | movzbl 7(%eax), %ecx |
418 | #if defined USE_AS_STRCASECMP_L || defined USE_AS_STRNCASECMP_L |
419 | movzbl 7(%edx), %edi |
420 | # ifdef PIC |
421 | movl _nl_C_LC_CTYPE_tolower@GOTOFF+128*4(%ebx,%ecx,4), %ecx |
422 | movl _nl_C_LC_CTYPE_tolower@GOTOFF+128*4(%ebx,%edi,4), %edi |
423 | # else |
424 | movl _nl_C_LC_CTYPE_tolower+128*4(,%ecx,4), %ecx |
425 | movl _nl_C_LC_CTYPE_tolower+128*4(,%edi,4), %edi |
426 | # endif |
427 | cmpl %ecx, %edi |
428 | #else |
429 | cmpb %cl, 7(%edx) |
430 | #endif |
431 | jne L(neq) |
432 | cmpl $0, %ecx |
433 | je L(eq) |
434 | |
435 | #if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L |
436 | sub $8, REM |
437 | je L(eq) |
438 | #endif |
439 | add $8, %eax |
440 | add $8, %edx |
441 | |
442 | #if !defined USE_AS_STRCASECMP_L && !defined USE_AS_STRNCASECMP_L |
443 | PUSH (%edi) |
444 | #endif |
445 | PUSH (%esi) |
446 | #if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L |
447 | cfi_remember_state |
448 | #endif |
449 | mov %edx, %edi |
450 | mov %eax, %esi |
451 | xorl %eax, %eax |
452 | L(check_offset): |
453 | movl %edi, %edx |
454 | movl %esi, %ecx |
455 | andl $0xfff, %edx |
456 | andl $0xfff, %ecx |
457 | cmpl %edx, %ecx |
458 | cmovl %edx, %ecx |
459 | lea -0xff0(%ecx), %edx |
460 | sub %edx, %edi |
461 | sub %edx, %esi |
462 | testl %edx, %edx |
463 | jg L(crosspage) |
464 | L(loop): |
465 | movdqu (%esi,%edx), %xmm2 |
466 | movdqu (%edi,%edx), %xmm1 |
467 | TOLOWER (%xmm2, %xmm1) |
468 | pcmpistri $0x1a, %xmm2, %xmm1 |
469 | jbe L(end) |
470 | |
471 | #if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L |
472 | sub $16, REM |
473 | jbe L(more16byteseq) |
474 | #endif |
475 | |
476 | add $16, %edx |
477 | jle L(loop) |
478 | L(crosspage): |
479 | movzbl (%edi,%edx), %eax |
480 | movzbl (%esi,%edx), %ecx |
481 | #if defined USE_AS_STRCASECMP_L || defined USE_AS_STRNCASECMP_L |
482 | # ifdef PIC |
483 | movl _nl_C_LC_CTYPE_tolower@GOTOFF+128*4(%ebx,%eax,4), %eax |
484 | movl _nl_C_LC_CTYPE_tolower@GOTOFF+128*4(%ebx,%ecx,4), %ecx |
485 | # else |
486 | movl _nl_C_LC_CTYPE_tolower+128*4(,%eax,4), %eax |
487 | movl _nl_C_LC_CTYPE_tolower+128*4(,%ecx,4), %ecx |
488 | # endif |
489 | #endif |
490 | subl %ecx, %eax |
491 | jne L(ret) |
492 | testl %ecx, %ecx |
493 | je L(ret) |
494 | #if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L |
495 | sub $1, REM |
496 | jbe L(more16byteseq) |
497 | #endif |
498 | inc %edx |
499 | cmp $15, %edx |
500 | jle L(crosspage) |
501 | add %edx, %edi |
502 | add %edx, %esi |
503 | jmp L(check_offset) |
504 | |
505 | .p2align 4 |
506 | L(end): |
507 | jnc L(ret) |
508 | #if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L |
509 | sub %ecx, REM |
510 | jbe L(more16byteseq) |
511 | #endif |
512 | lea (%ecx,%edx), %ecx |
513 | movzbl (%edi,%ecx), %eax |
514 | movzbl (%esi,%ecx), %ecx |
515 | #if defined USE_AS_STRCASECMP_L || defined USE_AS_STRNCASECMP_L |
516 | # ifdef PIC |
517 | movl _nl_C_LC_CTYPE_tolower@GOTOFF+128*4(%ebx,%eax,4), %eax |
518 | movl _nl_C_LC_CTYPE_tolower@GOTOFF+128*4(%ebx,%ecx,4), %ecx |
519 | # else |
520 | movl _nl_C_LC_CTYPE_tolower+128*4(,%eax,4), %eax |
521 | movl _nl_C_LC_CTYPE_tolower+128*4(,%ecx,4), %ecx |
522 | # endif |
523 | #endif |
524 | subl %ecx, %eax |
525 | L(ret): |
526 | POP (%esi) |
527 | POP (%edi) |
528 | #if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L |
529 | POP (REM) |
530 | #endif |
531 | #if defined USE_AS_STRCASECMP_L || defined USE_AS_STRNCASECMP_L |
532 | # ifdef PIC |
533 | POP (%ebx) |
534 | # endif |
535 | #endif |
536 | ret |
537 | |
538 | .p2align 4 |
539 | #if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L |
540 | cfi_restore_state |
541 | L(more16byteseq): |
542 | POP (%esi) |
543 | # ifdef USE_AS_STRNCMP |
544 | POP (%edi) |
545 | # endif |
546 | #endif |
547 | L(eq): |
548 | xorl %eax, %eax |
549 | RETURN |
550 | |
551 | L(neq): |
552 | mov $1, %eax |
553 | ja L(neq_bigger) |
554 | neg %eax |
555 | L(neq_bigger): |
556 | RETURN |
557 | |
558 | L(less16bytes): |
559 | add $0xfefefeff, %ecx |
560 | jnc L(less4bytes) |
561 | #if defined USE_AS_STRCASECMP_L || defined USE_AS_STRNCASECMP_L |
562 | movd %xmm3, %edi |
563 | xor %edi, %ecx |
564 | #else |
565 | xor (%edx), %ecx |
566 | #endif |
567 | or $0xfefefeff, %ecx |
568 | add $1, %ecx |
569 | jnz L(less4bytes) |
570 | |
571 | #if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L |
572 | cmp $4, REM |
573 | jbe L(eq) |
574 | #endif |
575 | #if defined USE_AS_STRCASECMP_L || defined USE_AS_STRNCASECMP_L |
576 | psrldq $4, %xmm3 |
577 | psrldq $4, %xmm4 |
578 | movd %xmm3, %ecx |
579 | movd %xmm4, %edi |
580 | cmp %edi, %ecx |
581 | mov %ecx, %edi |
582 | #else |
583 | mov 4(%edx), %ecx |
584 | cmp 4(%eax), %ecx |
585 | #endif |
586 | jne L(more4bytes) |
587 | add $0xfefefeff, %ecx |
588 | jnc L(more4bytes) |
589 | #if defined USE_AS_STRCASECMP_L || defined USE_AS_STRNCASECMP_L |
590 | xor %edi, %ecx |
591 | #else |
592 | xor 4(%edx), %ecx |
593 | #endif |
594 | or $0xfefefeff, %ecx |
595 | add $1, %ecx |
596 | jnz L(more4bytes) |
597 | |
598 | #if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L |
599 | sub $8, REM |
600 | jbe L(eq) |
601 | #endif |
602 | |
603 | add $8, %edx |
604 | add $8, %eax |
605 | L(less4bytes): |
606 | |
607 | movzbl (%eax), %ecx |
608 | #if defined USE_AS_STRCASECMP_L || defined USE_AS_STRNCASECMP_L |
609 | movzbl (%edx), %edi |
610 | # ifdef PIC |
611 | movl _nl_C_LC_CTYPE_tolower@GOTOFF+128*4(%ebx,%ecx,4), %ecx |
612 | movl _nl_C_LC_CTYPE_tolower@GOTOFF+128*4(%ebx,%edi,4), %edi |
613 | # else |
614 | movl _nl_C_LC_CTYPE_tolower+128*4(,%ecx,4), %ecx |
615 | movl _nl_C_LC_CTYPE_tolower+128*4(,%edi,4), %edi |
616 | # endif |
617 | cmpl %ecx, %edi |
618 | #else |
619 | cmpb %cl, (%edx) |
620 | #endif |
621 | jne L(neq) |
622 | cmpl $0, %ecx |
623 | je L(eq) |
624 | |
625 | #if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L |
626 | cmp $1, REM |
627 | je L(eq) |
628 | #endif |
629 | movzbl 1(%eax), %ecx |
630 | #if defined USE_AS_STRCASECMP_L || defined USE_AS_STRNCASECMP_L |
631 | movzbl 1(%edx), %edi |
632 | # ifdef PIC |
633 | movl _nl_C_LC_CTYPE_tolower@GOTOFF+128*4(%ebx,%ecx,4), %ecx |
634 | movl _nl_C_LC_CTYPE_tolower@GOTOFF+128*4(%ebx,%edi,4), %edi |
635 | # else |
636 | movl _nl_C_LC_CTYPE_tolower+128*4(,%ecx,4), %ecx |
637 | movl _nl_C_LC_CTYPE_tolower+128*4(,%edi,4), %edi |
638 | # endif |
639 | cmpl %ecx, %edi |
640 | #else |
641 | cmpb %cl, 1(%edx) |
642 | #endif |
643 | jne L(neq) |
644 | cmpl $0, %ecx |
645 | je L(eq) |
646 | |
647 | #if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L |
648 | cmp $2, REM |
649 | je L(eq) |
650 | #endif |
651 | |
652 | movzbl 2(%eax), %ecx |
653 | #if defined USE_AS_STRCASECMP_L || defined USE_AS_STRNCASECMP_L |
654 | movzbl 2(%edx), %edi |
655 | # ifdef PIC |
656 | movl _nl_C_LC_CTYPE_tolower@GOTOFF+128*4(%ebx,%ecx,4), %ecx |
657 | movl _nl_C_LC_CTYPE_tolower@GOTOFF+128*4(%ebx,%edi,4), %edi |
658 | # else |
659 | movl _nl_C_LC_CTYPE_tolower+128*4(,%ecx,4), %ecx |
660 | movl _nl_C_LC_CTYPE_tolower+128*4(,%edi,4), %edi |
661 | # endif |
662 | cmpl %ecx, %edi |
663 | #else |
664 | cmpb %cl, 2(%edx) |
665 | #endif |
666 | jne L(neq) |
667 | cmpl $0, %ecx |
668 | je L(eq) |
669 | |
670 | #if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L |
671 | cmp $3, REM |
672 | je L(eq) |
673 | #endif |
674 | movzbl 3(%eax), %ecx |
675 | #if defined USE_AS_STRCASECMP_L || defined USE_AS_STRNCASECMP_L |
676 | movzbl 3(%edx), %edi |
677 | # ifdef PIC |
678 | movl _nl_C_LC_CTYPE_tolower@GOTOFF+128*4(%ebx,%ecx,4), %ecx |
679 | movl _nl_C_LC_CTYPE_tolower@GOTOFF+128*4(%ebx,%edi,4), %edi |
680 | # else |
681 | movl _nl_C_LC_CTYPE_tolower+128*4(,%ecx,4), %ecx |
682 | movl _nl_C_LC_CTYPE_tolower+128*4(,%edi,4), %edi |
683 | # endif |
684 | cmpl %ecx, %edi |
685 | #else |
686 | cmpb %cl, 3(%edx) |
687 | #endif |
688 | jne L(neq) |
689 | cmpl $0, %ecx |
690 | je L(eq) |
691 | |
692 | L(more4bytes): |
693 | #if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L |
694 | cmp $4, REM |
695 | je L(eq) |
696 | #endif |
697 | movzbl 4(%eax), %ecx |
698 | #if defined USE_AS_STRCASECMP_L || defined USE_AS_STRNCASECMP_L |
699 | movzbl 4(%edx), %edi |
700 | # ifdef PIC |
701 | movl _nl_C_LC_CTYPE_tolower@GOTOFF+128*4(%ebx,%ecx,4), %ecx |
702 | movl _nl_C_LC_CTYPE_tolower@GOTOFF+128*4(%ebx,%edi,4), %edi |
703 | # else |
704 | movl _nl_C_LC_CTYPE_tolower+128*4(,%ecx,4), %ecx |
705 | movl _nl_C_LC_CTYPE_tolower+128*4(,%edi,4), %edi |
706 | # endif |
707 | cmpl %ecx, %edi |
708 | #else |
709 | cmpb %cl, 4(%edx) |
710 | #endif |
711 | jne L(neq) |
712 | cmpl $0, %ecx |
713 | je L(eq) |
714 | |
715 | |
716 | #if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L |
717 | cmp $5, REM |
718 | je L(eq) |
719 | #endif |
720 | movzbl 5(%eax), %ecx |
721 | #if defined USE_AS_STRCASECMP_L || defined USE_AS_STRNCASECMP_L |
722 | movzbl 5(%edx), %edi |
723 | # ifdef PIC |
724 | movl _nl_C_LC_CTYPE_tolower@GOTOFF+128*4(%ebx,%ecx,4), %ecx |
725 | movl _nl_C_LC_CTYPE_tolower@GOTOFF+128*4(%ebx,%edi,4), %edi |
726 | # else |
727 | movl _nl_C_LC_CTYPE_tolower+128*4(,%ecx,4), %ecx |
728 | movl _nl_C_LC_CTYPE_tolower+128*4(,%edi,4), %edi |
729 | # endif |
730 | cmpl %ecx, %edi |
731 | #else |
732 | cmpb %cl, 5(%edx) |
733 | #endif |
734 | jne L(neq) |
735 | cmpl $0, %ecx |
736 | je L(eq) |
737 | |
738 | #if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L |
739 | cmp $6, REM |
740 | je L(eq) |
741 | #endif |
742 | movzbl 6(%eax), %ecx |
743 | #if defined USE_AS_STRCASECMP_L || defined USE_AS_STRNCASECMP_L |
744 | movzbl 6(%edx), %edi |
745 | # ifdef PIC |
746 | movl _nl_C_LC_CTYPE_tolower@GOTOFF+128*4(%ebx,%ecx,4), %ecx |
747 | movl _nl_C_LC_CTYPE_tolower@GOTOFF+128*4(%ebx,%edi,4), %edi |
748 | # else |
749 | movl _nl_C_LC_CTYPE_tolower+128*4(,%ecx,4), %ecx |
750 | movl _nl_C_LC_CTYPE_tolower+128*4(,%edi,4), %edi |
751 | # endif |
752 | cmpl %ecx, %edi |
753 | #else |
754 | cmpb %cl, 6(%edx) |
755 | #endif |
756 | jne L(neq) |
757 | cmpl $0, %ecx |
758 | je L(eq) |
759 | |
760 | #if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L |
761 | cmp $7, REM |
762 | je L(eq) |
763 | #endif |
764 | movzbl 7(%eax), %ecx |
765 | #if defined USE_AS_STRCASECMP_L || defined USE_AS_STRNCASECMP_L |
766 | movzbl 7(%edx), %edi |
767 | # ifdef PIC |
768 | movl _nl_C_LC_CTYPE_tolower@GOTOFF+128*4(%ebx,%ecx,4), %ecx |
769 | movl _nl_C_LC_CTYPE_tolower@GOTOFF+128*4(%ebx,%edi,4), %edi |
770 | # else |
771 | movl _nl_C_LC_CTYPE_tolower+128*4(,%ecx,4), %ecx |
772 | movl _nl_C_LC_CTYPE_tolower+128*4(,%edi,4), %edi |
773 | # endif |
774 | cmpl %ecx, %edi |
775 | #else |
776 | cmpb %cl, 7(%edx) |
777 | #endif |
778 | jne L(neq) |
779 | jmp L(eq) |
780 | |
781 | END (STRCMP) |
782 | |
783 | #endif |
784 | |