arch/xtensa: Use ZSR assignments for the alloca exception

This is actually Cadence-authored code, but its use of EXCSAVE1 as a
sideband input to the exception handler is very much in the same
family of tricks.  Use ZSR assignments here too.

Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
This commit is contained in:
Andy Ross 2022-01-08 16:07:48 -08:00 committed by Anas Nashif
commit 3c7905b916
2 changed files with 16 additions and 12 deletions

View file

@ -1,8 +1,10 @@
/* /*
* Copyright (c) 2016 Cadence Design Systems, Inc. * Copyright (c) 2016 Cadence Design Systems, Inc.
* Copyright (c) 2022 Intel Corporation
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
#include <xtensa/coreasm.h> #include <xtensa/coreasm.h>
#include <zsr.h>
/* WINDOW OVERFLOW AND UNDERFLOW EXCEPTION VECTORS AND ALLOCA EXCEPTION /* WINDOW OVERFLOW AND UNDERFLOW EXCEPTION VECTORS AND ALLOCA EXCEPTION
* HANDLER * HANDLER
@ -80,13 +82,15 @@ _WindowUnderflow4:
rfwu rfwu
/* Handle alloca exception generated by interruptee executing 'movsp'. /* Handle alloca exception generated by interruptee executing 'movsp'.
* This uses space between the window vectors, so is essentially "free". * This uses space between the window vectors, so is essentially
* All interruptee's regs are intact except a0 which is saved in EXCSAVE_1, * "free". All interruptee's regs are intact except a0 which is saved
* and PS.EXCM has been set by the exception hardware (can't be interrupted). * in $ZSR_ALLOCA (assigned at build time, see gen_zsr.py for
* The fact the alloca exception was taken means the registers associated with * details), and PS.EXCM has been set by the exception hardware (can't
* the base-save area have been spilled and will be restored by the underflow * be interrupted). The fact the alloca exception was taken means the
* handler, so those 4 registers are available for scratch. * registers associated with the base-save area have been spilled and
* The code is optimized to avoid unaligned branches and minimize cache misses. * will be restored by the underflow handler, so those 4 registers are
* available for scratch. The code is optimized to avoid unaligned
* branches and minimize cache misses.
*/ */
.align 4 .align 4
@ -98,7 +102,7 @@ _xt_alloca_exc:
rsr a2, PS rsr a2, PS
extui a3, a2, XCHAL_PS_OWB_SHIFT, XCHAL_PS_OWB_BITS extui a3, a2, XCHAL_PS_OWB_SHIFT, XCHAL_PS_OWB_BITS
xor a3, a3, a4 /* bits changed from old to current windowbase */ xor a3, a3, a4 /* bits changed from old to current windowbase */
rsr a4, EXCSAVE_1 /* restore original a0 (now in a4) */ rsr a4, ZSR_ALLOCA /* restore original a0 (now in a4) */
slli a3, a3, XCHAL_PS_OWB_SHIFT slli a3, a3, XCHAL_PS_OWB_SHIFT
xor a2, a2, a3 /* flip changed bits in old window base */ xor a2, a2, a3 /* flip changed bits in old window base */
wsr a2, PS /* update PS.OWB to new window base */ wsr a2, PS /* update PS.OWB to new window base */

View file

@ -348,18 +348,18 @@ DEF_EXCINT XCHAL_DEBUGLEVEL, _handle_excint, xtensa_debugint_c
* to save these five cycles during other exceptions and L1 * to save these five cycles during other exceptions and L1
* interrupts. Maybe revisit at some point, with better benchmarking. * interrupts. Maybe revisit at some point, with better benchmarking.
* Note that _xt_alloca_exc is Xtensa-authored code which expects A0 * Note that _xt_alloca_exc is Xtensa-authored code which expects A0
* to have been saved to EXCSAVE1, which is an unfortunate ABI given * to have been saved to EXCSAVE1, we've modified it to use the zsr.h
* that Zephyr code otherwise does not use the EXCSAVE registers. * API to get assigned a scratch register.
*/ */
.pushsection .UserExceptionVector.text, "ax" .pushsection .UserExceptionVector.text, "ax"
.global _Level1RealVector .global _Level1RealVector
_Level1RealVector: _Level1RealVector:
wsr.excsave1 a0 wsr a0, ZSR_ALLOCA
rsr.exccause a0 rsr.exccause a0
bnei a0, EXCCAUSE_ALLOCA, _not_alloca bnei a0, EXCCAUSE_ALLOCA, _not_alloca
j _xt_alloca_exc j _xt_alloca_exc
_not_alloca: _not_alloca:
rsr.excsave1 a0 rsr a0, ZSR_ALLOCA
j _Level1Vector j _Level1Vector
.popsection .popsection