+#define __copy_from_user_big(to, from, n, fixup, copy) \
+ __asm__ __volatile__ \
+ ("10: movesl (%1)+,%%d0\n" \
+ " movel %%d0,(%0)+\n" \
+ " subql #1,%2\n" \
+ " jne 10b\n" \
+ ".section .fixup,\"ax\"\n" \
+ " .even\n" \
+ "11: movel %2,%%d0\n" \
+ "13: clrl (%0)+\n" \
+ " subql #1,%%d0\n" \
+ " jne 13b\n" \
+ " lsll #2,%2\n" \
+ fixup "\n" \
+ " jra 12f\n" \
+ ".previous\n" \
+ ".section __ex_table,\"a\"\n" \
+ " .align 4\n" \
+ " .long 10b,11b\n" \
+ ".previous\n" \
+ copy "\n" \
+ "12:" \
+ : "=a"(to), "=a"(from), "=d"(n) \
+ : "0"(to), "1"(from), "2"(n/4) \
+ : "d0", "memory")
+
+static inline unsigned long
+__constant_copy_from_user(void *to, const void __user *from, unsigned long n)
+{
+ switch (n) {
+ case 0:
+ break;
+ case 1:
+ __asm__ __volatile__
+ ("1: movesb (%1)+,%%d0\n"
+ " moveb %%d0,(%0)+\n"
+ "2:\n"
+ ".section .fixup,\"ax\"\n"
+ " .even\n"
+ "3: addql #1,%2\n"
+ " clrb (%0)+\n"
+ " jra 2b\n"
+ ".previous\n"
+ ".section __ex_table,\"a\"\n"
+ " .align 4\n"
+ " .long 1b,3b\n"
+ ".previous"
+ : "=a"(to), "=a"(from), "=d"(n)
+ : "0"(to), "1"(from), "2"(0)
+ : "d0", "memory");
+ break;
+ case 2:
+ __asm__ __volatile__
+ ("1: movesw (%1)+,%%d0\n"
+ " movew %%d0,(%0)+\n"
+ "2:\n"
+ ".section .fixup,\"ax\"\n"
+ " .even\n"
+ "3: addql #2,%2\n"
+ " clrw (%0)+\n"
+ " jra 2b\n"
+ ".previous\n"
+ ".section __ex_table,\"a\"\n"
+ " .align 4\n"
+ " .long 1b,3b\n"
+ ".previous"
+ : "=a"(to), "=a"(from), "=d"(n)
+ : "0"(to), "1"(from), "2"(0)
+ : "d0", "memory");
+ break;
+ case 3:
+ __asm__ __volatile__
+ ("1: movesw (%1)+,%%d0\n"
+ " movew %%d0,(%0)+\n"
+ "2: movesb (%1)+,%%d0\n"
+ " moveb %%d0,(%0)+\n"
+ "3:"
+ ".section .fixup,\"ax\"\n"
+ " .even\n"
+ "4: addql #2,%2\n"
+ " clrw (%0)+\n"
+ "5: addql #1,%2\n"
+ " clrb (%0)+\n"
+ " jra 3b\n"
+ ".previous\n"
+ ".section __ex_table,\"a\"\n"
+ " .align 4\n"
+ " .long 1b,4b\n"
+ " .long 2b,5b\n"
+ ".previous"
+ : "=a"(to), "=a"(from), "=d"(n)
+ : "0"(to), "1"(from), "2"(0)
+ : "d0", "memory");
+ break;
+ case 4:
+ __asm__ __volatile__
+ ("1: movesl (%1)+,%%d0\n"
+ " movel %%d0,(%0)+\n"
+ "2:"
+ ".section .fixup,\"ax\"\n"
+ " .even\n"
+ "3: addql #4,%2\n"
+ " clrl (%0)+\n"
+ " jra 2b\n"
+ ".previous\n"
+ ".section __ex_table,\"a\"\n"
+ " .align 4\n"
+ " .long 1b,3b\n"
+ ".previous"
+ : "=a"(to), "=a"(from), "=d"(n)
+ : "0"(to), "1"(from), "2"(0)
+ : "d0", "memory");
+ break;
+ case 8:
+ __asm__ __volatile__
+ ("1: movesl (%1)+,%%d0\n"
+ " movel %%d0,(%0)+\n"
+ "2: movesl (%1)+,%%d0\n"
+ " movel %%d0,(%0)+\n"
+ "3:"
+ ".section .fixup,\"ax\"\n"
+ " .even\n"
+ "4: addql #4,%2\n"
+ " clrl (%0)+\n"
+ "5: addql #4,%2\n"
+ " clrl (%0)+\n"
+ " jra 3b\n"
+ ".previous\n"
+ ".section __ex_table,\"a\"\n"
+ " .align 4\n"
+ " .long 1b,4b\n"
+ " .long 2b,5b\n"
+ ".previous"
+ : "=a"(to), "=a"(from), "=d"(n)
+ : "0"(to), "1"(from), "2"(0)
+ : "d0", "memory");
+ break;
+ case 12:
+ __asm__ __volatile__
+ ("1: movesl (%1)+,%%d0\n"
+ " movel %%d0,(%0)+\n"
+ "2: movesl (%1)+,%%d0\n"
+ " movel %%d0,(%0)+\n"
+ "3: movesl (%1)+,%%d0\n"
+ " movel %%d0,(%0)+\n"
+ "4:"
+ ".section .fixup,\"ax\"\n"
+ " .even\n"
+ "5: addql #4,%2\n"
+ " clrl (%0)+\n"
+ "6: addql #4,%2\n"
+ " clrl (%0)+\n"
+ "7: addql #4,%2\n"
+ " clrl (%0)+\n"
+ " jra 4b\n"
+ ".previous\n"
+ ".section __ex_table,\"a\"\n"
+ " .align 4\n"
+ " .long 1b,5b\n"
+ " .long 2b,6b\n"
+ " .long 3b,7b\n"
+ ".previous"
+ : "=a"(to), "=a"(from), "=d"(n)
+ : "0"(to), "1"(from), "2"(0)
+ : "d0", "memory");
+ break;
+ case 16:
+ __asm__ __volatile__
+ ("1: movesl (%1)+,%%d0\n"
+ " movel %%d0,(%0)+\n"
+ "2: movesl (%1)+,%%d0\n"
+ " movel %%d0,(%0)+\n"
+ "3: movesl (%1)+,%%d0\n"
+ " movel %%d0,(%0)+\n"
+ "4: movesl (%1)+,%%d0\n"
+ " movel %%d0,(%0)+\n"
+ "5:"
+ ".section .fixup,\"ax\"\n"
+ " .even\n"
+ "6: addql #4,%2\n"
+ " clrl (%0)+\n"
+ "7: addql #4,%2\n"
+ " clrl (%0)+\n"
+ "8: addql #4,%2\n"
+ " clrl (%0)+\n"
+ "9: addql #4,%2\n"
+ " clrl (%0)+\n"
+ " jra 5b\n"
+ ".previous\n"
+ ".section __ex_table,\"a\"\n"
+ " .align 4\n"
+ " .long 1b,6b\n"
+ " .long 2b,7b\n"
+ " .long 3b,8b\n"
+ " .long 4b,9b\n"
+ ".previous"
+ : "=a"(to), "=a"(from), "=d"(n)
+ : "0"(to), "1"(from), "2"(0)
+ : "d0", "memory");
+ break;
+ default:
+ switch (n & 3) {
+ case 0:
+ __copy_from_user_big(to, from, n, "", "");
+ break;