From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 2066) id 6A478388F075; Wed, 10 Jun 2020 03:48:26 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 6A478388F075 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1591760906; bh=yXXguFIYcIubCDwjopRexaRgqPZRLI5hseW0W0DUioQ=; h=From:To:Subject:Date:From; b=oR+hV6wE0uexbdLFdYyx0fAx/HgGwcdndmy3IZ7eW8eUnC6FilZkXPLLQ+VOr860O stVdQMWKfOCPUJa66x7yoWVhZ/auBTc+VI5jcpwcREWs3vYgbUB4dl0OqE3JmGWfI3 dC1WNwC0ZIaengl8wqjEKcGv16RdaWqzDr5U2nIg= Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: Jiu Fu Guo To: gcc-cvs@gcc.gnu.org Subject: [gcc(refs/users/guojiufu/heads/personal-branch)] xtensa: libgcc: fix PR target/95571 X-Act-Checkin: gcc X-Git-Author: Max Filippov X-Git-Refname: refs/users/guojiufu/heads/personal-branch X-Git-Oldrev: df2c0060e5d1e0a37001b93f36e9245bb75ef33b X-Git-Newrev: 1d9921cbdc732e1a7fc66b9c24a6dfa9625bd4c0 Message-Id: <20200610034826.6A478388F075@sourceware.org> Date: Wed, 10 Jun 2020 03:48:26 +0000 (GMT) X-BeenThere: gcc-cvs@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-cvs mailing list List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 10 Jun 2020 03:48:26 -0000 https://gcc.gnu.org/g:1d9921cbdc732e1a7fc66b9c24a6dfa9625bd4c0 commit 1d9921cbdc732e1a7fc66b9c24a6dfa9625bd4c0 Author: Max Filippov Date: Sat Jun 6 05:06:04 2020 -0700 xtensa: libgcc: fix PR target/95571 Rewrite uw_install_context without function calls to avoid register spilling in _Unwind_RaiseException during return context installation. 2020-06-08 Max Filippov gcc/testsuite/ * g++.target/xtensa/pr95571.C: New test. * g++.target/xtensa/xtensa.exp: New testsuite. libgcc/ * config/xtensa/unwind-dw2-xtensa.c (uw_install_context): Merge with uw_install_context_1. Diff: --- gcc/testsuite/g++.target/xtensa/pr95571.C | 43 ++++++++++++++++++++++++++++ gcc/testsuite/g++.target/xtensa/xtensa.exp | 43 ++++++++++++++++++++++++++++ libgcc/config/xtensa/unwind-dw2-xtensa.c | 46 ++++++++++++++---------------- 3 files changed, 108 insertions(+), 24 deletions(-) diff --git a/gcc/testsuite/g++.target/xtensa/pr95571.C b/gcc/testsuite/g++.target/xtensa/pr95571.C new file mode 100644 index 00000000000..59fe2852838 --- /dev/null +++ b/gcc/testsuite/g++.target/xtensa/pr95571.C @@ -0,0 +1,43 @@ +/* { dg-do run } */ + +extern "C" void abort(void); +extern "C" void __xtensa_libgcc_window_spill(void); + +static int call; +static int cnt; + +extern "C" void *memcpy(void *dst, const void *src, unsigned int sz) +{ + char *a = (char *)dst; + const char *b = (const char *)src; + + if (call++ == cnt) + __xtensa_libgcc_window_spill(); + + while (sz--) + *a++ = *b++; + + return dst; +} + +int main() +{ + int i; + + for (i = 0; i < 100; ++i) + { + call = 0; + cnt = i; + + try + { + throw 1; + } + catch (int v) + { + if (v != 1) + abort (); + } + } + return 0; +} diff --git a/gcc/testsuite/g++.target/xtensa/xtensa.exp b/gcc/testsuite/g++.target/xtensa/xtensa.exp new file mode 100644 index 00000000000..f4191201d11 --- /dev/null +++ b/gcc/testsuite/g++.target/xtensa/xtensa.exp @@ -0,0 +1,43 @@ +# Specific regression driver for Xtensa. +# Copyright (C) 2020 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. +# +# You should have received a copy of the GNU General Public License +# along with GCC; see the file COPYING3. If not see +# . */ + +# GCC testsuite that uses the `dg.exp' driver. + +# Exit immediately if this isn't an Xtensa target. +if {![istarget xtensa*-*-*] } then { + return +} + +# Load support procs. +load_lib g++-dg.exp + +global DEFAULT_CXXFLAGS +if ![info exists DEFAULT_CXXFLAGS] then { + set DEFAULT_CXXFLAGS " -pedantic-errors" +} + +# Initialize `dg'. +dg-init + +# Main loop. +dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.C]] \ + "" $DEFAULT_CXXFLAGS + +# All done. +dg-finish diff --git a/libgcc/config/xtensa/unwind-dw2-xtensa.c b/libgcc/config/xtensa/unwind-dw2-xtensa.c index 056182a794a..8a6a44a8b68 100644 --- a/libgcc/config/xtensa/unwind-dw2-xtensa.c +++ b/libgcc/config/xtensa/unwind-dw2-xtensa.c @@ -481,37 +481,35 @@ uw_init_context_1 (struct _Unwind_Context *context, void *outer_cfa, /* Install TARGET into CURRENT so that we can return to it. This is a macro because __builtin_eh_return must be invoked in the context of - our caller. */ + our caller, and also because spilling registers of the caller before + the context installation may result in reload of wrong register values + after the context installation due to the change of the stack pointer + in the base save area. This spilling may be caused by an interrupt + handler on baremetal host. */ -#define uw_install_context(CURRENT, TARGET, FRAMES) \ +#define uw_install_context(CURRENT, TARGET, FRAMES) \ do \ { \ - long offset = uw_install_context_1 ((CURRENT), (TARGET)); \ void *handler = __builtin_frob_return_addr ((TARGET)->ra); \ - __builtin_eh_return (offset, handler); \ + long i; \ + \ + /* The eh_return insn assumes a window size of 8, so don't bother \ + copying the save areas for registers a8-a15 since they won't be \ + reloaded. */ \ + for (i = 0; i < 2; ++i) \ + { \ + _Unwind_Word *c = (CURRENT)->reg[i]; \ + _Unwind_Word *t = (TARGET)->reg[i]; \ + int j; \ + \ + if (t && c && t != c) \ + for (j = 0; j < 4; ++j) \ + *c++ = *t++; \ + } \ + __builtin_eh_return (0, handler); \ } \ while (0) -static long -uw_install_context_1 (struct _Unwind_Context *current, - struct _Unwind_Context *target) -{ - long i; - - /* The eh_return insn assumes a window size of 8, so don't bother copying - the save areas for registers a8-a15 since they won't be reloaded. */ - for (i = 0; i < 2; ++i) - { - void *c = current->reg[i]; - void *t = target->reg[i]; - - if (t && c && t != c) - memcpy (c, t, 4 * sizeof (_Unwind_Word)); - } - - return 0; -} - static inline _Unwind_Ptr uw_identify_context (struct _Unwind_Context *context) {