162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * __clear_user_page, __clear_user, clear_page implementation of SuperH
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci * Copyright (C) 2001  Kaz Kojima
662306a36Sopenharmony_ci * Copyright (C) 2001, 2002  Niibe Yutaka
762306a36Sopenharmony_ci * Copyright (C) 2006  Paul Mundt
862306a36Sopenharmony_ci */
962306a36Sopenharmony_ci#include <linux/linkage.h>
1062306a36Sopenharmony_ci#include <asm/page.h>
1162306a36Sopenharmony_ci
1262306a36Sopenharmony_ciENTRY(__clear_user)
1362306a36Sopenharmony_ci	!
1462306a36Sopenharmony_ci	mov	#0, r0
1562306a36Sopenharmony_ci	mov	#0xffffffe0, r1
1662306a36Sopenharmony_ci	!
1762306a36Sopenharmony_ci	! r4..(r4+31)&~32 	   -------- not aligned	[ Area 0 ]
1862306a36Sopenharmony_ci	! (r4+31)&~32..(r4+r5)&~32 -------- aligned	[ Area 1 ]
1962306a36Sopenharmony_ci	! (r4+r5)&~32..r4+r5       -------- not aligned	[ Area 2 ]
2062306a36Sopenharmony_ci	!
2162306a36Sopenharmony_ci	! Clear area 0
2262306a36Sopenharmony_ci	mov	r4, r2
2362306a36Sopenharmony_ci	!
2462306a36Sopenharmony_ci	tst	r1, r5		! length < 32
2562306a36Sopenharmony_ci	bt	.Larea2		! skip to remainder
2662306a36Sopenharmony_ci	!
2762306a36Sopenharmony_ci	add	#31, r2
2862306a36Sopenharmony_ci	and	r1, r2
2962306a36Sopenharmony_ci	cmp/eq	r4, r2
3062306a36Sopenharmony_ci	bt	.Larea1
3162306a36Sopenharmony_ci	mov	r2, r3
3262306a36Sopenharmony_ci	sub	r4, r3
3362306a36Sopenharmony_ci	mov	r3, r7
3462306a36Sopenharmony_ci	mov	r4, r2
3562306a36Sopenharmony_ci	!
3662306a36Sopenharmony_ci.L0:	dt	r3
3762306a36Sopenharmony_ci0:	mov.b	r0, @r2
3862306a36Sopenharmony_ci	bf/s	.L0
3962306a36Sopenharmony_ci	 add	#1, r2
4062306a36Sopenharmony_ci	!
4162306a36Sopenharmony_ci	sub	r7, r5
4262306a36Sopenharmony_ci	mov	r2, r4
4362306a36Sopenharmony_ci.Larea1:
4462306a36Sopenharmony_ci	mov	r4, r3
4562306a36Sopenharmony_ci	add	r5, r3
4662306a36Sopenharmony_ci	and	r1, r3
4762306a36Sopenharmony_ci	cmp/hi	r2, r3
4862306a36Sopenharmony_ci	bf	.Larea2
4962306a36Sopenharmony_ci	!
5062306a36Sopenharmony_ci	! Clear area 1
5162306a36Sopenharmony_ci#if defined(CONFIG_CPU_SH4)
5262306a36Sopenharmony_ci1:	movca.l	r0, @r2
5362306a36Sopenharmony_ci#else
5462306a36Sopenharmony_ci1:	mov.l	r0, @r2
5562306a36Sopenharmony_ci#endif
5662306a36Sopenharmony_ci	add	#4, r2
5762306a36Sopenharmony_ci2:	mov.l	r0, @r2
5862306a36Sopenharmony_ci	add	#4, r2
5962306a36Sopenharmony_ci3:	mov.l	r0, @r2
6062306a36Sopenharmony_ci	add	#4, r2
6162306a36Sopenharmony_ci4:	mov.l	r0, @r2
6262306a36Sopenharmony_ci	add	#4, r2
6362306a36Sopenharmony_ci5:	mov.l	r0, @r2
6462306a36Sopenharmony_ci	add	#4, r2
6562306a36Sopenharmony_ci6:	mov.l	r0, @r2
6662306a36Sopenharmony_ci	add	#4, r2
6762306a36Sopenharmony_ci7:	mov.l	r0, @r2
6862306a36Sopenharmony_ci	add	#4, r2
6962306a36Sopenharmony_ci8:	mov.l	r0, @r2
7062306a36Sopenharmony_ci	add	#4, r2
7162306a36Sopenharmony_ci	cmp/hi	r2, r3
7262306a36Sopenharmony_ci	bt/s	1b
7362306a36Sopenharmony_ci	 nop
7462306a36Sopenharmony_ci	!
7562306a36Sopenharmony_ci	! Clear area 2
7662306a36Sopenharmony_ci.Larea2:
7762306a36Sopenharmony_ci	mov	r4, r3
7862306a36Sopenharmony_ci	add	r5, r3
7962306a36Sopenharmony_ci	cmp/hs	r3, r2
8062306a36Sopenharmony_ci	bt/s	.Ldone
8162306a36Sopenharmony_ci	 sub	r2, r3
8262306a36Sopenharmony_ci.L2:	dt	r3
8362306a36Sopenharmony_ci9:	mov.b	r0, @r2
8462306a36Sopenharmony_ci	bf/s	.L2
8562306a36Sopenharmony_ci	 add	#1, r2
8662306a36Sopenharmony_ci	!
8762306a36Sopenharmony_ci.Ldone:	rts
8862306a36Sopenharmony_ci	 mov	#0, r0	! return 0 as normal return
8962306a36Sopenharmony_ci
9062306a36Sopenharmony_ci	! return the number of bytes remained
9162306a36Sopenharmony_ci.Lbad_clear_user:
9262306a36Sopenharmony_ci	mov	r4, r0
9362306a36Sopenharmony_ci	add	r5, r0
9462306a36Sopenharmony_ci	rts
9562306a36Sopenharmony_ci	 sub	r2, r0
9662306a36Sopenharmony_ci
9762306a36Sopenharmony_ci.section __ex_table,"a"
9862306a36Sopenharmony_ci	.align 2
9962306a36Sopenharmony_ci	.long	0b, .Lbad_clear_user
10062306a36Sopenharmony_ci	.long	1b, .Lbad_clear_user
10162306a36Sopenharmony_ci	.long	2b, .Lbad_clear_user
10262306a36Sopenharmony_ci	.long	3b, .Lbad_clear_user
10362306a36Sopenharmony_ci	.long	4b, .Lbad_clear_user
10462306a36Sopenharmony_ci	.long	5b, .Lbad_clear_user
10562306a36Sopenharmony_ci	.long	6b, .Lbad_clear_user
10662306a36Sopenharmony_ci	.long	7b, .Lbad_clear_user
10762306a36Sopenharmony_ci	.long	8b, .Lbad_clear_user
10862306a36Sopenharmony_ci	.long	9b, .Lbad_clear_user
10962306a36Sopenharmony_ci.previous
110