1 |
148 |
jeremybenn |
#if defined __thumb__
|
2 |
|
|
|
3 |
|
|
#include "../../string/memcmp.c"
|
4 |
|
|
|
5 |
|
|
#else
|
6 |
|
|
|
7 |
|
|
#include <string.h>
|
8 |
|
|
#include "xscale.h"
|
9 |
|
|
|
10 |
|
|
int
|
11 |
|
|
memcmp (const void * s1, const void * s2, size_t len)
|
12 |
|
|
{
|
13 |
|
|
int result;
|
14 |
|
|
asm (
|
15 |
|
|
#ifndef __OPTIMIZE_SIZE__
|
16 |
|
|
"\n\
|
17 |
|
|
cmp %2, #0x3 @ Is the length a multiple of four ?\n\
|
18 |
|
|
bls 6f @ no = goto SLOW CHECK\n\
|
19 |
|
|
and r2, %0, #0x3 @ get alignment of first pointer\n\
|
20 |
|
|
and r3, %1, #0x3 @ get alignment of second pointer\n\
|
21 |
|
|
cmp r2, r3 @ Do the two pointers share the same alignment ?\n\
|
22 |
|
|
bne 6f @ no = goto SLOW CHECK\n\
|
23 |
|
|
mov lr, %0 @ copy first pointer into LR\n\
|
24 |
|
|
mov r4, %1 @ copy second pointer into R4\n\
|
25 |
|
|
cmp r2, #0x0 @ Are we comparing word aligned pointers ?\n\
|
26 |
|
|
beq 3f @ yes = goto START WORD CHECK LOOP\n\
|
27 |
|
|
b 1f @ jump to LOOP TEST\n\
|
28 |
|
|
0: @ LOOP START\n\
|
29 |
|
|
ldrb r2, [lr], #1 @ load byte from LR, post inc.\n\
|
30 |
|
|
" PRELOADSTR("lr") " @ preload\n\
|
31 |
|
|
ldrb r3, [r4], #1 @ load byte from R4, post inc.\n\
|
32 |
|
|
" PRELOADSTR("r4") " @ preload\n\
|
33 |
|
|
cmp r2, r3 @ are the two bytes the same ?\n\
|
34 |
|
|
bne 5f @ no = goto EXIT\n\
|
35 |
|
|
tst lr, #0x3 @ has the LR become word aligned ?\n\
|
36 |
|
|
bne 1f @ no = skip the next test\n\
|
37 |
|
|
cmp %2, #4 @ is the count >= 4 ?\n\
|
38 |
|
|
bhs 3f @ yes = goto START WORD CHECK LOOP\n\
|
39 |
|
|
1: @ LOOP TEST\n\
|
40 |
|
|
sub %2, %2, #1 @ decrement count by one\n\
|
41 |
|
|
cmn %2, #0x1 @ has the count reached -1 ?\n\
|
42 |
|
|
bne 0b @ no = loop back to LOOP START\n\
|
43 |
|
|
b 4f @ goto PASS END\n\
|
44 |
|
|
\n\
|
45 |
|
|
0: @ ??\n\
|
46 |
|
|
cmp %2, #0x7 @ Is the count a multiple of 8 ?\n\
|
47 |
|
|
bls 3f @ no = goto ???\n\
|
48 |
|
|
ldmia lr,{r2, r3} @ get two words from first pointer, post inc\n\
|
49 |
|
|
ldmia r4,{r5, r6} @ get two words from second pointer, post inc\n\
|
50 |
|
|
sub %2, %2, #0x4 @ decrement count by 4\n\
|
51 |
|
|
cmp r2, r5 @ has the count reached ????\n\
|
52 |
|
|
bne 1f @ no = goto\n\
|
53 |
|
|
sub %2, %2, #0x4 @ decrement the count by 4\n\
|
54 |
|
|
add lr, lr, #0x4 @ add 4 to first pointer\n\
|
55 |
|
|
add r4, r4, #0x4 @ add 4 to second pointer\n\
|
56 |
|
|
cmp r3, r6 @ ???\n\
|
57 |
|
|
beq 0b @ goto ???\n\
|
58 |
|
|
1: @ ??\n\
|
59 |
|
|
add %2, %2, #0x4 @ Add four to count\n\
|
60 |
|
|
sub %0, lr, #0x4 @ decrement first pointer by 4\n\
|
61 |
|
|
sub %1, r4, #0x4 @ decrement second pointer by 4\n\
|
62 |
|
|
b 6f @ goto SLOW CHECK\n\
|
63 |
|
|
\n\
|
64 |
|
|
3: @ START WORD CHECK LOOP\n\
|
65 |
|
|
cmp %2, #0x3 @ is the count <= 3 ?\n\
|
66 |
|
|
bls 1f @ yes = goto CHECK BYTES BY HAND\n\
|
67 |
|
|
ldr r2, [lr], #4 @ get word from LR, post inc\n\
|
68 |
|
|
ldr r3, [r4], #4 @ get word from R4, post inc\n\
|
69 |
|
|
sub %2, %2, #4 @ decrement count by 4\n\
|
70 |
|
|
cmp r2, r3 @ are the two words the same ?\n\
|
71 |
|
|
bne 1f @ no = goto CHECK WORD CONTENTS\n\
|
72 |
|
|
0: @ WORD CHECK LOOP\n\
|
73 |
|
|
cmp %2, #0x3 @ is the count <= 3 ?\n\
|
74 |
|
|
bls 1f @ yes = goto CHECK BYTES BY HAND\n\
|
75 |
|
|
ldr r2, [lr], #4 @ load word from LR, post inc\n\
|
76 |
|
|
" PRELOADSTR("lr") " @ preload\n\
|
77 |
|
|
ldr r3, [r4], #4 @ load word from R4, post inc\n\
|
78 |
|
|
" PRELOADSTR("r4") " @ preload\n\
|
79 |
|
|
sub %2, %2, #4 @ decrement count by 4\n\
|
80 |
|
|
cmp r2, r3 @ are the two words the same ?\n\
|
81 |
|
|
beq 0b @ yes = goto WORD CHECK LOOP\n\
|
82 |
|
|
1: @ CHECK BYTES BY HAND\n\
|
83 |
|
|
sub %0, lr, #0x4 @ move LR back a word and put into first pointer\n\
|
84 |
|
|
sub %1, r4, #0x4 @ move R4 back a word and put into second pointer\n\
|
85 |
|
|
add %2, %2, #4 @ increment the count by 4\n\
|
86 |
|
|
@ fall through into SLOW CHECK"
|
87 |
|
|
#endif /* !__OPTIMIZE_SIZE__ */
|
88 |
|
|
"\n\
|
89 |
|
|
6: @ SLOW CHECK\n\
|
90 |
|
|
sub %2, %2, #1 @ Decrement the count by one\n\
|
91 |
|
|
cmn %2, #0x1 @ Has the count reached -1 ?\n\
|
92 |
|
|
beq 4f @ Yes - we are finished, goto PASS END\n\
|
93 |
|
|
0: @ LOOP1\n\
|
94 |
|
|
ldrb r2, [%0], #1 @ get byte from first pointer\n\
|
95 |
|
|
" PRELOADSTR("%0") " @ preload first pointer\n\
|
96 |
|
|
ldrb r3, [%1], #1 @ get byte from second pointer\n\
|
97 |
|
|
" PRELOADSTR("%1") " @ preload second pointer\n\
|
98 |
|
|
cmp r2, r3 @ compare the two loaded bytes\n\
|
99 |
|
|
bne 5f @ if they are not equal goto EXIT\n\
|
100 |
|
|
sub %2, %2, #1 @ decremented count by 1\n\
|
101 |
|
|
cmn %2, #0x1 @ has the count reached -1 ?\n\
|
102 |
|
|
bne 0b @ no = then go back to LOOP1\n\
|
103 |
|
|
4: @ PASS END\n\
|
104 |
|
|
mov r3, r2 @ Default return value is 0\n\
|
105 |
|
|
5: @ EXIT\n\
|
106 |
|
|
rsb %0, r3, r2 @ return difference between last two bytes loaded"
|
107 |
|
|
: "=r" (result), "=&r" (s2), "=&r" (len)
|
108 |
|
|
: "0" (s1), "1" (s2), "2" (len)
|
109 |
|
|
: "r2", "r3", "r4", "r5", "r6", "cc", "lr");
|
110 |
|
|
return result;
|
111 |
|
|
}
|
112 |
|
|
#endif
|