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) 2022 Intel Corporation
* SPDX-License-Identifier: Apache-2.0
*/
#include <xtensa/coreasm.h>
#include <zsr.h>
/* WINDOW OVERFLOW AND UNDERFLOW EXCEPTION VECTORS AND ALLOCA EXCEPTION
* HANDLER
@ -80,13 +82,15 @@ _WindowUnderflow4:
rfwu
/* Handle alloca exception generated by interruptee executing 'movsp'.
* This uses space between the window vectors, so is essentially "free".
* All interruptee's regs are intact except a0 which is saved in EXCSAVE_1,
* and PS.EXCM has been set by the exception hardware (can't be interrupted).
* The fact the alloca exception was taken means the registers associated with
* the base-save area have been spilled and 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.
* This uses space between the window vectors, so is essentially
* "free". All interruptee's regs are intact except a0 which is saved
* in $ZSR_ALLOCA (assigned at build time, see gen_zsr.py for
* details), and PS.EXCM has been set by the exception hardware (can't
* be interrupted). The fact the alloca exception was taken means the
* registers associated with the base-save area have been spilled and
* 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
@ -98,7 +102,7 @@ _xt_alloca_exc:
rsr a2, PS
extui a3, a2, XCHAL_PS_OWB_SHIFT, XCHAL_PS_OWB_BITS
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
xor a2, a2, a3 /* flip changed bits in old 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
* interrupts. Maybe revisit at some point, with better benchmarking.
* Note that _xt_alloca_exc is Xtensa-authored code which expects A0
* to have been saved to EXCSAVE1, which is an unfortunate ABI given
* that Zephyr code otherwise does not use the EXCSAVE registers.
* to have been saved to EXCSAVE1, we've modified it to use the zsr.h
* API to get assigned a scratch register.
*/
.pushsection .UserExceptionVector.text, "ax"
.global _Level1RealVector
_Level1RealVector:
wsr.excsave1 a0
wsr a0, ZSR_ALLOCA
rsr.exccause a0
bnei a0, EXCCAUSE_ALLOCA, _not_alloca
j _xt_alloca_exc
_not_alloca:
rsr.excsave1 a0
rsr a0, ZSR_ALLOCA
j _Level1Vector
.popsection