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/* 23 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27#pragma ident "%Z%%M% %I% %E% SMI" 28 29 .file "%M%" 30 31/* 32 * strlen(s) 33 * 34 * Given string s, return length (not including the terminating null). 35 * 36 * Fast assembler language version of the following C-program strlen 37 * which represents the `standard' for the C-library. 38 * 39 * size_t 40 * strlen(s) 41 * register const char *s; 42 * { 43 * register const char *s0 = s + 1; 44 * 45 * while (*s++ != '\0') 46 * ; 47 * return (s - s0); 48 * } 49 */ 50 51#include <sys/asm_linkage.h> 52 53 ! The object of strlen is to, as quickly as possible, find the 54 ! null byte. To this end, we attempt to get our string aligned 55 ! and then blast across it using Alan Mycroft's algorithm for 56 ! finding null bytes. If we are not aligned, the string is 57 ! checked a byte at a time until it is. Once this occurs, 58 ! we can proceed word-wise across it. Once a word with a 59 ! zero byte has been found, we then check the word a byte 60 ! at a time until we've located the zero byte, and return 61 ! the proper length. 62 63 .align 32 64 ENTRY(strlen) 65 andcc %o0, 3, %o4 ! is src word aligned 66 bz,pt %icc, .nowalgnd 67 mov %o0, %o2 68 69 cmp %o4, 2 ! is src half-word aligned 70 be,a,pn %icc, .s2algn 71 lduh [%o2], %o1 72 73 ldub [%o2], %o1 74 tst %o1 ! byte zero? 75 bz,pn %icc, .done 76 cmp %o4, 3 ! src is byte aligned 77 78 be,pn %icc, .nowalgnd 79 inc 1, %o2 80 81 lduh [%o2], %o1 82 83.s2algn: 84 srl %o1, 8, %o4 85 tst %o4 86 bz,pn %icc, .done 87 andcc %o1, 0xff, %g0 88 89 bz,pn %icc, .done 90 inc 1, %o2 91 92 inc 1, %o2 93 94.nowalgnd: 95 ld [%o2], %o1 96 sethi %hi(0x01010101), %o4 97 sethi %hi(0x80808080), %o5 98 or %o4, %lo(0x01010101), %o4 99 or %o5, %lo(0x80808080), %o5 100 101 andn %o5, %o1, %o3 102 sub %o1, %o4, %g1 103 andcc %o3, %g1, %g0 104 bnz,a,pn %icc, .nullfound 105 sethi %hi(0xff000000), %o4 106 107 ld [%o2+4], %o1 108 inc 4, %o2 109 110.loop: ! this should be aligned to 32 111 inc 4, %o2 112 andn %o5, %o1, %o3 ! %o5 = ~word & 0x80808080 113 sub %o1, %o4, %g1 ! %g1 = word - 0x01010101 114 andcc %o3, %g1, %g0 115 bz,a,pt %icc, .loop 116 ld [%o2], %o1 117 118 dec 4, %o2 119 sethi %hi(0xff000000), %o4 120.nullfound: 121 andcc %o1, %o4, %g0 122 bz,pn %icc, .done ! first byte zero 123 srl %o4, 8, %o4 124 125 andcc %o1, %o4, %g0 126 bz,pn %icc, .done ! second byte zero 127 inc 1, %o2 128 129 srl %o4, 8, %o4 130 andcc %o1, %o4, %g0 131 bz,pn %icc, .done ! thrid byte zero 132 inc 1, %o2 133 134 inc 1, %o2 ! fourth byte zero 135.done: 136 retl 137 sub %o2, %o0, %o0 138 SET_SIZE(strlen) 139 140