.text .global _searchstr_maketbl .global _searchstr /* static int eq(s1,s2,n,eqv) register unsigned char *s1; register unsigned char *s2; register int n; register char *eqv; { for (;n>0;n--) if (eqv[*s1++] != eqv[*s2++]) return(0); return(1); } */ /* Pass arguments thus: s1 in r0 s2 in r1 n in r2 eqv in r3 return with Z bit set if equal, clr if not r0, r1, r2, r4, r5 destroyed r3 unchanged */ eq: 1: sobgeq r2,2f tstl $0 rsb 2: movzbl (r0)+,r5 movzbl (r1)+,r4 cmpb (r3)[r5],(r3)[r4] beql 1b rsb _searchstr_maketbl: /* searchstr_maketbl(tbl_,str_,len,equiv) register char (*tbl_)[256]; #define tbl ((unsigned char (*)[256])tbl_) register char *str_; #define str ((unsigned char *)str_) register int len; register char *equiv; { register unsigned char *str1; register int i; register int j; register int k; register int l; if (len < 1) return; str1 = str + 1; for (i=len-1;i>=0;i--) { l = len - 1 - i; for (j=255;j>=0;j--) { for (k=i;k>=0;k--) { if ( (equiv[str[k]] == equiv[j]) && ( (l == 0) || (k == i) || eq(str1+k,str1+i,l,equiv) ) ) { tbl[i][j] = i - k; break; } } if (k < 0) { for (k=0;k= l) tbl[i][j] = len; } } } } */ .word 0x0ffc /* r11-r2 */ tstl 12(ap) /* if (len < 1) return */ bgtr 1f ret 1: movl 16(ap),r3 /* equiv */ addl3 8(ap),$1,r11 /* str1 = str + 1 */ subl3 $1,12(ap),r10 /* i = len - 1 */ ashl $8,r10,r0 /* r6 holds &tbl[i] */ movab *4(ap)[r0],r6 clrl r9 /* l = len-1-i (which ==0 here) */ 2: movzbl $255,r8 /* j = 255 */ 3: movl r10,r7 /* k = i */ 4: movzbl -1(r11)[r7],r0 /* equiv[str[k]] == equiv[j] (str==str1-1) */ cmpb (r3)[r0],(r3)[r8] bneq 5f cmpl r10,r7 /* k == i */ beql 8f movl r9,r2 /* l == 0, and set up third arg for eq() */ beql 8f addl3 r11,r7,r0 /* eq(str1+k,str1+i,l,equiv) */ addl3 r11,r10,r1 jsb eq beql 8f 5: sobgeq r7,4b /* next k, and optimize k<0 test */ 6: aoblss r9,r7,7f /* next k, and optimize k>=l test */ movl 12(ap),r0 /* tmp = len */ brb 9f 7: subl3 $1,r11,r0 /* eq(str,str1+i+k,l-k,equiv) (str==str1-1) */ addl3 r11,r10,r1 addl2 r7,r1 subl3 r7,r9,r2 jsb eq bneq 6b addl3 r7,r10,r0 /* tmp = 1 + i + k */ incl r0 brb 9f 8: subl3 r7,r10,r0 /* tmp = i - k */ 9: movb r0,(r6)[r8] /* tbl[i][j] = tmp (&tbl[i] in r6) */ sobgeq r8,3b /* next j */ incl r9 /* update l to new len-1-i */ subl2 $256,r6 /* update r6 to new &tbl[i] */ sobgeq r10,2b /* next i */ ret _searchstr: /* int searchstr(str,len,tbl,tbllen) register unsigned char *str; register int len; register unsigned char (*tbl)[256]; register int tbllen; { register int strpos; register int stridx; register int stroff; register int adv; strpos = 0; while (1) { stroff = tbllen - 1; stridx = strpos + stroff; if (stridx >= len) return(-1); while (1) { adv = tbl[stroff][str[stridx]]; if (adv == 0) { if (stroff == 0) { return(stridx); } stroff --; stridx --; } else { strpos += adv; break; } } } } */ .word 0x0ff0 /* r11-r4 */ movl 4(ap),r11 /* str */ movl 8(ap),r10 /* len */ movl 12(ap),r9 /* tbl */ subl3 $1,16(ap),r8 /* tbllen (stored as tbllen-1) */ clrl r7 /* strpos = 0 */ 1: movl r8,r6 /* stroff = tbllen - 1 */ addl3 r7,r6,r5 /* stridx = strpos + stroff */ cmpl r5,r10 /* stridx >= len */ blss 2f mnegl $1,r0 /* return -1 */ ret 3: decl r5 /* stridx -- */ /* inner while loop */ 2: movzbl (r11)[r5],r0 /* adv = tbl[stroff][str[stridx]] */ ashl $8,r6,r1 addl2 r9,r1 movzbl (r1)[r0],r4 beql 4f /* adv == 0 */ addl2 r4,r7 /* strpos += adv */ brb 1b /* break inner while, continue outer while */ 4: sobgeq r6,3b /* stroff == 0, and following stroff-- */ movl r5,r0 /* return stridx */ ret