1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18#include <linux/linkage.h>
19#include <asm/current.h>
20#include <asm/asm-offsets.h>
21#include <asm/processor.h>
22
23
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#define UNALIGNED_USER_EXCEPTION
60
61
62
63#define HWORD_START 16
64#define INSN_OP0 28
65#define INSN_T 24
66#define INSN_OP1 16
67
68.macro __src_b r, w0, w1; src \r, \w0, \w1; .endm
69.macro __ssa8 r; ssa8b \r; .endm
70.macro __ssa8r r; ssa8l \r; .endm
71.macro __sh r, s; srl \r, \s; .endm
72.macro __sl r, s; sll \r, \s; .endm
73.macro __exth r, s; extui \r, \s, 0, 16; .endm
74.macro __extl r, s; slli \r, \s, 16; .endm
75
76#else
77
78#define HWORD_START 0
79#define INSN_OP0 0
80#define INSN_T 4
81#define INSN_OP1 12
82
83.macro __src_b r, w0, w1; src \r, \w1, \w0; .endm
84.macro __ssa8 r; ssa8l \r; .endm
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
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 xsr a3, excsave1
175 s32i a0, a2, PT_AREG2
176 s32i a3, a2, PT_AREG3
177
178
179
180 rsr a0, sar
181 rsr a8, excvaddr
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200 rsr a7, epc1
201 movi a3, ~3
202 and a3, a3, a7
203
204 l32i a4, a3, 0
205 l32i a5, a3, 4
206
207 __ssa8 a7
208 __src_b a4, a4, a5
209
210
211
212 extui a5, a4, INSN_OP0, 4
213
214
215 _beqi a5, OP0_L32I_N, .Lload
216 addi a6, a5, -OP0_S32I_N
217 _beqz a6, .Lstore
218#endif
219
220 _bbci.l a4, OP1_SI_BIT + INSN_OP1, .Lload
221
222
223
224.Lstore:movi a5, .Lstore_table
225 extui a6, a4, INSN_T, 4
226 addx8 a5, a6, a5
227 jx a5
228
229
230.Linvalid_instruction_load:
231 j .Linvalid_instruction
232
233
234
235.Lload: movi a3, ~3
236 and a3, a3, a8
237
238 __ssa8 a8
239#ifdef UNALIGNED_USER_EXCEPTION
240 addi a3, a3, 8
241 l32e a5, a3, -8
242 l32e a6, a3, -4
243#else
244 l32i a5, a3, 0
245 l32i a6, a3, 4
246#endif
247 __src_b a3, a5, a6
248
249
250 addi a7, a7, 2
251
252 extui a5, a4, INSN_OP0, 4
253 _beqi a5, OP0_L32I_N, 1f
254
255 addi a7, a7, 1
256#else
257 addi a7, a7, 3
258#endif
259
260 extui a5, a4, INSN_OP1, 4
261 _beqi a5, OP1_L32I, 1f
262
263 extui a3, a3, 0, 16
264 _beqi a5, OP1_L16UI, 1f
265 addi a5, a5, -OP1_L16SI
266 _bnez a5, .Linvalid_instruction_load
267
268
269
270 slli a3, a3, 16
271 srai a3, a3, 16
272
273
274
2751:
276
277
278 rsr a5, lend
279 bne a7, a5, 1f
280 rsr a5, lcount
281 beqz a5, 1f
282 addi a5, a5, -1
283 rsr a7, lbeg
284 wsr a5, lcount
285#endif
286
2871: wsr a7, epc1
288 extui a4, a4, INSN_T, 4
289 movi a5, .Lload_table
290 addx8 a4, a4, a5
291 jx a4
292
293 .align 8
294.Lload_table:
295 s32i a3, a2, PT_AREG0; _j .Lexit; .align 8
296 mov a1, a3; _j .Lexit; .align 8
297 s32i a3, a2, PT_AREG2; _j .Lexit; .align 8
298 s32i a3, a2, PT_AREG3; _j .Lexit; .align 8
299 s32i a3, a2, PT_AREG4; _j .Lexit; .align 8
300 s32i a3, a2, PT_AREG5; _j .Lexit; .align 8
301 s32i a3, a2, PT_AREG6; _j .Lexit; .align 8
302 s32i a3, a2, PT_AREG7; _j .Lexit; .align 8
303 s32i a3, a2, PT_AREG8; _j .Lexit; .align 8
304 mov a9, a3 ; _j .Lexit; .align 8
305 mov a10, a3 ; _j .Lexit; .align 8
306 mov a11, a3 ; _j .Lexit; .align 8
307 mov a12, a3 ; _j .Lexit; .align 8
308 mov a13, a3 ; _j .Lexit; .align 8
309 mov a14, a3 ; _j .Lexit; .align 8
310 mov a15, a3 ; _j .Lexit; .align 8
311
312.Lstore_table:
313 l32i a3, a2, PT_AREG0; _j 1f; .align 8
314 mov a3, a1; _j 1f; .align 8
315 l32i a3, a2, PT_AREG2; _j 1f; .align 8
316 l32i a3, a2, PT_AREG3; _j 1f; .align 8
317 l32i a3, a2, PT_AREG4; _j 1f; .align 8
318 l32i a3, a2, PT_AREG5; _j 1f; .align 8
319 l32i a3, a2, PT_AREG6; _j 1f; .align 8
320 l32i a3, a2, PT_AREG7; _j 1f; .align 8
321 l32i a3, a2, PT_AREG8; _j 1f; .align 8
322 mov a3, a9 ; _j 1f; .align 8
323 mov a3, a10 ; _j 1f; .align 8
324 mov a3, a11 ; _j 1f; .align 8
325 mov a3, a12 ; _j 1f; .align 8
326 mov a3, a13 ; _j 1f; .align 8
327 mov a3, a14 ; _j 1f; .align 8
328 mov a3, a15 ; _j 1f; .align 8
329
3301:
331
332 movi a6, 0
333
334
335 addi a7, a7, 2
336
337 extui a5, a4, INSN_OP0, 4
338 addi a5, a5, -OP0_S32I_N
339 _beqz a5, 1f
340
341 addi a7, a7, 1
342#else
343 addi a7, a7, 3
344#endif
345
346 extui a5, a4, INSN_OP1, 4
347 _beqi a5, OP1_S32I, 1f
348 _bnei a5, OP1_S16I, .Linvalid_instruction_store
349
350 movi a5, -1
351 __extl a3, a3
352 __exth a6, a5
353
354
355
3561:
357
358 rsr a4, lend
359 bne a7, a4, 1f
360 rsr a4, lcount
361 beqz a4, 1f
362 addi a4, a4, -1
363 rsr a7, lbeg
364 wsr a4, lcount
365#endif
366
3671: wsr a7, epc1
368 movi a4, ~3
369 and a4, a4, a8
370
371
372
373 movi a5, -1
374#ifdef UNALIGNED_USER_EXCEPTION
375 addi a4, a4, 8
376#endif
377
378 __ssa8r a8
379 __src_b a7, a5, a6
380 __src_b a6, a6, a5
381#ifdef UNALIGNED_USER_EXCEPTION
382 l32e a5, a4, -8
383#else
384 l32i a5, a4, 0
385#endif
386 and a5, a5, a7
387 __sh a7, a3
388 or a5, a5, a7
389#ifdef UNALIGNED_USER_EXCEPTION
390 s32e a5, a4, -8
391 l32e a7, a4, -4
392#else
393 s32i a5, a4, 0
394 l32i a7, a4, 4
395#endif
396 __sl a5, a3
397 and a6, a7, a6
398 or a6, a6, a5
399#ifdef UNALIGNED_USER_EXCEPTION
400 s32e a6, a4, -4
401#else
402 s32i a6, a4, 4
403#endif
404
405
406
407.Lexit:
408 movi a4, 0
409 rsr a3, excsave1
410 s32i a4, a3, EXC_TABLE_FIXUP
411
412
413
414 l32i a8, a2, PT_AREG8
415 l32i a7, a2, PT_AREG7
416 l32i a6, a2, PT_AREG6
417 l32i a5, a2, PT_AREG5
418 l32i a4, a2, PT_AREG4
419 l32i a3, a2, PT_AREG3
420
421
422
423 wsr a0, sar
424 l32i a0, a2, PT_AREG0
425 l32i a2, a2, PT_AREG2
426 rfe
427
428
429
430 .extern _kernel_exception
431.Linvalid_instruction_store:
432.Linvalid_instruction:
433
434
435
436 l32i a8, a2, PT_AREG8
437 l32i a7, a2, PT_AREG7
438 l32i a6, a2, PT_AREG6
439 l32i a5, a2, PT_AREG5
440 l32i a4, a2, PT_AREG4
441 wsr a0, sar
442 mov a1, a2
443
444 rsr a0, ps
445 bbsi.l a2, PS_UM_BIT, 1f
446
447 movi a0, _kernel_exception
448 jx a0
449
4501: movi a0, _user_exception
451 jx a0
452
453ENDPROC(fast_unaligned)
454
455#endif
456