xref: /openbmc/linux/arch/sh/lib/__clear_user.S (revision 56a0eccd)
1/*
2 * __clear_user_page, __clear_user, clear_page implementation of SuperH
3 *
4 * Copyright (C) 2001  Kaz Kojima
5 * Copyright (C) 2001, 2002  Niibe Yutaka
6 * Copyright (C) 2006  Paul Mundt
7 */
8#include <linux/linkage.h>
9#include <asm/page.h>
10
11ENTRY(__clear_user)
12	!
13	mov	#0, r0
14	mov	#0xffffffe0, r1
15	!
16	! r4..(r4+31)&~32 	   -------- not aligned	[ Area 0 ]
17	! (r4+31)&~32..(r4+r5)&~32 -------- aligned	[ Area 1 ]
18	! (r4+r5)&~32..r4+r5       -------- not aligned	[ Area 2 ]
19	!
20	! Clear area 0
21	mov	r4, r2
22	!
23	tst	r1, r5		! length < 32
24	bt	.Larea2		! skip to remainder
25	!
26	add	#31, r2
27	and	r1, r2
28	cmp/eq	r4, r2
29	bt	.Larea1
30	mov	r2, r3
31	sub	r4, r3
32	mov	r3, r7
33	mov	r4, r2
34	!
35.L0:	dt	r3
360:	mov.b	r0, @r2
37	bf/s	.L0
38	 add	#1, r2
39	!
40	sub	r7, r5
41	mov	r2, r4
42.Larea1:
43	mov	r4, r3
44	add	r5, r3
45	and	r1, r3
46	cmp/hi	r2, r3
47	bf	.Larea2
48	!
49	! Clear area 1
50#if defined(CONFIG_CPU_SH4)
511:	movca.l	r0, @r2
52#else
531:	mov.l	r0, @r2
54#endif
55	add	#4, r2
562:	mov.l	r0, @r2
57	add	#4, r2
583:	mov.l	r0, @r2
59	add	#4, r2
604:	mov.l	r0, @r2
61	add	#4, r2
625:	mov.l	r0, @r2
63	add	#4, r2
646:	mov.l	r0, @r2
65	add	#4, r2
667:	mov.l	r0, @r2
67	add	#4, r2
688:	mov.l	r0, @r2
69	add	#4, r2
70	cmp/hi	r2, r3
71	bt/s	1b
72	 nop
73	!
74	! Clear area 2
75.Larea2:
76	mov	r4, r3
77	add	r5, r3
78	cmp/hs	r3, r2
79	bt/s	.Ldone
80	 sub	r2, r3
81.L2:	dt	r3
829:	mov.b	r0, @r2
83	bf/s	.L2
84	 add	#1, r2
85	!
86.Ldone:	rts
87	 mov	#0, r0	! return 0 as normal return
88
89	! return the number of bytes remained
90.Lbad_clear_user:
91	mov	r4, r0
92	add	r5, r0
93	rts
94	 sub	r2, r0
95
96.section __ex_table,"a"
97	.align 2
98	.long	0b, .Lbad_clear_user
99	.long	1b, .Lbad_clear_user
100	.long	2b, .Lbad_clear_user
101	.long	3b, .Lbad_clear_user
102	.long	4b, .Lbad_clear_user
103	.long	5b, .Lbad_clear_user
104	.long	6b, .Lbad_clear_user
105	.long	7b, .Lbad_clear_user
106	.long	8b, .Lbad_clear_user
107	.long	9b, .Lbad_clear_user
108.previous
109