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 2004 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 .file "memchr.s" 27 28 / 29 / memchr(sptr, c1, n) 30 / 31 / Returns the pointer in sptr at which the character c1 appears; 32 / or NULL if not found in chars; doesn't stop at \0. 33 / 34 / Fast assembly language version of the following C-program memchr 35 / which represents the `standard' for the C-library. 36 / 37 / void * 38 / memchr(const void *sptr, int c1, size_t n) 39 / { 40 / if (n != 0) { 41 / unsigned char c = (unsigned char)c1; 42 / const unsigned char *sp = sptr; 43 / 44 / do { 45 / if (*sp++ == c) 46 / return ((void *)--sp); 47 / } while (--n != 0); 48 / } 49 / return (NULL); 50 / } 51 / 52 53 #include "SYS.h" 54 55 .globl memchr 56 .align 4 57 58 ENTRY(memchr) /* (void *s, uchar_t c, size_t n) */ 59 movl %esi, %eax / move "c" to %eax 60 cmpq $4, %rdx / if number of bytes < 4 61 jb .L1 / goto .L1 62 testq $3, %rdi / if %rdi not word aligned 63 jnz .L2 / goto .L2 64 .align 4 65 .L3: 66 movl (%rdi), %ecx / move 1 word from (%rdi) to %ecx 67 cmpb %cl, %al / if the first byte is %al 68 je .L4 / goto .L4 (found) 69 cmpb %ch, %al / if the second byte is %al 70 je .L5 / goto .L5 (found) 71 shrl $16, %ecx / right shift 16-bit 72 cmpb %cl, %al / if the third byte is %al 73 je .L6 / goto .L6 (found) 74 cmpb %ch, %al / if the fourth is %al 75 je .L7 / goto .L7 (found) 76 subq $4, %rdx / decrement number of bytes by 4 77 addq $4, %rdi / next word 78 cmpq $4, %rdx / if number of bytes >= 4 79 jae .L3 / goto .L3 80 .L1: 81 cmpq $0, %rdx / if number of bytes == 0 82 jz .L8 / goto .L8 (not found) 83 cmpb (%rdi), %al / if a byte in (%rdi) is %al 84 je .L4 / goto .L4 (found) 85 decq %rdx / decrement number of bytes by 1 86 incq %rdi / next byte 87 jmp .L1 / goto .L1 88 .align 4 89 .L8: 90 xorl %eax, %eax / not found 91 ret / return (0) 92 .align 4 93 .L2: 94 cmpq $0, %rdx / if number of bytes == 0 95 jz .L8 / goto .L8 (not found) 96 cmpb (%rdi), %al / if a byte in (%rdi) is %al 97 je .L4 / goto .L4 (found) 98 incq %rdi / next byte 99 decq %rdx / decrement number of bytes by 1 100 testq $3, %rdi / if %rdi not word aligned 101 jnz .L2 / goto .L2 102 cmpq $4, %rdx / if number of bytes >= 4 103 jae .L3 / goto .L3 (word aligned) 104 jmp .L1 / goto .L1 105 .align 4 106 .L7: 107 / found at the fourth byte 108 incq %rdi 109 .L6: 110 / found at the third byte 111 incq %rdi 112 .L5: 113 / found at the second byte 114 incq %rdi 115 .L4: 116 / found at the first byte 117 movq %rdi,%rax 118 ret 119 SET_SIZE(memchr) 120