vserver 1.9.3
[linux-2.6.git] / include / asm-m68k / uaccess.h
1 #ifndef __M68K_UACCESS_H
2 #define __M68K_UACCESS_H
3
4 /*
5  * User space memory access functions
6  */
7 #include <linux/errno.h>
8 #include <linux/sched.h>
9 #include <asm/segment.h>
10
11 #define VERIFY_READ     0
12 #define VERIFY_WRITE    1
13
14 /* We let the MMU do all checking */
15 #define access_ok(type,addr,size) 1
16
17 static inline int verify_area(int type, const void *addr, unsigned long size)
18 {
19         return access_ok(type,addr,size)?0:-EFAULT;
20 }
21
22 /*
23  * The exception table consists of pairs of addresses: the first is the
24  * address of an instruction that is allowed to fault, and the second is
25  * the address at which the program should continue.  No registers are
26  * modified, so it is entirely up to the continuation code to figure out
27  * what to do.
28  *
29  * All the routines below use bits of fixup code that are out of line
30  * with the main instruction path.  This means when everything is well,
31  * we don't even have to jump over them.  Further, they do not intrude
32  * on our cache or tlb entries.
33  */
34
35 struct exception_table_entry
36 {
37         unsigned long insn, fixup;
38 };
39
40
41 /*
42  * These are the main single-value transfer routines.  They automatically
43  * use the right size if we just have the right pointer type.
44  */
45
46 #define put_user(x, ptr)                                \
47 ({                                                      \
48     int __pu_err;                                       \
49     typeof(*(ptr)) __pu_val = (x);                      \
50     switch (sizeof (*(ptr))) {                          \
51     case 1:                                             \
52         __put_user_asm(__pu_err, __pu_val, ptr, b);     \
53         break;                                          \
54     case 2:                                             \
55         __put_user_asm(__pu_err, __pu_val, ptr, w);     \
56         break;                                          \
57     case 4:                                             \
58         __put_user_asm(__pu_err, __pu_val, ptr, l);     \
59         break;                                          \
60     case 8:                                             \
61        __pu_err = __constant_copy_to_user(ptr, &__pu_val, 8);        \
62        break;                                           \
63     default:                                            \
64         __pu_err = __put_user_bad();                    \
65         break;                                          \
66     }                                                   \
67     __pu_err;                                           \
68 })
69 #define __put_user(x, ptr) put_user(x, ptr)
70
71 extern int __put_user_bad(void);
72
73 /*
74  * Tell gcc we read from memory instead of writing: this is because
75  * we do not write to any memory gcc knows about, so there are no
76  * aliasing issues.
77  */
78 #define __put_user_asm(err,x,ptr,bwl)                   \
79 __asm__ __volatile__                                    \
80     ("21:moves" #bwl " %2,%1\n"                         \
81      "1:\n"                                             \
82      ".section .fixup,\"ax\"\n"                         \
83      "   .even\n"                                       \
84      "2: movel %3,%0\n"                                 \
85      "   jra 1b\n"                                      \
86      ".previous\n"                                      \
87      ".section __ex_table,\"a\"\n"                      \
88      "   .align 4\n"                                    \
89      "   .long 21b,2b\n"                                \
90      "   .long 1b,2b\n"                                 \
91      ".previous"                                        \
92      : "=d"(err)                                        \
93      : "m"(*(ptr)), "r"(x), "i"(-EFAULT), "0"(0))
94
95 #define get_user(x, ptr)                                        \
96 ({                                                              \
97     int __gu_err;                                               \
98     typeof(*(ptr)) __gu_val;                                    \
99     switch (sizeof(*(ptr))) {                                   \
100     case 1:                                                     \
101         __get_user_asm(__gu_err, __gu_val, ptr, b, "=d");       \
102         break;                                                  \
103     case 2:                                                     \
104         __get_user_asm(__gu_err, __gu_val, ptr, w, "=r");       \
105         break;                                                  \
106     case 4:                                                     \
107         __get_user_asm(__gu_err, __gu_val, ptr, l, "=r");       \
108         break;                                                  \
109     case 8:                                                     \
110         __gu_err = __constant_copy_from_user(&__gu_val, ptr, 8);  \
111         break;                                                  \
112     default:                                                    \
113         __gu_val = 0;                                           \
114         __gu_err = __get_user_bad();                            \
115         break;                                                  \
116     }                                                           \
117     (x) = __gu_val;                                             \
118     __gu_err;                                                   \
119 })
120 #define __get_user(x, ptr) get_user(x, ptr)
121
122 extern int __get_user_bad(void);
123
124 #define __get_user_asm(err,x,ptr,bwl,reg)       \
125 __asm__ __volatile__                            \
126     ("1: moves" #bwl " %2,%1\n"                 \
127      "2:\n"                                     \
128      ".section .fixup,\"ax\"\n"                 \
129      "   .even\n"                               \
130      "3: movel %3,%0\n"                         \
131      "   sub" #bwl " %1,%1\n"                   \
132      "   jra 2b\n"                              \
133      ".previous\n"                              \
134      ".section __ex_table,\"a\"\n"              \
135      "   .align 4\n"                            \
136      "   .long 1b,3b\n"                         \
137      ".previous"                                \
138      : "=d"(err), reg(x)                        \
139      : "m"(*(ptr)), "i" (-EFAULT), "0"(0))
140
141 static inline unsigned long
142 __generic_copy_from_user(void *to, const void *from, unsigned long n)
143 {
144     unsigned long tmp;
145     __asm__ __volatile__
146         ("   tstl %2\n"
147          "   jeq 2f\n"
148          "1: movesl (%1)+,%3\n"
149          "   movel %3,(%0)+\n"
150          "   subql #1,%2\n"
151          "   jne 1b\n"
152          "2: movel %4,%2\n"
153          "   bclr #1,%2\n"
154          "   jeq 4f\n"
155          "3: movesw (%1)+,%3\n"
156          "   movew %3,(%0)+\n"
157          "4: bclr #0,%2\n"
158          "   jeq 6f\n"
159          "5: movesb (%1)+,%3\n"
160          "   moveb %3,(%0)+\n"
161          "6:\n"
162          ".section .fixup,\"ax\"\n"
163          "   .even\n"
164          "7: movel %2,%%d0\n"
165          "71:clrl (%0)+\n"
166          "   subql #1,%%d0\n"
167          "   jne 71b\n"
168          "   lsll #2,%2\n"
169          "   addl %4,%2\n"
170          "   btst #1,%4\n"
171          "   jne 81f\n"
172          "   btst #0,%4\n"
173          "   jne 91f\n"
174          "   jra 6b\n"
175          "8: addql #2,%2\n"
176          "81:clrw (%0)+\n"
177          "   btst #0,%4\n"
178          "   jne 91f\n"
179          "   jra 6b\n"
180          "9: addql #1,%2\n"
181          "91:clrb (%0)+\n"
182          "   jra 6b\n"
183          ".previous\n"
184          ".section __ex_table,\"a\"\n"
185          "   .align 4\n"
186          "   .long 1b,7b\n"
187          "   .long 3b,8b\n"
188          "   .long 5b,9b\n"
189          ".previous"
190          : "=a"(to), "=a"(from), "=d"(n), "=&d"(tmp)
191          : "d"(n & 3), "0"(to), "1"(from), "2"(n/4)
192          : "d0", "memory");
193     return n;
194 }
195
196 static inline unsigned long
197 __generic_copy_to_user(void *to, const void *from, unsigned long n)
198 {
199     unsigned long tmp;
200     __asm__ __volatile__
201         ("   tstl %2\n"
202          "   jeq 3f\n"
203          "1: movel (%1)+,%3\n"
204          "22:movesl %3,(%0)+\n"
205          "2: subql #1,%2\n"
206          "   jne 1b\n"
207          "3: movel %4,%2\n"
208          "   bclr #1,%2\n"
209          "   jeq 4f\n"
210          "   movew (%1)+,%3\n"
211          "24:movesw %3,(%0)+\n"
212          "4: bclr #0,%2\n"
213          "   jeq 5f\n"
214          "   moveb (%1)+,%3\n"
215          "25:movesb %3,(%0)+\n"
216          "5:\n"
217          ".section .fixup,\"ax\"\n"
218          "   .even\n"
219          "60:addql #1,%2\n"
220          "6: lsll #2,%2\n"
221          "   addl %4,%2\n"
222          "   jra 5b\n"
223          "7: addql #2,%2\n"
224          "   jra 5b\n"
225          "8: addql #1,%2\n"
226          "   jra 5b\n"
227          ".previous\n"
228          ".section __ex_table,\"a\"\n"
229          "   .align 4\n"
230          "   .long 1b,60b\n"
231          "   .long 22b,6b\n"
232          "   .long 2b,6b\n"
233          "   .long 24b,7b\n"
234          "   .long 3b,60b\n"
235          "   .long 4b,7b\n"
236          "   .long 25b,8b\n"
237          "   .long 5b,8b\n"
238          ".previous"
239          : "=a"(to), "=a"(from), "=d"(n), "=&d"(tmp)
240          : "r"(n & 3), "0"(to), "1"(from), "2"(n / 4)
241          : "memory");
242     return n;
243 }
244
245 #define __copy_from_user_big(to, from, n, fixup, copy)  \
246     __asm__ __volatile__                                \
247         ("10: movesl (%1)+,%%d0\n"                      \
248          "    movel %%d0,(%0)+\n"                       \
249          "    subql #1,%2\n"                            \
250          "    jne 10b\n"                                \
251          ".section .fixup,\"ax\"\n"                     \
252          "    .even\n"                                  \
253          "11: movel %2,%%d0\n"                          \
254          "13: clrl (%0)+\n"                             \
255          "    subql #1,%%d0\n"                          \
256          "    jne 13b\n"                                \
257          "    lsll #2,%2\n"                             \
258          fixup "\n"                                     \
259          "    jra 12f\n"                                \
260          ".previous\n"                                  \
261          ".section __ex_table,\"a\"\n"                  \
262          "    .align 4\n"                               \
263          "    .long 10b,11b\n"                          \
264          ".previous\n"                                  \
265          copy "\n"                                      \
266          "12:"                                          \
267          : "=a"(to), "=a"(from), "=d"(n)                \
268          : "0"(to), "1"(from), "2"(n/4)                 \
269          : "d0", "memory")
270
271 static inline unsigned long
272 __constant_copy_from_user(void *to, const void *from, unsigned long n)
273 {
274     switch (n) {
275     case 0:
276         break;
277     case 1:
278         __asm__ __volatile__
279             ("1: movesb (%1)+,%%d0\n"
280              "   moveb %%d0,(%0)+\n"
281              "2:\n"
282              ".section .fixup,\"ax\"\n"
283              "   .even\n"
284              "3: addql #1,%2\n"
285              "   clrb (%0)+\n"
286              "   jra 2b\n"
287              ".previous\n"
288              ".section __ex_table,\"a\"\n"
289              "   .align 4\n"
290              "   .long 1b,3b\n"
291              ".previous"
292              : "=a"(to), "=a"(from), "=d"(n)
293              : "0"(to), "1"(from), "2"(0)
294              : "d0", "memory");
295         break;
296     case 2:
297         __asm__ __volatile__
298             ("1: movesw (%1)+,%%d0\n"
299              "   movew %%d0,(%0)+\n"
300              "2:\n"
301              ".section .fixup,\"ax\"\n"
302              "   .even\n"
303              "3: addql #2,%2\n"
304              "   clrw (%0)+\n"
305              "   jra 2b\n"
306              ".previous\n"
307              ".section __ex_table,\"a\"\n"
308              "   .align 4\n"
309              "   .long 1b,3b\n"
310              ".previous"
311              : "=a"(to), "=a"(from), "=d"(n)
312              : "0"(to), "1"(from), "2"(0)
313              : "d0", "memory");
314         break;
315     case 3:
316         __asm__ __volatile__
317             ("1: movesw (%1)+,%%d0\n"
318              "   movew %%d0,(%0)+\n"
319              "2: movesb (%1)+,%%d0\n"
320              "   moveb %%d0,(%0)+\n"
321              "3:"
322              ".section .fixup,\"ax\"\n"
323              "   .even\n"
324              "4: addql #2,%2\n"
325              "   clrw (%0)+\n"
326              "5: addql #1,%2\n"
327              "   clrb (%0)+\n"
328              "   jra 3b\n"
329              ".previous\n"
330              ".section __ex_table,\"a\"\n"
331              "   .align 4\n"
332              "   .long 1b,4b\n"
333              "   .long 2b,5b\n"
334              ".previous"
335              : "=a"(to), "=a"(from), "=d"(n)
336              : "0"(to), "1"(from), "2"(0)
337              : "d0", "memory");
338         break;
339     case 4:
340         __asm__ __volatile__
341             ("1: movesl (%1)+,%%d0\n"
342              "   movel %%d0,(%0)+\n"
343              "2:"
344              ".section .fixup,\"ax\"\n"
345              "   .even\n"
346              "3: addql #4,%2\n"
347              "   clrl (%0)+\n"
348              "   jra 2b\n"
349              ".previous\n"
350              ".section __ex_table,\"a\"\n"
351              "   .align 4\n"
352              "   .long 1b,3b\n"
353              ".previous"
354              : "=a"(to), "=a"(from), "=d"(n)
355              : "0"(to), "1"(from), "2"(0)
356              : "d0", "memory");
357         break;
358     case 8:
359         __asm__ __volatile__
360             ("1: movesl (%1)+,%%d0\n"
361              "   movel %%d0,(%0)+\n"
362              "2: movesl (%1)+,%%d0\n"
363              "   movel %%d0,(%0)+\n"
364              "3:"
365              ".section .fixup,\"ax\"\n"
366              "   .even\n"
367              "4: addql #4,%2\n"
368              "   clrl (%0)+\n"
369              "5: addql #4,%2\n"
370              "   clrl (%0)+\n"
371              "   jra 3b\n"
372              ".previous\n"
373              ".section __ex_table,\"a\"\n"
374              "   .align 4\n"
375              "   .long 1b,4b\n"
376              "   .long 2b,5b\n"
377              ".previous"
378              : "=a"(to), "=a"(from), "=d"(n)
379              : "0"(to), "1"(from), "2"(0)
380              : "d0", "memory");
381         break;
382     case 12:
383         __asm__ __volatile__
384             ("1: movesl (%1)+,%%d0\n"
385              "   movel %%d0,(%0)+\n"
386              "2: movesl (%1)+,%%d0\n"
387              "   movel %%d0,(%0)+\n"
388              "3: movesl (%1)+,%%d0\n"
389              "   movel %%d0,(%0)+\n"
390              "4:"
391              ".section .fixup,\"ax\"\n"
392              "   .even\n"
393              "5: addql #4,%2\n"
394              "   clrl (%0)+\n"
395              "6: addql #4,%2\n"
396              "   clrl (%0)+\n"
397              "7: addql #4,%2\n"
398              "   clrl (%0)+\n"
399              "   jra 4b\n"
400              ".previous\n"
401              ".section __ex_table,\"a\"\n"
402              "   .align 4\n"
403              "   .long 1b,5b\n"
404              "   .long 2b,6b\n"
405              "   .long 3b,7b\n"
406              ".previous"
407              : "=a"(to), "=a"(from), "=d"(n)
408              : "0"(to), "1"(from), "2"(0)
409              : "d0", "memory");
410         break;
411     case 16:
412         __asm__ __volatile__
413             ("1: movesl (%1)+,%%d0\n"
414              "   movel %%d0,(%0)+\n"
415              "2: movesl (%1)+,%%d0\n"
416              "   movel %%d0,(%0)+\n"
417              "3: movesl (%1)+,%%d0\n"
418              "   movel %%d0,(%0)+\n"
419              "4: movesl (%1)+,%%d0\n"
420              "   movel %%d0,(%0)+\n"
421              "5:"
422              ".section .fixup,\"ax\"\n"
423              "   .even\n"
424              "6: addql #4,%2\n"
425              "   clrl (%0)+\n"
426              "7: addql #4,%2\n"
427              "   clrl (%0)+\n"
428              "8: addql #4,%2\n"
429              "   clrl (%0)+\n"
430              "9: addql #4,%2\n"
431              "   clrl (%0)+\n"
432              "   jra 5b\n"
433              ".previous\n"
434              ".section __ex_table,\"a\"\n"
435              "   .align 4\n"
436              "   .long 1b,6b\n"
437              "   .long 2b,7b\n"
438              "   .long 3b,8b\n"
439              "   .long 4b,9b\n"
440              ".previous"
441              : "=a"(to), "=a"(from), "=d"(n)
442              : "0"(to), "1"(from), "2"(0)
443              : "d0", "memory");
444         break;
445     default:
446         switch (n & 3) {
447         case 0:
448             __copy_from_user_big(to, from, n, "", "");
449             break;
450         case 1:
451             __copy_from_user_big(to, from, n,
452                                  /* fixup */
453                                  "1: addql #1,%2\n"
454                                  "   clrb (%0)+",
455                                  /* copy */
456                                  "2: movesb (%1)+,%%d0\n"
457                                  "   moveb %%d0,(%0)+\n"
458                                  ".section __ex_table,\"a\"\n"
459                                  "   .long 2b,1b\n"
460                                  ".previous");
461             break;
462         case 2:
463             __copy_from_user_big(to, from, n,
464                                  /* fixup */
465                                  "1: addql #2,%2\n"
466                                  "   clrw (%0)+",
467                                  /* copy */
468                                  "2: movesw (%1)+,%%d0\n"
469                                  "   movew %%d0,(%0)+\n"
470                                  ".section __ex_table,\"a\"\n"
471                                  "   .long 2b,1b\n"
472                                  ".previous");
473             break;
474         case 3:
475             __copy_from_user_big(to, from, n,
476                                  /* fixup */
477                                  "1: addql #2,%2\n"
478                                  "   clrw (%0)+\n"
479                                  "2: addql #1,%2\n"
480                                  "   clrb (%0)+",
481                                  /* copy */
482                                  "3: movesw (%1)+,%%d0\n"
483                                  "   movew %%d0,(%0)+\n"
484                                  "4: movesb (%1)+,%%d0\n"
485                                  "   moveb %%d0,(%0)+\n"
486                                  ".section __ex_table,\"a\"\n"
487                                  "   .long 3b,1b\n"
488                                  "   .long 4b,2b\n"
489                                  ".previous");
490             break;
491         }
492         break;
493     }
494     return n;
495 }
496
497 #define __copy_to_user_big(to, from, n, fixup, copy)    \
498     __asm__ __volatile__                                \
499         ("10: movel (%1)+,%%d0\n"                       \
500          "31: movesl %%d0,(%0)+\n"                      \
501          "11: subql #1,%2\n"                            \
502          "    jne 10b\n"                                \
503          "41:\n"                                        \
504          ".section .fixup,\"ax\"\n"                     \
505          "   .even\n"                                   \
506          "22: addql #1,%2\n"                            \
507          "12: lsll #2,%2\n"                             \
508          fixup "\n"                                     \
509          "    jra 13f\n"                                \
510          ".previous\n"                                  \
511          ".section __ex_table,\"a\"\n"                  \
512          "    .align 4\n"                               \
513          "    .long 10b,22b\n"                          \
514          "    .long 31b,12b\n"                          \
515          "    .long 11b,12b\n"                          \
516          "    .long 41b,22b\n"                          \
517          ".previous\n"                                  \
518          copy "\n"                                      \
519          "13:"                                          \
520          : "=a"(to), "=a"(from), "=d"(n)                \
521          : "0"(to), "1"(from), "2"(n/4)                 \
522          : "d0", "memory")
523
524 #define __copy_to_user_inatomic __copy_to_user
525 #define __copy_from_user_inatomic __copy_from_user
526
527 static inline unsigned long
528 __constant_copy_to_user(void *to, const void *from, unsigned long n)
529 {
530     switch (n) {
531     case 0:
532         break;
533     case 1:
534         __asm__ __volatile__
535             ("   moveb (%1)+,%%d0\n"
536              "21:movesb %%d0,(%0)+\n"
537              "1:\n"
538              ".section .fixup,\"ax\"\n"
539              "   .even\n"
540              "2: addql #1,%2\n"
541              "   jra 1b\n"
542              ".previous\n"
543              ".section __ex_table,\"a\"\n"
544              "   .align 4\n  "
545              "   .long 21b,2b\n"
546              "   .long 1b,2b\n"
547              ".previous"
548              : "=a"(to), "=a"(from), "=d"(n)
549              : "0"(to), "1"(from), "2"(0)
550              : "d0", "memory");
551         break;
552     case 2:
553         __asm__ __volatile__
554             ("   movew (%1)+,%%d0\n"
555              "21:movesw %%d0,(%0)+\n"
556              "1:\n"
557              ".section .fixup,\"ax\"\n"
558              "   .even\n"
559              "2: addql #2,%2\n"
560              "   jra 1b\n"
561              ".previous\n"
562              ".section __ex_table,\"a\"\n"
563              "   .align 4\n"
564              "   .long 21b,2b\n"
565              "   .long 1b,2b\n"
566              ".previous"
567              : "=a"(to), "=a"(from), "=d"(n)
568              : "0"(to), "1"(from), "2"(0)
569              : "d0", "memory");
570         break;
571     case 3:
572         __asm__ __volatile__
573             ("   movew (%1)+,%%d0\n"
574              "21:movesw %%d0,(%0)+\n"
575              "1: moveb (%1)+,%%d0\n"
576              "22:movesb %%d0,(%0)+\n"
577              "2:\n"
578              ".section .fixup,\"ax\"\n"
579              "   .even\n"
580              "3: addql #2,%2\n"
581              "4: addql #1,%2\n"
582              "   jra 2b\n"
583              ".previous\n"
584              ".section __ex_table,\"a\"\n"
585              "   .align 4\n"
586              "   .long 21b,3b\n"
587              "   .long 1b,3b\n"
588              "   .long 22b,4b\n"
589              "   .long 2b,4b\n"
590              ".previous"
591              : "=a"(to), "=a"(from), "=d"(n)
592              : "0"(to), "1"(from), "2"(0)
593              : "d0", "memory");
594         break;
595     case 4:
596         __asm__ __volatile__
597             ("   movel (%1)+,%%d0\n"
598              "21:movesl %%d0,(%0)+\n"
599              "1:\n"
600              ".section .fixup,\"ax\"\n"
601              "   .even\n"
602              "2: addql #4,%2\n"
603              "   jra 1b\n"
604              ".previous\n"
605              ".section __ex_table,\"a\"\n"
606              "   .align 4\n"
607              "   .long 21b,2b\n"
608              "   .long 1b,2b\n"
609              ".previous"
610              : "=a"(to), "=a"(from), "=d"(n)
611              : "0"(to), "1"(from), "2"(0)
612              : "d0", "memory");
613         break;
614     case 8:
615         __asm__ __volatile__
616             ("   movel (%1)+,%%d0\n"
617              "21:movesl %%d0,(%0)+\n"
618              "1: movel (%1)+,%%d0\n"
619              "22:movesl %%d0,(%0)+\n"
620              "2:\n"
621              ".section .fixup,\"ax\"\n"
622              "   .even\n"
623              "3: addql #4,%2\n"
624              "4: addql #4,%2\n"
625              "   jra 2b\n"
626              ".previous\n"
627              ".section __ex_table,\"a\"\n"
628              "   .align 4\n"
629              "   .long 21b,3b\n"
630              "   .long 1b,3b\n"
631              "   .long 22b,4b\n"
632              "   .long 2b,4b\n"
633              ".previous"
634              : "=a"(to), "=a"(from), "=d"(n)
635              : "0"(to), "1"(from), "2"(0)
636              : "d0", "memory");
637         break;
638     case 12:
639         __asm__ __volatile__
640             ("   movel (%1)+,%%d0\n"
641              "21:movesl %%d0,(%0)+\n"
642              "1: movel (%1)+,%%d0\n"
643              "22:movesl %%d0,(%0)+\n"
644              "2: movel (%1)+,%%d0\n"
645              "23:movesl %%d0,(%0)+\n"
646              "3:\n"
647              ".section .fixup,\"ax\"\n"
648              "   .even\n"
649              "4: addql #4,%2\n"
650              "5: addql #4,%2\n"
651              "6: addql #4,%2\n"
652              "   jra 3b\n"
653              ".previous\n"
654              ".section __ex_table,\"a\"\n"
655              "   .align 4\n"
656              "   .long 21b,4b\n"
657              "   .long 1b,4b\n"
658              "   .long 22b,5b\n"
659              "   .long 2b,5b\n"
660              "   .long 23b,6b\n"
661              "   .long 3b,6b\n"
662              ".previous"
663              : "=a"(to), "=a"(from), "=d"(n)
664              : "0"(to), "1"(from), "2"(0)
665              : "d0", "memory");
666         break;
667     case 16:
668         __asm__ __volatile__
669             ("   movel (%1)+,%%d0\n"
670              "21:movesl %%d0,(%0)+\n"
671              "1: movel (%1)+,%%d0\n"
672              "22:movesl %%d0,(%0)+\n"
673              "2: movel (%1)+,%%d0\n"
674              "23:movesl %%d0,(%0)+\n"
675              "3: movel (%1)+,%%d0\n"
676              "24:movesl %%d0,(%0)+\n"
677              "4:"
678              ".section .fixup,\"ax\"\n"
679              "   .even\n"
680              "5: addql #4,%2\n"
681              "6: addql #4,%2\n"
682              "7: addql #4,%2\n"
683              "8: addql #4,%2\n"
684              "   jra 4b\n"
685              ".previous\n"
686              ".section __ex_table,\"a\"\n"
687              "   .align 4\n"
688              "   .long 21b,5b\n"
689              "   .long 1b,5b\n"
690              "   .long 22b,6b\n"
691              "   .long 2b,6b\n"
692              "   .long 23b,7b\n"
693              "   .long 3b,7b\n"
694              "   .long 24b,8b\n"
695              "   .long 4b,8b\n"
696              ".previous"
697              : "=a"(to), "=a"(from), "=d"(n)
698              : "0"(to), "1"(from), "2"(0)
699              : "d0", "memory");
700         break;
701     default:
702         switch (n & 3) {
703         case 0:
704             __copy_to_user_big(to, from, n, "", "");
705             break;
706         case 1:
707             __copy_to_user_big(to, from, n,
708                                /* fixup */
709                                "1: addql #1,%2",
710                                /* copy */
711                                "   moveb (%1)+,%%d0\n"
712                                "22:movesb %%d0,(%0)+\n"
713                                "2:"
714                                ".section __ex_table,\"a\"\n"
715                                "   .long 22b,1b\n"
716                                "   .long 2b,1b\n"
717                                ".previous");
718             break;
719         case 2:
720             __copy_to_user_big(to, from, n,
721                                /* fixup */
722                                "1: addql #2,%2",
723                                /* copy */
724                                "   movew (%1)+,%%d0\n"
725                                "22:movesw %%d0,(%0)+\n"
726                                "2:"
727                                ".section __ex_table,\"a\"\n"
728                                "   .long 22b,1b\n"
729                                "   .long 2b,1b\n"
730                                ".previous");
731             break;
732         case 3:
733             __copy_to_user_big(to, from, n,
734                                /* fixup */
735                                "1: addql #2,%2\n"
736                                "2: addql #1,%2",
737                                /* copy */
738                                "   movew (%1)+,%%d0\n"
739                                "23:movesw %%d0,(%0)+\n"
740                                "3: moveb (%1)+,%%d0\n"
741                                "24:movesb %%d0,(%0)+\n"
742                                "4:"
743                                ".section __ex_table,\"a\"\n"
744                                "   .long 23b,1b\n"
745                                "   .long 3b,1b\n"
746                                "   .long 24b,2b\n"
747                                "   .long 4b,2b\n"
748                                ".previous");
749             break;
750         }
751         break;
752     }
753     return n;
754 }
755
756 #define copy_from_user(to, from, n)             \
757 (__builtin_constant_p(n) ?                      \
758  __constant_copy_from_user(to, from, n) :       \
759  __generic_copy_from_user(to, from, n))
760
761 #define copy_to_user(to, from, n)               \
762 (__builtin_constant_p(n) ?                      \
763  __constant_copy_to_user(to, from, n) :         \
764  __generic_copy_to_user(to, from, n))
765
766 #define __copy_from_user(to, from, n) copy_from_user(to, from, n)
767 #define __copy_to_user(to, from, n) copy_to_user(to, from, n)
768
769 /*
770  * Copy a null terminated string from userspace.
771  */
772
773 static inline long
774 strncpy_from_user(char *dst, const char *src, long count)
775 {
776     long res;
777     if (count == 0) return count;
778     __asm__ __volatile__
779         ("1: movesb (%2)+,%%d0\n"
780          "12:moveb %%d0,(%1)+\n"
781          "   jeq 2f\n"
782          "   subql #1,%3\n"
783          "   jne 1b\n"
784          "2: subl %3,%0\n"
785          "3:\n"
786          ".section .fixup,\"ax\"\n"
787          "   .even\n"
788          "4: movel %4,%0\n"
789          "   jra 3b\n"
790          ".previous\n"
791          ".section __ex_table,\"a\"\n"
792          "   .align 4\n"
793          "   .long 1b,4b\n"
794          "   .long 12b,4b\n"
795          ".previous"
796          : "=d"(res), "=a"(dst), "=a"(src), "=d"(count)
797          : "i"(-EFAULT), "0"(count), "1"(dst), "2"(src), "3"(count)
798          : "d0", "memory");
799     return res;
800 }
801
802 /*
803  * Return the size of a string (including the ending 0)
804  *
805  * Return 0 on exception, a value greater than N if too long
806  */
807 static inline long strnlen_user(const char *src, long n)
808 {
809         long res;
810
811         res = -(long)src;
812         __asm__ __volatile__
813                 ("1:\n"
814                  "   tstl %2\n"
815                  "   jeq 3f\n"
816                  "2: movesb (%1)+,%%d0\n"
817                  "22:\n"
818                  "   subql #1,%2\n"
819                  "   tstb %%d0\n"
820                  "   jne 1b\n"
821                  "   jra 4f\n"
822                  "3:\n"
823                  "   addql #1,%0\n"
824                  "4:\n"
825                  "   addl %1,%0\n"
826                  "5:\n"
827                  ".section .fixup,\"ax\"\n"
828                  "   .even\n"
829                  "6: moveq %3,%0\n"
830                  "   jra 5b\n"
831                  ".previous\n"
832                  ".section __ex_table,\"a\"\n"
833                  "   .align 4\n"
834                  "   .long 2b,6b\n"
835                  "   .long 22b,6b\n"
836                  ".previous"
837                  : "=d"(res), "=a"(src), "=d"(n)
838                  : "i"(0), "0"(res), "1"(src), "2"(n)
839                  : "d0");
840         return res;
841 }
842
843 #define strlen_user(str) strnlen_user(str, 32767)
844
845 /*
846  * Zero Userspace
847  */
848
849 static inline unsigned long
850 clear_user(void *to, unsigned long n)
851 {
852     __asm__ __volatile__
853         ("   tstl %1\n"
854          "   jeq 3f\n"
855          "1: movesl %3,(%0)+\n"
856          "2: subql #1,%1\n"
857          "   jne 1b\n"
858          "3: movel %2,%1\n"
859          "   bclr #1,%1\n"
860          "   jeq 4f\n"
861          "24:movesw %3,(%0)+\n"
862          "4: bclr #0,%1\n"
863          "   jeq 5f\n"
864          "25:movesb %3,(%0)+\n"
865          "5:\n"
866          ".section .fixup,\"ax\"\n"
867          "   .even\n"
868          "61:addql #1,%1\n"
869          "6: lsll #2,%1\n"
870          "   addl %2,%1\n"
871          "   jra 5b\n"
872          "7: addql #2,%1\n"
873          "   jra 5b\n"
874          "8: addql #1,%1\n"
875          "   jra 5b\n"
876          ".previous\n"
877          ".section __ex_table,\"a\"\n"
878          "   .align 4\n"
879          "   .long 1b,61b\n"
880          "   .long 2b,6b\n"
881          "   .long 3b,61b\n"
882          "   .long 24b,7b\n"
883          "   .long 4b,7b\n"
884          "   .long 25b,8b\n"
885          "   .long 5b,8b\n"
886          ".previous"
887          : "=a"(to), "=d"(n)
888          : "r"(n & 3), "r"(0), "0"(to), "1"(n/4));
889     return n;
890 }
891
892 #endif /* _M68K_UACCESS_H */