coreasm.h 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526
  1. #ifndef XTENSA_COREASM_H
  2. #define XTENSA_COREASM_H
  3. /*
  4. * THIS FILE IS GENERATED -- DO NOT MODIFY BY HAND
  5. *
  6. * include/asm-xtensa/xtensa/coreasm.h -- assembler-specific
  7. * definitions that depend on CORE configuration.
  8. *
  9. * Source for configuration-independent binaries (which link in a
  10. * configuration-specific HAL library) must NEVER include this file.
  11. * It is perfectly normal, however, for the HAL itself to include this
  12. * file.
  13. *
  14. * This file must NOT include xtensa/config/system.h. Any assembler
  15. * header file that depends on system information should likely go in
  16. * a new systemasm.h (or sysasm.h) header file.
  17. *
  18. * NOTE: macro beqi32 is NOT configuration-dependent, and is placed
  19. * here til we will have configuration-independent header file.
  20. *
  21. * This file is subject to the terms and conditions of the GNU General
  22. * Public License. See the file "COPYING" in the main directory of
  23. * this archive for more details.
  24. *
  25. * Copyright (C) 2002 Tensilica Inc.
  26. */
  27. #include <xtensa/config/core.h>
  28. #include <xtensa/config/specreg.h>
  29. /*
  30. * Assembly-language specific definitions (assembly macros, etc.).
  31. */
  32. /*----------------------------------------------------------------------
  33. * find_ms_setbit
  34. *
  35. * This macro finds the most significant bit that is set in <as>
  36. * and return its index + <base> in <ad>, or <base> - 1 if <as> is zero.
  37. * The index counts starting at zero for the lsbit, so the return
  38. * value ranges from <base>-1 (no bit set) to <base>+31 (msbit set).
  39. *
  40. * Parameters:
  41. * <ad> destination address register (any register)
  42. * <as> source address register
  43. * <at> temporary address register (must be different than <as>)
  44. * <base> constant value added to result (usually 0 or 1)
  45. * On entry:
  46. * <ad> = undefined if different than <as>
  47. * <as> = value whose most significant set bit is to be found
  48. * <at> = undefined
  49. * no other registers are used by this macro.
  50. * On exit:
  51. * <ad> = <base> + index of msbit set in original <as>,
  52. * = <base> - 1 if original <as> was zero.
  53. * <as> clobbered (if not <ad>)
  54. * <at> clobbered (if not <ad>)
  55. * Example:
  56. * find_ms_setbit a0, a4, a0, 0 -- return in a0 index of msbit set in a4
  57. */
  58. .macro find_ms_setbit ad, as, at, base
  59. #if XCHAL_HAVE_NSA
  60. movi \at, 31+\base
  61. nsau \as, \as // get index of \as, numbered from msbit (32 if absent)
  62. sub \ad, \at, \as // get numbering from lsbit (0..31, -1 if absent)
  63. #else /* XCHAL_HAVE_NSA */
  64. movi \at, \base // start with result of 0 (point to lsbit of 32)
  65. beqz \as, 2f // special case for zero argument: return -1
  66. bltui \as, 0x10000, 1f // is it one of the 16 lsbits? (if so, check lower 16 bits)
  67. addi \at, \at, 16 // no, increment result to upper 16 bits (of 32)
  68. //srli \as, \as, 16 // check upper half (shift right 16 bits)
  69. extui \as, \as, 16, 16 // check upper half (shift right 16 bits)
  70. 1: bltui \as, 0x100, 1f // is it one of the 8 lsbits? (if so, check lower 8 bits)
  71. addi \at, \at, 8 // no, increment result to upper 8 bits (of 16)
  72. srli \as, \as, 8 // shift right to check upper 8 bits
  73. 1: bltui \as, 0x10, 1f // is it one of the 4 lsbits? (if so, check lower 4 bits)
  74. addi \at, \at, 4 // no, increment result to upper 4 bits (of 8)
  75. srli \as, \as, 4 // shift right 4 bits to check upper half
  76. 1: bltui \as, 0x4, 1f // is it one of the 2 lsbits? (if so, check lower 2 bits)
  77. addi \at, \at, 2 // no, increment result to upper 2 bits (of 4)
  78. srli \as, \as, 2 // shift right 2 bits to check upper half
  79. 1: bltui \as, 0x2, 1f // is it the lsbit?
  80. addi \at, \at, 2 // no, increment result to upper bit (of 2)
  81. 2: addi \at, \at, -1 // (from just above: add 1; from beqz: return -1)
  82. //srli \as, \as, 1
  83. 1: // done! \at contains index of msbit set (or -1 if none set)
  84. .if 0x\ad - 0x\at // destination different than \at ? (works because regs are a0-a15)
  85. mov \ad, \at // then move result to \ad
  86. .endif
  87. #endif /* XCHAL_HAVE_NSA */
  88. .endm // find_ms_setbit
  89. /*----------------------------------------------------------------------
  90. * find_ls_setbit
  91. *
  92. * This macro finds the least significant bit that is set in <as>,
  93. * and return its index in <ad>.
  94. * Usage is the same as for the find_ms_setbit macro.
  95. * Example:
  96. * find_ls_setbit a0, a4, a0, 0 -- return in a0 index of lsbit set in a4
  97. */
  98. .macro find_ls_setbit ad, as, at, base
  99. neg \at, \as // keep only the least-significant bit that is set...
  100. and \as, \at, \as // ... in \as
  101. find_ms_setbit \ad, \as, \at, \base
  102. .endm // find_ls_setbit
  103. /*----------------------------------------------------------------------
  104. * find_ls_one
  105. *
  106. * Same as find_ls_setbit with base zero.
  107. * Source (as) and destination (ad) registers must be different.
  108. * Provided for backward compatibility.
  109. */
  110. .macro find_ls_one ad, as
  111. find_ls_setbit \ad, \as, \ad, 0
  112. .endm // find_ls_one
  113. /*----------------------------------------------------------------------
  114. * floop, floopnez, floopgtz, floopend
  115. *
  116. * These macros are used for fast inner loops that
  117. * work whether or not the Loops options is configured.
  118. * If the Loops option is configured, they simply use
  119. * the zero-overhead LOOP instructions; otherwise
  120. * they use explicit decrement and branch instructions.
  121. *
  122. * They are used in pairs, with floop, floopnez or floopgtz
  123. * at the beginning of the loop, and floopend at the end.
  124. *
  125. * Each pair of loop macro calls must be given the loop count
  126. * address register and a unique label for that loop.
  127. *
  128. * Example:
  129. *
  130. * movi a3, 16 // loop 16 times
  131. * floop a3, myloop1
  132. * :
  133. * bnez a7, end1 // exit loop if a7 != 0
  134. * :
  135. * floopend a3, myloop1
  136. * end1:
  137. *
  138. * Like the LOOP instructions, these macros cannot be
  139. * nested, must include at least one instruction,
  140. * cannot call functions inside the loop, etc.
  141. * The loop can be exited by jumping to the instruction
  142. * following floopend (or elsewhere outside the loop),
  143. * or continued by jumping to a NOP instruction placed
  144. * immediately before floopend.
  145. *
  146. * Unlike LOOP instructions, the register passed to floop*
  147. * cannot be used inside the loop, because it is used as
  148. * the loop counter if the Loops option is not configured.
  149. * And its value is undefined after exiting the loop.
  150. * And because the loop counter register is active inside
  151. * the loop, you can't easily use this construct to loop
  152. * across a register file using ROTW as you might with LOOP
  153. * instructions, unless you copy the loop register along.
  154. */
  155. /* Named label version of the macros: */
  156. .macro floop ar, endlabel
  157. floop_ \ar, .Lfloopstart_\endlabel, .Lfloopend_\endlabel
  158. .endm
  159. .macro floopnez ar, endlabel
  160. floopnez_ \ar, .Lfloopstart_\endlabel, .Lfloopend_\endlabel
  161. .endm
  162. .macro floopgtz ar, endlabel
  163. floopgtz_ \ar, .Lfloopstart_\endlabel, .Lfloopend_\endlabel
  164. .endm
  165. .macro floopend ar, endlabel
  166. floopend_ \ar, .Lfloopstart_\endlabel, .Lfloopend_\endlabel
  167. .endm
  168. /* Numbered local label version of the macros: */
  169. #if 0 /*UNTESTED*/
  170. .macro floop89 ar
  171. floop_ \ar, 8, 9f
  172. .endm
  173. .macro floopnez89 ar
  174. floopnez_ \ar, 8, 9f
  175. .endm
  176. .macro floopgtz89 ar
  177. floopgtz_ \ar, 8, 9f
  178. .endm
  179. .macro floopend89 ar
  180. floopend_ \ar, 8b, 9
  181. .endm
  182. #endif /*0*/
  183. /* Underlying version of the macros: */
  184. .macro floop_ ar, startlabel, endlabelref
  185. .ifdef _infloop_
  186. .if _infloop_
  187. .err // Error: floop cannot be nested
  188. .endif
  189. .endif
  190. .set _infloop_, 1
  191. #if XCHAL_HAVE_LOOPS
  192. loop \ar, \endlabelref
  193. #else /* XCHAL_HAVE_LOOPS */
  194. \startlabel:
  195. addi \ar, \ar, -1
  196. #endif /* XCHAL_HAVE_LOOPS */
  197. .endm // floop_
  198. .macro floopnez_ ar, startlabel, endlabelref
  199. .ifdef _infloop_
  200. .if _infloop_
  201. .err // Error: floopnez cannot be nested
  202. .endif
  203. .endif
  204. .set _infloop_, 1
  205. #if XCHAL_HAVE_LOOPS
  206. loopnez \ar, \endlabelref
  207. #else /* XCHAL_HAVE_LOOPS */
  208. beqz \ar, \endlabelref
  209. \startlabel:
  210. addi \ar, \ar, -1
  211. #endif /* XCHAL_HAVE_LOOPS */
  212. .endm // floopnez_
  213. .macro floopgtz_ ar, startlabel, endlabelref
  214. .ifdef _infloop_
  215. .if _infloop_
  216. .err // Error: floopgtz cannot be nested
  217. .endif
  218. .endif
  219. .set _infloop_, 1
  220. #if XCHAL_HAVE_LOOPS
  221. loopgtz \ar, \endlabelref
  222. #else /* XCHAL_HAVE_LOOPS */
  223. bltz \ar, \endlabelref
  224. beqz \ar, \endlabelref
  225. \startlabel:
  226. addi \ar, \ar, -1
  227. #endif /* XCHAL_HAVE_LOOPS */
  228. .endm // floopgtz_
  229. .macro floopend_ ar, startlabelref, endlabel
  230. .ifndef _infloop_
  231. .err // Error: floopend without matching floopXXX
  232. .endif
  233. .ifeq _infloop_
  234. .err // Error: floopend without matching floopXXX
  235. .endif
  236. .set _infloop_, 0
  237. #if ! XCHAL_HAVE_LOOPS
  238. bnez \ar, \startlabelref
  239. #endif /* XCHAL_HAVE_LOOPS */
  240. \endlabel:
  241. .endm // floopend_
  242. /*----------------------------------------------------------------------
  243. * crsil -- conditional RSIL (read/set interrupt level)
  244. *
  245. * Executes the RSIL instruction if it exists, else just reads PS.
  246. * The RSIL instruction does not exist in the new exception architecture
  247. * if the interrupt option is not selected.
  248. */
  249. .macro crsil ar, newlevel
  250. #if XCHAL_HAVE_OLD_EXC_ARCH || XCHAL_HAVE_INTERRUPTS
  251. rsil \ar, \newlevel
  252. #else
  253. rsr \ar, PS
  254. #endif
  255. .endm // crsil
  256. /*----------------------------------------------------------------------
  257. * window_spill{4,8,12}
  258. *
  259. * These macros spill callers' register windows to the stack.
  260. * They work for both privileged and non-privileged tasks.
  261. * Must be called from a windowed ABI context, eg. within
  262. * a windowed ABI function (ie. valid stack frame, window
  263. * exceptions enabled, not in exception mode, etc).
  264. *
  265. * This macro requires a single invocation of the window_spill_common
  266. * macro in the same assembly unit and section.
  267. *
  268. * Note that using window_spill{4,8,12} macros is more efficient
  269. * than calling a function implemented using window_spill_function,
  270. * because the latter needs extra code to figure out the size of
  271. * the call to the spilling function.
  272. *
  273. * Example usage:
  274. *
  275. * .text
  276. * .align 4
  277. * .global some_function
  278. * .type some_function,@function
  279. * some_function:
  280. * entry a1, 16
  281. * :
  282. * :
  283. *
  284. * window_spill4 // spill windows of some_function's callers; preserves a0..a3 only;
  285. * // to use window_spill{8,12} in this example function we'd have
  286. * // to increase space allocated by the entry instruction, because
  287. * // 16 bytes only allows call4; 32 or 48 bytes (+locals) are needed
  288. * // for call8/window_spill8 or call12/window_spill12 respectively.
  289. * :
  290. *
  291. * retw
  292. *
  293. * window_spill_common // instantiates code used by window_spill4
  294. *
  295. *
  296. * On entry:
  297. * none (if window_spill4)
  298. * stack frame has enough space allocated for call8 (if window_spill8)
  299. * stack frame has enough space allocated for call12 (if window_spill12)
  300. * On exit:
  301. * a4..a15 clobbered (if window_spill4)
  302. * a8..a15 clobbered (if window_spill8)
  303. * a12..a15 clobbered (if window_spill12)
  304. * no caller windows are in live registers
  305. */
  306. .macro window_spill4
  307. #if XCHAL_HAVE_WINDOWED
  308. # if XCHAL_NUM_AREGS == 16
  309. movi a15, 0 // for 16-register files, no need to call to reach the end
  310. # elif XCHAL_NUM_AREGS == 32
  311. call4 .L__wdwspill_assist28 // call deep enough to clear out any live callers
  312. # elif XCHAL_NUM_AREGS == 64
  313. call4 .L__wdwspill_assist60 // call deep enough to clear out any live callers
  314. # endif
  315. #endif
  316. .endm // window_spill4
  317. .macro window_spill8
  318. #if XCHAL_HAVE_WINDOWED
  319. # if XCHAL_NUM_AREGS == 16
  320. movi a15, 0 // for 16-register files, no need to call to reach the end
  321. # elif XCHAL_NUM_AREGS == 32
  322. call8 .L__wdwspill_assist24 // call deep enough to clear out any live callers
  323. # elif XCHAL_NUM_AREGS == 64
  324. call8 .L__wdwspill_assist56 // call deep enough to clear out any live callers
  325. # endif
  326. #endif
  327. .endm // window_spill8
  328. .macro window_spill12
  329. #if XCHAL_HAVE_WINDOWED
  330. # if XCHAL_NUM_AREGS == 16
  331. movi a15, 0 // for 16-register files, no need to call to reach the end
  332. # elif XCHAL_NUM_AREGS == 32
  333. call12 .L__wdwspill_assist20 // call deep enough to clear out any live callers
  334. # elif XCHAL_NUM_AREGS == 64
  335. call12 .L__wdwspill_assist52 // call deep enough to clear out any live callers
  336. # endif
  337. #endif
  338. .endm // window_spill12
  339. /*----------------------------------------------------------------------
  340. * window_spill_function
  341. *
  342. * This macro outputs a function that will spill its caller's callers'
  343. * register windows to the stack. Eg. it could be used to implement
  344. * a version of xthal_window_spill() that works in non-privileged tasks.
  345. * This works for both privileged and non-privileged tasks.
  346. *
  347. * Typical usage:
  348. *
  349. * .text
  350. * .align 4
  351. * .global my_spill_function
  352. * .type my_spill_function,@function
  353. * my_spill_function:
  354. * window_spill_function
  355. *
  356. * On entry to resulting function:
  357. * none
  358. * On exit from resulting function:
  359. * none (no caller windows are in live registers)
  360. */
  361. .macro window_spill_function
  362. #if XCHAL_HAVE_WINDOWED
  363. # if XCHAL_NUM_AREGS == 32
  364. entry sp, 48
  365. bbci.l a0, 31, 1f // branch if called with call4
  366. bbsi.l a0, 30, 2f // branch if called with call12
  367. call8 .L__wdwspill_assist16 // called with call8, only need another 8
  368. retw
  369. 1: call12 .L__wdwspill_assist16 // called with call4, only need another 12
  370. retw
  371. 2: call4 .L__wdwspill_assist16 // called with call12, only need another 4
  372. retw
  373. # elif XCHAL_NUM_AREGS == 64
  374. entry sp, 48
  375. bbci.l a0, 31, 1f // branch if called with call4
  376. bbsi.l a0, 30, 2f // branch if called with call12
  377. call4 .L__wdwspill_assist52 // called with call8, only need a call4
  378. retw
  379. 1: call8 .L__wdwspill_assist52 // called with call4, only need a call8
  380. retw
  381. 2: call12 .L__wdwspill_assist40 // called with call12, can skip a call12
  382. retw
  383. # elif XCHAL_NUM_AREGS == 16
  384. entry sp, 16
  385. bbci.l a0, 31, 1f // branch if called with call4
  386. bbsi.l a0, 30, 2f // branch if called with call12
  387. movi a7, 0 // called with call8
  388. retw
  389. 1: movi a11, 0 // called with call4
  390. 2: retw // if called with call12, everything already spilled
  391. // movi a15, 0 // trick to spill all but the direct caller
  392. // j 1f
  393. // // The entry instruction is magical in the assembler (gets auto-aligned)
  394. // // so we have to jump to it to avoid falling through the padding.
  395. // // We need entry/retw to know where to return.
  396. //1: entry sp, 16
  397. // retw
  398. # else
  399. # error "unrecognized address register file size"
  400. # endif
  401. #endif /* XCHAL_HAVE_WINDOWED */
  402. window_spill_common
  403. .endm // window_spill_function
  404. /*----------------------------------------------------------------------
  405. * window_spill_common
  406. *
  407. * Common code used by any number of invocations of the window_spill##
  408. * and window_spill_function macros.
  409. *
  410. * Must be instantiated exactly once within a given assembly unit,
  411. * within call/j range of and same section as window_spill##
  412. * macro invocations for that assembly unit.
  413. * (Is automatically instantiated by the window_spill_function macro.)
  414. */
  415. .macro window_spill_common
  416. #if XCHAL_HAVE_WINDOWED && (XCHAL_NUM_AREGS == 32 || XCHAL_NUM_AREGS == 64)
  417. .ifndef .L__wdwspill_defined
  418. # if XCHAL_NUM_AREGS >= 64
  419. .L__wdwspill_assist60:
  420. entry sp, 32
  421. call8 .L__wdwspill_assist52
  422. retw
  423. .L__wdwspill_assist56:
  424. entry sp, 16
  425. call4 .L__wdwspill_assist52
  426. retw
  427. .L__wdwspill_assist52:
  428. entry sp, 48
  429. call12 .L__wdwspill_assist40
  430. retw
  431. .L__wdwspill_assist40:
  432. entry sp, 48
  433. call12 .L__wdwspill_assist28
  434. retw
  435. # endif
  436. .L__wdwspill_assist28:
  437. entry sp, 48
  438. call12 .L__wdwspill_assist16
  439. retw
  440. .L__wdwspill_assist24:
  441. entry sp, 32
  442. call8 .L__wdwspill_assist16
  443. retw
  444. .L__wdwspill_assist20:
  445. entry sp, 16
  446. call4 .L__wdwspill_assist16
  447. retw
  448. .L__wdwspill_assist16:
  449. entry sp, 16
  450. movi a15, 0
  451. retw
  452. .set .L__wdwspill_defined, 1
  453. .endif
  454. #endif /* XCHAL_HAVE_WINDOWED with 32 or 64 aregs */
  455. .endm // window_spill_common
  456. /*----------------------------------------------------------------------
  457. * beqi32
  458. *
  459. * macro implements version of beqi for arbitrary 32-bit immidiate value
  460. *
  461. * beqi32 ax, ay, imm32, label
  462. *
  463. * Compares value in register ax with imm32 value and jumps to label if
  464. * equal. Clobberes register ay if needed
  465. *
  466. */
  467. .macro beqi32 ax, ay, imm, label
  468. .ifeq ((\imm-1) & ~7) // 1..8 ?
  469. beqi \ax, \imm, \label
  470. .else
  471. .ifeq (\imm+1) // -1 ?
  472. beqi \ax, \imm, \label
  473. .else
  474. .ifeq (\imm) // 0 ?
  475. beqz \ax, \label
  476. .else
  477. // We could also handle immediates 10,12,16,32,64,128,256
  478. // but it would be a long macro...
  479. movi \ay, \imm
  480. beq \ax, \ay, \label
  481. .endif
  482. .endif
  483. .endif
  484. .endm // beqi32
  485. #endif /*XTENSA_COREASM_H*/