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 45ENTRY(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 */ 56loop: 57 ldwm 4(s2),s2word 58loop_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 */ 67wordcomparereturn: 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. */ 74nullins1: 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 */ 95samestring: 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. */ 100s1isnull: 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. */ 106s2isnull: 107 bv r0(rp) 108 ldbs 0(0,s1),ret0 109 110case_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 161eq_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 */ 169eq_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 */ 181shifts1_0: 182 addi -4,s1,s1 /* fix up s1 due to earlier read */ 183shifts1: 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 195masks2: 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 */ 202more: 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 216cmps1: movb,tr save,s1word,wordcomparereturn 217 nop 218 219ends1_0: 220 copy tmp7,s1word /* move tmp7 to s1word */ 221ends1: 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 */ 233shifts2: 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 245masks1: 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 */ 252more1: 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 266cmps2: movb,tr save,s2word,wordcomparereturn 267 nop 268 269ends2_0: 270 copy tmp7,s2word /* move tmp7 to s2word */ 271ends2: 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 282EXIT(strcmp) 283