2222#include <asm/asmmacro.h>
2323#include <asm/processor.h>
2424
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
2636
2737/ * First - level exception handler for unaligned exceptions.
2838 *
5868 * BE shift left / mask 0 0 X X
5969 * /
6070
61- #if XCHAL_HAVE_WINDOWED
62- #define UNALIGNED_USER_EXCEPTION
63- #endif
64-
6571#if XCHAL_HAVE_BE
6672
6773#define HWORD_START 16
103109 *
104110 * 23 0
105111 * -----------------------------
106- * res 0000 0010
112+ * L8UI xxxx xxxx 0000 ssss tttt 0010
107113 * L16UI xxxx xxxx 0001 ssss tttt 0010
108114 * L32I xxxx xxxx 0010 ssss tttt 0010
109115 * XXX 0011 ssss tttt 0010
128134
129135#define OP0_L32I_N 0x8 / * load immediate narrow * /
130136#define OP0_S32I_N 0x9 / * store immediate narrow * /
137+ #define OP0_LSAI 0x2 / * load/store * /
131138#define OP1_SI_MASK 0x4 / * OP1 bit set for stores * /
132139#define OP1_SI_BIT 2 / * OP1 bit number for stores * /
133140
141+ #define OP1_L8UI 0x0
134142#define OP1_L32I 0x2
135143#define OP1_L16UI 0x1
136144#define OP1_L16SI 0x9
155163 * /
156164
157165 .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
158229ENTRY(fast_unaligned)
159230
231+ #if XCHAL_UNALIGNED_LOAD_EXCEPTION || XCHAL_UNALIGNED_STORE_EXCEPTION
232+
160233 call0 .Lsave_and_load_instruction
161234
162235 / * Analyze the instruction (load or store?). * /
@@ -171,12 +244,17 @@ ENTRY(fast_unaligned)
171244 / * 'store indicator bit' not set , jump * /
172245 _bbci.l a4 , OP1_SI_BIT + INSN_OP1 , .Lload
173246
247+ #endif
248+ #if XCHAL_UNALIGNED_STORE_EXCEPTION
249+
174250 / * Store: Jump to table entry to get the value in the source register. * /
175251
176252.Lstore:movi a5 , .Lstore_table # table
177253 extui a6 , a4 , INSN_T , 4 # get source register
178254 addx8 a5 , a6 , a5
179255 jx a5 # jump into table
256+ #endif
257+ #if XCHAL_UNALIGNED_LOAD_EXCEPTION
180258
181259 / * Load: Load memory address. * /
182260
@@ -207,7 +285,9 @@ ENTRY(fast_unaligned)
207285
208286 extui a5 , a4 , INSN_OP1 , 4
209287 _beqi a5 , OP1_L32I , .Lload_w # l32i: jump
210-
288+ #endif
289+ #ifdef LOAD_EXCEPTION_HANDLER
290+ .Lload16:
211291 extui a3 , a3 , 0 , 16 # extract lower 16 bits
212292 _beqi a5 , OP1_L16UI , .Lload_w
213293 addi a5 , a5 , - OP1_L16SI
@@ -247,7 +327,8 @@ ENTRY(fast_unaligned)
247327 mov a13 , a3 ; _j .Lexit; .align 8
248328 mov a14 , a3 ; _j .Lexit; .align 8
249329 mov a15 , a3 ; _j .Lexit; .align 8
250-
330+ #endif
331+ #if XCHAL_UNALIGNED_STORE_EXCEPTION
251332.Lstore_table:
252333 l32i a3 , a2 , PT_AREG0 ; _j .Lstore_w; .align 8
253334 mov a3 , a1 ; _j .Lstore_w; .align 8 # fishy??
@@ -265,7 +346,9 @@ ENTRY(fast_unaligned)
265346 mov a3 , a13 ; _j .Lstore_w; .align 8
266347 mov a3 , a14 ; _j .Lstore_w; .align 8
267348 mov a3 , a15 ; _j .Lstore_w; .align 8
349+ #endif
268350
351+ #ifdef ANY_EXCEPTION_HANDLER
269352 / * We cannot handle this exception. * /
270353
271354 . extern _kernel_exception
@@ -294,6 +377,8 @@ ENTRY(fast_unaligned)
294377
2953782 : movi a0 , _user_exception
296379 jx a0
380+ #endif
381+ #if XCHAL_UNALIGNED_STORE_EXCEPTION
297382
298383 # a7: instruction pointer , a4: instruction , a3: value
299384.Lstore_w:
@@ -358,7 +443,8 @@ ENTRY(fast_unaligned)
358443#else
359444 s32i a6 , a4 , 4
360445#endif
361-
446+ #endif
447+ #ifdef ANY_EXCEPTION_HANDLER
362448.Lexit:
363449#if XCHAL_HAVE_LOOPS
364450 rsr a4 , lend # check if we reached LEND
@@ -453,7 +539,7 @@ ENTRY(fast_unaligned)
453539 __src_b a4 , a4 , a5 # a4 has the instruction
454540
455541 ret
456-
542+ #endif
457543ENDPROC(fast_unaligned)
458544
459545ENTRY(fast_unaligned_fixup)
@@ -490,5 +576,4 @@ ENTRY(fast_unaligned_fixup)
490576 jx a0
491577
492578ENDPROC(fast_unaligned_fixup)
493-
494- #endif / * XCHAL_UNALIGNED_LOAD_EXCEPTION || XCHAL_UNALIGNED_STORE_EXCEPTION * /
579+ #endif
0 commit comments