import less(1)
[unleashed/tickless.git] / usr / src / lib / libc / i386 / gen / memchr.s
blob92605eb08e2af019ef9c5dd7948cb66b9c2d1726
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 "memchr.s"
29 / memchr(sptr, c1, n)
31 / Returns the pointer in sptr at which the character c1 appears;
32 / or NULL if not found in chars; doesn't stop at \0.
34 / Fast assembly language version of the following C-program memchr
35 / which represents the `standard' for the C-library.
37 / void *
38 / memchr(const void *sptr, int c1, size_t n)
39 / {
40 / if (n != 0) {
41 / unsigned char c = (unsigned char)c1;
42 / const unsigned char *sp = sptr;
44 / do {
45 / if (*sp++ == c)
46 / return ((void *)--sp);
47 / } while (--n != 0);
48 / }
49 / return (NULL);
50 / }
53 #include "SYS.h"
55 .globl memchr
56 .align 4
58 ENTRY(memchr)
59 pushl %edi / save register variable
60 movl 8(%esp), %eax / %eax = string address
61 movl 12(%esp), %ecx / %cl = byte that is sought
62 movl 16(%esp), %edi / %edi = number of bytes
63 cmpl $4, %edi / if number of bytes < 4
64 jb .L1 / goto .L1
65 testl $3, %eax / if %eax not word aligned
66 jnz .L2 / goto .L2
67 .align 4
68 .L3:
69 movl (%eax), %edx / move 1 word from (%eax) to %edx
70 cmpb %dl, %cl / if the first byte is %cl
71 je .L4 / goto .L4 (found)
72 cmpb %dh, %cl / if the second byte is %cl
73 je .L5 / goto .L5 (found)
74 shrl $16, %edx / right shift 16-bit
75 cmpb %dl, %cl / if the third byte is %cl
76 je .L6 / goto .L6 (found)
77 cmpb %dh, %cl / if the fourth is %cl
78 je .L7 / goto .L7 (found)
79 subl $4, %edi / decrement number of bytes by 4
80 addl $4, %eax / next word
81 cmpl $4, %edi / if number of bytes >= 4
82 jae .L3 / goto .L3
83 .L1:
84 cmpl $0, %edi / if number of bytes == 0
85 jz .L8 / goto .L8 (not found)
86 cmpb (%eax), %cl / if a byte in (%eax) is %cl
87 je .L4 / goto .L4 (found)
88 decl %edi / decrement number of bytes by 1
89 incl %eax / next byte
90 jmp .L1 / goto .L1
91 .align 4
92 .L8:
93 xorl %eax, %eax / not found
94 popl %edi / restore register
95 ret / return (0)
96 .align 4
97 .L2:
98 cmpl $0, %edi / if number of bytes == 0
99 jz .L8 / goto .L8 (not found)
100 cmpb (%eax), %cl / if a byte in (%eax) is %cl
101 je .L4 / goto .L4 (found)
102 incl %eax / next byte
103 decl %edi / decrement number of bytes by 1
104 testl $3, %eax / if %eax not word aligned
105 jnz .L2 / goto .L2
106 cmpl $4, %edi / if number of bytes >= 4
107 jae .L3 / goto .L3 (word aligned)
108 jmp .L1 / goto .L1
109 .align 4
110 .L7:
111 / found at the fourth byte
112 incl %eax
113 .L6:
114 / found at the third byte
115 incl %eax
116 .L5:
117 / found at the second byte
118 incl %eax
119 .L4:
120 / found at the first byte
121 popl %edi / restore register variable
122 ret
123 SET_SIZE(memchr)