590e26360c
call0 is an ABI that doesn't use register windows. 2015-03-03 Max Filippov <jcmvbkbc@gmail.com> gcc/ * config/xtensa/constraints.md ("a" constraint): Include stack pointer in case of call0 ABI. ("q" constraint): Make empty in case of call0 ABI. ("D" constraint): Include stack pointer in case of call0 ABI. * config/xtensa/xtensa-protos.h (xtensa_set_return_address, xtensa_expand_epilogue, xtensa_regno_to_class): Add new function prototypes. * config/xtensa/xtensa.c (xtensa_callee_save_size): New variable. (xtensa_regno_to_class): Make it a local variable in the function xtensa_regno_to_class. (xtensa_function_epilogue, TARGET_ASM_FUNCTION_EPILOGUE): Remove macro, function prototype and implementation. (reg_nonleaf_alloc_order): Make it a local variable in the function order_regs_for_local_alloc. (xtensa_conditional_register_usage): New function. (TARGET_CONDITIONAL_REGISTER_USAGE): Define macro. (xtensa_valid_move): Allow direct moves to stack pointer register in call0 ABI. (xtensa_setup_frame_addresses): Only spill register windows in windowed ABI. (xtensa_emit_call): Emit call(x)8 or call(x)0 in windowed and call0 ABI respectively. (xtensa_function_arg_1): Only mark a7 register for copying in windowed ABI. (xtensa_call_save_reg): New function. (compute_frame_size): Add space for callee saved register storage to the frame size in call0 ABI. (xtensa_expand_prologue): Generate code to set up stack frame and save callee-saved registers in call0 ABI. (xtensa_expand_epilogue): New function. (xtensa_set_return_address): New function. (xtensa_return_addr): Calculate return address in call0 ABI. (xtensa_builtin_saveregs): Only mark a7 register for copying and emit copying code in windowed ABI. (order_regs_for_local_alloc): Add preferred register allocation order for non-leaf function in call0 ABI. (xtensa_static_chain): Add atatic chain passing for call0 ABI. (xtensa_asm_trampoline_template): Add trampoline generation for call0 ABI. (xtensa_trampoline_init): Add trampoline initialization for call0 ABI. (xtensa_conditional_register_usage, xtensa_regno_to_class): New functions. * config/xtensa/xtensa.h (TARGET_WINDOWED_ABI): New macro. (TARGET_CPU_CPP_BUILTINS): Add built-in define for call0 ABI. (CALL_USED_REGISTERS): Modify to encode both windowed and call0 ABI call-used registers. (HARD_FRAME_POINTER_REGNUM): Add frame pointer for call0 ABI. (INCOMING_REGNO, OUTGOING_REGNO): Use argument unchanged in call0 ABI. (REG_CLASS_CONTENTS): Include all registers into the preferred reload registers set, adjust the set in the xtensa_conditional_register_usage. (xtensa_regno_to_class): Drop variable declaration. (REGNO_REG_CLASS): Redefine to use xtensa_regno_to_class function. (WINDOW_SIZE): Define as 8 or 0 for windowed and call0 ABI respectively. (FUNCTION_PROFILER): Add _mcount call for call0 ABI. (TRAMPOLINE_SIZE): Define trampoline size for call0 ABI. (RETURN_ADDR_IN_PREVIOUS_FRAME): Define to 0 in call0 ABI. (ASM_OUTPUT_POOL_PROLOGUE): Always generate literal pool location in call0 ABI. (EH_RETURN_STACKADJ_RTX): New definition, use a10 for passing stack adjustment size when handling exception. (CRT_CALL_STATIC_FUNCTION): Add definition for call0 ABI. * config/xtensa/xtensa.md (A9_REG, UNSPECV_BLOCKAGE): New definitions. ("return" pattern): Generate ret.n/ret in call0 ABI. ("epilogue" pattern): Expand epilogue. ("nonlocal_goto" pattern): Use default in call0 ABI. ("eh_return" pattern): Move implementation to eh_set_a0_windowed, emit eh_set_a0_* depending on ABI. ("eh_set_a0_windowed" pattern): Former eh_return pattern. ("eh_set_a0_call0", "blockage"): New patterns. libgcc/ * config/xtensa/lib2funcs.S (__xtensa_libgcc_window_spill, __xtensa_nonlocal_goto): Don't compile for call0 ABI. (__xtensa_sync_caches): Only use entry and retw in windowed ABI, use ret in call0 ABI. * config/xtensa/t-windowed: New file. * libgcc/config/xtensa/t-xtensa (LIB2ADDEH): Move to t-windowed. * libgcc/configure: Regenerated. * libgcc/configure.ac: Check if xtensa target is configured for windowed ABI and thus needs to use custom unwind code. From-SVN: r221158
101 lines
2.9 KiB
C
101 lines
2.9 KiB
C
/* DWARF2 EH unwinding support for Xtensa.
|
|
Copyright (C) 2008-2015 Free Software Foundation, Inc.
|
|
|
|
This file is part of GCC.
|
|
|
|
GCC is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; either version 3, or (at your option)
|
|
any later version.
|
|
|
|
GCC is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
Under Section 7 of GPL version 3, you are granted additional
|
|
permissions described in the GCC Runtime Library Exception, version
|
|
3.1, as published by the Free Software Foundation.
|
|
|
|
You should have received a copy of the GNU General Public License and
|
|
a copy of the GCC Runtime Library Exception along with this program;
|
|
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
|
<http://www.gnu.org/licenses/>. */
|
|
|
|
/* Do code reading to identify a signal frame, and set the frame
|
|
state data appropriately. See unwind-dw2-xtensa.c for the structs.
|
|
Don't use this at all if inhibit_libc is used. */
|
|
|
|
#ifndef inhibit_libc
|
|
|
|
#include <signal.h>
|
|
#include <sys/ucontext.h>
|
|
|
|
/* Encoded bytes for Xtensa instructions:
|
|
movi a2, __NR_rt_sigreturn
|
|
syscall
|
|
entry (first byte only)
|
|
Some of the bytes are endian-dependent. */
|
|
|
|
#define MOVI_BYTE0 0x22
|
|
#define MOVI_BYTE2 225 /* __NR_rt_sigreturn */
|
|
#define SYSC_BYTE0 0
|
|
#define SYSC_BYTE2 0
|
|
|
|
#ifdef __XTENSA_EB__
|
|
#define MOVI_BYTE1 0x0a
|
|
#define SYSC_BYTE1 0x05
|
|
#define ENTRY_BYTE 0x6c
|
|
#else
|
|
#define MOVI_BYTE1 0xa0
|
|
#define SYSC_BYTE1 0x50
|
|
#define ENTRY_BYTE 0x36
|
|
#endif
|
|
|
|
#ifdef __XTENSA_WINDOWED_ABI__
|
|
#define MD_FALLBACK_FRAME_STATE_FOR xtensa_fallback_frame_state
|
|
|
|
static _Unwind_Reason_Code
|
|
xtensa_fallback_frame_state (struct _Unwind_Context *context,
|
|
_Unwind_FrameState *fs)
|
|
{
|
|
unsigned char *pc = context->ra;
|
|
struct sigcontext *sc;
|
|
|
|
struct rt_sigframe {
|
|
siginfo_t info;
|
|
struct ucontext uc;
|
|
} *rt_;
|
|
|
|
/* movi a2, __NR_rt_sigreturn; syscall */
|
|
if (pc[0] != MOVI_BYTE0
|
|
|| pc[1] != MOVI_BYTE1
|
|
|| pc[2] != MOVI_BYTE2
|
|
|| pc[3] != SYSC_BYTE0
|
|
|| pc[4] != SYSC_BYTE1
|
|
|| pc[5] != SYSC_BYTE2)
|
|
return _URC_END_OF_STACK;
|
|
|
|
rt_ = context->sp;
|
|
sc = &rt_->uc.uc_mcontext;
|
|
fs->signal_regs = (_Unwind_Word *) sc->sc_a;
|
|
|
|
/* If the signal arrived just before an ENTRY instruction, find the return
|
|
address and pretend the signal arrived before executing the CALL. */
|
|
if (*(unsigned char *) sc->sc_pc == ENTRY_BYTE)
|
|
{
|
|
unsigned callinc = (sc->sc_ps >> 16) & 3;
|
|
fs->signal_ra = ((sc->sc_a[callinc << 2] & XTENSA_RA_FIELD_MASK)
|
|
| context->ra_high_bits) - 3;
|
|
}
|
|
else
|
|
fs->signal_ra = sc->sc_pc;
|
|
|
|
fs->signal_frame = 1;
|
|
return _URC_NO_REASON;
|
|
}
|
|
|
|
#endif /* __XTENSA_WINDOWED_ABI__ */
|
|
|
|
#endif /* ifdef inhibit_libc */
|