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