/* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License (the "License"). * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright 2004 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ .file "memchr.s" / / memchr(sptr, c1, n) / / Returns the pointer in sptr at which the character c1 appears; / or NULL if not found in chars; doesn't stop at \0. / / Fast assembly language version of the following C-program memchr / which represents the `standard' for the C-library. / / void * / memchr(const void *sptr, int c1, size_t n) / { / if (n != 0) { / unsigned char c = (unsigned char)c1; / const unsigned char *sp = sptr; / / do { / if (*sp++ == c) / return ((void *)--sp); / } while (--n != 0); / } / return (NULL); / } / #include "SYS.h" .globl memchr .align 4 ENTRY(memchr) pushl %edi / save register variable movl 8(%esp), %eax / %eax = string address movl 12(%esp), %ecx / %cl = byte that is sought movl 16(%esp), %edi / %edi = number of bytes cmpl $4, %edi / if number of bytes < 4 jb .L1 / goto .L1 testl $3, %eax / if %eax not word aligned jnz .L2 / goto .L2 .align 4 .L3: movl (%eax), %edx / move 1 word from (%eax) to %edx cmpb %dl, %cl / if the first byte is %cl je .L4 / goto .L4 (found) cmpb %dh, %cl / if the second byte is %cl je .L5 / goto .L5 (found) shrl $16, %edx / right shift 16-bit cmpb %dl, %cl / if the third byte is %cl je .L6 / goto .L6 (found) cmpb %dh, %cl / if the fourth is %cl je .L7 / goto .L7 (found) subl $4, %edi / decrement number of bytes by 4 addl $4, %eax / next word cmpl $4, %edi / if number of bytes >= 4 jae .L3 / goto .L3 .L1: cmpl $0, %edi / if number of bytes == 0 jz .L8 / goto .L8 (not found) cmpb (%eax), %cl / if a byte in (%eax) is %cl je .L4 / goto .L4 (found) decl %edi / decrement number of bytes by 1 incl %eax / next byte jmp .L1 / goto .L1 .align 4 .L8: xorl %eax, %eax / not found popl %edi / restore register ret / return (0) .align 4 .L2: cmpl $0, %edi / if number of bytes == 0 jz .L8 / goto .L8 (not found) cmpb (%eax), %cl / if a byte in (%eax) is %cl je .L4 / goto .L4 (found) incl %eax / next byte decl %edi / decrement number of bytes by 1 testl $3, %eax / if %eax not word aligned jnz .L2 / goto .L2 cmpl $4, %edi / if number of bytes >= 4 jae .L3 / goto .L3 (word aligned) jmp .L1 / goto .L1 .align 4 .L7: / found at the fourth byte incl %eax .L6: / found at the third byte incl %eax .L5: / found at the second byte incl %eax .L4: / found at the first byte popl %edi / restore register variable ret SET_SIZE(memchr)