1/* 2 * CDDL HEADER START 3 * 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. 7 * 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. 12 * 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] 18 * 19 * CDDL HEADER END 20 */ 21/* 22 * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 .file "memchr.s" 27 28/ 29/ memchr(sptr, c1, n) 30/ 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. 33/ 34/ Fast assembly language version of the following C-program memchr 35/ which represents the `standard' for the C-library. 36/ 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; 43/ 44/ do { 45/ if (*sp++ == c) 46/ return ((void *)--sp); 47/ } while (--n != 0); 48/ } 49/ return (NULL); 50/ } 51/ 52 53#include "SYS.h" 54 55 .globl memchr 56 .align 4 57 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) 124