fixes for host gcc 4.6.1
[zpugcc/jano.git] / toolchain / gcc / newlib / libc / machine / xscale / strcmp.c
blob6c94d126fd98ef64c22b6493052c522ab854013e
1 #if defined __thumb__
3 #include "../../string/strcmp.c"
5 #else
7 #include <string.h>
8 #include "xscale.h"
10 int
11 strcmp (const char *s1, const char *s2)
13 asm (PRELOADSTR ("%0") : : "r" (s1));
14 asm (PRELOADSTR ("%0") : : "r" (s2));
16 #ifndef __OPTIMIZE_SIZE__
17 if (((long)s1 & 3) == ((long)s2 & 3))
19 int result;
21 /* Skip unaligned part. */
22 while ((long)s1 & 3)
24 if (*s1 == '\0' || *s1 != *s2)
25 goto out;
26 s1++;
27 s2++;
30 /* Load two constants:
31 lr = 0xfefefeff [ == ~(0x80808080 << 1) ]
32 ip = 0x80808080 */
34 asm (
35 "ldr r2, [%1, #0]\n\
36 ldr r3, [%2, #0]\n\
37 cmp r2, r3\n\
38 bne 2f\n\
39 \n\
40 mov ip, #0x80\n\
41 add ip, ip, #0x8000\n\
42 add ip, ip, ip, lsl #16\n\
43 mvn lr, ip, lsl #1\n\
44 \n\
45 0:\n\
46 ldr r2, [%1, #0]\n\
47 add r3, r2, lr\n\
48 bic r3, r3, r2\n\
49 tst r3, ip\n\
50 beq 1f\n\
51 mov %0, #0x0\n\
52 b 3f\n\
53 1:\n\
54 ldr r2, [%1, #4]!\n\
55 ldr r3, [%2, #4]!\n\
56 " PRELOADSTR("%1") "\n\
57 " PRELOADSTR("%2") "\n\
58 cmp r2, r3\n\
59 beq 0b"
61 /* The following part could be done in a C loop as well, but it needs
62 to be assembler to save some cycles in the case where the optimized
63 loop above finds the strings to be equal. */
64 "\n\
65 2:\n\
66 ldrb r2, [%1, #0]\n\
67 " PRELOADSTR("%1") "\n\
68 " PRELOADSTR("%2") "\n\
69 cmp r2, #0x0\n\
70 beq 1f\n\
71 ldrb r3, [%2, #0]\n\
72 cmp r2, r3\n\
73 bne 1f\n\
74 0:\n\
75 ldrb r3, [%1, #1]!\n\
76 add %2, %2, #1\n\
77 ands ip, r3, #0xff\n\
78 beq 1f\n\
79 ldrb r3, [%2]\n\
80 cmp ip, r3\n\
81 beq 0b\n\
82 1:\n\
83 ldrb lr, [%1, #0]\n\
84 ldrb ip, [%2, #0]\n\
85 rsb %0, ip, lr\n\
86 3:\n\
89 : "=r" (result), "=&r" (s1), "=&r" (s2)
90 : "1" (s1), "2" (s2)
91 : "lr", "ip", "r2", "r3", "cc");
92 return result;
94 #endif
96 while (*s1 != '\0' && *s1 == *s2)
98 asm (PRELOADSTR("%0") : : "r" (s1));
99 asm (PRELOADSTR("%0") : : "r" (s2));
100 s1++;
101 s2++;
103 out:
104 return (*(unsigned char *) s1) - (*(unsigned char *) s2);
107 #endif