Index: b/usr/src/lib/libc/amd64/gen/rawmemchr.s =================================================================== --- /dev/null +++ b/usr/src/lib/libc/amd64/gen/rawmemchr.s @@ -0,0 +1,96 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + + .file "rawmemchr.s" + +/ +/ rawmemchr(sptr, c1) +/ +/ Returns the pointer in sptr at which the character c1 appears; +/ doesn't stop at all +/ +/ Fast assembly language version of the following C-program memchr +/ which represents the `standard' for the C-library. +/ +/ void * +/ rawmemchr(const void *sptr, int c1) +/ { +/ unsigned char c = (unsigned char)c1; +/ const unsigned char *sp = sptr; +/ +/ do { +/ if (*sp++ == c) +/ return ((void *)--sp); +/ } while (1); +/ return (NULL); +/ } +/ + +#include "SYS.h" + + .globl rawmemchr + .align 4 + + ENTRY(rawmemchr) /* (void *s, uchar_t c) */ + movl %esi, %eax / move "c" to %eax + testq $3, %rdi / if %rdi not word aligned + jnz .L2 / goto .L2 + .align 4 +.L3: + movl (%rdi), %ecx / move 1 word from (%rdi) to %ecx + cmpb %cl, %al / if the first byte is %al + je .L4 / goto .L4 (found) + cmpb %ch, %al / if the second byte is %al + je .L5 / goto .L5 (found) + shrl $16, %ecx / right shift 16-bit + cmpb %cl, %al / if the third byte is %al + je .L6 / goto .L6 (found) + cmpb %ch, %al / if the fourth is %al + je .L7 / goto .L7 (found) + addq $4, %rdi / next word + jmp .L3 / goto .L3 + .align 4 +.L2: + cmpb (%rdi), %al / if a byte in (%rdi) is %al + je .L4 / goto .L4 (found) + incq %rdi / next byte + testq $3, %rdi / if %rdi not word aligned + jnz .L2 / goto .L2 + jmp .L3 / goto .L3 + .align 4 +.L7: + / found at the fourth byte + incq %rdi +.L6: + / found at the third byte + incq %rdi +.L5: + / found at the second byte + incq %rdi +.L4: + / found at the first byte + movq %rdi,%rax + ret + SET_SIZE(rawmemchr) Index: b/usr/src/lib/libc/amd64/Makefile =================================================================== --- a/usr/src/lib/libc/amd64/Makefile +++ b/usr/src/lib/libc/amd64/Makefile @@ -129,6 +129,7 @@ GENOBJS= \ new_list.o \ proc64_id.o \ proc64_support.o \ + rawmemchr.o \ setjmp.o \ siginfolst.o \ siglongjmp.o \ Index: b/usr/src/lib/libc/port/mapfile-vers =================================================================== --- a/usr/src/lib/libc/port/mapfile-vers +++ b/usr/src/lib/libc/port/mapfile-vers @@ -279,6 +279,7 @@ SYMBOL_VERSION DYSON_1 { memrchr; program_invocation_name; program_invocation_short_name; + rawmemchr; } ILLUMOS_0.3; SYMBOL_VERSION ILLUMOS_0.3 { # Illumos additions Index: b/usr/src/lib/libc/i386/gen/rawmemchr.s =================================================================== --- /dev/null +++ b/usr/src/lib/libc/i386/gen/rawmemchr.s @@ -0,0 +1,100 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + + .file "rawmemchr.s" + +/ +/ rawmemchr(sptr, c1) +/ +/ Returns the pointer in sptr at which the character c1 appears; +/ doesn't stop at all +/ +/ Fast assembly language version of the following C-program memchr +/ which represents the `standard' for the C-library. +/ +/ void * +/ rawmemchr(const void *sptr, int c1) +/ { +/ unsigned char c = (unsigned char)c1; +/ const unsigned char *sp = sptr; +/ +/ do { +/ if (*sp++ == c) +/ return ((void *)--sp); +/ } while (1); +/ return (NULL); +/ } +/ + +#include "SYS.h" + + .globl rawmemchr + .align 4 + + ENTRY(rawmemchr) + pushl %edi / save register variable + movl 8(%esp), %eax / %eax = string address + movl 12(%esp), %ecx / %cl = byte that is sought + testl $3, %eax / if %eax not word aligned + jnz .L2 / goto .L2 + .align 4 +.L3: + movl (%eax), %edx / move 1 word from (%eax) to %edx + cmpb %dl, %cl / if the first byte is %cl + je .L4 / goto .L4 (found) + cmpb %dh, %cl / if the second byte is %cl + je .L5 / goto .L5 (found) + shrl $16, %edx / right shift 16-bit + cmpb %dl, %cl / if the third byte is %cl + je .L6 / goto .L6 (found) + cmpb %dh, %cl / if the fourth is %cl + je .L7 / goto .L7 (found) + subl $4, %edi / decrement number of bytes by 4 + addl $4, %eax / next word + cmpl $4, %edi / if number of bytes >= 4 + jae .L3 / goto .L3 + .align 4 +.L2: + cmpb (%eax), %cl / if a byte in (%eax) is %cl + je .L4 / goto .L4 (found) + incl %eax / next byte + testl $3, %eax / if %eax not word aligned + jnz .L2 / goto .L2 + jmp .L3 / goto .L3 + .align 4 +.L7: + / found at the fourth byte + incl %eax +.L6: + / found at the third byte + incl %eax +.L5: + / found at the second byte + incl %eax +.L4: + / found at the first byte + popl %edi / restore register variable + ret + SET_SIZE(rawmemchr) Index: b/usr/src/lib/libc/i386/Makefile.com =================================================================== --- a/usr/src/lib/libc/i386/Makefile.com +++ b/usr/src/lib/libc/i386/Makefile.com @@ -139,6 +139,7 @@ GENOBJS= \ memcpy.o \ memset.o \ new_list.o \ + rawmemchr.o \ setjmp.o \ siginfolst.o \ siglongjmp.o \ Index: b/usr/src/head/string.h =================================================================== --- a/usr/src/head/string.h +++ b/usr/src/head/string.h @@ -141,6 +141,7 @@ extern char *strdup(const char *); #define __mempcpy mempcpy extern void *mempcpy(void *, const void *, size_t); extern void *memrchr(const void *, int, size_t); +extern void *rawmemchr(const void *, int); #endif #if defined(__EXTENSIONS__) || \