123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155 |
- /*
- * 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 <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, as, incr
- * ar start address (modified)
- * as scratch register used by __loops/__loopi macros or
- * end address used by __loopt 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 as
- */
- .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 */
|