Subject: strchr.S

From: Matthew Wilcox <[email-masked]>
Date: Mon, 20 Apr 1998 11:52:59 +0100 (BST)

Here's a 39-instruction of strchr which works word-at-a-time.  I have
neither tested nor benchmarked it.  Phil, does glibc have a testsuite
for strchr?  If not, I ought to write one - there are so many cases to
take care of.

-- 
Set Alias$Case Set Alias$[ |||| |MSet Alias$Otherwise Set Alias$[ \ Matthew
"" |MSet Alias$When If %0=%%0 Then Set Alias$[ "" ||MIf %0=%%0    \ Wilcox
Then Set Alias$Otherwise Set Alias$[ |||||||||||||||| ||MIf       \
%0=%%0 Then Set Alias$When Set Alias$[ ||||||||||||||||

strchr:
   tst    r0, #3
   beq    2f
1: ldrb   r2, [r0], #1
   cmp    r2, r1
   tstne  r0, #3
   bne    1b
   subcs  r0, r0, #1
   movcs  pc, r14
2: orr    r1, r1, r1, LSL #8
   orr    r1, r1, r1, LSL #16
3: ldr    r2, [r0], #4
   eor    r3, r2, r1
   tst    r3, #&000000ff
   tstne  r3, #&0000ff00
   tstne  r3, #&00ff0000
   tstne  r3, #&ff000000
   beq    5f
   tst    r2, #&000000ff
   tstne  r2, #&0000ff00
   tstne  r2, #&00ff0000
   tstne  r2, #&ff000000
   bne    3b
4: mov    r0, #0
   mov    pc, r14
5: tst    r2, #&000000ff
   beq    4b
   tst    r3, #&000000ff
   subeq  r0, r0, #1
   tstne  r3, #&0000ff00
   subeq  r0, r0, #2
   moveq  pc, r14
   tst    r2, #&0000ff00
   tstne  r2, #&00ff0000
   beq    4b
   tst    r3, #&00ff0000
   subeq  r0, r0, #1
   tstne  r3, #&ff000000
   moveq  pc, r14
   b      4b

unsubscribe: body of `unsubscribe linux-arm' to [email-masked]

---

From: Philip Blundell <[email-masked]>
Date: Mon, 20 Apr 1998 12:15:34 +0100

>for strchr?  If not, I ought to write one - there are so many cases to

Yes, we do have one.  Here's the code.  If you can think of additional tests 
to add then please do.

void
test_strchr (void)
{
  it = "strchr";
  check (strchr ("abcd", 'z') == NULL, 1);	/* Not found. */
  (void) strcpy (one, "abcd");
  check (strchr (one, 'c') == one+2, 2);	/* Basic test. */
  check (strchr (one, 'd') == one+3, 3);	/* End of string. */
  check (strchr (one, 'a') == one, 4);		/* Beginning. */
  check (strchr (one, '\0') == one+4, 5);	/* Finding NUL. */
  (void) strcpy (one, "ababa");
  check (strchr (one, 'b') == one+1, 6);	/* Finding first. */
  (void) strcpy (one, "");
  check (strchr (one, 'b') == NULL, 7);		/* Empty string. */
  check (strchr (one, '\0') == one, 8);		/* NUL in empty string. */
  {
    char buf[4096];
    int i;
    char *p;
    for (i=0; i < 0x100; i++)
      {
	p = (char *) ((unsigned long int) (buf + 0xff) & ~0xff) + i;
	strcpy (p, "OK");
	strcpy (p+3, "BAD/WRONG");
	check (strchr (p, '/') == NULL, 9+i);
      }
   }
}

p.