|  | /* | 
|  | * include/asm-xtensa/asmmacro.h | 
|  | * | 
|  | * This file is subject to the terms and conditions of the GNU General Public | 
|  | * License.  See the file "COPYING" in the main directory of this archive | 
|  | * for more details. | 
|  | * | 
|  | * Copyright (C) 2005 Tensilica Inc. | 
|  | */ | 
|  |  | 
|  | #ifndef _XTENSA_ASMMACRO_H | 
|  | #define _XTENSA_ASMMACRO_H | 
|  |  | 
|  | #include <asm/variant/core.h> | 
|  |  | 
|  | /* | 
|  | * Some little helpers for loops. Use zero-overhead-loops | 
|  | * where applicable and if supported by the processor. | 
|  | * | 
|  | * __loopi ar, at, size, inc | 
|  | *         ar	register initialized with the start address | 
|  | *	   at	scratch register used by macro | 
|  | *	   size	size immediate value | 
|  | *	   inc	increment | 
|  | * | 
|  | * __loops ar, as, at, inc_log2[, mask_log2][, cond][, ncond] | 
|  | *	   ar	register initialized with the start address | 
|  | *	   as	register initialized with the size | 
|  | *	   at	scratch register use by macro | 
|  | *	   inc_log2	increment [in log2] | 
|  | *	   mask_log2	mask [in log2] | 
|  | *	   cond		true condition (used in loop'cond') | 
|  | *	   ncond	false condition (used in b'ncond') | 
|  | * | 
|  | * __loop  as | 
|  | *	   restart loop. 'as' register must not have been modified! | 
|  | * | 
|  | * __endla ar, at, incr | 
|  | *	   ar	start address (modified) | 
|  | *	   as	scratch register used by macro | 
|  | *	   inc	increment | 
|  | */ | 
|  |  | 
|  | /* | 
|  | * loop for given size as immediate | 
|  | */ | 
|  |  | 
|  | .macro	__loopi ar, at, size, incr | 
|  |  | 
|  | #if XCHAL_HAVE_LOOPS | 
|  | movi	\at, ((\size + \incr - 1) / (\incr)) | 
|  | loop	\at, 99f | 
|  | #else | 
|  | addi	\at, \ar, \size | 
|  | 98: | 
|  | #endif | 
|  |  | 
|  | .endm | 
|  |  | 
|  | /* | 
|  | * loop for given size in register | 
|  | */ | 
|  |  | 
|  | .macro	__loops	ar, as, at, incr_log2, mask_log2, cond, ncond | 
|  |  | 
|  | #if XCHAL_HAVE_LOOPS | 
|  | .ifgt \incr_log2 - 1 | 
|  | addi	\at, \as, (1 << \incr_log2) - 1 | 
|  | .ifnc \mask_log2, | 
|  | extui	\at, \at, \incr_log2, \mask_log2 | 
|  | .else | 
|  | srli	\at, \at, \incr_log2 | 
|  | .endif | 
|  | .endif | 
|  | loop\cond	\at, 99f | 
|  | #else | 
|  | .ifnc \mask_log2, | 
|  | extui	\at, \as, \incr_log2, \mask_log2 | 
|  | .else | 
|  | .ifnc \ncond, | 
|  | srli	\at, \as, \incr_log2 | 
|  | .endif | 
|  | .endif | 
|  | .ifnc \ncond, | 
|  | b\ncond	\at, 99f | 
|  |  | 
|  | .endif | 
|  | .ifnc \mask_log2, | 
|  | slli	\at, \at, \incr_log2 | 
|  | add	\at, \ar, \at | 
|  | .else | 
|  | add	\at, \ar, \as | 
|  | .endif | 
|  | #endif | 
|  | 98: | 
|  |  | 
|  | .endm | 
|  |  | 
|  | /* | 
|  | * loop from ar to ax | 
|  | */ | 
|  |  | 
|  | .macro	__loopt	ar, as, at, incr_log2 | 
|  |  | 
|  | #if XCHAL_HAVE_LOOPS | 
|  | sub	\at, \as, \ar | 
|  | .ifgt	\incr_log2 - 1 | 
|  | addi	\at, \at, (1 << \incr_log2) - 1 | 
|  | srli	\at, \at, \incr_log2 | 
|  | .endif | 
|  | loop	\at, 99f | 
|  | #else | 
|  | 98: | 
|  | #endif | 
|  |  | 
|  | .endm | 
|  |  | 
|  | /* | 
|  | * restart loop. registers must be unchanged | 
|  | */ | 
|  |  | 
|  | .macro	__loop	as | 
|  |  | 
|  | #if XCHAL_HAVE_LOOPS | 
|  | loop	\as, 99f | 
|  | #else | 
|  | 98: | 
|  | #endif | 
|  |  | 
|  | .endm | 
|  |  | 
|  | /* | 
|  | * end of loop with no increment of the address. | 
|  | */ | 
|  |  | 
|  | .macro	__endl	ar, as | 
|  | #if !XCHAL_HAVE_LOOPS | 
|  | bltu	\ar, \as, 98b | 
|  | #endif | 
|  | 99: | 
|  | .endm | 
|  |  | 
|  | /* | 
|  | * end of loop with increment of the address. | 
|  | */ | 
|  |  | 
|  | .macro	__endla	ar, as, incr | 
|  | addi	\ar, \ar, \incr | 
|  | __endl	\ar \as | 
|  | .endm | 
|  |  | 
|  |  | 
|  | #endif /* _XTENSA_ASMMACRO_H */ |