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