1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19#include <linux/linkage.h>
20#include <asm/current.h>
21#include <asm/asm-offsets.h>
22#include <asm/asmmacro.h>
23#include <asm/processor.h>
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62#define UNALIGNED_USER_EXCEPTION
63#endif
64
65
66
67#define HWORD_START 16
68#define INSN_OP0 28
69#define INSN_T 24
70#define INSN_OP1 16
71
72.macro __ssa8r r; ssa8l \r; .endm
73.macro __sh r, s; srl \r, \s; .endm
74.macro __sl r, s; sll \r, \s; .endm
75.macro __exth r, s; extui \r, \s, 0, 16; .endm
76.macro __extl r, s; slli \r, \s, 16; .endm
77
78#else
79
80#define HWORD_START 0
81#define INSN_OP0 0
82#define INSN_T 4
83#define INSN_OP1 12
84
85.macro __ssa8r r; ssa8b \r; .endm
86.macro __sh r, s; sll \r, \s; .endm
87.macro __sl r, s; srl \r, \s; .endm
88.macro __exth r, s; slli \r, \s, 16; .endm
89.macro __extl r, s; extui \r, \s, 0, 16; .endm
90
91#endif
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129#define OP0_L32I_N 0x8
130#define OP0_S32I_N 0x9
131#define OP1_SI_MASK 0x4
132#define OP1_SI_BIT 2
133
134#define OP1_L32I 0x2
135#define OP1_L16UI 0x1
136#define OP1_L16SI 0x9
137#define OP1_L32AI 0xb
138
139#define OP1_S32I 0x6
140#define OP1_S16I 0x5
141#define OP1_S32RI 0xf
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157 .literal_position
158ENTRY(fast_unaligned)
159
160
161
162
163
164
165
166
167 s32i a4, a2, PT_AREG4
168 s32i a5, a2, PT_AREG5
169 s32i a6, a2, PT_AREG6
170 s32i a7, a2, PT_AREG7
171 s32i a8, a2, PT_AREG8
172
173 rsr a0, depc
174 s32i a0, a2, PT_AREG2
175 s32i a3, a2, PT_AREG3
176
177 rsr a3, excsave1
178 movi a4, fast_unaligned_fixup
179 s32i a4, a3, EXC_TABLE_FIXUP
180
181
182
183 rsr a0, sar
184 rsr a8, excvaddr
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203 rsr a7, epc1
204 movi a3, ~3
205 and a3, a3, a7
206
207 l32i a4, a3, 0
208 l32i a5, a3, 4
209
210 __ssa8 a7
211 __src_b a4, a4, a5
212
213
214
215 extui a5, a4, INSN_OP0, 4
216
217
218 _beqi a5, OP0_L32I_N, .Lload
219 addi a6, a5, -OP0_S32I_N
220 _beqz a6, .Lstore
221#endif
222
223 _bbci.l a4, OP1_SI_BIT + INSN_OP1, .Lload
224
225
226
227.Lstore:movi a5, .Lstore_table
228 extui a6, a4, INSN_T, 4
229 addx8 a5, a6, a5
230 jx a5
231
232
233
234.Lload: movi a3, ~3
235 and a3, a3, a8
236
237 __ssa8 a8
238#ifdef UNALIGNED_USER_EXCEPTION
239 addi a3, a3, 8
240 l32e a5, a3, -8
241 l32e a6, a3, -4
242#else
243 l32i a5, a3, 0
244 l32i a6, a3, 4
245#endif
246 __src_b a3, a5, a6
247
248
249 addi a7, a7, 2
250
251 extui a5, a4, INSN_OP0, 4
252 _beqi a5, OP0_L32I_N, 1f
253
254 addi a7, a7, 1
255#else
256 addi a7, a7, 3
257#endif
258
259 extui a5, a4, INSN_OP1, 4
260 _beqi a5, OP1_L32I, 1f
261
262 extui a3, a3, 0, 16
263 _beqi a5, OP1_L16UI, 1f
264 addi a5, a5, -OP1_L16SI
265 _bnez a5, .Linvalid_instruction_load
266
267
268
269 slli a3, a3, 16
270 srai a3, a3, 16
271
272
273
2741:
275 extui a4, a4, INSN_T, 4
276 movi a5, .Lload_table
277 addx8 a4, a4, a5
278 jx a4
279
280 .align 8
281.Lload_table:
282 s32i a3, a2, PT_AREG0; _j .Lexit; .align 8
283 mov a1, a3; _j .Lexit; .align 8
284 s32i a3, a2, PT_AREG2; _j .Lexit; .align 8
285 s32i a3, a2, PT_AREG3; _j .Lexit; .align 8
286 s32i a3, a2, PT_AREG4; _j .Lexit; .align 8
287 s32i a3, a2, PT_AREG5; _j .Lexit; .align 8
288 s32i a3, a2, PT_AREG6; _j .Lexit; .align 8
289 s32i a3, a2, PT_AREG7; _j .Lexit; .align 8
290 s32i a3, a2, PT_AREG8; _j .Lexit; .align 8
291 mov a9, a3 ; _j .Lexit; .align 8
292 mov a10, a3 ; _j .Lexit; .align 8
293 mov a11, a3 ; _j .Lexit; .align 8
294 mov a12, a3 ; _j .Lexit; .align 8
295 mov a13, a3 ; _j .Lexit; .align 8
296 mov a14, a3 ; _j .Lexit; .align 8
297 mov a15, a3 ; _j .Lexit; .align 8
298
299.Lstore_table:
300 l32i a3, a2, PT_AREG0; _j 1f; .align 8
301 mov a3, a1; _j 1f; .align 8
302 l32i a3, a2, PT_AREG2; _j 1f; .align 8
303 l32i a3, a2, PT_AREG3; _j 1f; .align 8
304 l32i a3, a2, PT_AREG4; _j 1f; .align 8
305 l32i a3, a2, PT_AREG5; _j 1f; .align 8
306 l32i a3, a2, PT_AREG6; _j 1f; .align 8
307 l32i a3, a2, PT_AREG7; _j 1f; .align 8
308 l32i a3, a2, PT_AREG8; _j 1f; .align 8
309 mov a3, a9 ; _j 1f; .align 8
310 mov a3, a10 ; _j 1f; .align 8
311 mov a3, a11 ; _j 1f; .align 8
312 mov a3, a12 ; _j 1f; .align 8
313 mov a3, a13 ; _j 1f; .align 8
314 mov a3, a14 ; _j 1f; .align 8
315 mov a3, a15 ; _j 1f; .align 8
316
317
318
319 .extern _kernel_exception
320.Linvalid_instruction_load:
321.Linvalid_instruction_store:
322
323 movi a4, 0
324 rsr a3, excsave1
325 s32i a4, a3, EXC_TABLE_FIXUP
326
327
328
329 l32i a8, a2, PT_AREG8
330 l32i a7, a2, PT_AREG7
331 l32i a6, a2, PT_AREG6
332 l32i a5, a2, PT_AREG5
333 l32i a4, a2, PT_AREG4
334 wsr a0, sar
335 mov a1, a2
336
337 rsr a0, ps
338 bbsi.l a0, PS_UM_BIT, 2f
339
340 movi a0, _kernel_exception
341 jx a0
342
3432: movi a0, _user_exception
344 jx a0
345
3461:
347
348 movi a6, 0
349
350
351 addi a7, a7, 2
352
353 extui a5, a4, INSN_OP0, 4
354 addi a5, a5, -OP0_S32I_N
355 _beqz a5, 1f
356
357 addi a7, a7, 1
358#else
359 addi a7, a7, 3
360#endif
361
362 extui a5, a4, INSN_OP1, 4
363 _beqi a5, OP1_S32I, 1f
364 _bnei a5, OP1_S16I, .Linvalid_instruction_store
365
366 movi a5, -1
367 __extl a3, a3
368 __exth a6, a5
369
370
371
3721:
373 movi a4, ~3
374 and a4, a4, a8
375
376
377
378 movi a5, -1
379#ifdef UNALIGNED_USER_EXCEPTION
380 addi a4, a4, 8
381#endif
382
383 __ssa8r a8
384 __src_b a8, a5, a6
385 __src_b a6, a6, a5
386#ifdef UNALIGNED_USER_EXCEPTION
387 l32e a5, a4, -8
388#else
389 l32i a5, a4, 0
390#endif
391 and a5, a5, a8
392 __sh a8, a3
393 or a5, a5, a8
394#ifdef UNALIGNED_USER_EXCEPTION
395 s32e a5, a4, -8
396 l32e a8, a4, -4
397#else
398 s32i a5, a4, 0
399 l32i a8, a4, 4
400#endif
401 __sl a5, a3
402 and a6, a8, a6
403 or a6, a6, a5
404#ifdef UNALIGNED_USER_EXCEPTION
405 s32e a6, a4, -4
406#else
407 s32i a6, a4, 4
408#endif
409
410.Lexit:
411
412 rsr a4, lend
413 bne a7, a4, 1f
414 rsr a4, lcount
415 beqz a4, 1f
416 addi a4, a4, -1
417 rsr a7, lbeg
418 wsr a4, lcount
419#endif
420
4211: wsr a7, epc1
422
423
424 rsr a4, icountlevel
425 beqz a4, 1f
426 bgeui a4, LOCKLEVEL + 1, 1f
427 rsr a4, icount
428 addi a4, a4, 1
429 wsr a4, icount
4301:
431 movi a4, 0
432 rsr a3, excsave1
433 s32i a4, a3, EXC_TABLE_FIXUP
434
435
436
437 l32i a8, a2, PT_AREG8
438 l32i a7, a2, PT_AREG7
439 l32i a6, a2, PT_AREG6
440 l32i a5, a2, PT_AREG5
441 l32i a4, a2, PT_AREG4
442 l32i a3, a2, PT_AREG3
443
444
445
446 wsr a0, sar
447 l32i a0, a2, PT_AREG0
448 l32i a2, a2, PT_AREG2
449 rfe
450
451ENDPROC(fast_unaligned)
452
453ENTRY(fast_unaligned_fixup)
454
455 l32i a2, a3, EXC_TABLE_DOUBLE_SAVE
456 wsr a3, excsave1
457
458 l32i a8, a2, PT_AREG8
459 l32i a7, a2, PT_AREG7
460 l32i a6, a2, PT_AREG6
461 l32i a5, a2, PT_AREG5
462 l32i a4, a2, PT_AREG4
463 l32i a0, a2, PT_AREG2
464 xsr a0, depc
465 wsr a0, sar
466
467 rsr a0, exccause
468 s32i a0, a2, PT_DEPC
469
470 rsr a0, ps
471 bbsi.l a0, PS_UM_BIT, 1f
472
473 rsr a0, exccause
474 addx4 a0, a0, a3
475 l32i a0, a0, EXC_TABLE_FAST_KERNEL
476 l32i a3, a2, PT_AREG3
477 jx a0
4781:
479 rsr a0, exccause
480 addx4 a0, a0, a3
481 l32i a0, a0, EXC_TABLE_FAST_USER
482 l32i a3, a2, PT_AREG3
483 jx a0
484
485ENDPROC(fast_unaligned_fixup)
486
487#endif
488