Linux kernel mirror (for testing)
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel
os
linux
1/*
2 * include/asm-xtensa/asmmacro.h
3 *
4 * This file is subject to the terms and conditions of the GNU General Public
5 * License. See the file "COPYING" in the main directory of this archive
6 * for more details.
7 *
8 * Copyright (C) 2005 Tensilica Inc.
9 */
10
11#ifndef _XTENSA_ASMMACRO_H
12#define _XTENSA_ASMMACRO_H
13
14#include <asm-generic/export.h>
15#include <asm/core.h>
16
17/*
18 * Some little helpers for loops. Use zero-overhead-loops
19 * where applicable and if supported by the processor.
20 *
21 * __loopi ar, at, size, inc
22 * ar register initialized with the start address
23 * at scratch register used by macro
24 * size size immediate value
25 * inc increment
26 *
27 * __loops ar, as, at, inc_log2[, mask_log2][, cond][, ncond]
28 * ar register initialized with the start address
29 * as register initialized with the size
30 * at scratch register use by macro
31 * inc_log2 increment [in log2]
32 * mask_log2 mask [in log2]
33 * cond true condition (used in loop'cond')
34 * ncond false condition (used in b'ncond')
35 *
36 * __loop as
37 * restart loop. 'as' register must not have been modified!
38 *
39 * __endla ar, as, incr
40 * ar start address (modified)
41 * as scratch register used by __loops/__loopi macros or
42 * end address used by __loopt macro
43 * inc increment
44 */
45
46/*
47 * loop for given size as immediate
48 */
49
50 .macro __loopi ar, at, size, incr
51
52#if XCHAL_HAVE_LOOPS
53 movi \at, ((\size + \incr - 1) / (\incr))
54 loop \at, 99f
55#else
56 addi \at, \ar, \size
57 98:
58#endif
59
60 .endm
61
62/*
63 * loop for given size in register
64 */
65
66 .macro __loops ar, as, at, incr_log2, mask_log2, cond, ncond
67
68#if XCHAL_HAVE_LOOPS
69 .ifgt \incr_log2 - 1
70 addi \at, \as, (1 << \incr_log2) - 1
71 .ifnc \mask_log2,
72 extui \at, \at, \incr_log2, \mask_log2
73 .else
74 srli \at, \at, \incr_log2
75 .endif
76 .endif
77 loop\cond \at, 99f
78#else
79 .ifnc \mask_log2,
80 extui \at, \as, \incr_log2, \mask_log2
81 .else
82 .ifnc \ncond,
83 srli \at, \as, \incr_log2
84 .endif
85 .endif
86 .ifnc \ncond,
87 b\ncond \at, 99f
88
89 .endif
90 .ifnc \mask_log2,
91 slli \at, \at, \incr_log2
92 add \at, \ar, \at
93 .else
94 add \at, \ar, \as
95 .endif
96#endif
97 98:
98
99 .endm
100
101/*
102 * loop from ar to as
103 */
104
105 .macro __loopt ar, as, at, incr_log2
106
107#if XCHAL_HAVE_LOOPS
108 sub \at, \as, \ar
109 .ifgt \incr_log2 - 1
110 addi \at, \at, (1 << \incr_log2) - 1
111 srli \at, \at, \incr_log2
112 .endif
113 loop \at, 99f
114#else
115 98:
116#endif
117
118 .endm
119
120/*
121 * restart loop. registers must be unchanged
122 */
123
124 .macro __loop as
125
126#if XCHAL_HAVE_LOOPS
127 loop \as, 99f
128#else
129 98:
130#endif
131
132 .endm
133
134/*
135 * end of loop with no increment of the address.
136 */
137
138 .macro __endl ar, as
139#if !XCHAL_HAVE_LOOPS
140 bltu \ar, \as, 98b
141#endif
142 99:
143 .endm
144
145/*
146 * end of loop with increment of the address.
147 */
148
149 .macro __endla ar, as, incr
150 addi \ar, \ar, \incr
151 __endl \ar \as
152 .endm
153
154/* Load or store instructions that may cause exceptions use the EX macro. */
155
156#define EX(handler) \
157 .section __ex_table, "a"; \
158 .word 97f, handler; \
159 .previous \
16097:
161
162
163/*
164 * Extract unaligned word that is split between two registers w0 and w1
165 * into r regardless of machine endianness. SAR must be loaded with the
166 * starting bit of the word (see __ssa8).
167 */
168
169 .macro __src_b r, w0, w1
170#ifdef __XTENSA_EB__
171 src \r, \w0, \w1
172#else
173 src \r, \w1, \w0
174#endif
175 .endm
176
177/*
178 * Load 2 lowest address bits of r into SAR for __src_b to extract unaligned
179 * word starting at r from two registers loaded from consecutive aligned
180 * addresses covering r regardless of machine endianness.
181 *
182 * r 0 1 2 3
183 * LE SAR 0 8 16 24
184 * BE SAR 32 24 16 8
185 */
186
187 .macro __ssa8 r
188#ifdef __XTENSA_EB__
189 ssa8b \r
190#else
191 ssa8l \r
192#endif
193 .endm
194
195 .macro do_nsau cnt, val, tmp, a
196#if XCHAL_HAVE_NSA
197 nsau \cnt, \val
198#else
199 mov \a, \val
200 movi \cnt, 0
201 extui \tmp, \a, 16, 16
202 bnez \tmp, 0f
203 movi \cnt, 16
204 slli \a, \a, 16
2050:
206 extui \tmp, \a, 24, 8
207 bnez \tmp, 1f
208 addi \cnt, \cnt, 8
209 slli \a, \a, 8
2101:
211 movi \tmp, __nsau_data
212 extui \a, \a, 24, 8
213 add \tmp, \tmp, \a
214 l8ui \tmp, \tmp, 0
215 add \cnt, \cnt, \tmp
216#endif /* !XCHAL_HAVE_NSA */
217 .endm
218
219 .macro do_abs dst, src, tmp
220#if XCHAL_HAVE_ABS
221 abs \dst, \src
222#else
223 neg \tmp, \src
224 movgez \tmp, \src, \src
225 mov \dst, \tmp
226#endif
227 .endm
228
229#if defined(__XTENSA_WINDOWED_ABI__)
230
231/* Assembly instructions for windowed kernel ABI. */
232#define KABI_W
233/* Assembly instructions for call0 kernel ABI (will be ignored). */
234#define KABI_C0 #
235
236#define XTENSA_FRAME_SIZE_RESERVE 16
237#define XTENSA_SPILL_STACK_RESERVE 32
238
239#define abi_entry(frame_size) \
240 entry sp, (XTENSA_FRAME_SIZE_RESERVE + \
241 (((frame_size) + XTENSA_STACK_ALIGNMENT - 1) & \
242 -XTENSA_STACK_ALIGNMENT))
243#define abi_entry_default abi_entry(0)
244
245#define abi_ret(frame_size) retw
246#define abi_ret_default retw
247
248 /* direct call */
249#define abi_call call4
250 /* indirect call */
251#define abi_callx callx4
252 /* outgoing call argument registers */
253#define abi_arg0 a6
254#define abi_arg1 a7
255#define abi_arg2 a8
256#define abi_arg3 a9
257#define abi_arg4 a10
258#define abi_arg5 a11
259 /* return value */
260#define abi_rv a6
261 /* registers preserved across call */
262#define abi_saved0 a2
263#define abi_saved1 a3
264
265 /* none of the above */
266#define abi_tmp0 a4
267#define abi_tmp1 a5
268
269#elif defined(__XTENSA_CALL0_ABI__)
270
271/* Assembly instructions for windowed kernel ABI (will be ignored). */
272#define KABI_W #
273/* Assembly instructions for call0 kernel ABI. */
274#define KABI_C0
275
276#define XTENSA_SPILL_STACK_RESERVE 0
277
278#define abi_entry(frame_size) __abi_entry (frame_size)
279
280 .macro __abi_entry frame_size
281 .ifgt \frame_size
282 addi sp, sp, -(((\frame_size) + XTENSA_STACK_ALIGNMENT - 1) & \
283 -XTENSA_STACK_ALIGNMENT)
284 .endif
285 .endm
286
287#define abi_entry_default
288
289#define abi_ret(frame_size) __abi_ret (frame_size)
290
291 .macro __abi_ret frame_size
292 .ifgt \frame_size
293 addi sp, sp, (((\frame_size) + XTENSA_STACK_ALIGNMENT - 1) & \
294 -XTENSA_STACK_ALIGNMENT)
295 .endif
296 ret
297 .endm
298
299#define abi_ret_default ret
300
301 /* direct call */
302#define abi_call call0
303 /* indirect call */
304#define abi_callx callx0
305 /* outgoing call argument registers */
306#define abi_arg0 a2
307#define abi_arg1 a3
308#define abi_arg2 a4
309#define abi_arg3 a5
310#define abi_arg4 a6
311#define abi_arg5 a7
312 /* return value */
313#define abi_rv a2
314 /* registers preserved across call */
315#define abi_saved0 a12
316#define abi_saved1 a13
317
318 /* none of the above */
319#define abi_tmp0 a8
320#define abi_tmp1 a9
321
322#else
323#error Unsupported Xtensa ABI
324#endif
325
326#if defined(USER_SUPPORT_WINDOWED)
327/* Assembly instructions for windowed user ABI. */
328#define UABI_W
329/* Assembly instructions for call0 user ABI (will be ignored). */
330#define UABI_C0 #
331#else
332/* Assembly instructions for windowed user ABI (will be ignored). */
333#define UABI_W #
334/* Assembly instructions for call0 user ABI. */
335#define UABI_C0
336#endif
337
338#define __XTENSA_HANDLER .section ".exception.text", "ax"
339
340#endif /* _XTENSA_ASMMACRO_H */