1/* strcmp with SSE4.2
2   Copyright (C) 2010-2022 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
98ENTRY (__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
121END (__strcasecmp_sse4_2)
122#endif
123
124#ifdef USE_AS_STRNCASECMP_L
125ENTRY (__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
148END (__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
166L(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
261L(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
452L(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)
464L(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)
478L(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
506L(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
525L(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
541L(more16byteseq):
542	POP	(%esi)
543# ifdef USE_AS_STRNCMP
544	POP	(%edi)
545# endif
546#endif
547L(eq):
548	xorl	%eax, %eax
549	RETURN
550
551L(neq):
552	mov	$1, %eax
553	ja	L(neq_bigger)
554	neg	%eax
555L(neq_bigger):
556	RETURN
557
558L(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
605L(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
692L(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
781END (STRCMP)
782
783#endif
784