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