MIPS: Actually decode JALX in `__compute_return_epc_for_insn'
[GitHub/mt8127/android_kernel_alcatel_ttab.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