xref: /kernel/linux/linux-6.6/arch/m68k/lib/uaccess.c (revision 62306a36)
162306a36Sopenharmony_ci/*
262306a36Sopenharmony_ci * This file is subject to the terms and conditions of the GNU General Public
362306a36Sopenharmony_ci * License.  See the file COPYING in the main directory of this archive
462306a36Sopenharmony_ci * for more details.
562306a36Sopenharmony_ci */
662306a36Sopenharmony_ci
762306a36Sopenharmony_ci#include <linux/module.h>
862306a36Sopenharmony_ci#include <linux/uaccess.h>
962306a36Sopenharmony_ci
1062306a36Sopenharmony_ciunsigned long __generic_copy_from_user(void *to, const void __user *from,
1162306a36Sopenharmony_ci				       unsigned long n)
1262306a36Sopenharmony_ci{
1362306a36Sopenharmony_ci	unsigned long tmp, res;
1462306a36Sopenharmony_ci
1562306a36Sopenharmony_ci	asm volatile ("\n"
1662306a36Sopenharmony_ci		"	tst.l	%0\n"
1762306a36Sopenharmony_ci		"	jeq	2f\n"
1862306a36Sopenharmony_ci		"1:	"MOVES".l	(%1)+,%3\n"
1962306a36Sopenharmony_ci		"	move.l	%3,(%2)+\n"
2062306a36Sopenharmony_ci		"	subq.l	#1,%0\n"
2162306a36Sopenharmony_ci		"	jne	1b\n"
2262306a36Sopenharmony_ci		"2:	btst	#1,%5\n"
2362306a36Sopenharmony_ci		"	jeq	4f\n"
2462306a36Sopenharmony_ci		"3:	"MOVES".w	(%1)+,%3\n"
2562306a36Sopenharmony_ci		"	move.w	%3,(%2)+\n"
2662306a36Sopenharmony_ci		"4:	btst	#0,%5\n"
2762306a36Sopenharmony_ci		"	jeq	6f\n"
2862306a36Sopenharmony_ci		"5:	"MOVES".b	(%1)+,%3\n"
2962306a36Sopenharmony_ci		"	move.b  %3,(%2)+\n"
3062306a36Sopenharmony_ci		"6:\n"
3162306a36Sopenharmony_ci		"	.section .fixup,\"ax\"\n"
3262306a36Sopenharmony_ci		"	.even\n"
3362306a36Sopenharmony_ci		"10:	lsl.l	#2,%0\n"
3462306a36Sopenharmony_ci		"	btst	#1,%5\n"
3562306a36Sopenharmony_ci		"	jeq	8f\n"
3662306a36Sopenharmony_ci		"30:	addq.l	#2,%0\n"
3762306a36Sopenharmony_ci		"8:	btst	#0,%5\n"
3862306a36Sopenharmony_ci		"	jeq	6b\n"
3962306a36Sopenharmony_ci		"50:	addq.l	#1,%0\n"
4062306a36Sopenharmony_ci		"	jra	6b\n"
4162306a36Sopenharmony_ci		"	.previous\n"
4262306a36Sopenharmony_ci		"\n"
4362306a36Sopenharmony_ci		"	.section __ex_table,\"a\"\n"
4462306a36Sopenharmony_ci		"	.align	4\n"
4562306a36Sopenharmony_ci		"	.long	1b,10b\n"
4662306a36Sopenharmony_ci		"	.long	3b,30b\n"
4762306a36Sopenharmony_ci		"	.long	5b,50b\n"
4862306a36Sopenharmony_ci		"	.previous"
4962306a36Sopenharmony_ci		: "=d" (res), "+a" (from), "+a" (to), "=&d" (tmp)
5062306a36Sopenharmony_ci		: "0" (n / 4), "d" (n & 3));
5162306a36Sopenharmony_ci
5262306a36Sopenharmony_ci	return res;
5362306a36Sopenharmony_ci}
5462306a36Sopenharmony_ciEXPORT_SYMBOL(__generic_copy_from_user);
5562306a36Sopenharmony_ci
5662306a36Sopenharmony_ciunsigned long __generic_copy_to_user(void __user *to, const void *from,
5762306a36Sopenharmony_ci				     unsigned long n)
5862306a36Sopenharmony_ci{
5962306a36Sopenharmony_ci	unsigned long tmp, res;
6062306a36Sopenharmony_ci
6162306a36Sopenharmony_ci	asm volatile ("\n"
6262306a36Sopenharmony_ci		"	tst.l	%0\n"
6362306a36Sopenharmony_ci		"	jeq	4f\n"
6462306a36Sopenharmony_ci		"1:	move.l	(%1)+,%3\n"
6562306a36Sopenharmony_ci		"2:	"MOVES".l	%3,(%2)+\n"
6662306a36Sopenharmony_ci		"3:	subq.l	#1,%0\n"
6762306a36Sopenharmony_ci		"	jne	1b\n"
6862306a36Sopenharmony_ci		"4:	btst	#1,%5\n"
6962306a36Sopenharmony_ci		"	jeq	6f\n"
7062306a36Sopenharmony_ci		"	move.w	(%1)+,%3\n"
7162306a36Sopenharmony_ci		"5:	"MOVES".w	%3,(%2)+\n"
7262306a36Sopenharmony_ci		"6:	btst	#0,%5\n"
7362306a36Sopenharmony_ci		"	jeq	8f\n"
7462306a36Sopenharmony_ci		"	move.b	(%1)+,%3\n"
7562306a36Sopenharmony_ci		"7:	"MOVES".b  %3,(%2)+\n"
7662306a36Sopenharmony_ci		"8:\n"
7762306a36Sopenharmony_ci		"	.section .fixup,\"ax\"\n"
7862306a36Sopenharmony_ci		"	.even\n"
7962306a36Sopenharmony_ci		"20:	lsl.l	#2,%0\n"
8062306a36Sopenharmony_ci		"50:	add.l	%5,%0\n"
8162306a36Sopenharmony_ci		"	jra	8b\n"
8262306a36Sopenharmony_ci		"	.previous\n"
8362306a36Sopenharmony_ci		"\n"
8462306a36Sopenharmony_ci		"	.section __ex_table,\"a\"\n"
8562306a36Sopenharmony_ci		"	.align	4\n"
8662306a36Sopenharmony_ci		"	.long	2b,20b\n"
8762306a36Sopenharmony_ci		"	.long	3b,20b\n"
8862306a36Sopenharmony_ci		"	.long	5b,50b\n"
8962306a36Sopenharmony_ci		"	.long	6b,50b\n"
9062306a36Sopenharmony_ci		"	.long	7b,50b\n"
9162306a36Sopenharmony_ci		"	.long	8b,50b\n"
9262306a36Sopenharmony_ci		"	.previous"
9362306a36Sopenharmony_ci		: "=d" (res), "+a" (from), "+a" (to), "=&d" (tmp)
9462306a36Sopenharmony_ci		: "0" (n / 4), "d" (n & 3));
9562306a36Sopenharmony_ci
9662306a36Sopenharmony_ci	return res;
9762306a36Sopenharmony_ci}
9862306a36Sopenharmony_ciEXPORT_SYMBOL(__generic_copy_to_user);
9962306a36Sopenharmony_ci
10062306a36Sopenharmony_ci/*
10162306a36Sopenharmony_ci * Zero Userspace
10262306a36Sopenharmony_ci */
10362306a36Sopenharmony_ci
10462306a36Sopenharmony_ciunsigned long __clear_user(void __user *to, unsigned long n)
10562306a36Sopenharmony_ci{
10662306a36Sopenharmony_ci	unsigned long res;
10762306a36Sopenharmony_ci
10862306a36Sopenharmony_ci	asm volatile ("\n"
10962306a36Sopenharmony_ci		"	tst.l	%0\n"
11062306a36Sopenharmony_ci		"	jeq	3f\n"
11162306a36Sopenharmony_ci		"1:	"MOVES".l	%2,(%1)+\n"
11262306a36Sopenharmony_ci		"2:	subq.l	#1,%0\n"
11362306a36Sopenharmony_ci		"	jne	1b\n"
11462306a36Sopenharmony_ci		"3:	btst	#1,%4\n"
11562306a36Sopenharmony_ci		"	jeq	5f\n"
11662306a36Sopenharmony_ci		"4:	"MOVES".w	%2,(%1)+\n"
11762306a36Sopenharmony_ci		"5:	btst	#0,%4\n"
11862306a36Sopenharmony_ci		"	jeq	7f\n"
11962306a36Sopenharmony_ci		"6:	"MOVES".b	%2,(%1)\n"
12062306a36Sopenharmony_ci		"7:\n"
12162306a36Sopenharmony_ci		"	.section .fixup,\"ax\"\n"
12262306a36Sopenharmony_ci		"	.even\n"
12362306a36Sopenharmony_ci		"10:	lsl.l	#2,%0\n"
12462306a36Sopenharmony_ci		"40:	add.l	%4,%0\n"
12562306a36Sopenharmony_ci		"	jra	7b\n"
12662306a36Sopenharmony_ci		"	.previous\n"
12762306a36Sopenharmony_ci		"\n"
12862306a36Sopenharmony_ci		"	.section __ex_table,\"a\"\n"
12962306a36Sopenharmony_ci		"	.align	4\n"
13062306a36Sopenharmony_ci		"	.long	1b,10b\n"
13162306a36Sopenharmony_ci		"	.long	2b,10b\n"
13262306a36Sopenharmony_ci		"	.long	4b,40b\n"
13362306a36Sopenharmony_ci		"	.long	5b,40b\n"
13462306a36Sopenharmony_ci		"	.long	6b,40b\n"
13562306a36Sopenharmony_ci		"	.long	7b,40b\n"
13662306a36Sopenharmony_ci		"	.previous"
13762306a36Sopenharmony_ci		: "=d" (res), "+a" (to)
13862306a36Sopenharmony_ci		: "d" (0), "0" (n / 4), "d" (n & 3));
13962306a36Sopenharmony_ci
14062306a36Sopenharmony_ci    return res;
14162306a36Sopenharmony_ci}
14262306a36Sopenharmony_ciEXPORT_SYMBOL(__clear_user);
143