1*5d9d9091SRichard Lowe/* 2*5d9d9091SRichard Lowe * CDDL HEADER START 3*5d9d9091SRichard Lowe * 4*5d9d9091SRichard Lowe * The contents of this file are subject to the terms of the 5*5d9d9091SRichard Lowe * Common Development and Distribution License (the "License"). 6*5d9d9091SRichard Lowe * You may not use this file except in compliance with the License. 7*5d9d9091SRichard Lowe * 8*5d9d9091SRichard Lowe * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*5d9d9091SRichard Lowe * or http://www.opensolaris.org/os/licensing. 10*5d9d9091SRichard Lowe * See the License for the specific language governing permissions 11*5d9d9091SRichard Lowe * and limitations under the License. 12*5d9d9091SRichard Lowe * 13*5d9d9091SRichard Lowe * When distributing Covered Code, include this CDDL HEADER in each 14*5d9d9091SRichard Lowe * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*5d9d9091SRichard Lowe * If applicable, add the following below this CDDL HEADER, with the 16*5d9d9091SRichard Lowe * fields enclosed by brackets "[]" replaced with your own identifying 17*5d9d9091SRichard Lowe * information: Portions Copyright [yyyy] [name of copyright owner] 18*5d9d9091SRichard Lowe * 19*5d9d9091SRichard Lowe * CDDL HEADER END 20*5d9d9091SRichard Lowe */ 21*5d9d9091SRichard Lowe/* 22*5d9d9091SRichard Lowe * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 23*5d9d9091SRichard Lowe * Use is subject to license terms. 24*5d9d9091SRichard Lowe */ 25*5d9d9091SRichard Lowe 26*5d9d9091SRichard Lowe .file "strchr.s" 27*5d9d9091SRichard Lowe 28*5d9d9091SRichard Lowe#include "SYS.h" 29*5d9d9091SRichard Lowe 30*5d9d9091SRichard Lowe ENTRY(strchr) 31*5d9d9091SRichard Lowe mov 4(%esp), %ecx / src string here 32*5d9d9091SRichard Lowe mov 8(%esp), %edx / character to find 33*5d9d9091SRichard Lowe mov %ecx, %eax / save src 34*5d9d9091SRichard Lowe and $3, %ecx / check if src is aligned 35*5d9d9091SRichard Lowe jz prepword / search wordwise if it is 36*5d9d9091SRichard Lowe 37*5d9d9091SRichard Lowe cmpb %dl, (%eax) / src == char? 38*5d9d9091SRichard Lowe jz done 39*5d9d9091SRichard Lowe cmpb $0, (%eax) / src == 0? 40*5d9d9091SRichard Lowe jz not_found 41*5d9d9091SRichard Lowe add $1, %eax / increment src 42*5d9d9091SRichard Lowe cmp $3, %ecx / check alignment 43*5d9d9091SRichard Lowe jz prepword 44*5d9d9091SRichard Lowe cmpb %dl, (%eax) / src byte contains char? 45*5d9d9091SRichard Lowe jz done 46*5d9d9091SRichard Lowe cmpb $0, (%eax) / src byte == 0? 47*5d9d9091SRichard Lowe jz not_found 48*5d9d9091SRichard Lowe add $1, %eax / increment src ptr 49*5d9d9091SRichard Lowe cmp $2, %ecx / check alignment 50*5d9d9091SRichard Lowe jz prepword 51*5d9d9091SRichard Lowe cmpb %dl, (%eax) / check this byte 52*5d9d9091SRichard Lowe jz done 53*5d9d9091SRichard Lowe cmpb $0, (%eax) / is byte zero? 54*5d9d9091SRichard Lowe jz not_found 55*5d9d9091SRichard Lowe add $1, %eax / increment src ptr 56*5d9d9091SRichard Lowe 57*5d9d9091SRichard Loweprepword: 58*5d9d9091SRichard Lowe push %ebx / save regs per calling convention 59*5d9d9091SRichard Lowe push %esi 60*5d9d9091SRichard Lowe and $0xff, %edx / only want 1st byte 61*5d9d9091SRichard Lowe mov %edx, %ebx / copy character across all bytes in wd 62*5d9d9091SRichard Lowe shl $8, %edx 63*5d9d9091SRichard Lowe or %ebx, %edx 64*5d9d9091SRichard Lowe mov %edx, %ebx 65*5d9d9091SRichard Lowe shl $16, %edx 66*5d9d9091SRichard Lowe or %ebx, %edx 67*5d9d9091SRichard Lowe 68*5d9d9091SRichard Lowe .align 16 / align loop for max performance 69*5d9d9091SRichard Lowe 70*5d9d9091SRichard Lowesearchchar: 71*5d9d9091SRichard Lowe mov (%eax), %esi / load src word 72*5d9d9091SRichard Lowe add $4, %eax / increment src by four 73*5d9d9091SRichard Lowe mov %esi, %ebx / copy word 74*5d9d9091SRichard Lowe lea -0x01010101(%esi), %ecx / (word - 0x01010101) 75*5d9d9091SRichard Lowe xor %edx, %ebx / tmpword = word ^ char 76*5d9d9091SRichard Lowe not %esi / ~word 77*5d9d9091SRichard Lowe and $0x80808080, %esi / ~word & 0x80808080 78*5d9d9091SRichard Lowe and %ecx, %esi / (wd - 0x01010101) & ~wd & 0x80808080 79*5d9d9091SRichard Lowe jnz has_zero_byte 80*5d9d9091SRichard Lowe lea -0x01010101(%ebx), %ecx / repeat with tmpword 81*5d9d9091SRichard Lowe not %ebx 82*5d9d9091SRichard Lowe and $0x80808080, %ebx 83*5d9d9091SRichard Lowe and %ecx, %ebx 84*5d9d9091SRichard Lowe jz searchchar / repeat if char not found 85*5d9d9091SRichard Lowe 86*5d9d9091SRichard Lowefound_char: 87*5d9d9091SRichard Lowe add $0x01010101, %ecx / restore tmpword 88*5d9d9091SRichard Lowe pop %esi / restore esi ebx as per calling cvntn 89*5d9d9091SRichard Lowe pop %ebx 90*5d9d9091SRichard Lowe test $0x000000ff, %ecx / look for character's position in word 91*5d9d9091SRichard Lowe jz done0 92*5d9d9091SRichard Lowe test $0x0000ff00, %ecx 93*5d9d9091SRichard Lowe jz done1 94*5d9d9091SRichard Lowe test $0x00ff0000, %ecx 95*5d9d9091SRichard Lowe jz done2 96*5d9d9091SRichard Lowedone3: 97*5d9d9091SRichard Lowe sub $1, %eax 98*5d9d9091SRichard Lowe ret 99*5d9d9091SRichard Lowedone2: 100*5d9d9091SRichard Lowe sub $2, %eax 101*5d9d9091SRichard Lowe ret 102*5d9d9091SRichard Lowedone1: 103*5d9d9091SRichard Lowe sub $3, %eax 104*5d9d9091SRichard Lowe ret 105*5d9d9091SRichard Lowedone0: 106*5d9d9091SRichard Lowe sub $4, %eax 107*5d9d9091SRichard Lowe ret 108*5d9d9091SRichard Lowehas_zero_byte: 109*5d9d9091SRichard Lowe add $0x01010101, %ecx / restore registers here 110*5d9d9091SRichard Lowe pop %esi 111*5d9d9091SRichard Lowe pop %ebx 112*5d9d9091SRichard Lowe cmpb %dl, %cl / check for character 113*5d9d9091SRichard Lowe je done0 114*5d9d9091SRichard Lowe testb %cl, %cl / check for null byte 115*5d9d9091SRichard Lowe jz not_found 116*5d9d9091SRichard Lowe cmpb %dh, %ch / continue checking for char, null 117*5d9d9091SRichard Lowe je done1 118*5d9d9091SRichard Lowe testb %ch, %ch 119*5d9d9091SRichard Lowe jz not_found 120*5d9d9091SRichard Lowe shr $16, %ecx / put bytes 2,3 into 8-but registers 121*5d9d9091SRichard Lowe cmpb %dl, %cl 122*5d9d9091SRichard Lowe je done2 123*5d9d9091SRichard Lowe testb %cl, %cl 124*5d9d9091SRichard Lowe jz not_found 125*5d9d9091SRichard Lowe cmpb %dh, %ch / repeat checking last 2 bytes 126*5d9d9091SRichard Lowe je done3 127*5d9d9091SRichard Lowe testb %ch, %ch 128*5d9d9091SRichard Lowe jz not_found 129*5d9d9091SRichard Lowe sub $1, %eax / correct for last loop iteration 130*5d9d9091SRichard Lowedone: 131*5d9d9091SRichard Lowe ret 132*5d9d9091SRichard Lowenot_found: 133*5d9d9091SRichard Lowe xor %eax, %eax 134*5d9d9091SRichard Lowe ret 135*5d9d9091SRichard Lowe SET_SIZE(strchr) 136