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