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 |
}
|