157
157
.literal_position
158
158
ENTRY(fast_unaligned)
159
159
160
- / * Note: We don't expect the address to be aligned on a word
161
- * boundary. After all , the processor generated th at exception
162
- * and it would be a hardware fault.
163
- * /
164
-
165
- / * Save some working register * /
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
- / * Keep value of SAR in a0 * /
182
-
183
- rsr a0 , sar
184
- rsr a8 , excvaddr # load unaligned memory address
185
-
186
- / * Now , identify one of the following load/store instructions.
187
- *
188
- * The only possible danger of a double exception on the
189
- * following l32i instructions is kernel code in vmalloc
190
- * memory. The processor was just executing at the EPC_1
191
- * address , and indeed , already fetched the instruction. Th at
192
- * guarantees a TLB mapping , which hasn't been replaced by
193
- * this unaligned exception handler th at uses only static TLB
194
- * mappings. However , high - level interrupt handlers might
195
- * modify TLB entries , so for the generic case , we register a
196
- * TABLE_FIXUP handler here , too.
197
- * /
198
-
199
- / * a3...a6 saved on stack , a2 = SP * /
200
-
201
- / * Extract the instruction th at caused the unaligned access. * /
202
-
203
- rsr a7 , epc1 # load exception address
204
- movi a3 , ~ 3
205
- and a3 , a3 , a7 # mask lower bits
206
-
207
- l32i a4 , a3 , 0 # load 2 words
208
- l32i a5 , a3 , 4
209
-
210
- __ssa8 a7
211
- __src_b a4 , a4 , a5 # a4 has the instruction
160
+ call0 .Lsave_and_load_instruction
212
161
213
162
/ * Analyze the instruction (load or store?). * /
214
163
@@ -249,29 +198,32 @@ ENTRY(fast_unaligned)
249
198
addi a7 , a7 , 2 # increment PC (assume 16 - bit insn)
250
199
251
200
extui a5 , a4 , INSN_OP0 , 4
252
- _beqi a5 , OP0_L32I_N , 1f # l32i.n: jump
201
+ _beqi a5 , OP0_L32I_N , .Lload_w # l32i.n: jump
253
202
254
203
addi a7 , a7 , 1
255
204
#else
256
205
addi a7 , a7 , 3
257
206
#endif
258
207
259
208
extui a5 , a4 , INSN_OP1 , 4
260
- _beqi a5 , OP1_L32I , 1f # l32i: jump
209
+ _beqi a5 , OP1_L32I , .Lload_w # l32i: jump
261
210
262
211
extui a3 , a3 , 0 , 16 # extract lower 16 bits
263
- _beqi a5 , OP1_L16UI , 1f
212
+ _beqi a5 , OP1_L16UI , .Lload_w
264
213
addi a5 , a5 , - OP1_L16SI
265
- _bnez a5 , .Linvalid_instruction_load
214
+ _bnez a5 , .Linvalid_instruction
266
215
267
216
/ * sign extend value * /
268
-
217
+ #if XCHAL_HAVE_SEXT
218
+ sext a3 , a3 , 15
219
+ #else
269
220
slli a3 , a3 , 16
270
221
srai a3 , a3 , 16
222
+ #endif
271
223
272
224
/ * Set target register. * /
273
225
274
- 1 :
226
+ .Lload_w :
275
227
extui a4 , a4 , INSN_T , 4 # extract target register
276
228
movi a5 , .Lload_table
277
229
addx8 a4 , a4 , a5
@@ -297,35 +249,35 @@ ENTRY(fast_unaligned)
297
249
mov a15 , a3 ; _j .Lexit; .align 8
298
250
299
251
.Lstore_table:
300
- l32i a3 , a2 , PT_AREG0 ; _j 1f ; .align 8
301
- mov a3 , a1 ; _j 1f ; .align 8 # fishy??
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
252
+ l32i a3 , a2 , PT_AREG0 ; _j .Lstore_w ; .align 8
253
+ mov a3 , a1 ; _j .Lstore_w ; .align 8 # fishy??
254
+ l32i a3 , a2 , PT_AREG2 ; _j .Lstore_w ; .align 8
255
+ l32i a3 , a2 , PT_AREG3 ; _j .Lstore_w ; .align 8
256
+ l32i a3 , a2 , PT_AREG4 ; _j .Lstore_w ; .align 8
257
+ l32i a3 , a2 , PT_AREG5 ; _j .Lstore_w ; .align 8
258
+ l32i a3 , a2 , PT_AREG6 ; _j .Lstore_w ; .align 8
259
+ l32i a3 , a2 , PT_AREG7 ; _j .Lstore_w ; .align 8
260
+ l32i a3 , a2 , PT_AREG8 ; _j .Lstore_w ; .align 8
261
+ mov a3 , a9 ; _j .Lstore_w ; .align 8
262
+ mov a3 , a10 ; _j .Lstore_w ; .align 8
263
+ mov a3 , a11 ; _j .Lstore_w ; .align 8
264
+ mov a3 , a12 ; _j .Lstore_w ; .align 8
265
+ mov a3 , a13 ; _j .Lstore_w ; .align 8
266
+ mov a3 , a14 ; _j .Lstore_w ; .align 8
267
+ mov a3 , a15 ; _j .Lstore_w ; .align 8
316
268
317
269
/ * We cannot handle this exception. * /
318
270
319
271
. extern _kernel_exception
320
- .Linvalid_instruction_load:
321
- .Linvalid_instruction_store:
272
+ .Linvalid_instruction:
322
273
323
274
movi a4 , 0
324
275
rsr a3 , excsave1
325
276
s32i a4 , a3 , EXC_TABLE_FIXUP
326
277
327
278
/ * Restore a4...a8 and SAR , set SP , and jump to default exception. * /
328
279
280
+ l32i a0 , a2 , PT_SAR
329
281
l32i a8 , a2 , PT_AREG8
330
282
l32i a7 , a2 , PT_AREG7
331
283
l32i a6 , a2 , PT_AREG6
@@ -343,8 +295,8 @@ ENTRY(fast_unaligned)
343
295
2 : movi a0 , _user_exception
344
296
jx a0
345
297
346
- 1 : # a7: instruction pointer, a4: instruction , a3: value
347
-
298
+ # a7: instruction pointer , a4: instruction , a3: value
299
+ .Lstore_w:
348
300
movi a6 , 0 # mask: ffffffff: 00000000
349
301
350
302
#if XCHAL_HAVE_DENSITY
@@ -361,7 +313,7 @@ ENTRY(fast_unaligned)
361
313
362
314
extui a5 , a4 , INSN_OP1 , 4 # extract OP1
363
315
_beqi a5 , OP1_S32I , 1f # jump if 32 bit store
364
- _bnei a5 , OP1_S16I , .Linvalid_instruction_store
316
+ _bnei a5 , OP1_S16I , .Linvalid_instruction
365
317
366
318
movi a5 , - 1
367
319
__extl a3 , a3 # get 16 - bit value
@@ -434,6 +386,7 @@ ENTRY(fast_unaligned)
434
386
435
387
/ * Restore working register * /
436
388
389
+ l32i a0 , a2 , PT_SAR
437
390
l32i a8 , a2 , PT_AREG8
438
391
l32i a7 , a2 , PT_AREG7
439
392
l32i a6 , a2 , PT_AREG6
@@ -448,6 +401,59 @@ ENTRY(fast_unaligned)
448
401
l32i a2 , a2 , PT_AREG2
449
402
rfe
450
403
404
+ . align 4
405
+ .Lsave_and_load_instruction:
406
+
407
+ / * Save some working register * /
408
+
409
+ s32i a3 , a2 , PT_AREG3
410
+ s32i a4 , a2 , PT_AREG4
411
+ s32i a5 , a2 , PT_AREG5
412
+ s32i a6 , a2 , PT_AREG6
413
+ s32i a7 , a2 , PT_AREG7
414
+ s32i a8 , a2 , PT_AREG8
415
+
416
+ rsr a4 , depc
417
+ s32i a4 , a2 , PT_AREG2
418
+
419
+ rsr a5 , sar
420
+ s32i a5 , a2 , PT_SAR
421
+
422
+ rsr a3 , excsave1
423
+ movi a4 , fast_unaligned_fixup
424
+ s32i a4 , a3 , EXC_TABLE_FIXUP
425
+
426
+ rsr a8 , excvaddr # load unaligned memory address
427
+
428
+ / * Now , identify one of the following load/store instructions.
429
+ *
430
+ * The only possible danger of a double exception on the
431
+ * following l32i instructions is kernel code in vmalloc
432
+ * memory. The processor was just executing at the EPC_1
433
+ * address , and indeed , already fetched the instruction. Th at
434
+ * guarantees a TLB mapping , which hasn't been replaced by
435
+ * this unaligned exception handler th at uses only static TLB
436
+ * mappings. However , high - level interrupt handlers might
437
+ * modify TLB entries , so for the generic case , we register a
438
+ * TABLE_FIXUP handler here , too.
439
+ * /
440
+
441
+ / * a3...a6 saved on stack , a2 = SP * /
442
+
443
+ / * Extract the instruction th at caused the unaligned access. * /
444
+
445
+ rsr a7 , epc1 # load exception address
446
+ movi a3 , ~ 3
447
+ and a3 , a3 , a7 # mask lower bits
448
+
449
+ l32i a4 , a3 , 0 # load 2 words
450
+ l32i a5 , a3 , 4
451
+
452
+ __ssa8 a7
453
+ __src_b a4 , a4 , a5 # a4 has the instruction
454
+
455
+ ret
456
+
451
457
ENDPROC(fast_unaligned)
452
458
453
459
ENTRY(fast_unaligned_fixup)
@@ -459,10 +465,11 @@ ENTRY(fast_unaligned_fixup)
459
465
l32i a7 , a2 , PT_AREG7
460
466
l32i a6 , a2 , PT_AREG6
461
467
l32i a5 , a2 , PT_AREG5
462
- l32i a4 , a2 , PT_AREG4
468
+ l32i a4 , a2 , PT_SAR
463
469
l32i a0 , a2 , PT_AREG2
464
- xsr a0 , depc # restore depc and a0
465
- wsr a0 , sar
470
+ wsr a4 , sar
471
+ wsr a0 , depc # restore depc and a0
472
+ l32i a4 , a2 , PT_AREG4
466
473
467
474
rsr a0 , exccause
468
475
s32i a0 , a2 , PT_DEPC # mark as a regular exception
0 commit comments