Merge branch 'next' of git://git.infradead.org/users/vkoul/slave-dma
[linux-2.6.git] / arch / unicore32 / lib / copy_template.S
1 /*
2  * linux/arch/unicore32/lib/copy_template.S
3  *
4  * Code specific to PKUnity SoC and UniCore ISA
5  *
6  * Copyright (C) 2001-2010 GUAN Xue-tao
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License version 2 as
10  * published by the Free Software Foundation.
11  */
12
13 /*
14  * Theory of operation
15  * -------------------
16  *
17  * This file provides the core code for a forward memory copy used in
18  * the implementation of memcopy(), copy_to_user() and copy_from_user().
19  *
20  * The including file must define the following accessor macros
21  * according to the need of the given function:
22  *
23  * ldr1w ptr reg abort
24  *
25  *      This loads one word from 'ptr', stores it in 'reg' and increments
26  *      'ptr' to the next word. The 'abort' argument is used for fixup tables.
27  *
28  * ldr4w ptr reg1 reg2 reg3 reg4 abort
29  * ldr8w ptr, reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort
30  *
31  *      This loads four or eight words starting from 'ptr', stores them
32  *      in provided registers and increments 'ptr' past those words.
33  *      The'abort' argument is used for fixup tables.
34  *
35  * ldr1b ptr reg cond abort
36  *
37  *      Similar to ldr1w, but it loads a byte and increments 'ptr' one byte.
38  *      It also must apply the condition code if provided, otherwise the
39  *      "al" condition is assumed by default.
40  *
41  * str1w ptr reg abort
42  * str8w ptr reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort
43  * str1b ptr reg cond abort
44  *
45  *      Same as their ldr* counterparts, but data is stored to 'ptr' location
46  *      rather than being loaded.
47  *
48  * enter
49  *
50  *      Preserve the provided registers on the stack plus any additional
51  *      data as needed by the implementation including this code. Called
52  *      upon code entry.
53  *
54  * exit
55  *
56  *      Restore registers with the values previously saved with the
57  *      'preserv' macro. Called upon code termination.
58  */
59
60
61                 enter
62
63                 sub.a   r2, r2, #4
64                 bsl     8f
65                 and.a   ip, r0, #3
66                 bne     9f
67                 and.a   ip, r1, #3
68                 bne     10f
69
70 1:              sub.a   r2, r2, #(28)
71                 stm.w   (r5 - r8), [sp-]
72                 bsl     5f
73
74 3:
75 4:              ldr8w   r1, r3, r4, r5, r6, r7, r8, r10, r11, abort=20f
76                 sub.a   r2, r2, #32
77                 str8w   r0, r3, r4, r5, r6, r7, r8, r10, r11, abort=20f
78                 beg     3b
79
80 5:              and.a   ip, r2, #28
81                 rsub    ip, ip, #32
82                 beq     7f
83                 add     pc, pc, ip              @ C is always clear here
84                 nop
85
86                 ldr1w   r1, r3, abort=20f
87                 ldr1w   r1, r4, abort=20f
88                 ldr1w   r1, r5, abort=20f
89                 ldr1w   r1, r6, abort=20f
90                 ldr1w   r1, r7, abort=20f
91                 ldr1w   r1, r8, abort=20f
92                 ldr1w   r1, r11, abort=20f
93
94                 add     pc, pc, ip
95                 nop
96
97                 str1w   r0, r3, abort=20f
98                 str1w   r0, r4, abort=20f
99                 str1w   r0, r5, abort=20f
100                 str1w   r0, r6, abort=20f
101                 str1w   r0, r7, abort=20f
102                 str1w   r0, r8, abort=20f
103                 str1w   r0, r11, abort=20f
104
105 7:              ldm.w   (r5 - r8), [sp]+
106
107 8:              mov.a   r2, r2 << #31
108                 ldr1b   r1, r3, ne, abort=21f
109                 ldr1b   r1, r4, ea, abort=21f
110                 ldr1b   r1, r10, ea, abort=21f
111                 str1b   r0, r3, ne, abort=21f
112                 str1b   r0, r4, ea, abort=21f
113                 str1b   r0, r10, ea, abort=21f
114
115                 exit
116
117 9:              rsub    ip, ip, #4
118                 csub.a  ip, #2
119                 ldr1b   r1, r3, sg, abort=21f
120                 ldr1b   r1, r4, eg, abort=21f
121                 ldr1b   r1, r11, abort=21f
122                 str1b   r0, r3, sg, abort=21f
123                 str1b   r0, r4, eg, abort=21f
124                 sub.a   r2, r2, ip
125                 str1b   r0, r11, abort=21f
126                 bsl     8b
127                 and.a   ip, r1, #3
128                 beq     1b
129
130 10:             andn    r1, r1, #3
131                 csub.a  ip, #2
132                 ldr1w   r1, r11, abort=21f
133                 beq     17f
134                 bsg     18f
135
136
137                 .macro  forward_copy_shift a b
138
139                 sub.a   r2, r2, #28
140                 bsl     14f
141
142 11:             stm.w   (r5 - r9), [sp-]
143
144 12:
145                 ldr4w   r1, r4, r5, r6, r7, abort=19f
146                 mov     r3, r11 pull #\a
147                 sub.a   r2, r2, #32
148                 ldr4w   r1, r8, r9, r10, r11, abort=19f
149                 or      r3, r3, r4 push #\b
150                 mov     r4, r4 pull #\a
151                 or      r4, r4, r5 push #\b
152                 mov     r5, r5 pull #\a
153                 or      r5, r5, r6 push #\b
154                 mov     r6, r6 pull #\a
155                 or      r6, r6, r7 push #\b
156                 mov     r7, r7 pull #\a
157                 or      r7, r7, r8 push #\b
158                 mov     r8, r8 pull #\a
159                 or      r8, r8, r9 push #\b
160                 mov     r9, r9 pull #\a
161                 or      r9, r9, r10 push #\b
162                 mov     r10, r10 pull #\a
163                 or      r10, r10, r11 push #\b
164                 str8w   r0, r3, r4, r5, r6, r7, r8, r9, r10, , abort=19f
165                 beg     12b
166
167                 ldm.w   (r5 - r9), [sp]+
168
169 14:             and.a   ip, r2, #28
170                 beq     16f
171
172 15:             mov     r3, r11 pull #\a
173                 ldr1w   r1, r11, abort=21f
174                 sub.a   ip, ip, #4
175                 or      r3, r3, r11 push #\b
176                 str1w   r0, r3, abort=21f
177                 bsg     15b
178
179 16:             sub     r1, r1, #(\b / 8)
180                 b       8b
181
182                 .endm
183
184
185                 forward_copy_shift      a=8     b=24
186
187 17:             forward_copy_shift      a=16    b=16
188
189 18:             forward_copy_shift      a=24    b=8
190
191
192 /*
193  * Abort preamble and completion macros.
194  * If a fixup handler is required then those macros must surround it.
195  * It is assumed that the fixup code will handle the private part of
196  * the exit macro.
197  */
198
199         .macro  copy_abort_preamble
200 19:     ldm.w   (r5 - r9), [sp]+
201         b       21f
202 299:    .word   0                       @ store lr
203                                         @ to avoid function call in fixup
204 20:     ldm.w   (r5 - r8), [sp]+
205 21:
206         adr     r1, 299b
207         stw     lr, [r1]
208         .endm
209
210         .macro  copy_abort_end
211         adr     lr, 299b
212         ldw     pc, [lr]
213         .endm
214