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