blob: d5bec088cca83630465e8460bd9fbaf1ef72592d [file] [log] [blame]
The Android Open Source Project5b1eb062009-03-03 19:29:32 -08001/*
2 * Taken from Linux /usr/include/asm/string.h
3 * All except memcpy, memmove, memset and memcmp removed.
4 */
5
6#ifndef _I386_STRING_H_
7#define _I386_STRING_H_
8
9/*
10 * This string-include defines all string functions as inline
11 * functions. Use gcc. It also assumes ds=es=data space, this should be
12 * normal. Most of the string-functions are rather heavily hand-optimized,
13 * see especially strtok,strstr,str[c]spn. They should work, but are not
14 * very easy to understand. Everything is done entirely within the register
15 * set, making the functions fast and clean. String instructions have been
16 * used through-out, making for "slightly" unclear code :-)
17 *
18 * NO Copyright (C) 1991, 1992 Linus Torvalds,
19 * consider these trivial functions to be PD.
20 */
21
22typedef int size_t;
23
24extern void *__memcpy(void * to, const void * from, size_t n);
25extern void *__constant_memcpy(void * to, const void * from, size_t n);
26extern void *memmove(void * dest,const void * src, size_t n);
27extern void *__memset_generic(void * s, char c,size_t count);
28extern void *__constant_c_memset(void * s, unsigned long c, size_t count);
29extern void *__constant_c_and_count_memset(void * s, unsigned long pattern, size_t count);
30
31
32extern inline void * __memcpy(void * to, const void * from, size_t n)
33{
34int d0, d1, d2;
35__asm__ __volatile__(
36 "cld\n\t"
37 "rep ; movsl\n\t"
38 "testb $2,%b4\n\t"
39 "je 1f\n\t"
40 "movsw\n"
41 "1:\ttestb $1,%b4\n\t"
42 "je 2f\n\t"
43 "movsb\n"
44 "2:"
45 : "=&c" (d0), "=&D" (d1), "=&S" (d2)
46 :"0" (n/4), "q" (n),"1" ((long) to),"2" ((long) from)
47 : "memory");
48return (to);
49}
50
51/*
52 * This looks horribly ugly, but the compiler can optimize it totally,
53 * as the count is constant.
54 */
55extern inline void * __constant_memcpy(void * to, const void * from, size_t n)
56{
57 switch (n) {
58 case 0:
59 return to;
60 case 1:
61 *(unsigned char *)to = *(const unsigned char *)from;
62 return to;
63 case 2:
64 *(unsigned short *)to = *(const unsigned short *)from;
65 return to;
66 case 3:
67 *(unsigned short *)to = *(const unsigned short *)from;
68 *(2+(unsigned char *)to) = *(2+(const unsigned char *)from);
69 return to;
70 case 4:
71 *(unsigned long *)to = *(const unsigned long *)from;
72 return to;
73 case 6: /* for Ethernet addresses */
74 *(unsigned long *)to = *(const unsigned long *)from;
75 *(2+(unsigned short *)to) = *(2+(const unsigned short *)from);
76 return to;
77 case 8:
78 *(unsigned long *)to = *(const unsigned long *)from;
79 *(1+(unsigned long *)to) = *(1+(const unsigned long *)from);
80 return to;
81 case 12:
82 *(unsigned long *)to = *(const unsigned long *)from;
83 *(1+(unsigned long *)to) = *(1+(const unsigned long *)from);
84 *(2+(unsigned long *)to) = *(2+(const unsigned long *)from);
85 return to;
86 case 16:
87 *(unsigned long *)to = *(const unsigned long *)from;
88 *(1+(unsigned long *)to) = *(1+(const unsigned long *)from);
89 *(2+(unsigned long *)to) = *(2+(const unsigned long *)from);
90 *(3+(unsigned long *)to) = *(3+(const unsigned long *)from);
91 return to;
92 case 20:
93 *(unsigned long *)to = *(const unsigned long *)from;
94 *(1+(unsigned long *)to) = *(1+(const unsigned long *)from);
95 *(2+(unsigned long *)to) = *(2+(const unsigned long *)from);
96 *(3+(unsigned long *)to) = *(3+(const unsigned long *)from);
97 *(4+(unsigned long *)to) = *(4+(const unsigned long *)from);
98 return to;
99 }
100#define COMMON(x) \
101__asm__ __volatile__( \
102 "cld\n\t" \
103 "rep ; movsl" \
104 x \
105 : "=&c" (d0), "=&D" (d1), "=&S" (d2) \
106 : "0" (n/4),"1" ((long) to),"2" ((long) from) \
107 : "memory");
108{
109 int d0, d1, d2;
110 switch (n % 4) {
111 case 0: COMMON(""); return to;
112 case 1: COMMON("\n\tmovsb"); return to;
113 case 2: COMMON("\n\tmovsw"); return to;
114 default: COMMON("\n\tmovsw\n\tmovsb"); return to;
115 }
116}
117
118#undef COMMON
119}
120
121#define __HAVE_ARCH_MEMCPY
122#define memcpy(t, f, n) \
123(__builtin_constant_p(n) ? \
124 __constant_memcpy((t),(f),(n)) : \
125 __memcpy((t),(f),(n)))
126
127#define __HAVE_ARCH_MEMMOVE
128extern inline void * memmove(void * dest,const void * src, size_t n)
129{
130int d0, d1, d2;
131if (dest<src)
132__asm__ __volatile__(
133 "cld\n\t"
134 "rep\n\t"
135 "movsb"
136 : "=&c" (d0), "=&S" (d1), "=&D" (d2)
137 :"0" (n),"1" (src),"2" (dest)
138 : "memory");
139else
140__asm__ __volatile__(
141 "std\n\t"
142 "rep\n\t"
143 "movsb\n\t"
144 "cld"
145 : "=&c" (d0), "=&S" (d1), "=&D" (d2)
146 :"0" (n),
147 "1" (n-1+(const char *)src),
148 "2" (n-1+(char *)dest)
149 :"memory");
150return dest;
151}
152
153#define memcmp __builtin_memcmp
154
155extern inline void * __memset_generic(void * s, char c,size_t count)
156{
157int d0, d1;
158__asm__ __volatile__(
159 "cld\n\t"
160 "rep\n\t"
161 "stosb"
162 : "=&c" (d0), "=&D" (d1)
163 :"a" (c),"1" (s),"0" (count)
164 :"memory");
165return s;
166}
167
168/* we might want to write optimized versions of these later */
169#define __constant_count_memset(s,c,count) __memset_generic((s),(c),(count))
170
171/*
172 * memset(x,0,y) is a reasonably common thing to do, so we want to fill
173 * things 32 bits at a time even when we don't know the size of the
174 * area at compile-time..
175 */
176extern inline void * __constant_c_memset(void * s, unsigned long c, size_t count)
177{
178int d0, d1;
179__asm__ __volatile__(
180 "cld\n\t"
181 "rep ; stosl\n\t"
182 "testb $2,%b3\n\t"
183 "je 1f\n\t"
184 "stosw\n"
185 "1:\ttestb $1,%b3\n\t"
186 "je 2f\n\t"
187 "stosb\n"
188 "2:"
189 : "=&c" (d0), "=&D" (d1)
190 :"a" (c), "q" (count), "0" (count/4), "1" ((long) s)
191 :"memory");
192return (s);
193}
194
195/*
196 * This looks horribly ugly, but the compiler can optimize it totally,
197 * as we by now know that both pattern and count is constant..
198 */
199extern inline void * __constant_c_and_count_memset(void * s, unsigned long pattern, size_t count)
200{
201 switch (count) {
202 case 0:
203 return s;
204 case 1:
205 *(unsigned char *)s = pattern;
206 return s;
207 case 2:
208 *(unsigned short *)s = pattern;
209 return s;
210 case 3:
211 *(unsigned short *)s = pattern;
212 *(2+(unsigned char *)s) = pattern;
213 return s;
214 case 4:
215 *(unsigned long *)s = pattern;
216 return s;
217 }
218#define COMMON(x) \
219__asm__ __volatile__("cld\n\t" \
220 "rep ; stosl" \
221 x \
222 : "=&c" (d0), "=&D" (d1) \
223 : "a" (pattern),"0" (count/4),"1" ((long) s) \
224 : "memory")
225{
226 int d0, d1;
227 switch (count % 4) {
228 case 0: COMMON(""); return s;
229 case 1: COMMON("\n\tstosb"); return s;
230 case 2: COMMON("\n\tstosw"); return s;
231 default: COMMON("\n\tstosw\n\tstosb"); return s;
232 }
233}
234
235#undef COMMON
236}
237
238#define __constant_c_x_memset(s, c, count) \
239(__builtin_constant_p(count) ? \
240 __constant_c_and_count_memset((s),(c),(count)) : \
241 __constant_c_memset((s),(c),(count)))
242
243#define __memset(s, c, count) \
244(__builtin_constant_p(count) ? \
245 __constant_count_memset((s),(c),(count)) : \
246 __memset_generic((s),(c),(count)))
247
248#define __HAVE_ARCH_MEMSET
249#define memset(s, c, count) \
250(__builtin_constant_p(c) ? \
251 __constant_c_x_memset((s),(c),(count)) : \
252 __memset((s),(c),(count)))
253
254#define __HAVE_ARCH_STRNCMP
255static inline int strncmp(const char * cs,const char * ct,size_t count)
256{
257register int __res;
258int d0, d1, d2;
259__asm__ __volatile__(
260 "1:\tdecl %3\n\t"
261 "js 2f\n\t"
262 "lodsb\n\t"
263 "scasb\n\t"
264 "jne 3f\n\t"
265 "testb %%al,%%al\n\t"
266 "jne 1b\n"
267 "2:\txorl %%eax,%%eax\n\t"
268 "jmp 4f\n"
269 "3:\tsbbl %%eax,%%eax\n\t"
270 "orb $1,%%al\n"
271 "4:"
272 :"=a" (__res), "=&S" (d0), "=&D" (d1), "=&c" (d2)
273 :"1" (cs),"2" (ct),"3" (count));
274return __res;
275}
276
277#define __HAVE_ARCH_STRLEN
278static inline size_t strlen(const char * s)
279{
280int d0;
281register int __res;
282__asm__ __volatile__(
283 "repne\n\t"
284 "scasb\n\t"
285 "notl %0\n\t"
286 "decl %0"
287 :"=c" (__res), "=&D" (d0) :"1" (s),"a" (0), "0" (0xffffffff));
288return __res;
289}
290
291#endif