32bit memcmp/strcmp/strncmp optimized for SSSE3/SSS4.2
[glibc.git] / sysdeps / i386 / i686 / multiarch / strcmp-sse4.S
blob977647203f3d7992c5a4e43ca5f5a5d66345b192
1 /* strcmp with SSE4.2
2    Copyright (C) 2010 Free Software Foundation, Inc.
3    Contributed by Intel Corporation.
4    This file is part of the GNU C Library.
6    The GNU C Library is free software; you can redistribute it and/or
7    modify it under the terms of the GNU Lesser General Public
8    License as published by the Free Software Foundation; either
9    version 2.1 of the License, or (at your option) any later version.
11    The GNU C Library is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14    Lesser General Public License for more details.
16    You should have received a copy of the GNU Lesser General Public
17    License along with the GNU C Library; if not, write to the Free
18    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19    02111-1307 USA.  */
21 #ifndef NOT_IN_libc
23 #include <sysdep.h>
24 #include "asm-syntax.h"
26 #define CFI_PUSH(REG)                                           \
27   cfi_adjust_cfa_offset (4);                                    \
28   cfi_rel_offset (REG, 0)
30 #define CFI_POP(REG)                                            \
31   cfi_adjust_cfa_offset (-4);                                   \
32   cfi_restore (REG)
34 #define PUSH(REG)       pushl REG; CFI_PUSH (REG)
35 #define POP(REG)        popl REG; CFI_POP (REG)
37 #ifndef USE_AS_STRNCMP
38 # ifndef STRCMP
39 #  define STRCMP        __strcmp_sse4_2
40 # endif
41 # define STR1           4
42 # define STR2           STR1+4
43 #else
44 # ifndef STRCMP
45 #  define STRCMP        __strncmp_sse4_2
46 # endif
47 # define STR1           8
48 # define STR2           STR1+4
49 # define CNT            STR2+4
50 #endif
52         .section .text.sse4.2,"ax",@progbits
53 ENTRY (STRCMP)
54 #ifdef USE_AS_STRNCMP
55         PUSH    (%ebp)
56 #endif
57         mov     STR1(%esp), %edx
58         mov     STR2(%esp), %eax
59 #ifdef USE_AS_STRNCMP
60         movl    CNT(%esp), %ebp
61         test    %ebp, %ebp
62         je      L(eq)
63 #endif
64         mov     %dx, %cx
65         and     $0xfff, %cx
66         cmp     $0xff0, %cx
67         ja      L(first4bytes)
68         movdqu  (%edx), %xmm2
69         mov     %eax, %ecx
70         and     $0xfff, %ecx
71         cmp     $0xff0, %ecx
72         ja      L(first4bytes)
73         movd    %xmm2, %ecx
74         cmp     (%eax), %ecx
75         jne     L(less4bytes)
76         movdqu  (%eax), %xmm1
77         pxor    %xmm2, %xmm1
78         pxor    %xmm0, %xmm0
79         ptest   %xmm1, %xmm0
80         jnc     L(less16bytes)
81         pcmpeqb %xmm0, %xmm2
82         ptest   %xmm2, %xmm0
83         jnc     L(less16bytes)
85 #ifdef USE_AS_STRNCMP
86         sub     $16, %ebp
87         jbe     L(eq)
88 #endif
89         add     $16, %edx
90         add     $16, %eax
91 L(first4bytes):
92         movzbl  (%eax), %ecx
93         cmpb    %cl, (%edx)
94         jne     L(neq)
95         cmpl    $0, %ecx
96         je      L(eq)
98 #ifdef USE_AS_STRNCMP
99         cmp     $1, %ebp
100         je      L(eq)
101 #endif
103         movzbl  1(%eax), %ecx
104         cmpb    %cl, 1(%edx)
105         jne     L(neq)
106         cmpl    $0, %ecx
107         je      L(eq)
109 #ifdef USE_AS_STRNCMP
110         cmp     $2, %ebp
111         je      L(eq)
112 #endif
113         movzbl  2(%eax), %ecx
114         cmpb    %cl, 2(%edx)
115         jne     L(neq)
116         cmpl    $0, %ecx
117         je      L(eq)
119 #ifdef USE_AS_STRNCMP
120         cmp     $3, %ebp
121         je      L(eq)
122 #endif
123         movzbl  3(%eax), %ecx
124         cmpb    %cl, 3(%edx)
125         jne     L(neq)
126         cmpl    $0, %ecx
127         je      L(eq)
129 #ifdef USE_AS_STRNCMP
130         cmp     $4, %ebp
131         je      L(eq)
132 #endif
133         movzbl  4(%eax), %ecx
134         cmpb    %cl, 4(%edx)
135         jne     L(neq)
136         cmpl    $0, %ecx
137         je      L(eq)
139 #ifdef USE_AS_STRNCMP
140         cmp     $5, %ebp
141         je      L(eq)
142 #endif
143         movzbl  5(%eax), %ecx
144         cmpb    %cl, 5(%edx)
145         jne     L(neq)
146         cmpl    $0, %ecx
147         je      L(eq)
149 #ifdef USE_AS_STRNCMP
150         cmp     $6, %ebp
151         je      L(eq)
152 #endif
153         movzbl  6(%eax), %ecx
154         cmpb    %cl, 6(%edx)
155         jne     L(neq)
156         cmpl    $0, %ecx
157         je      L(eq)
159 #ifdef USE_AS_STRNCMP
160         cmp     $7, %ebp
161         je      L(eq)
162 #endif
163         movzbl  7(%eax), %ecx
164         cmpb    %cl, 7(%edx)
165         jne     L(neq)
166         cmpl    $0, %ecx
167         je      L(eq)
169 #ifdef USE_AS_STRNCMP
170         sub     $8, %ebp
171         je      L(eq)
172 #endif
173         add     $8, %eax
174         add     $8, %edx
176         PUSH    (%ebx)
177         PUSH    (%edi)
178         PUSH    (%esi)
179         mov     %edx, %edi
180         mov     %eax, %esi
181         xorl    %eax, %eax
182 L(check_offset):
183         movl    %edi, %ebx
184         movl    %esi, %ecx
185         andl    $0xfff, %ebx
186         andl    $0xfff, %ecx
187         cmpl    %ebx, %ecx
188         cmovl   %ebx, %ecx
189         lea     -0xff0(%ecx), %edx
190         sub     %edx, %edi
191         sub     %edx, %esi
192         testl   %edx, %edx
193         jg      L(crosspage)
194 L(loop):
195         movdqu  (%esi,%edx), %xmm2
196         movdqu  (%edi,%edx), %xmm1
197         pcmpistri       $0x1a, %xmm2, %xmm1
198         jbe     L(end)
200 #ifdef USE_AS_STRNCMP
201         sub     $16, %ebp
202         jbe     L(more16byteseq)
203 #endif
205         add     $16, %edx
206         jle     L(loop)
207 L(crosspage):
208         movzbl  (%edi,%edx), %eax
209         movzbl  (%esi,%edx), %ebx
210         subl    %ebx, %eax
211         jne     L(ret)
212         testl   %ebx, %ebx
213         je      L(ret)
214 #ifdef USE_AS_STRNCMP
215         sub     $1, %ebp
216         jbe     L(more16byteseq)
217 #endif
218         inc     %edx
219         cmp     $15, %edx
220         jle     L(crosspage)
221         add     $16, %edi
222         add     $16, %esi
223         jmp     L(check_offset)
225 L(end):
226         jnc     L(ret)
227 #ifdef USE_AS_STRNCMP
228         sub     %ecx, %ebp
229         jbe     L(more16byteseq)
230 #endif
231         lea     (%ecx,%edx), %ebx
232         movzbl  (%edi,%ebx), %eax
233         movzbl  (%esi,%ebx), %ecx
234         subl    %ecx, %eax
235 L(ret):
236         POP     (%esi)
237         POP     (%edi)
238         POP     (%ebx)
239 #ifdef USE_AS_STRNCMP
240         POP     (%ebp)
241 #endif
242         ret
244 #ifdef USE_AS_STRNCMP
245 L(more16byteseq):
246         POP     (%esi)
247         POP     (%edi)
248         POP     (%ebx)
249 #endif
250 L(eq):
251         xorl    %eax, %eax
252 #ifdef USE_AS_STRNCMP
253         POP     (%ebp)
254 #endif
255         ret
256 L(neq):
257         mov     $1, %eax
258         ja      L(neq_bigger)
259         neg     %eax
260 L(neq_bigger):
261 #ifdef USE_AS_STRNCMP
262         POP     (%ebp)
263 #endif
264         ret
265         .p2align 4
266 L(less16bytes):
267         add     $0xfefefeff, %ecx
268         jnc     L(less4bytes)
269         xor     (%edx), %ecx
270         or      $0xfefefeff, %ecx
271         add     $1, %ecx
272         jnz     L(less4bytes)
274 #ifdef USE_AS_STRNCMP
275         cmp     $4, %ebp
276         jbe     L(eq)
277 #endif
278         mov     4(%edx), %ecx
279         cmp     4(%eax), %ecx
280         jne     L(more4bytes)
281         add     $0xfefefeff, %ecx
282         jnc     L(more4bytes)
283         xor     4(%edx), %ecx
284         or      $0xfefefeff, %ecx
285         add     $1, %ecx
286         jnz     L(more4bytes)
288 #ifdef USE_AS_STRNCMP
289         sub     $8, %ebp
290         jbe     L(eq)
291 #endif
293         add     $8, %edx
294         add     $8, %eax
295 L(less4bytes):
297         movzbl  (%eax), %ecx
298         cmpb    %cl, (%edx)
299         jne     L(neq)
300         cmpl    $0, %ecx
301         je      L(eq)
303 #ifdef USE_AS_STRNCMP
304         cmp     $1, %ebp
305         je      L(eq)
306 #endif
307         movzbl  1(%eax), %ecx
308         cmpb    %cl, 1(%edx)
309         jne     L(neq)
310         cmpl    $0, %ecx
311         je      L(eq)
313 #ifdef USE_AS_STRNCMP
314         cmp     $2, %ebp
315         je      L(eq)
316 #endif
318         movzbl  2(%eax), %ecx
319         cmpb    %cl, 2(%edx)
320         jne     L(neq)
321         cmpl    $0, %ecx
322         je      L(eq)
324 #ifdef USE_AS_STRNCMP
325         cmp     $3, %ebp
326         je      L(eq)
327 #endif
328         movzbl  3(%eax), %ecx
329         cmpb    %cl, 3(%edx)
330         jne     L(neq)
331         cmpl    $0, %ecx
332         je      L(eq)
334 L(more4bytes):
335 #ifdef USE_AS_STRNCMP
336         cmp     $4, %ebp
337         je      L(eq)
338 #endif
339         movzbl  4(%eax), %ecx
340         cmpb    %cl, 4(%edx)
341         jne     L(neq)
342         cmpl    $0, %ecx
343         je      L(eq)
346 #ifdef USE_AS_STRNCMP
347         cmp     $5, %ebp
348         je      L(eq)
349 #endif
350         movzbl  5(%eax), %ecx
351         cmpb    %cl, 5(%edx)
352         jne     L(neq)
353         cmpl    $0, %ecx
354         je      L(eq)
356 #ifdef USE_AS_STRNCMP
357         cmp     $6, %ebp
358         je      L(eq)
359 #endif
360         movzbl  6(%eax), %ecx
361         cmpb    %cl, 6(%edx)
362         jne     L(neq)
363         cmpl    $0, %ecx
364         je      L(eq)
366 #ifdef USE_AS_STRNCMP
367         cmp     $7, %ebp
368         je      L(eq)
369 #endif
370         movzbl  7(%eax), %ecx
371         cmpb    %cl, 7(%edx)
372         jne     L(neq)
373         cmpl    $0, %ecx
374         je      L(eq)
376 END (STRCMP)
378 #endif