xref: /linux/arch/sh/lib/__clear_user.S (revision b77e0ce62d63a761ffb7f7245a215a49f5921c2f)
1/* SPDX-License-Identifier: GPL-2.0 */
2/*
3 * __clear_user_page, __clear_user, clear_page implementation of SuperH
4 *
5 * Copyright (C) 2001  Kaz Kojima
6 * Copyright (C) 2001, 2002  Niibe Yutaka
7 * Copyright (C) 2006  Paul Mundt
8 */
9#include <linux/linkage.h>
10#include <asm/page.h>
11
12ENTRY(__clear_user)
13	!
14	mov	#0, r0
15	mov	#0xffffffe0, r1
16	!
17	! r4..(r4+31)&~32 	   -------- not aligned	[ Area 0 ]
18	! (r4+31)&~32..(r4+r5)&~32 -------- aligned	[ Area 1 ]
19	! (r4+r5)&~32..r4+r5       -------- not aligned	[ Area 2 ]
20	!
21	! Clear area 0
22	mov	r4, r2
23	!
24	tst	r1, r5		! length < 32
25	bt	.Larea2		! skip to remainder
26	!
27	add	#31, r2
28	and	r1, r2
29	cmp/eq	r4, r2
30	bt	.Larea1
31	mov	r2, r3
32	sub	r4, r3
33	mov	r3, r7
34	mov	r4, r2
35	!
36.L0:	dt	r3
370:	mov.b	r0, @r2
38	bf/s	.L0
39	 add	#1, r2
40	!
41	sub	r7, r5
42	mov	r2, r4
43.Larea1:
44	mov	r4, r3
45	add	r5, r3
46	and	r1, r3
47	cmp/hi	r2, r3
48	bf	.Larea2
49	!
50	! Clear area 1
51#if defined(CONFIG_CPU_SH4)
521:	movca.l	r0, @r2
53#else
541:	mov.l	r0, @r2
55#endif
56	add	#4, r2
572:	mov.l	r0, @r2
58	add	#4, r2
593:	mov.l	r0, @r2
60	add	#4, r2
614:	mov.l	r0, @r2
62	add	#4, r2
635:	mov.l	r0, @r2
64	add	#4, r2
656:	mov.l	r0, @r2
66	add	#4, r2
677:	mov.l	r0, @r2
68	add	#4, r2
698:	mov.l	r0, @r2
70	add	#4, r2
71	cmp/hi	r2, r3
72	bt/s	1b
73	 nop
74	!
75	! Clear area 2
76.Larea2:
77	mov	r4, r3
78	add	r5, r3
79	cmp/hs	r3, r2
80	bt/s	.Ldone
81	 sub	r2, r3
82.L2:	dt	r3
839:	mov.b	r0, @r2
84	bf/s	.L2
85	 add	#1, r2
86	!
87.Ldone:	rts
88	 mov	#0, r0	! return 0 as normal return
89
90	! return the number of bytes remained
91.Lbad_clear_user:
92	mov	r4, r0
93	add	r5, r0
94	rts
95	 sub	r2, r0
96
97.section __ex_table,"a"
98	.align 2
99	.long	0b, .Lbad_clear_user
100	.long	1b, .Lbad_clear_user
101	.long	2b, .Lbad_clear_user
102	.long	3b, .Lbad_clear_user
103	.long	4b, .Lbad_clear_user
104	.long	5b, .Lbad_clear_user
105	.long	6b, .Lbad_clear_user
106	.long	7b, .Lbad_clear_user
107	.long	8b, .Lbad_clear_user
108	.long	9b, .Lbad_clear_user
109.previous
110