asmmacro.h 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  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, at, incr
  36. * ar start address (modified)
  37. * as scratch register used by macro
  38. * inc increment
  39. */
  40. /*
  41. * loop for given size as immediate
  42. */
  43. .macro __loopi ar, at, size, incr
  44. #if XCHAL_HAVE_LOOPS
  45. movi \at, ((\size + \incr - 1) / (\incr))
  46. loop \at, 99f
  47. #else
  48. addi \at, \ar, \size
  49. 98:
  50. #endif
  51. .endm
  52. /*
  53. * loop for given size in register
  54. */
  55. .macro __loops ar, as, at, incr_log2, mask_log2, cond, ncond
  56. #if XCHAL_HAVE_LOOPS
  57. .ifgt \incr_log2 - 1
  58. addi \at, \as, (1 << \incr_log2) - 1
  59. .ifnc \mask_log2,
  60. extui \at, \at, \incr_log2, \mask_log2
  61. .else
  62. srli \at, \at, \incr_log2
  63. .endif
  64. .endif
  65. loop\cond \at, 99f
  66. #else
  67. .ifnc \mask_log2,
  68. extui \at, \as, \incr_log2, \mask_log2
  69. .else
  70. .ifnc \ncond,
  71. srli \at, \as, \incr_log2
  72. .endif
  73. .endif
  74. .ifnc \ncond,
  75. b\ncond \at, 99f
  76. .endif
  77. .ifnc \mask_log2,
  78. slli \at, \at, \incr_log2
  79. add \at, \ar, \at
  80. .else
  81. add \at, \ar, \as
  82. .endif
  83. #endif
  84. 98:
  85. .endm
  86. /*
  87. * loop from ar to ax
  88. */
  89. .macro __loopt ar, as, at, incr_log2
  90. #if XCHAL_HAVE_LOOPS
  91. sub \at, \as, \ar
  92. .ifgt \incr_log2 - 1
  93. addi \at, \at, (1 << \incr_log2) - 1
  94. srli \at, \at, \incr_log2
  95. .endif
  96. loop \at, 99f
  97. #else
  98. 98:
  99. #endif
  100. .endm
  101. /*
  102. * restart loop. registers must be unchanged
  103. */
  104. .macro __loop as
  105. #if XCHAL_HAVE_LOOPS
  106. loop \as, 99f
  107. #else
  108. 98:
  109. #endif
  110. .endm
  111. /*
  112. * end of loop with no increment of the address.
  113. */
  114. .macro __endl ar, as
  115. #if !XCHAL_HAVE_LOOPS
  116. bltu \ar, \as, 98b
  117. #endif
  118. 99:
  119. .endm
  120. /*
  121. * end of loop with increment of the address.
  122. */
  123. .macro __endla ar, as, incr
  124. addi \ar, \ar, \incr
  125. __endl \ar \as
  126. .endm
  127. #endif /* _XTENSA_ASMMACRO_H */