Commit | Line | Data |
---|---|---|
1394f032 BW |
1 | #ifndef _BLACKFIN_STRING_H_ |
2 | #define _BLACKFIN_STRING_H_ | |
3 | ||
d0025e5e MF |
4 | #include <linux/types.h> |
5 | ||
1394f032 BW |
6 | #ifdef __KERNEL__ /* only set these up for kernel code */ |
7 | ||
8 | #define __HAVE_ARCH_STRCPY | |
9 | extern inline char *strcpy(char *dest, const char *src) | |
10 | { | |
11 | char *xdest = dest; | |
12 | char temp = 0; | |
13 | ||
0931ce84 MF |
14 | __asm__ __volatile__ ( |
15 | "1:" | |
16 | "%2 = B [%1++] (Z);" | |
17 | "B [%0++] = %2;" | |
18 | "CC = %2;" | |
19 | "if cc jump 1b (bp);" | |
20 | : "+&a" (dest), "+&a" (src), "=&d" (temp) | |
21 | : | |
22 | : "memory", "CC"); | |
23 | ||
1394f032 BW |
24 | return xdest; |
25 | } | |
26 | ||
27 | #define __HAVE_ARCH_STRNCPY | |
28 | extern inline char *strncpy(char *dest, const char *src, size_t n) | |
29 | { | |
30 | char *xdest = dest; | |
31 | char temp = 0; | |
32 | ||
33 | if (n == 0) | |
34 | return xdest; | |
35 | ||
0931ce84 MF |
36 | __asm__ __volatile__ ( |
37 | "1:" | |
38 | "%3 = B [%1++] (Z);" | |
39 | "B [%0++] = %3;" | |
40 | "CC = %3;" | |
41 | "if ! cc jump 2f;" | |
42 | "%2 += -1;" | |
43 | "CC = %2 == 0;" | |
44 | "if ! cc jump 1b (bp);" | |
45 | "jump 4f;" | |
46 | "2:" | |
47 | /* if src is shorter than n, we need to null pad bytes now */ | |
48 | "%3 = 0;" | |
49 | "3:" | |
50 | "%2 += -1;" | |
51 | "CC = %2 == 0;" | |
52 | "if cc jump 4f;" | |
53 | "B [%0++] = %3;" | |
54 | "jump 3b;" | |
55 | "4:" | |
56 | : "+&a" (dest), "+&a" (src), "+&da" (n), "=&d" (temp) | |
57 | : | |
58 | : "memory", "CC"); | |
59 | ||
1394f032 BW |
60 | return xdest; |
61 | } | |
62 | ||
63 | #define __HAVE_ARCH_STRCMP | |
64 | extern inline int strcmp(const char *cs, const char *ct) | |
65 | { | |
0931ce84 MF |
66 | /* need to use int's here so the char's in the assembly don't get |
67 | * sign extended incorrectly when we don't want them to be | |
68 | */ | |
69 | int __res1, __res2; | |
70 | ||
71 | __asm__ __volatile__ ( | |
72 | "1:" | |
73 | "%2 = B[%0++] (Z);" /* get *cs */ | |
74 | "%3 = B[%1++] (Z);" /* get *ct */ | |
75 | "CC = %2 == %3;" /* compare a byte */ | |
76 | "if ! cc jump 2f;" /* not equal, break out */ | |
77 | "CC = %2;" /* at end of cs? */ | |
78 | "if cc jump 1b (bp);" /* no, keep going */ | |
79 | "jump.s 3f;" /* strings are equal */ | |
80 | "2:" | |
81 | "%2 = %2 - %3;" /* *cs - *ct */ | |
82 | "3:" | |
83 | : "+&a" (cs), "+&a" (ct), "=&d" (__res1), "=&d" (__res2) | |
84 | : | |
85 | : "memory", "CC"); | |
1394f032 BW |
86 | |
87 | return __res1; | |
88 | } | |
89 | ||
90 | #define __HAVE_ARCH_STRNCMP | |
91 | extern inline int strncmp(const char *cs, const char *ct, size_t count) | |
92 | { | |
0931ce84 MF |
93 | /* need to use int's here so the char's in the assembly don't get |
94 | * sign extended incorrectly when we don't want them to be | |
95 | */ | |
96 | int __res1, __res2; | |
1394f032 BW |
97 | |
98 | if (!count) | |
99 | return 0; | |
0931ce84 MF |
100 | |
101 | __asm__ __volatile__ ( | |
102 | "1:" | |
103 | "%3 = B[%0++] (Z);" /* get *cs */ | |
104 | "%4 = B[%1++] (Z);" /* get *ct */ | |
105 | "CC = %3 == %4;" /* compare a byte */ | |
106 | "if ! cc jump 3f;" /* not equal, break out */ | |
107 | "CC = %3;" /* at end of cs? */ | |
108 | "if ! cc jump 4f;" /* yes, all done */ | |
109 | "%2 += -1;" /* no, adjust count */ | |
110 | "CC = %2 == 0;" | |
111 | "if ! cc jump 1b;" /* more to do, keep going */ | |
112 | "2:" | |
113 | "%3 = 0;" /* strings are equal */ | |
114 | "jump.s 4f;" | |
115 | "3:" | |
116 | "%3 = %3 - %4;" /* *cs - *ct */ | |
117 | "4:" | |
118 | : "+&a" (cs), "+&a" (ct), "+&da" (count), "=&d" (__res1), "=&d" (__res2) | |
119 | : | |
120 | : "memory", "CC"); | |
121 | ||
1394f032 BW |
122 | return __res1; |
123 | } | |
124 | ||
125 | #define __HAVE_ARCH_MEMSET | |
126 | extern void *memset(void *s, int c, size_t count); | |
127 | #define __HAVE_ARCH_MEMCPY | |
128 | extern void *memcpy(void *d, const void *s, size_t count); | |
129 | #define __HAVE_ARCH_MEMCMP | |
130 | extern int memcmp(const void *, const void *, __kernel_size_t); | |
131 | #define __HAVE_ARCH_MEMCHR | |
132 | extern void *memchr(const void *s, int c, size_t n); | |
133 | #define __HAVE_ARCH_MEMMOVE | |
134 | extern void *memmove(void *dest, const void *src, size_t count); | |
135 | ||
136 | #endif /*__KERNEL__*/ | |
137 | #endif /* _BLACKFIN_STRING_H_ */ |