1 | /* |
---|
2 | * (c) Copyright 1986 HEWLETT-PACKARD COMPANY |
---|
3 | * |
---|
4 | * To anyone who acknowledges that this file is provided "AS IS" |
---|
5 | * without any express or implied warranty: |
---|
6 | * permission to use, copy, modify, and distribute this file |
---|
7 | * for any purpose is hereby granted without fee, provided that |
---|
8 | * the above copyright notice and this notice appears in all |
---|
9 | * copies, and that the name of Hewlett-Packard Company not be |
---|
10 | * used in advertising or publicity pertaining to distribution |
---|
11 | * of the software without specific, written prior permission. |
---|
12 | * Hewlett-Packard Company makes no representations about the |
---|
13 | * suitability of this software for any purpose. |
---|
14 | */ |
---|
15 | |
---|
16 | /* |
---|
17 | |
---|
18 | strcmp |
---|
19 | |
---|
20 | Jerry Huck |
---|
21 | Edgar Circenis |
---|
22 | |
---|
23 | */ |
---|
24 | /* |
---|
25 | * strcmp(s1, s2) |
---|
26 | * |
---|
27 | * returns integer: < 0 iff s1 lexicographically less than s2 |
---|
28 | * > 0 iff s1 lexicographically greater than s2 |
---|
29 | * = 0 iff s1 lexicographically equal to s2 |
---|
30 | */ |
---|
31 | |
---|
32 | #include "DEFS.h" |
---|
33 | |
---|
34 | #define s1 26 |
---|
35 | #define s2 25 |
---|
36 | #define tmp1 19 |
---|
37 | #define s2word 20 |
---|
38 | #define tmp3 21 |
---|
39 | #define tmp7 22 |
---|
40 | #define s1word 23 |
---|
41 | #define save 1 |
---|
42 | #define tmp6 24 |
---|
43 | #define tmp5 28 |
---|
44 | |
---|
45 | ENTRY(strcmp) |
---|
46 | comb,=,n s1,s2,samestring |
---|
47 | comib,=,n 0,s1,s1isnull |
---|
48 | comib,=,n 0,s2,s2isnull |
---|
49 | /* Hope for word alignment. Pick up low two bits of each adress */ |
---|
50 | extru,<> s1,31,2,tmp1 |
---|
51 | ldwm 4(s1),s1word |
---|
52 | dep,= s2,29,2,tmp1 |
---|
53 | b,n case_analysis |
---|
54 | |
---|
55 | /* Start looping until null is found in s1 or they mis-compare */ |
---|
56 | loop: |
---|
57 | ldwm 4(s2),s2word |
---|
58 | loop_plus: |
---|
59 | uxor,nbz s1word,r0,r0 /* Null in this? */ |
---|
60 | b,n nullins1 |
---|
61 | comb,=,n s1word,s2word,loop |
---|
62 | ldwm 4(s1),s1word |
---|
63 | |
---|
64 | /* The words do not compare equal and s1 does not have a null. |
---|
65 | Need to treat words as unsigned and generate either a positive |
---|
66 | or negative return value */ |
---|
67 | wordcomparereturn: |
---|
68 | comclr,>> s1word,s2word,ret0 /*Set ret0 to 0 and skip if greater*/ |
---|
69 | ldi -2,ret0 /*Set ret0 to -2 when less */ |
---|
70 | bv r0(rp) |
---|
71 | addi 1,ret0,ret0 /*Fix return value to be -1 or +1 */ |
---|
72 | |
---|
73 | /* s1 has a null. s2 has not been checked. */ |
---|
74 | nullins1: |
---|
75 | /*If s2 has no nulls this is simple, but assume that it might |
---|
76 | and fix up s1 to allow the word comparision to work by |
---|
77 | scanning s1 and duplicating all the bytes in s2 below that byte into |
---|
78 | the remainder of s1. A remainder only exists if the zero byte |
---|
79 | is found in the upper three bytes */ |
---|
80 | extru,<> s1word,7,8,r0 /*in the first byte? */ |
---|
81 | dep,tr s2word,31,24,s1word /*copy low 3 bytes of *s2 into *s1 */ |
---|
82 | extru,<> s1word,15,8,r0 /*in the second byte? */ |
---|
83 | dep,tr s2word,31,16,s1word /*copy low 2 bytes of *s2 into *s1 */ |
---|
84 | extru,<> s1word,23,8,r0 /*in the third byte? */ |
---|
85 | dep s2word,31,8,s1word /*copy low 1 byte of *s2 into *s1 */ |
---|
86 | /* Do the normal unsigned compare and return */ |
---|
87 | comclr,<> s1word,s2word,ret0 /*Set ret0 to 0 and skip if not equal */ |
---|
88 | bv,n r0(rp) |
---|
89 | comclr,>> s1word,s2word,ret0 /*Set ret0 to 0 and skip if greater*/ |
---|
90 | ldi -2,ret0 /*Set ret0 to -2 when less */ |
---|
91 | bv r0(rp) |
---|
92 | addi 1,ret0,ret0 /*Fix return value to be -1 or +1 */ |
---|
93 | |
---|
94 | /* s1 and s2 are the same string and therefore equal */ |
---|
95 | samestring: |
---|
96 | bv r0(rp) |
---|
97 | copy r0,ret0 |
---|
98 | /* s1 is null. Treat as string of nulls. Therefore return |
---|
99 | the negative of s2's first byte. s2 cannot be zero. */ |
---|
100 | s1isnull: |
---|
101 | ldbs 0(0,s2),ret0 |
---|
102 | bv r0(rp) |
---|
103 | sub 0,ret0,ret0 |
---|
104 | /* s2 is null. Treat as string of nulls. Therefore return |
---|
105 | s1's first byte. s1 cannot be zero. */ |
---|
106 | s2isnull: |
---|
107 | bv r0(rp) |
---|
108 | ldbs 0(0,s1),ret0 |
---|
109 | |
---|
110 | case_analysis: |
---|
111 | blr tmp1,r0 |
---|
112 | nop |
---|
113 | |
---|
114 | /* |
---|
115 | Case statement for non-aligned cases (we've already |
---|
116 | checked the aligned case. |
---|
117 | NOTE: for non-aligned cases, the absolute shift value |
---|
118 | gets loaded into tmp3. |
---|
119 | */ |
---|
120 | |
---|
121 | /* S2 S1 */ |
---|
122 | nop /* 00 00 can't happen */ |
---|
123 | nop |
---|
124 | b shifts2 /* 00 01 */ |
---|
125 | ldi 8,tmp3 /* load shift count (delay slot) */ |
---|
126 | b shifts2 /* 00 10 */ |
---|
127 | ldi 16,tmp3 /* load shift count (delay slot) */ |
---|
128 | b shifts2 /* 00 11 */ |
---|
129 | ldi 24,tmp3 /* load shift count (delay slot) */ |
---|
130 | b shifts1_0 /* 01 00 */ |
---|
131 | ldi 8,tmp3 /* load shift count (delay slot) */ |
---|
132 | b eq_align1 /* 01 01 */ |
---|
133 | ldbs,ma 1(s1),s1word |
---|
134 | b shifts2 /* 01 10 */ |
---|
135 | ldi 8,tmp3 /* load shift count (delay slot) */ |
---|
136 | b shifts2 /* 01 11 */ |
---|
137 | ldi 16,tmp3 /* load shift count (delay slot) */ |
---|
138 | b shifts1_0 /* 10 00 */ |
---|
139 | ldi 16,tmp3 /* load shift count (delay slot) */ |
---|
140 | b shifts1 /* 10 01 */ |
---|
141 | ldi 8,tmp3 /* load shift count (delay slot) */ |
---|
142 | b eq_align2 /* 10 10 */ |
---|
143 | ldhs,ma 2(s1),s1word |
---|
144 | b shifts2 /* 10 11 */ |
---|
145 | ldi 8,tmp3 /* load shift count (delay slot) */ |
---|
146 | b shifts1_0 /* 11 00 */ |
---|
147 | ldi 24,tmp3 /* load shift count (delay slot) */ |
---|
148 | b shifts1 /* 11 01 */ |
---|
149 | ldi 16,tmp3 /* load shift count (delay slot) */ |
---|
150 | b shifts1 /* 11 10 */ |
---|
151 | ldi 8,tmp3 /* load shift count (delay slot) */ |
---|
152 | ldbs,ma 1(s1),s1word /* 11 11 */ |
---|
153 | ldbs,ma 1(s2),s2word |
---|
154 | sub,= s1word,s2word,ret0 /* if not equal, we can return now */ |
---|
155 | bv,n r0(rp) |
---|
156 | comclr,<> s1word,r0,ret0 |
---|
157 | bv,n r0(rp) |
---|
158 | b loop /* fall into main loop */ |
---|
159 | ldwm 4(s1),s1word |
---|
160 | |
---|
161 | eq_align1: |
---|
162 | ldbs,ma 1(s2),s2word |
---|
163 | sub,= s1word,s2word,ret0 /* if not equal, we can return now */ |
---|
164 | bv,n r0(rp) |
---|
165 | comclr,<> s1word,r0,ret0 |
---|
166 | bv,n r0(rp) |
---|
167 | /* fall through to half-word aligned case */ |
---|
168 | ldhs,ma 2(s1),s1word /* load next halfword */ |
---|
169 | eq_align2: |
---|
170 | ldhs,ma 2(s2),s2word /* load next halfword */ |
---|
171 | /* form the mask: 0xffff0000 and mask leading nulls in s1word and s2word |
---|
172 | so that we can fall into the main loop with word aligned data */ |
---|
173 | ldi 16,save |
---|
174 | mtctl save,r11 |
---|
175 | zvdepi -2,32,save |
---|
176 | or save,s1word,s1word |
---|
177 | b loop_plus /* fall into main loop */ |
---|
178 | or save,s2word,s2word |
---|
179 | |
---|
180 | /* s2's alignment is greater than s1's alignment, so we will shift s1 */ |
---|
181 | shifts1_0: |
---|
182 | addi -4,s1,s1 /* fix up s1 due to earlier read */ |
---|
183 | shifts1: |
---|
184 | extru s1,31,2,tmp1 |
---|
185 | extru s2,31,2,tmp5 |
---|
186 | dep r0,31,2,s1 /* Compute word address of s1 */ |
---|
187 | dep r0,31,2,s2 /* Compute word address of s2 */ |
---|
188 | ldwm 4(s1),s1word /* get first word of s1 */ |
---|
189 | ldwm 4(s2),s2word /* get first word of s2 */ |
---|
190 | combt,=,n r0,tmp1,masks2 /* Do we need to mask beginning of s1 */ |
---|
191 | sh3add tmp1,r0,save /* save now has number of bits to mask */ |
---|
192 | mtctl save,r11 |
---|
193 | zvdepi -2,32,save /* load save with proper mask */ |
---|
194 | or save,s1word,s1word |
---|
195 | masks2: |
---|
196 | sh3add tmp5,r0,save /* save now has number of bits to mask */ |
---|
197 | mtctl save,r11 |
---|
198 | zvdepi -2,32,save /* load save with proper mask */ |
---|
199 | or save,s2word,s2word |
---|
200 | ldi -1,tmp7 /* load tmp7 with 0xffffffff */ |
---|
201 | mtctl tmp3,r11 /* Move shift amount to CR11 */ |
---|
202 | more: uxor,nbz s1word,r0,r0 /* Is there a null in s1? */ |
---|
203 | b ends1 |
---|
204 | vshd tmp7,s1word,save |
---|
205 | combf,=,n save,s2word,cmps1 |
---|
206 | ldwm 4(s1),tmp7 |
---|
207 | ldwm 4(s2),s2word |
---|
208 | uxor,nbz tmp7,r0,r0 /* is there a null in s1? */ |
---|
209 | b ends1_0 |
---|
210 | vshd s1word,tmp7,save |
---|
211 | combf,=,n save,s2word,cmps1 |
---|
212 | ldwm 4(s1),s1word |
---|
213 | b more |
---|
214 | ldwm 4(s2),s2word |
---|
215 | |
---|
216 | cmps1: movb,tr save,s1word,wordcomparereturn |
---|
217 | nop |
---|
218 | |
---|
219 | ends1_0: |
---|
220 | copy tmp7,s1word /* move tmp7 to s1word */ |
---|
221 | ends1: |
---|
222 | combf,=,n save,s2word,nullins1 /* branch if no match */ |
---|
223 | copy save,s1word /* delay slot */ |
---|
224 | /* At this point, we know that we've read a null */ |
---|
225 | /* from s1, so we can't read more from s1 */ |
---|
226 | uxor,nbz save,r0,r0 /* are the strings equal? */ |
---|
227 | b,n samestring |
---|
228 | vshd s1word,r0,s1word |
---|
229 | b nullins1 |
---|
230 | ldwm 4(s2),s2word |
---|
231 | |
---|
232 | /* s1's alignment is greater than s2's alignment, so we will shift s2 */ |
---|
233 | shifts2: |
---|
234 | extru s1,31,2,tmp1 |
---|
235 | extru s2,31,2,tmp5 |
---|
236 | dep r0,31,2,s1 /* Compute word address of s1 */ |
---|
237 | dep r0,31,2,s2 /* Compute word address of s2 */ |
---|
238 | ldwm 4(s2),s2word /* get first word of s2 */ |
---|
239 | ldwm 4(s1),s1word /* get first word of s1 */ |
---|
240 | combt,=,n r0,tmp5,masks1 /* Do we need to mask beginning of s2 */ |
---|
241 | sh3add tmp5,r0,save /* save now has number of bits to mask */ |
---|
242 | mtctl save,r11 |
---|
243 | zvdepi -2,32,save /* load save with proper mask */ |
---|
244 | or save,s2word,s2word |
---|
245 | masks1: |
---|
246 | sh3add tmp1,r0,save /* save now has number of bits to mask */ |
---|
247 | mtctl save,r11 |
---|
248 | zvdepi -2,32,save /* load save with proper mask */ |
---|
249 | or save,s1word,s1word |
---|
250 | ldi -1,tmp7 /* load tmp7 with 0xffffffff */ |
---|
251 | mtctl tmp3,r11 /* Move shift amount to CR11 */ |
---|
252 | more1: uxor,nbz s2word,r0,r0 /* is there a null in s2? */ |
---|
253 | b ends2 |
---|
254 | vshd tmp7,s2word,save |
---|
255 | combf,=,n s1word,save,cmps2 |
---|
256 | ldwm 4(s2),tmp7 |
---|
257 | ldwm 4(s1),s1word |
---|
258 | uxor,nbz tmp7,r0,r0 /* is there a null in s2? */ |
---|
259 | b ends2_0 |
---|
260 | vshd s2word,tmp7,save |
---|
261 | combf,=,n s1word,save,cmps2 |
---|
262 | ldwm 4(s2),s2word |
---|
263 | b more1 |
---|
264 | ldwm 4(s1),s1word |
---|
265 | |
---|
266 | cmps2: movb,tr save,s2word,wordcomparereturn |
---|
267 | nop |
---|
268 | |
---|
269 | ends2_0: |
---|
270 | copy tmp7,s2word /* move tmp7 to s2word */ |
---|
271 | ends2: |
---|
272 | combf,=,n s1word,save,nullins1 /* branch if no match */ |
---|
273 | copy save,s2word /* delay slot */ |
---|
274 | /* At this point, we know that we've read a null */ |
---|
275 | /* from s2, so we can't read more from s2 */ |
---|
276 | uxor,nbz save,r0,r0 /* are the strings equal? */ |
---|
277 | b,n samestring |
---|
278 | vshd s2word,r0,s2word |
---|
279 | b nullins1 |
---|
280 | ldwm 4(s1),s1word |
---|
281 | |
---|
282 | EXIT(strcmp) |
---|