38
by Michael Hope
Added the XScale specific routines from Newlib 1.19.0 |
1 |
#include <string.h> |
2 |
#include "xscale.h" |
|
3 |
||
4 |
void * |
|
5 |
memchr (const void *start, int c, size_t len) |
|
6 |
{
|
|
7 |
const char *str = start; |
|
8 |
||
9 |
if (len == 0) |
|
10 |
return 0; |
|
11 |
||
12 |
asm (PRELOADSTR ("%0") : : "r" (start)); |
|
13 |
||
14 |
c &= 0xff; |
|
15 |
||
16 |
#ifndef __OPTIMIZE_SIZE__
|
|
17 |
/* Skip unaligned part. */
|
|
18 |
if ((long)str & 3) |
|
19 |
{
|
|
20 |
str--; |
|
21 |
do
|
|
22 |
{
|
|
23 |
if (*++str == c) |
|
24 |
return (void *)str; |
|
25 |
}
|
|
26 |
while (((long)str & 3) != 0 && --len > 0); |
|
27 |
}
|
|
28 |
||
29 |
if (len > 3) |
|
30 |
{
|
|
31 |
unsigned int c2 = c + (c << 8); |
|
32 |
c2 += c2 << 16; |
|
33 |
||
34 |
/* Load two constants:
|
|
35 |
R7 = 0xfefefeff [ == ~(0x80808080 << 1) ]
|
|
36 |
R6 = 0x80808080 */
|
|
37 |
||
38 |
asm ( |
|
39 |
"mov r6, #0x80\n\ |
|
40 |
add r6, r6, #0x8000\n\ |
|
41 |
add r6, r6, r6, lsl #16\n\ |
|
42 |
mvn r7, r6, lsl #1\n\ |
|
43 |
\n\ |
|
44 |
0:\n\ |
|
45 |
cmp %1, #0x7\n\ |
|
46 |
bls 1f\n\ |
|
47 |
\n\ |
|
48 |
ldmia %0!, { r3, r9 }\n\ |
|
49 |
" PRELOADSTR ("%0") "\n\ |
|
50 |
sub %1, %1, #8\n\ |
|
51 |
eor r3, r3, %2\n\ |
|
52 |
eor r9, r9, %2\n\ |
|
53 |
add r2, r3, r7\n\ |
|
54 |
add r8, r9, r7\n\ |
|
55 |
bic r2, r2, r3\n\ |
|
56 |
bic r8, r8, r9\n\ |
|
57 |
and r1, r2, r6\n\ |
|
58 |
and r9, r8, r6\n\ |
|
59 |
orrs r1, r1, r9\n\ |
|
60 |
beq 0b\n\ |
|
61 |
\n\ |
|
62 |
add %1, %1, #8\n\ |
|
63 |
sub %0, %0, #8\n\ |
|
64 |
1:\n\ |
|
65 |
cmp %1, #0x3\n\ |
|
66 |
bls 2f\n\ |
|
67 |
\n\ |
|
68 |
ldr r3, [%0], #4\n\ |
|
69 |
" PRELOADSTR ("%0") "\n\ |
|
70 |
sub %1, %1, #4\n\ |
|
71 |
eor r3, r3, %2\n\ |
|
72 |
add r2, r3, r7\n\ |
|
73 |
bic r2, r2, r3\n\ |
|
74 |
ands r1, r2, r6\n\ |
|
75 |
beq 1b\n\ |
|
76 |
\n\ |
|
77 |
sub %0, %0, #4\n\ |
|
78 |
add %1, %1, #4\n\ |
|
79 |
2:\n\ |
|
80 |
"
|
|
81 |
: "=&r" (str), "=&r" (len) |
|
82 |
: "r" (c2), "0" (str), "1" (len) |
|
83 |
: "r1", "r2", "r3", "r6", "r7", "r8", "r9", "cc"); |
|
84 |
}
|
|
85 |
#endif
|
|
86 |
||
87 |
while (len-- > 0) |
|
88 |
{
|
|
89 |
if (*str == c) |
|
90 |
return (void *)str; |
|
91 |
str++; |
|
92 |
}
|
|
93 |
||
94 |
return 0; |
|
95 |
}
|