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, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22/* 23 * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 .ident "%Z%%M% %I% %E% SMI" 28 29 .file "%M%" 30 31/ 32/ memchr(sptr, c1, n) 33/ 34/ Returns the pointer in sptr at which the character c1 appears; 35/ or NULL if not found in chars; doesn't stop at \0. 36/ 37/ Fast assembly language version of the following C-program memchr 38/ which represents the `standard' for the C-library. 39/ 40/ void * 41/ memchr(const void *sptr, int c1, size_t n) 42/ { 43/ if (n != 0) { 44/ unsigned char c = (unsigned char)c1; 45/ const unsigned char *sp = sptr; 46/ 47/ do { 48/ if (*sp++ == c) 49/ return ((void *)--sp); 50/ } while (--n != 0); 51/ } 52/ return (NULL); 53/ } 54/ 55 56#include "SYS.h" 57 58 .globl memchr 59 .align 4 60 61 ENTRY(memchr) 62 pushl %edi / save register variable 63 movl 8(%esp), %eax / %eax = string address 64 movl 12(%esp), %ecx / %cl = byte that is sought 65 movl 16(%esp), %edi / %edi = number of bytes 66 cmpl $4, %edi / if number of bytes < 4 67 jb .L1 / goto .L1 68 testl $3, %eax / if %eax not word aligned 69 jnz .L2 / goto .L2 70 .align 4 71.L3: 72 movl (%eax), %edx / move 1 word from (%eax) to %edx 73 cmpb %dl, %cl / if the first byte is %cl 74 je .L4 / goto .L4 (found) 75 cmpb %dh, %cl / if the second byte is %cl 76 je .L5 / goto .L5 (found) 77 shrl $16, %edx / right shift 16-bit 78 cmpb %dl, %cl / if the third byte is %cl 79 je .L6 / goto .L6 (found) 80 cmpb %dh, %cl / if the fourth is %cl 81 je .L7 / goto .L7 (found) 82 subl $4, %edi / decrement number of bytes by 4 83 addl $4, %eax / next word 84 cmpl $4, %edi / if number of bytes >= 4 85 jae .L3 / goto .L3 86.L1: 87 cmpl $0, %edi / if number of bytes == 0 88 jz .L8 / goto .L8 (not found) 89 cmpb (%eax), %cl / if a byte in (%eax) is %cl 90 je .L4 / goto .L4 (found) 91 decl %edi / decrement number of bytes by 1 92 incl %eax / next byte 93 jmp .L1 / goto .L1 94 .align 4 95.L8: 96 xorl %eax, %eax / not found 97 popl %edi / restore register 98 ret / return (0) 99 .align 4 100.L2: 101 cmpl $0, %edi / if number of bytes == 0 102 jz .L8 / goto .L8 (not found) 103 cmpb (%eax), %cl / if a byte in (%eax) is %cl 104 je .L4 / goto .L4 (found) 105 incl %eax / next byte 106 decl %edi / decrement number of bytes by 1 107 testl $3, %eax / if %eax not word aligned 108 jnz .L2 / goto .L2 109 cmpl $4, %edi / if number of bytes >= 4 110 jae .L3 / goto .L3 (word aligned) 111 jmp .L1 / goto .L1 112 .align 4 113.L7: 114 / found at the fourth byte 115 incl %eax 116.L6: 117 / found at the third byte 118 incl %eax 119.L5: 120 / found at the second byte 121 incl %eax 122.L4: 123 / found at the first byte 124 popl %edi / restore register variable 125 ret 126 SET_SIZE(memchr) 127