~linaro-toolchain-dev/cortex-strings/trunk

38 by Michael Hope
Added the XScale specific routines from Newlib 1.19.0
1
#include <string.h>
2
#include "xscale.h"
3
#undef strcmp
4
5
int
6
strcmp (const char *s1, const char *s2)
7
{
8
  asm (PRELOADSTR ("%0") : : "r" (s1));
9
  asm (PRELOADSTR ("%0") : : "r" (s2));
10
11
#ifndef __OPTIMIZE_SIZE__
12
  if (((long)s1 & 3) == ((long)s2 & 3))
13
    {
14
      int result;
15
16
      /* Skip unaligned part.  */
17
      while ((long)s1 & 3)
18
	{
19
	  if (*s1 == '\0' || *s1 != *s2)
20
	    goto out;
21
	  s1++;
22
	  s2++;
23
	}
24
25
  /* Load two constants:
26
     lr = 0xfefefeff [ == ~(0x80808080 << 1) ]
27
     ip = 0x80808080  */
28
29
      asm (
30
       "ldr	r2, [%1, #0]\n\
31
	ldr	r3, [%2, #0]\n\
32
	cmp	r2, r3\n\
33
	bne	2f\n\
34
\n\
35
	mov	ip, #0x80\n\
36
	add	ip, ip, #0x8000\n\
37
	add	ip, ip, ip, lsl #16\n\
38
	mvn	lr, ip, lsl #1\n\
39
\n\
40
0:\n\
41
	ldr	r2, [%1, #0]\n\
42
	add	r3, r2, lr\n\
43
	bic	r3, r3, r2\n\
44
	tst	r3, ip\n\
45
	beq	1f\n\
46
	mov	%0, #0x0\n\
47
	b	3f\n\
48
1:\n\
49
	ldr	r2, [%1, #4]!\n\
50
	ldr	r3, [%2, #4]!\n\
51
"	PRELOADSTR("%1") "\n\
52
"	PRELOADSTR("%2") "\n\
53
	cmp	r2, r3\n\
54
	beq	0b"
55
56
       /* The following part could be done in a C loop as well, but it needs
57
	  to be assembler to save some cycles in the case where the optimized
58
	  loop above finds the strings to be equal.  */
59
"\n\
60
2:\n\
61
	ldrb	r2, [%1, #0]\n\
62
"	PRELOADSTR("%1") "\n\
63
"	PRELOADSTR("%2") "\n\
64
	cmp	r2, #0x0\n\
65
	beq	1f\n\
66
	ldrb	r3, [%2, #0]\n\
67
	cmp	r2, r3\n\
68
	bne	1f\n\
69
0:\n\
70
	ldrb	r3, [%1, #1]!\n\
71
	add	%2, %2, #1\n\
72
	ands	ip, r3, #0xff\n\
73
	beq	1f\n\
74
	ldrb	r3, [%2]\n\
75
	cmp	ip, r3\n\
76
	beq	0b\n\
77
1:\n\
78
	ldrb	lr, [%1, #0]\n\
79
	ldrb	ip, [%2, #0]\n\
80
	rsb	%0, ip, lr\n\
81
3:\n\
82
"
83
84
       : "=r" (result), "=&r" (s1), "=&r" (s2)
85
       : "1" (s1), "2" (s2)
86
       : "lr", "ip", "r2", "r3", "cc");
87
      return result;
88
    }
89
#endif
90
91
  while (*s1 != '\0' && *s1 == *s2)
92
    {
93
      asm (PRELOADSTR("%0") : : "r" (s1));
94
      asm (PRELOADSTR("%0") : : "r" (s2));
95
      s1++;
96
      s2++;
97
    }
98
 out:
99
  return (*(unsigned char *) s1) - (*(unsigned char *) s2);
100
}