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