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