Merge branch 'drm-patches' of git://git.kernel.org/pub/scm/linux/kernel/git/airlied...
[linux-2.6] / arch / sh / mm / clear_page.S
1 /* $Id: clear_page.S,v 1.13 2003/08/25 17:03:10 lethal Exp $
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  *
8  */
9 #include <linux/linkage.h>
10
11 /*
12  * clear_page_slow
13  * @to: P1 address
14  *
15  * void clear_page_slow(void *to)
16  */
17
18 /*
19  * r0 --- scratch
20  * r4 --- to
21  * r5 --- to + 4096
22  */
23 ENTRY(clear_page_slow)
24         mov     r4,r5
25         mov.w   .Llimit,r0
26         add     r0,r5
27         mov     #0,r0
28         !
29 1:
30 #if defined(CONFIG_CPU_SH3)
31         mov.l   r0,@r4
32 #elif defined(CONFIG_CPU_SH4)
33         movca.l r0,@r4
34         mov     r4,r1
35 #endif
36         add     #32,r4
37         mov.l   r0,@-r4
38         mov.l   r0,@-r4
39         mov.l   r0,@-r4
40         mov.l   r0,@-r4
41         mov.l   r0,@-r4
42         mov.l   r0,@-r4
43         mov.l   r0,@-r4
44 #if defined(CONFIG_CPU_SH4)
45         ocbwb   @r1
46 #endif
47         cmp/eq  r5,r4
48         bf/s    1b
49          add    #28,r4
50         !
51         rts
52          nop
53 .Llimit:        .word   (4096-28)
54
55 ENTRY(__clear_user)
56         !
57         mov     #0, r0
58         mov     #0xe0, r1       ! 0xffffffe0
59         !
60         ! r4..(r4+31)&~32          -------- not aligned [ Area 0 ]
61         ! (r4+31)&~32..(r4+r5)&~32 -------- aligned     [ Area 1 ]
62         ! (r4+r5)&~32..r4+r5       -------- not aligned [ Area 2 ]
63         !
64         ! Clear area 0
65         mov     r4, r2
66         !
67         tst     r1, r5          ! length < 32
68         bt      .Larea2         ! skip to remainder
69         !
70         add     #31, r2
71         and     r1, r2
72         cmp/eq  r4, r2
73         bt      .Larea1
74         mov     r2, r3
75         sub     r4, r3
76         mov     r3, r7
77         mov     r4, r2
78         !
79 .L0:    dt      r3
80 0:      mov.b   r0, @r2
81         bf/s    .L0
82          add    #1, r2
83         !
84         sub     r7, r5
85         mov     r2, r4
86 .Larea1:
87         mov     r4, r3
88         add     r5, r3
89         and     r1, r3
90         cmp/hi  r2, r3
91         bf      .Larea2
92         !
93         ! Clear area 1
94 #if defined(CONFIG_CPU_SH4)
95 1:      movca.l r0, @r2
96 #else
97 1:      mov.l   r0, @r2
98 #endif
99         add     #4, r2
100 2:      mov.l   r0, @r2
101         add     #4, r2
102 3:      mov.l   r0, @r2
103         add     #4, r2
104 4:      mov.l   r0, @r2
105         add     #4, r2
106 5:      mov.l   r0, @r2
107         add     #4, r2
108 6:      mov.l   r0, @r2
109         add     #4, r2
110 7:      mov.l   r0, @r2
111         add     #4, r2
112 8:      mov.l   r0, @r2
113         add     #4, r2
114         cmp/hi  r2, r3
115         bt/s    1b
116          nop
117         !
118         ! Clear area 2
119 .Larea2:
120         mov     r4, r3
121         add     r5, r3
122         cmp/hs  r3, r2
123         bt/s    .Ldone
124          sub    r2, r3
125 .L2:    dt      r3
126 9:      mov.b   r0, @r2
127         bf/s    .L2
128          add    #1, r2
129         !
130 .Ldone: rts
131          mov    #0, r0  ! return 0 as normal return
132
133         ! return the number of bytes remained
134 .Lbad_clear_user:
135         mov     r4, r0
136         add     r5, r0
137         rts
138          sub    r2, r0
139
140 .section __ex_table,"a"
141         .align 2
142         .long   0b, .Lbad_clear_user
143         .long   1b, .Lbad_clear_user
144         .long   2b, .Lbad_clear_user
145         .long   3b, .Lbad_clear_user
146         .long   4b, .Lbad_clear_user
147         .long   5b, .Lbad_clear_user
148         .long   6b, .Lbad_clear_user
149         .long   7b, .Lbad_clear_user
150         .long   8b, .Lbad_clear_user
151         .long   9b, .Lbad_clear_user
152 .previous
153
154 #if defined(CONFIG_CPU_SH4)
155 /*
156  * __clear_user_page
157  * @to: P3 address (with same color)
158  * @orig_to: P1 address
159  *
160  * void __clear_user_page(void *to, void *orig_to)
161  */
162
163 /*
164  * r0 --- scratch 
165  * r4 --- to
166  * r5 --- orig_to
167  * r6 --- to + 4096
168  */
169 ENTRY(__clear_user_page)
170         mov.w   .L4096,r0
171         mov     r4,r6
172         add     r0,r6
173         mov     #0,r0
174         !
175 1:      ocbi    @r5
176         add     #32,r5
177         movca.l r0,@r4
178         mov     r4,r1
179         add     #32,r4
180         mov.l   r0,@-r4
181         mov.l   r0,@-r4
182         mov.l   r0,@-r4
183         mov.l   r0,@-r4
184         mov.l   r0,@-r4
185         mov.l   r0,@-r4
186         mov.l   r0,@-r4
187         add     #28,r4
188         cmp/eq  r6,r4
189         bf/s    1b
190          ocbwb  @r1
191         !
192         rts
193          nop
194 .L4096: .word   4096
195
196 #endif
197