1 /* 2 * Copyright (c) 2017, Intel Corporation 3 * 4 * SPDX-License-Identifier: Apache-2.0 5 */ 6 7 /* Copyright 2015-2018 Espressif Systems (Shanghai) PTE LTD 8 * 9 * Licensed under the Apache License, Version 2.0 (the "License"); 10 * you may not use this file except in compliance with the License. 11 * You may obtain a copy of the License at 12 * 13 * http://www.apache.org/licenses/LICENSE-2.0 14 * 15 * Unless required by applicable law or agreed to in writing, software 16 * distributed under the License is distributed on an "AS IS" BASIS, 17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 * See the License for the specific language governing permissions and 19 * limitations under the License. 20 */ 21 22 /* File adapted to use on IDF FreeRTOS component, extracted 23 * originally from zephyr RTOS code base: 24 * https://github.com/zephyrproject-rtos/zephyr/blob/dafd348/arch/xtensa/include/xtensa-asm2-s.h 25 */ 26 27 #ifndef __XT_ASM_UTILS_H 28 #define __XT_ASM_UTILS_H 29 30 /* 31 * SPILL_ALL_WINDOWS 32 * 33 * Spills all windowed registers (i.e. registers not visible as 34 * A0-A15) to their ABI-defined spill regions on the stack. 35 * 36 * Unlike the Xtensa HAL implementation, this code requires that the 37 * EXCM and WOE bit be enabled in PS, and relies on repeated hardware 38 * exception handling to do the register spills. The trick is to do a 39 * noop write to the high registers, which the hardware will trap 40 * (into an overflow exception) in the case where those registers are 41 * already used by an existing call frame. Then it rotates the window 42 * and repeats until all but the A0-A3 registers of the original frame 43 * are guaranteed to be spilled, eventually rotating back around into 44 * the original frame. Advantages: 45 * 46 * - Vastly smaller code size 47 * 48 * - More easily maintained if changes are needed to window over/underflow 49 * exception handling. 50 * 51 * - Requires no scratch registers to do its work, so can be used safely in any 52 * context. 53 * 54 * - If the WOE bit is not enabled (for example, in code written for 55 * the CALL0 ABI), this becomes a silent noop and operates compatbily. 56 * 57 * - Hilariously it's ACTUALLY FASTER than the HAL routine. And not 58 * just a little bit, it's MUCH faster. With a mostly full register 59 * file on an LX6 core (ESP-32) I'm measuring 145 cycles to spill 60 * registers with this vs. 279 (!) to do it with 61 * xthal_spill_windows(). 62 */ 63 64 .macro SPILL_ALL_WINDOWS 65 #if XCHAL_NUM_AREGS == 64 66 and a12, a12, a12 67 rotw 3 68 and a12, a12, a12 69 rotw 3 70 and a12, a12, a12 71 rotw 3 72 and a12, a12, a12 73 rotw 3 74 and a12, a12, a12 75 rotw 4 76 #elif XCHAL_NUM_AREGS == 32 77 and a12, a12, a12 78 rotw 3 79 and a12, a12, a12 80 rotw 3 81 and a4, a4, a4 82 rotw 2 83 #else 84 #error Unrecognized XCHAL_NUM_AREGS 85 #endif 86 .endm 87 88 #endif 89