xref: /titanic_50/usr/src/lib/libc/amd64/gen/strcmp.s (revision d29f5a711240f866521445b1656d114da090335e)
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	.file	"strcmp.s"
49
50#include "SYS.h"
51#include "cache.h"
52
53#define LABEL(s) .strcmp/**/s
54
55#ifdef USE_AS_STRNCMP
56	ENTRY(strncmp)
57#else
58	ENTRY(strcmp)			/* (const char *, const char *) */
59#endif
60        xor     %ecx, %ecx
61
62#ifdef USE_AS_STRNCMP
63	test	%rdx, %rdx		/* (const char *, const char *, size_t) */
64        mov	%r14, -8 (%rsp)
65	mov	%rdx, %r14
66	mov	%edx, %eax
67	jz	LABEL(exitz)		/* early exit */
68#endif
69
70LABEL(aligntry):
71        mov     %rsi, %r8		/* align by "source" */
72        and     $8 - 1, %r8		/* between 0 and 8 characters compared */
73	jz	LABEL(alignafter)
74
75LABEL(align):
76        sub     $8, %r8
77
78        .p2align 4
79
80LABEL(alignloop):
81        mov     (%rsi, %rcx), %al
82        mov	(%rdi, %rcx), %dl
83
84#ifdef USE_AS_STRNCMP
85	dec	%r14
86	jl	LABEL(exitafter)
87#endif
88
89        cmp     %dl, %al		/* check if same character */
90        jne     LABEL(exitafter)
91        test    %al, %al		/* check if character a NUL */
92        jz      LABEL(exitafter)
93
94        inc     %ecx
95
96        inc     %r8
97        jnz     LABEL(alignloop)
98
99        .p2align 4
100
101LABEL(alignafter):
102
103        mov	%r15, -32 (%rsp)
104        mov	%rbp, -24 (%rsp)
105        mov	%rbx, -16 (%rsp)
106
107LABEL(pagealigntry):			/* page align by "destination" */
108        lea	(%rdi, %rcx), %ebp
109	mov	$AMD64PAGESIZE, %r15d
110        and     $AMD64PAGEMASK, %ebp
111        sub	%r15d, %ebp
112
113LABEL(64):                              /* 64-byte */
114	mov     $0xfefefefefefefeff, %rbx /* magic number */
115
116        .p2align 4
117
118LABEL(64loop):
119	add	$64, %ebp		/* check if "destination" crosses a page unevenly */
120	jle	LABEL(64gobble)
121
122        sub	%r15d, %ebp
123        lea	64 (%rcx), %r8
124
125        .p2align 4
126
127LABEL(64nibble):
128        mov     (%rsi, %rcx), %al
129        mov	(%rdi, %rcx), %dl
130
131#ifdef USE_AS_STRNCMP
132	dec	%r14
133	jl	LABEL(exit)
134#endif
135
136        cmp     %dl, %al		/* check if same character */
137        jne     LABEL(exit)
138        test    %al, %al		/* check if character a NUL */
139        jz      LABEL(exit)
140
141        inc	%ecx
142
143        cmp	%ecx, %r8d
144        ja	LABEL(64nibble)
145
146        .p2align 4
147
148LABEL(64gobble):
149        mov     (%rsi, %rcx), %rax
150        mov     (%rdi, %rcx), %rdx
151
152#ifdef USE_AS_STRNCMP
153	sub	$8, %r14
154	jl	LABEL(tail)
155#endif
156
157        mov     %rbx, %r8
158        add     %rax, %r8
159        sbb     %r10, %r10
160
161        mov     %rbx, %r9
162        add     %rdx, %r9
163        sbb     %r11, %r11
164
165        xor     %rax, %r8
166        or      %rbx, %r8
167        sub     %r10, %r8
168        jnz     LABEL(tail)
169
170        xor     %rdx, %r9
171        or      %rbx, %r9
172        sub     %r11, %r9
173        jnz     LABEL(tail)
174
175        cmp     %rdx, %rax
176        jne     LABEL(tail)
177
178        mov     8 (%rsi, %rcx), %rax
179        mov     8 (%rdi, %rcx), %rdx
180        add     $8, %ecx
181
182#ifdef USE_AS_STRNCMP
183	sub	$8, %r14
184	jl	LABEL(tail)
185#endif
186
187        mov     %rbx, %r8
188        add     %rax, %r8
189        sbb     %r10, %r10
190
191        mov     %rbx, %r9
192        add     %rdx, %r9
193        sbb     %r11, %r11
194
195        xor     %rax, %r8
196        or      %rbx, %r8
197        sub     %r10, %r8
198        jnz     LABEL(tail)
199
200        xor     %rdx, %r9
201        or      %rbx, %r9
202        sub     %r11, %r9
203        jnz     LABEL(tail)
204
205        cmp     %rdx, %rax
206        jne     LABEL(tail)
207
208        mov     8 (%rsi, %rcx), %rax
209        mov     8 (%rdi, %rcx), %rdx
210        add     $8, %ecx
211
212#ifdef USE_AS_STRNCMP
213	sub	$8, %r14
214	jl	LABEL(tail)
215#endif
216
217        mov     %rbx, %r8
218        add     %rax, %r8
219        sbb     %r10, %r10
220
221        mov     %rbx, %r9
222        add     %rdx, %r9
223        sbb     %r11, %r11
224
225        xor     %rax, %r8
226        or      %rbx, %r8
227        sub     %r10, %r8
228        jnz     LABEL(tail)
229
230        xor     %rdx, %r9
231        or      %rbx, %r9
232        sub     %r11, %r9
233        jnz     LABEL(tail)
234
235        cmp     %rdx, %rax
236        jne     LABEL(tail)
237
238        mov     8 (%rsi, %rcx), %rax
239        mov     8 (%rdi, %rcx), %rdx
240        add     $8, %ecx
241
242#ifdef USE_AS_STRNCMP
243	sub	$8, %r14
244	jl	LABEL(tail)
245#endif
246
247        mov     %rbx, %r8
248        add     %rax, %r8
249        sbb     %r10, %r10
250
251        mov     %rbx, %r9
252        add     %rdx, %r9
253        sbb     %r11, %r11
254
255        xor     %rax, %r8
256        or      %rbx, %r8
257        sub     %r10, %r8
258        jnz     LABEL(tail)
259
260        xor     %rdx, %r9
261        or      %rbx, %r9
262        sub     %r11, %r9
263        jnz     LABEL(tail)
264
265        cmp     %rdx, %rax
266        jne     LABEL(tail)
267
268        mov     8 (%rsi, %rcx), %rax
269        mov     8 (%rdi, %rcx), %rdx
270        add     $8, %ecx
271
272#ifdef USE_AS_STRNCMP
273	sub	$8, %r14
274	jl	LABEL(tail)
275#endif
276
277        mov     %rbx, %r8
278        add     %rax, %r8
279        sbb     %r10, %r10
280
281        mov     %rbx, %r9
282        add     %rdx, %r9
283        sbb     %r11, %r11
284
285        xor     %rax, %r8
286        or      %rbx, %r8
287        sub     %r10, %r8
288        jnz     LABEL(tail)
289
290        xor     %rdx, %r9
291        or      %rbx, %r9
292        sub     %r11, %r9
293        jnz     LABEL(tail)
294
295        cmp     %rdx, %rax
296        jne     LABEL(tail)
297
298        mov     8 (%rsi, %rcx), %rax
299        mov     8 (%rdi, %rcx), %rdx
300        add     $8, %ecx
301
302#ifdef USE_AS_STRNCMP
303	sub	$8, %r14
304	jl	LABEL(tail)
305#endif
306
307        mov     %rbx, %r8
308        add     %rax, %r8
309        sbb     %r10, %r10
310
311        mov     %rbx, %r9
312        add     %rdx, %r9
313        sbb     %r11, %r11
314
315        xor     %rax, %r8
316        or      %rbx, %r8
317        sub     %r10, %r8
318        jnz     LABEL(tail)
319
320        xor     %rdx, %r9
321        or      %rbx, %r9
322        sub     %r11, %r9
323        jnz     LABEL(tail)
324
325        cmp     %rdx, %rax
326        jne     LABEL(tail)
327
328        mov     8 (%rsi, %rcx), %rax
329        mov     8 (%rdi, %rcx), %rdx
330        add     $8, %ecx
331
332#ifdef USE_AS_STRNCMP
333	sub	$8, %r14
334	jl	LABEL(tail)
335#endif
336
337        mov     %rbx, %r8
338        add     %rax, %r8
339        sbb     %r10, %r10
340
341        mov     %rbx, %r9
342        add     %rdx, %r9
343        sbb     %r11, %r11
344
345        xor     %rax, %r8
346        or      %rbx, %r8
347        sub     %r10, %r8
348        jnz     LABEL(tail)
349
350        xor     %rdx, %r9
351        or      %rbx, %r9
352        sub     %r11, %r9
353        jnz     LABEL(tail)
354
355        cmp     %rdx, %rax
356        jne     LABEL(tail)
357
358        mov     8 (%rsi, %rcx), %rax
359        mov     8 (%rdi, %rcx), %rdx
360        add     $8, %ecx
361
362#ifdef USE_AS_STRNCMP
363	sub	$8, %r14
364	jl	LABEL(tail)
365#endif
366
367        mov     %rbx, %r8
368        add     %rax, %r8
369        sbb     %r10, %r10
370
371        mov     %rbx, %r9
372        add     %rdx, %r9
373        sbb     %r11, %r11
374
375        xor     %rax, %r8
376        or      %rbx, %r8
377        sub     %r10, %r8
378        jnz     LABEL(tail)
379
380        xor     %rdx, %r9
381        or      %rbx, %r9
382        sub     %r11, %r9
383        jnz     LABEL(tail)
384
385        cmp     %rdx, %rax
386        jne     LABEL(tail)
387
388        add	$8, %ecx
389
390        jmp	LABEL(64loop)
391
392LABEL(64after):
393
394LABEL(tailtry):
395
396LABEL(tail):				/* byte tail */
397#ifdef USE_AS_STRNCMP
398	add	$7, %r14
399#endif
400
401        cmp     %dl, %al		/* check if same character */
402        jne     LABEL(exit)
403        test    %al, %al		/* check if character a NUL */
404        jz      LABEL(exit)
405
406        shr	$8, %rax
407        shr	$8, %rdx
408
409#ifdef USE_AS_STRNCMP
410	dec	%r14
411	jl	LABEL(exit)
412#endif
413
414        cmp     %dl, %al
415        jne     LABEL(exit)
416        test    %al, %al
417        jz      LABEL(exit)
418
419        shr	$8, %rax
420        shr	$8, %rdx
421
422#ifdef USE_AS_STRNCMP
423	dec	%r14
424	jl	LABEL(exit)
425#endif
426
427        cmp     %dl, %al
428        jne     LABEL(exit)
429        test    %al, %al
430        jz      LABEL(exit)
431
432        shr	$8, %rax
433        shr	$8, %rdx
434
435#ifdef USE_AS_STRNCMP
436	dec	%r14
437	jl	LABEL(exit)
438#endif
439
440        cmp     %dl, %al
441        jne     LABEL(exit)
442        test    %al, %al
443        jz      LABEL(exit)
444
445        shr	$8, %rax
446        shr	$8, %rdx
447
448#ifdef USE_AS_STRNCMP
449	dec	%r14
450	jl	LABEL(exit)
451#endif
452
453        cmp     %dl, %al
454        jne     LABEL(exit)
455        test    %al, %al
456        jz      LABEL(exit)
457
458        shr	$8, %eax
459        shr	$8, %edx
460
461#ifdef USE_AS_STRNCMP
462	dec	%r14
463	jl	LABEL(exit)
464#endif
465
466        cmp     %dl, %al
467        jne     LABEL(exit)
468        test    %al, %al
469        jz      LABEL(exit)
470
471        shr	$8, %eax
472        shr	$8, %edx
473
474#ifdef USE_AS_STRNCMP
475	dec	%r14
476	jl	LABEL(exit)
477#endif
478
479        cmp     %dl, %al
480        jne     LABEL(exit)
481        test    %al, %al
482        jz      LABEL(exit)
483
484        shr	$8, %eax
485        shr	$8, %edx
486
487#ifdef USE_AS_STRNCMP
488	dec	%r14
489	jl	LABEL(exit)
490#endif
491
492        cmp     %dl, %al
493        jne     LABEL(exit)
494
495        .p2align 4,, 15
496
497LABEL(tailafter):
498
499LABEL(exit):
500	mov	-32 (%rsp), %r15
501	mov	-24 (%rsp), %rbp
502        mov	-16 (%rsp), %rbx
503
504        .p2align 4,, 3
505
506LABEL(exitafter):
507#ifdef USE_AS_STRNCMP
508	test	%r14, %r14
509	cmovl	%edx, %eax
510#endif
511
512	movzx	%al, %eax
513	movzx	%dl, %edx
514	sub	%eax, %edx
515	xchg	%edx, %eax
516
517#ifdef USE_AS_STRNCMP
518LABEL(exitz):
519	mov	-8 (%rsp), %r14
520#endif
521        ret
522
523#ifdef USE_AS_STRNCMP
524	SET_SIZE(strncmp)
525#else
526	SET_SIZE(strcmp)		/* (const char *, const char *) */
527#endif
528