5863 psiginfo arguments should be const
[unleashed.git] / usr / src / lib / libc / i386 / gen / memcmp.s
blob92442ff024e0223e17e130cb83ddce9dbbce93e7
1 /*
2 * CDDL HEADER START
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
19 * CDDL HEADER END
22 * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
26 .file "memcmp.s"
29 / memcmp(s1, s2, n)
31 / Compares n bytes: s1>s2: >0 s1==s2: 0 s1<s2: <0
33 / Fast assembly language version of the following C-program strcat
34 / which represents the `standard' for the C-library.
36 / int
37 / memcmp(const void *s1, const void *s2, size_t n)
38 / {
39 / if (s1 != s2 && n != 0) {
40 / const unsigned char *ps1 = s1;
41 / const unsigned char *ps2 = s2;
43 / do {
44 / if (*ps1++ != *ps2++)
45 / return (ps1[-1] - ps2[-1]);
46 / } while (--n != 0);
47 / }
48 / return (NULL);
49 / }
51 / This implementation conforms to SVID but does not implement
52 / the same algorithm as the portable version because it is
53 / inconvenient to get the difference of the differing characters.
55 #include <sys/asm_linkage.h>
57 ANSI_PRAGMA_WEAK(memcmp,function)
59 #include "SYS.h"
61 ENTRY(memcmp)
62 pushl %edi / save register variable
63 movl 8(%esp), %eax / %eax = address of string 1
64 movl 12(%esp), %ecx / %ecx = address of string 2
65 cmpl %eax, %ecx / if the same string
66 je .equal / goto .equal
67 movl 16(%esp), %edi / %edi = length in bytes
68 cmpl $4, %edi / if %edi < 4
69 jb .byte_check / goto .byte_check
70 .align 4
71 .word_loop:
72 movl (%ecx), %edx / move 1 word from (%ecx) to %edx
73 leal -4(%edi), %edi / %edi -= 4
74 cmpl (%eax), %edx / compare 1 word from (%eax) with %edx
75 jne .word_not_equal / if not equal, goto .word_not_equal
76 leal 4(%ecx), %ecx / %ecx += 4 (next word)
77 leal 4(%eax), %eax / %eax += 4 (next word)
78 cmpl $4, %edi / if %edi >= 4
79 jae .word_loop / goto .word_loop
80 .byte_check:
81 cmpl $0, %edi / if %edi == 0
82 je .equal / goto .equal
83 jmp .byte_loop / goto .byte_loop (checks in bytes)
84 .word_not_equal:
85 leal 4(%edi), %edi / %edi += 4 (post-decremented)
86 .align 4
87 .byte_loop:
88 movb (%ecx), %dl / move 1 byte from (%ecx) to %dl
89 cmpb %dl, (%eax) / compare %dl with 1 byte from (%eax)
90 jne .not_equal / if not equal, goto .not_equal
91 incl %ecx / %ecx++ (next byte)
92 incl %eax / %eax++ (next byte)
93 decl %edi / %edi--
94 jnz .byte_loop / if not zero, goto .byte_loop
95 .equal:
96 xorl %eax, %eax / %eax = 0
97 popl %edi / restore register variable
98 ret / return (NULL)
99 .align 4
100 .not_equal:
101 sbbl %eax, %eax / %eax = 0 if no carry, %eax = -1 if carry
102 orl $1, %eax / %eax = 1 if no carry, %eax = -1 if carry
103 popl %edi / restore register variable
104 ret / return (NULL)
105 SET_SIZE(memcmp)