asmmacro.h 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339
  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 <asm/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. /* Load or store instructions that may cause exceptions use the EX macro. */
  129. #define EX(handler) \
  130. .section __ex_table, "a"; \
  131. .word 97f, handler; \
  132. .previous \
  133. 97:
  134. /*
  135. * Extract unaligned word that is split between two registers w0 and w1
  136. * into r regardless of machine endianness. SAR must be loaded with the
  137. * starting bit of the word (see __ssa8).
  138. */
  139. .macro __src_b r, w0, w1
  140. #ifdef __XTENSA_EB__
  141. src \r, \w0, \w1
  142. #else
  143. src \r, \w1, \w0
  144. #endif
  145. .endm
  146. /*
  147. * Load 2 lowest address bits of r into SAR for __src_b to extract unaligned
  148. * word starting at r from two registers loaded from consecutive aligned
  149. * addresses covering r regardless of machine endianness.
  150. *
  151. * r 0 1 2 3
  152. * LE SAR 0 8 16 24
  153. * BE SAR 32 24 16 8
  154. */
  155. .macro __ssa8 r
  156. #ifdef __XTENSA_EB__
  157. ssa8b \r
  158. #else
  159. ssa8l \r
  160. #endif
  161. .endm
  162. .macro do_nsau cnt, val, tmp, a
  163. #if XCHAL_HAVE_NSA
  164. nsau \cnt, \val
  165. #else
  166. mov \a, \val
  167. movi \cnt, 0
  168. extui \tmp, \a, 16, 16
  169. bnez \tmp, 0f
  170. movi \cnt, 16
  171. slli \a, \a, 16
  172. 0:
  173. extui \tmp, \a, 24, 8
  174. bnez \tmp, 1f
  175. addi \cnt, \cnt, 8
  176. slli \a, \a, 8
  177. 1:
  178. movi \tmp, __nsau_data
  179. extui \a, \a, 24, 8
  180. add \tmp, \tmp, \a
  181. l8ui \tmp, \tmp, 0
  182. add \cnt, \cnt, \tmp
  183. #endif /* !XCHAL_HAVE_NSA */
  184. .endm
  185. .macro do_abs dst, src, tmp
  186. #if XCHAL_HAVE_ABS
  187. abs \dst, \src
  188. #else
  189. neg \tmp, \src
  190. movgez \tmp, \src, \src
  191. mov \dst, \tmp
  192. #endif
  193. .endm
  194. #if defined(__XTENSA_WINDOWED_ABI__)
  195. /* Assembly instructions for windowed kernel ABI. */
  196. #define KABI_W
  197. /* Assembly instructions for call0 kernel ABI (will be ignored). */
  198. #define KABI_C0 #
  199. #define XTENSA_FRAME_SIZE_RESERVE 16
  200. #define XTENSA_SPILL_STACK_RESERVE 32
  201. #define abi_entry(frame_size) \
  202. entry sp, (XTENSA_FRAME_SIZE_RESERVE + \
  203. (((frame_size) + XTENSA_STACK_ALIGNMENT - 1) & \
  204. -XTENSA_STACK_ALIGNMENT))
  205. #define abi_entry_default abi_entry(0)
  206. #define abi_ret(frame_size) retw
  207. #define abi_ret_default retw
  208. /* direct call */
  209. #define abi_call call4
  210. /* indirect call */
  211. #define abi_callx callx4
  212. /* outgoing call argument registers */
  213. #define abi_arg0 a6
  214. #define abi_arg1 a7
  215. #define abi_arg2 a8
  216. #define abi_arg3 a9
  217. #define abi_arg4 a10
  218. #define abi_arg5 a11
  219. /* return value */
  220. #define abi_rv a6
  221. /* registers preserved across call */
  222. #define abi_saved0 a2
  223. #define abi_saved1 a3
  224. /* none of the above */
  225. #define abi_tmp0 a4
  226. #define abi_tmp1 a5
  227. #elif defined(__XTENSA_CALL0_ABI__)
  228. /* Assembly instructions for windowed kernel ABI (will be ignored). */
  229. #define KABI_W #
  230. /* Assembly instructions for call0 kernel ABI. */
  231. #define KABI_C0
  232. #define XTENSA_SPILL_STACK_RESERVE 0
  233. #define abi_entry(frame_size) __abi_entry (frame_size)
  234. .macro __abi_entry frame_size
  235. .ifgt \frame_size
  236. addi sp, sp, -(((\frame_size) + XTENSA_STACK_ALIGNMENT - 1) & \
  237. -XTENSA_STACK_ALIGNMENT)
  238. .endif
  239. .endm
  240. #define abi_entry_default
  241. #define abi_ret(frame_size) __abi_ret (frame_size)
  242. .macro __abi_ret frame_size
  243. .ifgt \frame_size
  244. addi sp, sp, (((\frame_size) + XTENSA_STACK_ALIGNMENT - 1) & \
  245. -XTENSA_STACK_ALIGNMENT)
  246. .endif
  247. ret
  248. .endm
  249. #define abi_ret_default ret
  250. /* direct call */
  251. #define abi_call call0
  252. /* indirect call */
  253. #define abi_callx callx0
  254. /* outgoing call argument registers */
  255. #define abi_arg0 a2
  256. #define abi_arg1 a3
  257. #define abi_arg2 a4
  258. #define abi_arg3 a5
  259. #define abi_arg4 a6
  260. #define abi_arg5 a7
  261. /* return value */
  262. #define abi_rv a2
  263. /* registers preserved across call */
  264. #define abi_saved0 a12
  265. #define abi_saved1 a13
  266. /* none of the above */
  267. #define abi_tmp0 a8
  268. #define abi_tmp1 a9
  269. #else
  270. #error Unsupported Xtensa ABI
  271. #endif
  272. #if defined(USER_SUPPORT_WINDOWED)
  273. /* Assembly instructions for windowed user ABI. */
  274. #define UABI_W
  275. /* Assembly instructions for call0 user ABI (will be ignored). */
  276. #define UABI_C0 #
  277. #else
  278. /* Assembly instructions for windowed user ABI (will be ignored). */
  279. #define UABI_W #
  280. /* Assembly instructions for call0 user ABI. */
  281. #define UABI_C0
  282. #endif
  283. #define __XTENSA_HANDLER .section ".exception.text", "ax"
  284. #endif /* _XTENSA_ASMMACRO_H */