fixes for host gcc 4.6.1
[zpugcc/jano.git] / toolchain / gcc / newlib / libc / machine / xscale / memcmp.c
blob1eba4b8ddb3a7d70ed8555ef11b5b439fc6a1adc
1 #if defined __thumb__
3 #include "../../string/memcmp.c"
5 #else
7 #include <string.h>
8 #include "xscale.h"
10 int
11 memcmp (const void * s1, const void * s2, size_t len)
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;
112 #endif