~smartboyhw/wubi/bug-1080090-new

« back to all changes in this revision

Viewing changes to src/grub4dos/netboot/.svn/text-base/linux-asm-string.h.svn-base

  • Committer: Howard Chan
  • Date: 2012-11-20 10:16:05 UTC
  • Revision ID: smartboyhw@gmail.com-20121120101605-qfmjfsdynpzg9an9
Added images

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
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
 
 
22
 
typedef int     size_t;
23
 
 
24
 
extern void *__memcpy(void * to, const void * from, size_t n);
25
 
extern void *__constant_memcpy(void * to, const void * from, size_t n);
26
 
extern void *memmove(void * dest,const void * src, size_t n);
27
 
extern void *__memset_generic(void * s, char c,size_t count);
28
 
extern void *__constant_c_memset(void * s, unsigned long c, size_t count);
29
 
extern void *__constant_c_and_count_memset(void * s, unsigned long pattern, size_t count);
30
 
 
31
 
 
32
 
extern inline void * __memcpy(void * to, const void * from, size_t n)
33
 
{
34
 
int 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");
48
 
return (to);
49
 
}
50
 
 
51
 
/*
52
 
 * This looks horribly ugly, but the compiler can optimize it totally,
53
 
 * as the count is constant.
54
 
 */
55
 
extern 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
128
 
extern inline void * memmove(void * dest,const void * src, size_t n)
129
 
{
130
 
int d0, d1, d2;
131
 
if (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");
139
 
else
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");
150
 
return dest;
151
 
}
152
 
 
153
 
#define memcmp __builtin_memcmp
154
 
 
155
 
extern inline void * __memset_generic(void * s, char c,size_t count)
156
 
{
157
 
int 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");
165
 
return 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
 
 */
176
 
extern inline void * __constant_c_memset(void * s, unsigned long c, size_t count)
177
 
{
178
 
int 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");
192
 
return (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
 
 */
199
 
extern 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
255
 
static inline int strncmp(const char * cs,const char * ct,size_t count)
256
 
{
257
 
register int __res;
258
 
int 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));
274
 
return __res;
275
 
}
276
 
 
277
 
#define __HAVE_ARCH_STRLEN
278
 
static inline size_t strlen(const char * s)
279
 
{
280
 
int d0;
281
 
register 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));
288
 
return __res;
289
 
}
290
 
 
291
 
#endif