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.
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.
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]
23 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
31 * Compare strings: s1>s2: >0 s1==s2: 0 s1<s2: <0
33 * Fast assembler language version of the following C-program for strcmp
34 * which represents the `standard' for the C-library.
38 * register const char *s1;
39 * register const char *s2;
47 * return(*s1 - s2[-1]);
51 #include <sys/asm_linkage.h>
53 ! This strcmp implementation first determines whether s1 is aligned.
54 ! If it is
not, it attempts to align it
and then checks the
55 ! alignment of the destination string. If it is possible to
56 ! align s2
, this also happens
and then the compare begins. Otherwise
,
57 ! a different compare for non-aligned strings is used.
58 ! In this case
, we have multiple routines depending upon the
59 ! degree to which
a string is mis-aligned.
65 subcc
%o0
, %o1
, %o2
! s1
== s2 ?
66 bz
.stringsequal1 ! yup, same string, done
67 sethi
%hi
(0x01010101), %o5
! start loading Mycroft
's magic2
68 andcc %o0, 3, %o3 ! s1 word-aligned ?
69 or %o5, %lo(0x01010101),%o5! finish loading Mycroft's magic2
71 sll
%o5
, 7, %o4
! load Mycroft
's magic1
72 sub %o3, 4, %o3 ! number of bytes till aligned
75 ldub [%o1 + %o2], %o0 ! s1[]
76 ldub [%o1], %g1 ! s2[]
77 subcc %o0, %g1, %o0 ! s1[] != s2[] ?
79 addcc %o0, %g1, %g0 ! s1[] == 0 ?
81 inccc %o3 ! s1 aligned yet?
82 bnz .aligns1 ! nope, compare another pair of bytes
86 andcc %o1, 3, %o3 ! s2 word aligned ?
88 cmp %o3, 2 ! s2 half-word aligned ?
90 cmp %o3, 3 ! s2 offset to dword == 3 ?
92 ldub [%o1], %o0 ! new lower word in s2
95 lduw [%o1 - 1], %o0 ! new lower word in s2
96 sethi %hi(0xff000000), %o3 ! mask for forcing byte 1 non-zero
97 sll %o0, 8, %g1 ! partial unaligned word from s2
98 or %o0, %o3, %o0 ! force byte 1 non-zero
101 andn %o4, %o0, %o3 ! ~word & 0x80808080
102 sub %o0, %o5, %o0 ! word - 0x01010101
103 andcc %o0, %o3, %g0 ! (word - 0x01010101) & ~word & 0x80808080
104 bz,a .doload1 ! no null byte in previous word from s2
105 lduw [%o1 + 3], %o0 ! load next aligned word from s2
107 srl %o0, 24, %o3 ! byte 1 of new aligned word from s2
108 or %g1, %o3, %g1 ! merge to get unaligned word from s2
109 lduw [%o1 + %o2], %o3 ! word from s1
110 cmp %o3, %g1 ! *s1 != *s2 ?
111 bne .wordsdiffer ! yup, find the byte that is different
112 add %o1, 4, %o1 ! s1+=4, s2+=4
113 andn %o4, %o3, %g1 ! ~word & 0x80808080
114 sub %o3, %o5, %o3 ! word - 0x01010101
115 andcc %o3, %g1, %g0 ! (word - 0x01010101) & ~word & 0x80808080
116 bz .cmp1 ! no null-byte in s1 yet
117 sll %o0, 8, %g1 ! partial unaligned word from s2
119 ! words are equal but the end of s1 has been reached
120 ! this means the strings must be equal
122 retl ! return from leaf function
123 mov %g0, %o0 ! return 0, i.e. strings are equal
124 nop ! pad for optimal alignment of .cmp2
125 nop ! pad for optimal alignment of .cmp2
128 lduh [%o1], %o0 ! new lower word in s2
129 sethi %hi(0xffff0000), %o3 ! mask for forcing bytes 1,2 non-zero
130 sll %o0, 16, %g1 ! partial unaligned word from s2
131 or %o0, %o3, %o0 ! force bytes 1,2 non-zero
134 andn %o4, %o0, %o3 ! ~word & 0x80808080
135 sub %o0, %o5, %o0 ! word - 0x01010101
136 andcc %o0, %o3, %g0 ! (word - 0x01010101) & ~word & 0x80808080
137 bz,a .doload2 ! no null byte in previous word from s2
138 lduw [%o1 + 2], %o0 ! load next aligned word from s2
140 srl %o0, 16, %o3 ! bytes 1,2 of new aligned word from s2
141 or %g1, %o3, %g1 ! merge to get unaligned word from s2
142 lduw [%o1 + %o2], %o3 ! word from s1
143 cmp %o3, %g1 ! *s1 != *s2 ?
144 bne .wordsdiffer ! yup, find the byte that is different
145 add %o1, 4, %o1 ! s1+=4, s2+=4
146 andn %o4, %o3, %g1 ! ~word & 0x80808080
147 sub %o3, %o5, %o3 ! word - 0x01010101
148 andcc %o3, %g1, %g0 ! (word - 0x01010101) & ~word & 0x80808080
149 bz .cmp2 ! no null-byte in s1 yet
150 sll %o0, 16, %g1 ! partial unaligned word from s2
152 ! words are equal but the end of s1 has been reached
153 ! this means the strings must be equal
155 retl ! return from leaf function
156 mov %g0, %o0 ! return 0, i.e. strings are equal
159 sll %o0, 24, %g1 ! partial unaligned word from s2
160 nop ! pad for optimal alignment of .cmp3
162 andcc %o0, 0xff, %g0 ! did previous word contain null-byte ?
163 bnz,a .doload3 ! nope, load next word from s2
164 lduw [%o1 + 1], %o0 ! load next aligned word from s2
166 srl %o0, 8, %o3 ! bytes 1,2,3 from new aligned s2 word
167 or %g1, %o3, %g1 ! merge to get unaligned word from s2
168 lduw [%o1 + %o2], %o3 ! word from s1
169 cmp %o3, %g1 ! *s1 != *s2 ?
170 bne .wordsdiffer ! yup, find the byte that is different
171 add %o1, 4, %o1 ! s1+=4, s2+=4
172 andn %o4, %o3, %g1 ! ~word & 0x80808080
173 sub %o3, %o5, %o3 ! word - 0x01010101
174 andcc %o3, %g1, %g0 ! (word - 0x01010101) & ~word & 0x80808080
175 bz .cmp3 ! no null-byte in s1 yet
176 sll %o0, 24, %g1 ! partial unaligned word from s2
178 ! words are equal but the end of s1 has been reached
179 ! this means the strings must be equal
181 retl ! return from leaf function
182 mov %g0, %o0 ! return 0, i.e. strings are equal
185 lduw [%o1 + %o2], %o3 ! load word from s1
186 nop ! pad for optimal alignment of .cmp4
187 nop ! pad for optimal alignment of .cmp4
188 nop ! pad for optimal alignment of .cmp4
191 lduw [%o1], %g1 ! load word from s2
192 cmp %o3, %g1 ! *scr1 == *src2 ?
193 bne .wordsdiffer ! nope, find mismatching character
194 add %o1, 4, %o1 ! src1 += 4, src2 += 4
195 andn %o4, %o3, %o0 ! ~word & 0x80808080
196 sub %o3, %o5, %o3 ! word - 0x01010101
197 andcc %o3, %o0, %g0 ! (word - 0x01010101) & ~word & 0x80808080
198 bz,a .cmp4 ! no null-byte in s1 yet
199 lduw [%o1 + %o2], %o3 ! load word from s1
201 ! words are equal but the end of s1 has been reached
202 ! this means the strings must be equal
204 retl ! return from leaf function
205 mov %g0, %o0 ! return 0, i.e. strings are equal
208 srl %g1, 24, %o2 ! first byte of mismatching word in s2
209 srl %o3, 24, %o1 ! first byte of mismatching word in s1
210 subcc %o1, %o2, %o0 ! *s1-*s2
211 bnz .done ! bytes differ, return difference
212 srl %g1, 16, %o2 ! second byte of mismatching word in s2
213 andcc %o1, 0xff, %o0 ! *s1 == 0 ?
216 ! we know byte 1 is equal, so can compare bytes 1,2 as a group
218 srl %o3, 16, %o1 ! second byte of mismatching word in s1
219 subcc %o1, %o2, %o0 ! *s1-*s2
220 bnz .done ! bytes differ, return difference
221 srl %g1, 8, %o2 ! third byte of mismatching word in s2
222 andcc %o1, 0xff, %o0 ! *s1 == 0 ?
225 ! we know bytes 1, 2 are equal, so can compare bytes 1,2,3 as a group
227 srl %o3, 8, %o1 ! third byte of mismatching word in s1
228 subcc %o1, %o2, %o0 ! *s1-*s2
229 bnz .done ! bytes differ, return difference
230 andcc %o1, 0xff, %g0 ! *s1 == 0 ?
231 bz .stringsequal1 ! yup
233 ! we know bytes 1,2,3 are equal, so can compare bytes 1,2,3,4 as group
235 subcc %o3, %g1, %o0 ! *s1-*s2
236 bz,a .done ! bytes differ, return difference
237 andcc %o3, 0xff, %o0 ! *s1 == 0 ?
240 retl ! return from leaf routine