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