• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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