diff options
Diffstat (limited to 'arch/blackfin/include/asm/string.h')
-rw-r--r-- | arch/blackfin/include/asm/string.h | 137 |
1 files changed, 137 insertions, 0 deletions
diff --git a/arch/blackfin/include/asm/string.h b/arch/blackfin/include/asm/string.h new file mode 100644 index 000000000000..321f4d96e4ae --- /dev/null +++ b/arch/blackfin/include/asm/string.h | |||
@@ -0,0 +1,137 @@ | |||
1 | #ifndef _BLACKFIN_STRING_H_ | ||
2 | #define _BLACKFIN_STRING_H_ | ||
3 | |||
4 | #include <linux/types.h> | ||
5 | |||
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 | |||
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 | |||
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 | |||
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 | |||
60 | return xdest; | ||
61 | } | ||
62 | |||
63 | #define __HAVE_ARCH_STRCMP | ||
64 | extern inline int strcmp(const char *cs, const char *ct) | ||
65 | { | ||
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"); | ||
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 | { | ||
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; | ||
97 | |||
98 | if (!count) | ||
99 | return 0; | ||
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 | |||
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_ */ | ||