strchr.s revision 2
1N/A/*
1N/A * CDDL HEADER START
1N/A *
1N/A * The contents of this file are subject to the terms of the
1N/A * Common Development and Distribution License (the "License").
1N/A * You may not use this file except in compliance with the License.
1N/A *
1N/A * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
1N/A * or http://www.opensolaris.org/os/licensing.
1N/A * See the License for the specific language governing permissions
1N/A * and limitations under the License.
1N/A *
1N/A * When distributing Covered Code, include this CDDL HEADER in each
1N/A * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1N/A * If applicable, add the following below this CDDL HEADER, with the
1N/A * fields enclosed by brackets "[]" replaced with your own identifying
1N/A * information: Portions Copyright [yyyy] [name of copyright owner]
1N/A *
1N/A * CDDL HEADER END
1N/A */
1N/A/*
1N/A * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
1N/A * Use is subject to license terms.
1N/A */
1N/A
1N/A .file "strchr.s"
1N/A
1N/A#include "SYS.h"
1N/A
1N/A ENTRY(strchr)
1N/A mov 4(%esp), %ecx / src string here
1N/A mov 8(%esp), %edx / character to find
1N/A mov %ecx, %eax / save src
1N/A and $3, %ecx / check if src is aligned
1N/A jz prepword / search wordwise if it is
1N/A
1N/A cmpb %dl, (%eax) / src == char?
1N/A jz done
1N/A cmpb $0, (%eax) / src == 0?
1N/A jz not_found
1N/A add $1, %eax / increment src
1N/A cmp $3, %ecx / check alignment
1N/A jz prepword
1N/A cmpb %dl, (%eax) / src byte contains char?
1N/A jz done
1N/A cmpb $0, (%eax) / src byte == 0?
1N/A jz not_found
1N/A add $1, %eax / increment src ptr
1N/A cmp $2, %ecx / check alignment
1N/A jz prepword
1N/A cmpb %dl, (%eax) / check this byte
1N/A jz done
1N/A cmpb $0, (%eax) / is byte zero?
1N/A jz not_found
1N/A add $1, %eax / increment src ptr
1N/A
1N/Aprepword:
1N/A push %ebx / save regs per calling convention
1N/A push %esi
1N/A and $0xff, %edx / only want 1st byte
1N/A mov %edx, %ebx / copy character across all bytes in wd
1N/A shl $8, %edx
1N/A or %ebx, %edx
1N/A mov %edx, %ebx
1N/A shl $16, %edx
1N/A or %ebx, %edx
1N/A
1N/A .align 16 / align loop for max performance
1N/A
1N/Asearchchar:
1N/A mov (%eax), %esi / load src word
1N/A add $4, %eax / increment src by four
1N/A mov %esi, %ebx / copy word
1N/A lea -0x01010101(%esi), %ecx / (word - 0x01010101)
1N/A xor %edx, %ebx / tmpword = word ^ char
1N/A not %esi / ~word
1N/A and $0x80808080, %esi / ~word & 0x80808080
1N/A and %ecx, %esi / (wd - 0x01010101) & ~wd & 0x80808080
1N/A jnz has_zero_byte
1N/A lea -0x01010101(%ebx), %ecx / repeat with tmpword
1N/A not %ebx
1N/A and $0x80808080, %ebx
1N/A and %ecx, %ebx
1N/A jz searchchar / repeat if char not found
1N/A
1N/Afound_char:
1N/A add $0x01010101, %ecx / restore tmpword
1N/A pop %esi / restore esi ebx as per calling cvntn
1N/A pop %ebx
1N/A test $0x000000ff, %ecx / look for character's position in word
1N/A jz done0
1N/A test $0x0000ff00, %ecx
1N/A jz done1
1N/A test $0x00ff0000, %ecx
1N/A jz done2
1N/Adone3:
1N/A sub $1, %eax
1N/A ret
1N/Adone2:
1N/A sub $2, %eax
1N/A ret
1N/Adone1:
1N/A sub $3, %eax
1N/A ret
1N/Adone0:
1N/A sub $4, %eax
1N/A ret
1N/Ahas_zero_byte:
1N/A add $0x01010101, %ecx / restore registers here
1N/A pop %esi
1N/A pop %ebx
1N/A cmpb %dl, %cl / check for character
1N/A je done0
1N/A testb %cl, %cl / check for null byte
1N/A jz not_found
1N/A cmpb %dh, %ch / continue checking for char, null
1N/A je done1
1N/A testb %ch, %ch
1N/A jz not_found
1N/A shr $16, %ecx / put bytes 2,3 into 8-but registers
1N/A cmpb %dl, %cl
1N/A je done2
1N/A testb %cl, %cl
1N/A jz not_found
1N/A cmpb %dh, %ch / repeat checking last 2 bytes
1N/A je done3
1N/A testb %ch, %ch
1N/A jz not_found
1N/A sub $1, %eax / correct for last loop iteration
1N/Adone:
1N/A ret
1N/Anot_found:
1N/A xor %eax, %eax
1N/A ret
1N/A SET_SIZE(strchr)
1N/A