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