xref: /titanic_51/usr/src/lib/libc/amd64/gen/strcmp.s (revision 5a7763bf3e9db4cfe6cb523b096cb74af71e3793)
1/*
2 * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
3 * Use is subject to license terms.
4 */
5
6/*
7 * Copyright (c) 2002 Advanced Micro Devices, Inc.
8 *
9 * All rights reserved.
10 *
11 * Redistribution and  use in source and binary  forms, with or
12 * without  modification,  are   permitted  provided  that  the
13 * following conditions are met:
14 *
15 * + Redistributions  of source  code  must  retain  the  above
16 *   copyright  notice,   this  list  of   conditions  and  the
17 *   following disclaimer.
18 *
19 * + Redistributions  in binary  form must reproduce  the above
20 *   copyright  notice,   this  list  of   conditions  and  the
21 *   following  disclaimer in  the  documentation and/or  other
22 *   materials provided with the distribution.
23 *
24 * + Neither the  name of Advanced Micro Devices,  Inc. nor the
25 *   names  of  its contributors  may  be  used  to endorse  or
26 *   promote  products  derived   from  this  software  without
27 *   specific prior written permission.
28 *
29 * THIS  SOFTWARE  IS PROVIDED  BY  THE  COPYRIGHT HOLDERS  AND
30 * CONTRIBUTORS AS IS AND  ANY EXPRESS OR IMPLIED WARRANTIES,
31 * INCLUDING,  BUT NOT  LIMITED TO,  THE IMPLIED  WARRANTIES OF
32 * MERCHANTABILITY  AND FITNESS  FOR A  PARTICULAR  PURPOSE ARE
33 * DISCLAIMED.  IN  NO  EVENT  SHALL  ADVANCED  MICRO  DEVICES,
34 * INC.  OR CONTRIBUTORS  BE LIABLE  FOR ANY  DIRECT, INDIRECT,
35 * INCIDENTAL,  SPECIAL,  EXEMPLARY,  OR CONSEQUENTIAL  DAMAGES
36 * (INCLUDING,  BUT NOT LIMITED  TO, PROCUREMENT  OF SUBSTITUTE
37 * GOODS  OR  SERVICES;  LOSS  OF  USE, DATA,  OR  PROFITS;  OR
38 * BUSINESS INTERRUPTION)  HOWEVER CAUSED AND ON  ANY THEORY OF
39 * LIABILITY,  WHETHER IN CONTRACT,  STRICT LIABILITY,  OR TORT
40 * (INCLUDING NEGLIGENCE  OR OTHERWISE) ARISING IN  ANY WAY OUT
41 * OF THE  USE  OF  THIS  SOFTWARE, EVEN  IF  ADVISED  OF  THE
42 * POSSIBILITY OF SUCH DAMAGE.
43 *
44 * It is  licensee's responsibility  to comply with  any export
45 * regulations applicable in licensee's jurisdiction.
46 */
47
48	.ident	"%Z%%M%	%I%	%E% SMI"
49
50	.file	"%M%"
51
52#include "SYS.h"
53#include "cache.h"
54
55#define LABEL(s) .strcmp/**/s
56
57#ifdef USE_AS_STRNCMP
58	ENTRY(strncmp)
59#else
60	ENTRY(strcmp)			/* (const char *, const char *) */
61#endif
62        xor     %ecx, %ecx
63
64#ifdef USE_AS_STRNCMP
65	test	%rdx, %rdx		/* (const char *, const char *, size_t) */
66        mov	%r14, -8 (%rsp)
67	mov	%rdx, %r14
68	mov	%edx, %eax
69	jz	LABEL(exitz)		/* early exit */
70#endif
71
72LABEL(aligntry):
73        mov     %rsi, %r8		/* align by "source" */
74        and     $8 - 1, %r8		/* between 0 and 8 characters compared */
75	jz	LABEL(alignafter)
76
77LABEL(align):
78        sub     $8, %r8
79
80        .p2align 4
81
82LABEL(alignloop):
83        mov     (%rsi, %rcx), %al
84        mov	(%rdi, %rcx), %dl
85
86#ifdef USE_AS_STRNCMP
87	dec	%r14
88	jl	LABEL(exitafter)
89#endif
90
91        cmp     %dl, %al		/* check if same character */
92        jne     LABEL(exitafter)
93        test    %al, %al		/* check if character a NUL */
94        jz      LABEL(exitafter)
95
96        inc     %ecx
97
98        inc     %r8
99        jnz     LABEL(alignloop)
100
101        .p2align 4
102
103LABEL(alignafter):
104
105        mov	%r15, -32 (%rsp)
106        mov	%rbp, -24 (%rsp)
107        mov	%rbx, -16 (%rsp)
108
109LABEL(pagealigntry):			/* page align by "destination" */
110        lea	(%rdi, %rcx), %ebp
111	mov	$AMD64PAGESIZE, %r15d
112        and     $AMD64PAGEMASK, %ebp
113        sub	%r15d, %ebp
114
115LABEL(64):                              /* 64-byte */
116	mov     $0xfefefefefefefeff, %rbx /* magic number */
117
118        .p2align 4
119
120LABEL(64loop):
121	add	$64, %ebp		/* check if "destination" crosses a page unevenly */
122	jle	LABEL(64gobble)
123
124        sub	%r15d, %ebp
125        lea	64 (%rcx), %r8
126
127        .p2align 4
128
129LABEL(64nibble):
130        mov     (%rsi, %rcx), %al
131        mov	(%rdi, %rcx), %dl
132
133#ifdef USE_AS_STRNCMP
134	dec	%r14
135	jl	LABEL(exit)
136#endif
137
138        cmp     %dl, %al		/* check if same character */
139        jne     LABEL(exit)
140        test    %al, %al		/* check if character a NUL */
141        jz      LABEL(exit)
142
143        inc	%ecx
144
145        cmp	%ecx, %r8d
146        ja	LABEL(64nibble)
147
148        .p2align 4
149
150LABEL(64gobble):
151        mov     (%rsi, %rcx), %rax
152        mov     (%rdi, %rcx), %rdx
153
154#ifdef USE_AS_STRNCMP
155	sub	$8, %r14
156	jl	LABEL(tail)
157#endif
158
159        mov     %rbx, %r8
160        add     %rax, %r8
161        sbb     %r10, %r10
162
163        mov     %rbx, %r9
164        add     %rdx, %r9
165        sbb     %r11, %r11
166
167        xor     %rax, %r8
168        or      %rbx, %r8
169        sub     %r10, %r8
170        jnz     LABEL(tail)
171
172        xor     %rdx, %r9
173        or      %rbx, %r9
174        sub     %r11, %r9
175        jnz     LABEL(tail)
176
177        cmp     %rdx, %rax
178        jne     LABEL(tail)
179
180        mov     8 (%rsi, %rcx), %rax
181        mov     8 (%rdi, %rcx), %rdx
182        add     $8, %ecx
183
184#ifdef USE_AS_STRNCMP
185	sub	$8, %r14
186	jl	LABEL(tail)
187#endif
188
189        mov     %rbx, %r8
190        add     %rax, %r8
191        sbb     %r10, %r10
192
193        mov     %rbx, %r9
194        add     %rdx, %r9
195        sbb     %r11, %r11
196
197        xor     %rax, %r8
198        or      %rbx, %r8
199        sub     %r10, %r8
200        jnz     LABEL(tail)
201
202        xor     %rdx, %r9
203        or      %rbx, %r9
204        sub     %r11, %r9
205        jnz     LABEL(tail)
206
207        cmp     %rdx, %rax
208        jne     LABEL(tail)
209
210        mov     8 (%rsi, %rcx), %rax
211        mov     8 (%rdi, %rcx), %rdx
212        add     $8, %ecx
213
214#ifdef USE_AS_STRNCMP
215	sub	$8, %r14
216	jl	LABEL(tail)
217#endif
218
219        mov     %rbx, %r8
220        add     %rax, %r8
221        sbb     %r10, %r10
222
223        mov     %rbx, %r9
224        add     %rdx, %r9
225        sbb     %r11, %r11
226
227        xor     %rax, %r8
228        or      %rbx, %r8
229        sub     %r10, %r8
230        jnz     LABEL(tail)
231
232        xor     %rdx, %r9
233        or      %rbx, %r9
234        sub     %r11, %r9
235        jnz     LABEL(tail)
236
237        cmp     %rdx, %rax
238        jne     LABEL(tail)
239
240        mov     8 (%rsi, %rcx), %rax
241        mov     8 (%rdi, %rcx), %rdx
242        add     $8, %ecx
243
244#ifdef USE_AS_STRNCMP
245	sub	$8, %r14
246	jl	LABEL(tail)
247#endif
248
249        mov     %rbx, %r8
250        add     %rax, %r8
251        sbb     %r10, %r10
252
253        mov     %rbx, %r9
254        add     %rdx, %r9
255        sbb     %r11, %r11
256
257        xor     %rax, %r8
258        or      %rbx, %r8
259        sub     %r10, %r8
260        jnz     LABEL(tail)
261
262        xor     %rdx, %r9
263        or      %rbx, %r9
264        sub     %r11, %r9
265        jnz     LABEL(tail)
266
267        cmp     %rdx, %rax
268        jne     LABEL(tail)
269
270        mov     8 (%rsi, %rcx), %rax
271        mov     8 (%rdi, %rcx), %rdx
272        add     $8, %ecx
273
274#ifdef USE_AS_STRNCMP
275	sub	$8, %r14
276	jl	LABEL(tail)
277#endif
278
279        mov     %rbx, %r8
280        add     %rax, %r8
281        sbb     %r10, %r10
282
283        mov     %rbx, %r9
284        add     %rdx, %r9
285        sbb     %r11, %r11
286
287        xor     %rax, %r8
288        or      %rbx, %r8
289        sub     %r10, %r8
290        jnz     LABEL(tail)
291
292        xor     %rdx, %r9
293        or      %rbx, %r9
294        sub     %r11, %r9
295        jnz     LABEL(tail)
296
297        cmp     %rdx, %rax
298        jne     LABEL(tail)
299
300        mov     8 (%rsi, %rcx), %rax
301        mov     8 (%rdi, %rcx), %rdx
302        add     $8, %ecx
303
304#ifdef USE_AS_STRNCMP
305	sub	$8, %r14
306	jl	LABEL(tail)
307#endif
308
309        mov     %rbx, %r8
310        add     %rax, %r8
311        sbb     %r10, %r10
312
313        mov     %rbx, %r9
314        add     %rdx, %r9
315        sbb     %r11, %r11
316
317        xor     %rax, %r8
318        or      %rbx, %r8
319        sub     %r10, %r8
320        jnz     LABEL(tail)
321
322        xor     %rdx, %r9
323        or      %rbx, %r9
324        sub     %r11, %r9
325        jnz     LABEL(tail)
326
327        cmp     %rdx, %rax
328        jne     LABEL(tail)
329
330        mov     8 (%rsi, %rcx), %rax
331        mov     8 (%rdi, %rcx), %rdx
332        add     $8, %ecx
333
334#ifdef USE_AS_STRNCMP
335	sub	$8, %r14
336	jl	LABEL(tail)
337#endif
338
339        mov     %rbx, %r8
340        add     %rax, %r8
341        sbb     %r10, %r10
342
343        mov     %rbx, %r9
344        add     %rdx, %r9
345        sbb     %r11, %r11
346
347        xor     %rax, %r8
348        or      %rbx, %r8
349        sub     %r10, %r8
350        jnz     LABEL(tail)
351
352        xor     %rdx, %r9
353        or      %rbx, %r9
354        sub     %r11, %r9
355        jnz     LABEL(tail)
356
357        cmp     %rdx, %rax
358        jne     LABEL(tail)
359
360        mov     8 (%rsi, %rcx), %rax
361        mov     8 (%rdi, %rcx), %rdx
362        add     $8, %ecx
363
364#ifdef USE_AS_STRNCMP
365	sub	$8, %r14
366	jl	LABEL(tail)
367#endif
368
369        mov     %rbx, %r8
370        add     %rax, %r8
371        sbb     %r10, %r10
372
373        mov     %rbx, %r9
374        add     %rdx, %r9
375        sbb     %r11, %r11
376
377        xor     %rax, %r8
378        or      %rbx, %r8
379        sub     %r10, %r8
380        jnz     LABEL(tail)
381
382        xor     %rdx, %r9
383        or      %rbx, %r9
384        sub     %r11, %r9
385        jnz     LABEL(tail)
386
387        cmp     %rdx, %rax
388        jne     LABEL(tail)
389
390        add	$8, %ecx
391
392        jmp	LABEL(64loop)
393
394LABEL(64after):
395
396LABEL(tailtry):
397
398LABEL(tail):				/* byte tail */
399#ifdef USE_AS_STRNCMP
400	add	$7, %r14
401#endif
402
403        cmp     %dl, %al		/* check if same character */
404        jne     LABEL(exit)
405        test    %al, %al		/* check if character a NUL */
406        jz      LABEL(exit)
407
408        shr	$8, %rax
409        shr	$8, %rdx
410
411#ifdef USE_AS_STRNCMP
412	dec	%r14
413	jl	LABEL(exit)
414#endif
415
416        cmp     %dl, %al
417        jne     LABEL(exit)
418        test    %al, %al
419        jz      LABEL(exit)
420
421        shr	$8, %rax
422        shr	$8, %rdx
423
424#ifdef USE_AS_STRNCMP
425	dec	%r14
426	jl	LABEL(exit)
427#endif
428
429        cmp     %dl, %al
430        jne     LABEL(exit)
431        test    %al, %al
432        jz      LABEL(exit)
433
434        shr	$8, %rax
435        shr	$8, %rdx
436
437#ifdef USE_AS_STRNCMP
438	dec	%r14
439	jl	LABEL(exit)
440#endif
441
442        cmp     %dl, %al
443        jne     LABEL(exit)
444        test    %al, %al
445        jz      LABEL(exit)
446
447        shr	$8, %rax
448        shr	$8, %rdx
449
450#ifdef USE_AS_STRNCMP
451	dec	%r14
452	jl	LABEL(exit)
453#endif
454
455        cmp     %dl, %al
456        jne     LABEL(exit)
457        test    %al, %al
458        jz      LABEL(exit)
459
460        shr	$8, %eax
461        shr	$8, %edx
462
463#ifdef USE_AS_STRNCMP
464	dec	%r14
465	jl	LABEL(exit)
466#endif
467
468        cmp     %dl, %al
469        jne     LABEL(exit)
470        test    %al, %al
471        jz      LABEL(exit)
472
473        shr	$8, %eax
474        shr	$8, %edx
475
476#ifdef USE_AS_STRNCMP
477	dec	%r14
478	jl	LABEL(exit)
479#endif
480
481        cmp     %dl, %al
482        jne     LABEL(exit)
483        test    %al, %al
484        jz      LABEL(exit)
485
486        shr	$8, %eax
487        shr	$8, %edx
488
489#ifdef USE_AS_STRNCMP
490	dec	%r14
491	jl	LABEL(exit)
492#endif
493
494        cmp     %dl, %al
495        jne     LABEL(exit)
496
497        .p2align 4,, 15
498
499LABEL(tailafter):
500
501LABEL(exit):
502	mov	-32 (%rsp), %r15
503	mov	-24 (%rsp), %rbp
504        mov	-16 (%rsp), %rbx
505
506        .p2align 4,, 3
507
508LABEL(exitafter):
509#ifdef USE_AS_STRNCMP
510	test	%r14, %r14
511	cmovl	%edx, %eax
512#endif
513
514	movzx	%al, %eax
515	movzx	%dl, %edx
516	sub	%eax, %edx
517	xchg	%edx, %eax
518
519#ifdef USE_AS_STRNCMP
520LABEL(exitz):
521	mov	-8 (%rsp), %r14
522#endif
523        ret
524
525#ifdef USE_AS_STRNCMP
526	SET_SIZE(strncmp)
527#else
528	SET_SIZE(strcmp)		/* (const char *, const char *) */
529#endif
530