File Index
Files and directories
Sign in
FILE

asmmacro.h

File preview with syntax highlighting.

linux-6.19.14/arch/xtensa/include/asm/asmmacro.h OBJECTIVE-C
  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 <linux/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 */
~/ Read-only file preview.