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 2005 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#include "SYS.h" 32 33 ENTRY(strchr) 34 mov 4(%esp), %ecx / src string here 35 mov 8(%esp), %edx / character to find 36 mov %ecx, %eax / save src 37 and $3, %ecx / check if src is aligned 38 jz prepword / search wordwise if it is 39 40 cmpb %dl, (%eax) / src == char? 41 jz done 42 cmpb $0, (%eax) / src == 0? 43 jz not_found 44 add $1, %eax / increment src 45 cmp $3, %ecx / check alignment 46 jz prepword 47 cmpb %dl, (%eax) / src byte contains char? 48 jz done 49 cmpb $0, (%eax) / src byte == 0? 50 jz not_found 51 add $1, %eax / increment src ptr 52 cmp $2, %ecx / check alignment 53 jz prepword 54 cmpb %dl, (%eax) / check this byte 55 jz done 56 cmpb $0, (%eax) / is byte zero? 57 jz not_found 58 add $1, %eax / increment src ptr 59 60prepword: 61 push %ebx / save regs per calling convention 62 push %esi 63 and $0xff, %edx / only want 1st byte 64 mov %edx, %ebx / copy character across all bytes in wd 65 shl $8, %edx 66 or %ebx, %edx 67 mov %edx, %ebx 68 shl $16, %edx 69 or %ebx, %edx 70 71 .align 16 / align loop for max performance 72 73searchchar: 74 mov (%eax), %esi / load src word 75 add $4, %eax / increment src by four 76 mov %esi, %ebx / copy word 77 lea -0x01010101(%esi), %ecx / (word - 0x01010101) 78 xor %edx, %ebx / tmpword = word ^ char 79 not %esi / ~word 80 and $0x80808080, %esi / ~word & 0x80808080 81 and %ecx, %esi / (wd - 0x01010101) & ~wd & 0x80808080 82 jnz has_zero_byte 83 lea -0x01010101(%ebx), %ecx / repeat with tmpword 84 not %ebx 85 and $0x80808080, %ebx 86 and %ecx, %ebx 87 jz searchchar / repeat if char not found 88 89found_char: 90 add $0x01010101, %ecx / restore tmpword 91 pop %esi / restore esi ebx as per calling cvntn 92 pop %ebx 93 test $0x000000ff, %ecx / look for character's position in word 94 jz done0 95 test $0x0000ff00, %ecx 96 jz done1 97 test $0x00ff0000, %ecx 98 jz done2 99done3: 100 sub $1, %eax 101 ret 102done2: 103 sub $2, %eax 104 ret 105done1: 106 sub $3, %eax 107 ret 108done0: 109 sub $4, %eax 110 ret 111has_zero_byte: 112 add $0x01010101, %ecx / restore registers here 113 pop %esi 114 pop %ebx 115 cmpb %dl, %cl / check for character 116 je done0 117 testb %cl, %cl / check for null byte 118 jz not_found 119 cmpb %dh, %ch / continue checking for char, null 120 je done1 121 testb %ch, %ch 122 jz not_found 123 shr $16, %ecx / put bytes 2,3 into 8-but registers 124 cmpb %dl, %cl 125 je done2 126 testb %cl, %cl 127 jz not_found 128 cmpb %dh, %ch / repeat checking last 2 bytes 129 je done3 130 testb %ch, %ch 131 jz not_found 132 sub $1, %eax / correct for last loop iteration 133done: 134 ret 135not_found: 136 xor %eax, %eax 137 ret 138 SET_SIZE(strchr) 139