asmmacro.h 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  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. #ifndef _XTENSA_ASMMACRO_H
  11. #define _XTENSA_ASMMACRO_H
  12. #include <variant/core.h>
  13. /*
  14. * Some little helpers for loops. Use zero-overhead-loops
  15. * where applicable and if supported by the processor.
  16. *
  17. * __loopi ar, at, size, inc
  18. * ar register initialized with the start address
  19. * at scratch register used by macro
  20. * size size immediate value
  21. * inc increment
  22. *
  23. * __loops ar, as, at, inc_log2[, mask_log2][, cond][, ncond]
  24. * ar register initialized with the start address
  25. * as register initialized with the size
  26. * at scratch register use by macro
  27. * inc_log2 increment [in log2]
  28. * mask_log2 mask [in log2]
  29. * cond true condition (used in loop'cond')
  30. * ncond false condition (used in b'ncond')
  31. *
  32. * __loop as
  33. * restart loop. 'as' register must not have been modified!
  34. *
  35. * __endla ar, as, incr
  36. * ar start address (modified)
  37. * as scratch register used by __loops/__loopi macros or
  38. * end address used by __loopt macro
  39. * inc increment
  40. */
  41. /*
  42. * loop for given size as immediate
  43. */
  44. .macro __loopi ar, at, size, incr
  45. #if XCHAL_HAVE_LOOPS
  46. movi \at, ((\size + \incr - 1) / (\incr))
  47. loop \at, 99f
  48. #else
  49. addi \at, \ar, \size
  50. 98:
  51. #endif
  52. .endm
  53. /*
  54. * loop for given size in register
  55. */
  56. .macro __loops ar, as, at, incr_log2, mask_log2, cond, ncond
  57. #if XCHAL_HAVE_LOOPS
  58. .ifgt \incr_log2 - 1
  59. addi \at, \as, (1 << \incr_log2) - 1
  60. .ifnc \mask_log2,
  61. extui \at, \at, \incr_log2, \mask_log2
  62. .else
  63. srli \at, \at, \incr_log2
  64. .endif
  65. .endif
  66. loop\cond \at, 99f
  67. #else
  68. .ifnc \mask_log2,
  69. extui \at, \as, \incr_log2, \mask_log2
  70. .else
  71. .ifnc \ncond,
  72. srli \at, \as, \incr_log2
  73. .endif
  74. .endif
  75. .ifnc \ncond,
  76. b\ncond \at, 99f
  77. .endif
  78. .ifnc \mask_log2,
  79. slli \at, \at, \incr_log2
  80. add \at, \ar, \at
  81. .else
  82. add \at, \ar, \as
  83. .endif
  84. #endif
  85. 98:
  86. .endm
  87. /*
  88. * loop from ar to as
  89. */
  90. .macro __loopt ar, as, at, incr_log2
  91. #if XCHAL_HAVE_LOOPS
  92. sub \at, \as, \ar
  93. .ifgt \incr_log2 - 1
  94. addi \at, \at, (1 << \incr_log2) - 1
  95. srli \at, \at, \incr_log2
  96. .endif
  97. loop \at, 99f
  98. #else
  99. 98:
  100. #endif
  101. .endm
  102. /*
  103. * restart loop. registers must be unchanged
  104. */
  105. .macro __loop as
  106. #if XCHAL_HAVE_LOOPS
  107. loop \as, 99f
  108. #else
  109. 98:
  110. #endif
  111. .endm
  112. /*
  113. * end of loop with no increment of the address.
  114. */
  115. .macro __endl ar, as
  116. #if !XCHAL_HAVE_LOOPS
  117. bltu \ar, \as, 98b
  118. #endif
  119. 99:
  120. .endm
  121. /*
  122. * end of loop with increment of the address.
  123. */
  124. .macro __endla ar, as, incr
  125. addi \ar, \ar, \incr
  126. __endl \ar \as
  127. .endm
  128. #endif /* _XTENSA_ASMMACRO_H */