📄 coreasm.h
字号:
bnez \ar, \startlabelref#endif /* XCHAL_HAVE_LOOPS */\endlabel: .endm // floopend_/*---------------------------------------------------------------------- * crsil -- conditional RSIL (read/set interrupt level) * * Executes the RSIL instruction if it exists, else just reads PS. * The RSIL instruction does not exist in the new exception architecture * if the interrupt option is not selected. */ .macro crsil ar, newlevel#if XCHAL_HAVE_OLD_EXC_ARCH || XCHAL_HAVE_INTERRUPTS rsil \ar, \newlevel#else rsr \ar, PS#endif .endm // crsil/*---------------------------------------------------------------------- * window_spill{4,8,12} * * These macros spill callers' register windows to the stack. * They work for both privileged and non-privileged tasks. * Must be called from a windowed ABI context, eg. within * a windowed ABI function (ie. valid stack frame, window * exceptions enabled, not in exception mode, etc). * * This macro requires a single invocation of the window_spill_common * macro in the same assembly unit and section. * * Note that using window_spill{4,8,12} macros is more efficient * than calling a function implemented using window_spill_function, * because the latter needs extra code to figure out the size of * the call to the spilling function. * * Example usage: * * .text * .align 4 * .global some_function * .type some_function,@function * some_function: * entry a1, 16 * : * : * * window_spill4 // spill windows of some_function's callers; preserves a0..a3 only; * // to use window_spill{8,12} in this example function we'd have * // to increase space allocated by the entry instruction, because * // 16 bytes only allows call4; 32 or 48 bytes (+locals) are needed * // for call8/window_spill8 or call12/window_spill12 respectively. * : * * retw * * window_spill_common // instantiates code used by window_spill4 * * * On entry: * none (if window_spill4) * stack frame has enough space allocated for call8 (if window_spill8) * stack frame has enough space allocated for call12 (if window_spill12) * On exit: * a4..a15 clobbered (if window_spill4) * a8..a15 clobbered (if window_spill8) * a12..a15 clobbered (if window_spill12) * no caller windows are in live registers */ .macro window_spill4#if XCHAL_HAVE_WINDOWED# if XCHAL_NUM_AREGS == 16 movi a15, 0 // for 16-register files, no need to call to reach the end# elif XCHAL_NUM_AREGS == 32 call4 .L__wdwspill_assist28 // call deep enough to clear out any live callers# elif XCHAL_NUM_AREGS == 64 call4 .L__wdwspill_assist60 // call deep enough to clear out any live callers# endif#endif .endm // window_spill4 .macro window_spill8#if XCHAL_HAVE_WINDOWED# if XCHAL_NUM_AREGS == 16 movi a15, 0 // for 16-register files, no need to call to reach the end# elif XCHAL_NUM_AREGS == 32 call8 .L__wdwspill_assist24 // call deep enough to clear out any live callers# elif XCHAL_NUM_AREGS == 64 call8 .L__wdwspill_assist56 // call deep enough to clear out any live callers# endif#endif .endm // window_spill8 .macro window_spill12#if XCHAL_HAVE_WINDOWED# if XCHAL_NUM_AREGS == 16 movi a15, 0 // for 16-register files, no need to call to reach the end# elif XCHAL_NUM_AREGS == 32 call12 .L__wdwspill_assist20 // call deep enough to clear out any live callers# elif XCHAL_NUM_AREGS == 64 call12 .L__wdwspill_assist52 // call deep enough to clear out any live callers# endif#endif .endm // window_spill12/*---------------------------------------------------------------------- * window_spill_function * * This macro outputs a function that will spill its caller's callers' * register windows to the stack. Eg. it could be used to implement * a version of xthal_window_spill() that works in non-privileged tasks. * This works for both privileged and non-privileged tasks. * * Typical usage: * * .text * .align 4 * .global my_spill_function * .type my_spill_function,@function * my_spill_function: * window_spill_function * * On entry to resulting function: * none * On exit from resulting function: * none (no caller windows are in live registers) */ .macro window_spill_function#if XCHAL_HAVE_WINDOWED# if XCHAL_NUM_AREGS == 32 entry sp, 48 bbci.l a0, 31, 1f // branch if called with call4 bbsi.l a0, 30, 2f // branch if called with call12 call8 .L__wdwspill_assist16 // called with call8, only need another 8 retw1: call12 .L__wdwspill_assist16 // called with call4, only need another 12 retw2: call4 .L__wdwspill_assist16 // called with call12, only need another 4 retw# elif XCHAL_NUM_AREGS == 64 entry sp, 48 bbci.l a0, 31, 1f // branch if called with call4 bbsi.l a0, 30, 2f // branch if called with call12 call4 .L__wdwspill_assist52 // called with call8, only need a call4 retw1: call8 .L__wdwspill_assist52 // called with call4, only need a call8 retw2: call12 .L__wdwspill_assist40 // called with call12, can skip a call12 retw# elif XCHAL_NUM_AREGS == 16 entry sp, 16 bbci.l a0, 31, 1f // branch if called with call4 bbsi.l a0, 30, 2f // branch if called with call12 movi a7, 0 // called with call8 retw1: movi a11, 0 // called with call42: retw // if called with call12, everything already spilled// movi a15, 0 // trick to spill all but the direct caller// j 1f// // The entry instruction is magical in the assembler (gets auto-aligned)// // so we have to jump to it to avoid falling through the padding.// // We need entry/retw to know where to return.//1: entry sp, 16// retw# else# error "unrecognized address register file size"# endif#endif /* XCHAL_HAVE_WINDOWED */ window_spill_common .endm // window_spill_function/*---------------------------------------------------------------------- * window_spill_common * * Common code used by any number of invocations of the window_spill## * and window_spill_function macros. * * Must be instantiated exactly once within a given assembly unit, * within call/j range of and same section as window_spill## * macro invocations for that assembly unit. * (Is automatically instantiated by the window_spill_function macro.) */ .macro window_spill_common#if XCHAL_HAVE_WINDOWED && (XCHAL_NUM_AREGS == 32 || XCHAL_NUM_AREGS == 64) .ifndef .L__wdwspill_defined# if XCHAL_NUM_AREGS >= 64.L__wdwspill_assist60: entry sp, 32 call8 .L__wdwspill_assist52 retw.L__wdwspill_assist56: entry sp, 16 call4 .L__wdwspill_assist52 retw.L__wdwspill_assist52: entry sp, 48 call12 .L__wdwspill_assist40 retw.L__wdwspill_assist40: entry sp, 48 call12 .L__wdwspill_assist28 retw# endif.L__wdwspill_assist28: entry sp, 48 call12 .L__wdwspill_assist16 retw.L__wdwspill_assist24: entry sp, 32 call8 .L__wdwspill_assist16 retw.L__wdwspill_assist20: entry sp, 16 call4 .L__wdwspill_assist16 retw.L__wdwspill_assist16: entry sp, 16 movi a15, 0 retw .set .L__wdwspill_defined, 1 .endif#endif /* XCHAL_HAVE_WINDOWED with 32 or 64 aregs */ .endm // window_spill_common/*---------------------------------------------------------------------- * beqi32 * * macro implements version of beqi for arbitrary 32-bit immidiate value * * beqi32 ax, ay, imm32, label * * Compares value in register ax with imm32 value and jumps to label if * equal. Clobberes register ay if needed * */ .macro beqi32 ax, ay, imm, label .ifeq ((\imm-1) & ~7) // 1..8 ? beqi \ax, \imm, \label .else .ifeq (\imm+1) // -1 ? beqi \ax, \imm, \label .else .ifeq (\imm) // 0 ? beqz \ax, \label .else // We could also handle immediates 10,12,16,32,64,128,256 // but it would be a long macro... movi \ay, \imm beq \ax, \ay, \label .endif .endif .endif .endm // beqi32#endif /*XTENSA_COREASM_H*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -