22
22
#include <asm/asmmacro.h>
23
23
#include <asm/processor.h>
24
24
25
- #if XCHAL_UNALIGNED_LOAD_EXCEPTION || XCHAL_UNALIGNED_STORE_EXCEPTION
25
+ #if XCHAL_UNALIGNED_LOAD_EXCEPTION || defined CONFIG_XTENSA_LOAD_STORE
26
+ #define LOAD_EXCEPTION_HANDLER
27
+ #endif
28
+
29
+ #if XCHAL_UNALIGNED_STORE_EXCEPTION || defined LOAD_EXCEPTION_HANDLER
30
+ #define ANY_EXCEPTION_HANDLER
31
+ #endif
32
+
33
+ #if XCHAL_HAVE_WINDOWED
34
+ #define UNALIGNED_USER_EXCEPTION
35
+ #endif
26
36
27
37
/ * First - level exception handler for unaligned exceptions.
28
38
*
58
68
* BE shift left / mask 0 0 X X
59
69
* /
60
70
61
- #if XCHAL_HAVE_WINDOWED
62
- #define UNALIGNED_USER_EXCEPTION
63
- #endif
64
-
65
71
#if XCHAL_HAVE_BE
66
72
67
73
#define HWORD_START 16
103
109
*
104
110
* 23 0
105
111
* -----------------------------
106
- * res 0000 0010
112
+ * L8UI xxxx xxxx 0000 ssss tttt 0010
107
113
* L16UI xxxx xxxx 0001 ssss tttt 0010
108
114
* L32I xxxx xxxx 0010 ssss tttt 0010
109
115
* XXX 0011 ssss tttt 0010
128
134
129
135
#define OP0_L32I_N 0x8 / * load immediate narrow * /
130
136
#define OP0_S32I_N 0x9 / * store immediate narrow * /
137
+ #define OP0_LSAI 0x2 / * load/store * /
131
138
#define OP1_SI_MASK 0x4 / * OP1 bit set for stores * /
132
139
#define OP1_SI_BIT 2 / * OP1 bit number for stores * /
133
140
141
+ #define OP1_L8UI 0x0
134
142
#define OP1_L32I 0x2
135
143
#define OP1_L16UI 0x1
136
144
#define OP1_L16SI 0x9
155
163
* /
156
164
157
165
.literal_position
166
+ #ifdef CONFIG_XTENSA_LOAD_STORE
167
+ ENTRY(fast_load_store)
168
+
169
+ call0 .Lsave_and_load_instruction
170
+
171
+ / * Analyze the instruction (load or store?). * /
172
+
173
+ extui a0 , a4 , INSN_OP0 , 4 # get insn.op0 nibble
174
+
175
+ #if XCHAL_HAVE_DENSITY
176
+ _beqi a0 , OP0_L32I_N , 1f # L32I.N , jump
177
+ #endif
178
+ bnei a0 , OP0_LSAI , .Linvalid_instruction
179
+ / * 'store indicator bit' set , jump * /
180
+ bbsi.l a4 , OP1_SI_BIT + INSN_OP1 , .Linvalid_instruction
181
+
182
+ 1 :
183
+ movi a3 , ~ 3
184
+ and a3 , a3 , a8 # align memory address
185
+
186
+ __ssa8 a8
187
+
188
+ #ifdef CONFIG_MMU
189
+ / * l32e can 't be used here even when it' s available. * /
190
+ / * TODO access_ok(a3) could be used here * /
191
+ j .Linvalid_instruction
192
+ #endif
193
+ l32i a5 , a3 , 0
194
+ l32i a6 , a3 , 4
195
+ __src_b a3 , a5 , a6 # a3 has the data word
196
+
197
+ #if XCHAL_HAVE_DENSITY
198
+ addi a7 , a7 , 2 # increment PC (assume 16 - bit insn)
199
+ _beqi a0 , OP0_L32I_N , .Lload_w# l32i.n: jump
200
+ addi a7 , a7 , 1
201
+ #else
202
+ addi a7 , a7 , 3
203
+ #endif
204
+
205
+ extui a5 , a4 , INSN_OP1 , 4
206
+ _beqi a5 , OP1_L32I , .Lload_w
207
+ bnei a5 , OP1_L8UI , .Lload16
208
+ extui a3 , a3 , 0 , 8
209
+ j .Lload_w
210
+
211
+ ENDPROC(fast_load_store)
212
+ #endif
213
+
214
+ / *
215
+ * Entry condition:
216
+ *
217
+ * a0: trashed , original value saved on stack (PT_AREG0)
218
+ * a1: a1
219
+ * a2: new stack pointer , original in DEPC
220
+ * a3: a3
221
+ * depc: a2 , original value saved on stack (PT_DEPC)
222
+ * excsave_1: dispatch table
223
+ *
224
+ * PT_DEPC >= VALID_DOUBLE_EXCEPTION_ADDRESS: double exception , DEPC
225
+ * < VALID_DOUBLE_EXCEPTION_ADDRESS: regular exception
226
+ * /
227
+
228
+ #ifdef ANY_EXCEPTION_HANDLER
158
229
ENTRY(fast_unaligned)
159
230
231
+ #if XCHAL_UNALIGNED_LOAD_EXCEPTION || XCHAL_UNALIGNED_STORE_EXCEPTION
232
+
160
233
call0 .Lsave_and_load_instruction
161
234
162
235
/ * Analyze the instruction (load or store?). * /
@@ -171,12 +244,17 @@ ENTRY(fast_unaligned)
171
244
/ * 'store indicator bit' not set , jump * /
172
245
_bbci.l a4 , OP1_SI_BIT + INSN_OP1 , .Lload
173
246
247
+ #endif
248
+ #if XCHAL_UNALIGNED_STORE_EXCEPTION
249
+
174
250
/ * Store: Jump to table entry to get the value in the source register. * /
175
251
176
252
.Lstore:movi a5 , .Lstore_table # table
177
253
extui a6 , a4 , INSN_T , 4 # get source register
178
254
addx8 a5 , a6 , a5
179
255
jx a5 # jump into table
256
+ #endif
257
+ #if XCHAL_UNALIGNED_LOAD_EXCEPTION
180
258
181
259
/ * Load: Load memory address. * /
182
260
@@ -207,7 +285,9 @@ ENTRY(fast_unaligned)
207
285
208
286
extui a5 , a4 , INSN_OP1 , 4
209
287
_beqi a5 , OP1_L32I , .Lload_w # l32i: jump
210
-
288
+ #endif
289
+ #ifdef LOAD_EXCEPTION_HANDLER
290
+ .Lload16:
211
291
extui a3 , a3 , 0 , 16 # extract lower 16 bits
212
292
_beqi a5 , OP1_L16UI , .Lload_w
213
293
addi a5 , a5 , - OP1_L16SI
@@ -247,7 +327,8 @@ ENTRY(fast_unaligned)
247
327
mov a13 , a3 ; _j .Lexit; .align 8
248
328
mov a14 , a3 ; _j .Lexit; .align 8
249
329
mov a15 , a3 ; _j .Lexit; .align 8
250
-
330
+ #endif
331
+ #if XCHAL_UNALIGNED_STORE_EXCEPTION
251
332
.Lstore_table:
252
333
l32i a3 , a2 , PT_AREG0 ; _j .Lstore_w; .align 8
253
334
mov a3 , a1 ; _j .Lstore_w; .align 8 # fishy??
@@ -265,7 +346,9 @@ ENTRY(fast_unaligned)
265
346
mov a3 , a13 ; _j .Lstore_w; .align 8
266
347
mov a3 , a14 ; _j .Lstore_w; .align 8
267
348
mov a3 , a15 ; _j .Lstore_w; .align 8
349
+ #endif
268
350
351
+ #ifdef ANY_EXCEPTION_HANDLER
269
352
/ * We cannot handle this exception. * /
270
353
271
354
. extern _kernel_exception
@@ -294,6 +377,8 @@ ENTRY(fast_unaligned)
294
377
295
378
2 : movi a0 , _user_exception
296
379
jx a0
380
+ #endif
381
+ #if XCHAL_UNALIGNED_STORE_EXCEPTION
297
382
298
383
# a7: instruction pointer , a4: instruction , a3: value
299
384
.Lstore_w:
@@ -358,7 +443,8 @@ ENTRY(fast_unaligned)
358
443
#else
359
444
s32i a6 , a4 , 4
360
445
#endif
361
-
446
+ #endif
447
+ #ifdef ANY_EXCEPTION_HANDLER
362
448
.Lexit:
363
449
#if XCHAL_HAVE_LOOPS
364
450
rsr a4 , lend # check if we reached LEND
@@ -453,7 +539,7 @@ ENTRY(fast_unaligned)
453
539
__src_b a4 , a4 , a5 # a4 has the instruction
454
540
455
541
ret
456
-
542
+ #endif
457
543
ENDPROC(fast_unaligned)
458
544
459
545
ENTRY(fast_unaligned_fixup)
@@ -490,5 +576,4 @@ ENTRY(fast_unaligned_fixup)
490
576
jx a0
491
577
492
578
ENDPROC(fast_unaligned_fixup)
493
-
494
- #endif / * XCHAL_UNALIGNED_LOAD_EXCEPTION || XCHAL_UNALIGNED_STORE_EXCEPTION * /
579
+ #endif
0 commit comments