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