import less(1)
[unleashed/tickless.git] / usr / src / lib / libc / amd64 / gen / memchr.s
blob6491017e970854924174ed559a8da4278f84e959
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) /* (void *s, uchar_t c, size_t n) */
59 movl %esi, %eax / move "c" to %eax
60 cmpq $4, %rdx / if number of bytes < 4
61 jb .L1 / goto .L1
62 testq $3, %rdi / if %rdi not word aligned
63 jnz .L2 / goto .L2
64 .align 4
65 .L3:
66 movl (%rdi), %ecx / move 1 word from (%rdi) to %ecx
67 cmpb %cl, %al / if the first byte is %al
68 je .L4 / goto .L4 (found)
69 cmpb %ch, %al / if the second byte is %al
70 je .L5 / goto .L5 (found)
71 shrl $16, %ecx / right shift 16-bit
72 cmpb %cl, %al / if the third byte is %al
73 je .L6 / goto .L6 (found)
74 cmpb %ch, %al / if the fourth is %al
75 je .L7 / goto .L7 (found)
76 subq $4, %rdx / decrement number of bytes by 4
77 addq $4, %rdi / next word
78 cmpq $4, %rdx / if number of bytes >= 4
79 jae .L3 / goto .L3
80 .L1:
81 cmpq $0, %rdx / if number of bytes == 0
82 jz .L8 / goto .L8 (not found)
83 cmpb (%rdi), %al / if a byte in (%rdi) is %al
84 je .L4 / goto .L4 (found)
85 decq %rdx / decrement number of bytes by 1
86 incq %rdi / next byte
87 jmp .L1 / goto .L1
88 .align 4
89 .L8:
90 xorl %eax, %eax / not found
91 ret / return (0)
92 .align 4
93 .L2:
94 cmpq $0, %rdx / if number of bytes == 0
95 jz .L8 / goto .L8 (not found)
96 cmpb (%rdi), %al / if a byte in (%rdi) is %al
97 je .L4 / goto .L4 (found)
98 incq %rdi / next byte
99 decq %rdx / decrement number of bytes by 1
100 testq $3, %rdi / if %rdi not word aligned
101 jnz .L2 / goto .L2
102 cmpq $4, %rdx / if number of bytes >= 4
103 jae .L3 / goto .L3 (word aligned)
104 jmp .L1 / goto .L1
105 .align 4
106 .L7:
107 / found at the fourth byte
108 incq %rdi
109 .L6:
110 / found at the third byte
111 incq %rdi
112 .L5:
113 / found at the second byte
114 incq %rdi
115 .L4:
116 / found at the first byte
117 movq %rdi,%rax
118 ret
119 SET_SIZE(memchr)