Ping.
________________________________ From: Dragan Mladjenovic Sent: Thursday, May 9, 2019 12:29 PM To: gcc-patches@gcc.gnu.org Cc: Dragan Mladjenovic; Jakub Jelinek; Matthew Fortune Subject: [PATCH] Fix __builtin_init_dwarf_reg_size_table when built with -mfpxx From: "Dragan Mladjenovic" <dmladjeno...@wavecomp.com> Hi all, For TARGET_FLOATXX the odd-numbered FP registers in SFmode are HARD_REGNO_CALL_PART_CLOBBERED. This causes dwarf_frame_reg_mode to fall back to VOIDmode and for __builtin_init_dwarf_reg_size_table to fill them as zero sized. This prevents libgcc's unwinder form ever restoring high parts of calle-saved double precision registers. This patch fixes the issue by forcing dwarf_frame_reg_mode to use SImode for FP registers. Bootstrapped and done regression tests on mipsel-unknown-linux-gnu - no new failures found. Best regards, Dragan gcc/ChangeLog: 2019-04-23 Dragan Mladjenovic <dmladjeno...@wavecomp.com> * gcc/config/mips/mips.c(mips_dwarf_frame_reg_mode): Replace TARGET_FLOAT64 with !TARGET_FLOAT32, thus handling both fp64 and fpxx modes. gcc/testsuite/ChangeLog: 2019-04-23 Dragan Mladjenovic <dmladjeno...@wavecomp.com> * g++.dg/eh/o32-fp.C: New. * gcc.target/mips/dwarfregtable-1.c: New. * gcc.target/mips/dwarfregtable-2.c: New. * gcc.target/mips/dwarfregtable-3.c: New. * gcc.target/mips/dwarfregtable-4.c: New. * gcc.target/mips/dwarfregtable.h: New. --- gcc/config/mips/mips.c | 2 +- gcc/testsuite/g++.dg/eh/o32-fp.C | 47 +++++++++++++++++++++++++ gcc/testsuite/gcc.target/mips/dwarfregtable-1.c | 5 +++ gcc/testsuite/gcc.target/mips/dwarfregtable-2.c | 5 +++ gcc/testsuite/gcc.target/mips/dwarfregtable-3.c | 5 +++ gcc/testsuite/gcc.target/mips/dwarfregtable-4.c | 5 +++ gcc/testsuite/gcc.target/mips/dwarfregtable.h | 22 ++++++++++++ 7 files changed, 90 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/g++.dg/eh/o32-fp.C create mode 100644 gcc/testsuite/gcc.target/mips/dwarfregtable-1.c create mode 100644 gcc/testsuite/gcc.target/mips/dwarfregtable-2.c create mode 100644 gcc/testsuite/gcc.target/mips/dwarfregtable-3.c create mode 100644 gcc/testsuite/gcc.target/mips/dwarfregtable-4.c create mode 100644 gcc/testsuite/gcc.target/mips/dwarfregtable.h diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c index 1de33b2..c0c995a 100644 --- a/gcc/config/mips/mips.c +++ b/gcc/config/mips/mips.c @@ -9577,7 +9577,7 @@ mips_dwarf_frame_reg_mode (int regno) { machine_mode mode = default_dwarf_frame_reg_mode (regno); - if (FP_REG_P (regno) && mips_abi == ABI_32 && TARGET_FLOAT64) + if (FP_REG_P (regno) && mips_abi == ABI_32 && !TARGET_FLOAT32) mode = SImode; return mode; diff --git a/gcc/testsuite/g++.dg/eh/o32-fp.C b/gcc/testsuite/g++.dg/eh/o32-fp.C new file mode 100644 index 0000000..08fa51b --- /dev/null +++ b/gcc/testsuite/g++.dg/eh/o32-fp.C @@ -0,0 +1,47 @@ +// Test whether call saved float are restored properly for O32 ABI +// { dg-do run { target { { { mips*-*-linux* } && hard_float } && { ! mips64 } } } } +// { dg-options "-O2" } + +void __attribute__((noinline)) +bar (void) +{ + throw 1; +} + +void __attribute__((noinline)) +foo (void) +{ + register double f20 __asm__ ("f20") = 0.0; + register double f22 __asm__ ("f22") = 0.0; + register double f24 __asm__ ("f24") = 0.0; + register double f26 __asm__ ("f26") = 0.0; + register double f28 __asm__ ("f28") = 0.0; + register double f30 __asm__ ("f30") = 0.0; + __asm__ __volatile__("":"+f"(f20),"+f"(f22),"+f"(f24),"+f"(f26),"+f"(f30)); + bar (); +} + +int +main (void) +{ + register double f20 __asm__ ("f20") = 12.0; + register double f22 __asm__ ("f22") = 13.0; + register double f24 __asm__ ("f24") = 14.0; + register double f26 __asm__ ("f26") = 15.0; + register double f28 __asm__ ("f28") = 16.0; + register double f30 __asm__ ("f30") = 17.0; + + try + { + foo (); + } + catch (...) + { + __asm__ ("":"+f"(f20),"+f"(f22),"+f"(f24),"+f"(f26),"+f"(f30)); + } + + if (f20 != 12.0 || f22 != 13.0 || f24 != 14.0 + || f26 != 15.0 || f28 != 16.0 || f30 != 17.0) + __builtin_abort (); + return 0; +} diff --git a/gcc/testsuite/gcc.target/mips/dwarfregtable-1.c b/gcc/testsuite/gcc.target/mips/dwarfregtable-1.c new file mode 100644 index 0000000..93d0844 --- /dev/null +++ b/gcc/testsuite/gcc.target/mips/dwarfregtable-1.c @@ -0,0 +1,5 @@ +/* Check if content of dwarf reg size table matches the expected. */ +/* { dg-do run } */ +/* { dg-options "-mabi=32 -mfp32" } */ + +#include "dwarfregtable.h" diff --git a/gcc/testsuite/gcc.target/mips/dwarfregtable-2.c b/gcc/testsuite/gcc.target/mips/dwarfregtable-2.c new file mode 100644 index 0000000..c6dea94 --- /dev/null +++ b/gcc/testsuite/gcc.target/mips/dwarfregtable-2.c @@ -0,0 +1,5 @@ +/* Check if content of dwarf reg size table matches the expected. */ +/* { dg-do run } */ +/* { dg-options "-mabi=32 -mfpxx" } */ + +#include "dwarfregtable.h" diff --git a/gcc/testsuite/gcc.target/mips/dwarfregtable-3.c b/gcc/testsuite/gcc.target/mips/dwarfregtable-3.c new file mode 100644 index 0000000..87937c4 --- /dev/null +++ b/gcc/testsuite/gcc.target/mips/dwarfregtable-3.c @@ -0,0 +1,5 @@ +/* Check if content of dwarf reg size table matches the expected. */ +/* { dg-do run } */ +/* { dg-options "-mabi=32 -mfp64" } */ + +#include "dwarfregtable.h" diff --git a/gcc/testsuite/gcc.target/mips/dwarfregtable-4.c b/gcc/testsuite/gcc.target/mips/dwarfregtable-4.c new file mode 100644 index 0000000..2dd6dea --- /dev/null +++ b/gcc/testsuite/gcc.target/mips/dwarfregtable-4.c @@ -0,0 +1,5 @@ +/* Check if content of dwarf reg size table matches the expected. */ +/* { dg-do run } */ +/* { dg-options "-mabi=32 -mfp64 -modd-spreg" } */ + +#include "dwarfregtable.h" diff --git a/gcc/testsuite/gcc.target/mips/dwarfregtable.h b/gcc/testsuite/gcc.target/mips/dwarfregtable.h new file mode 100644 index 0000000..5f2f6e1 --- /dev/null +++ b/gcc/testsuite/gcc.target/mips/dwarfregtable.h @@ -0,0 +1,22 @@ + +typedef unsigned Unwind_Word __attribute__((__mode__(__unwind_word__))); + +#define DWARF_FRAME_REGISTERS 188 + +static unsigned char ref_dwarf_reg_size_table[DWARF_FRAME_REGISTERS + 1] = + { + [0 ... 66] = sizeof (Unwind_Word), + [80 ... 181] = sizeof (Unwind_Word) + }; + +static unsigned char dwarf_reg_size_table[DWARF_FRAME_REGISTERS + 1] = {}; + +int +main (void) +{ + __builtin_init_dwarf_reg_size_table (dwarf_reg_size_table); + if (__builtin_memcmp (ref_dwarf_reg_size_table, + dwarf_reg_size_table, DWARF_FRAME_REGISTERS + 1) != 0) + __builtin_abort (); + return 0; +} -- 1.9.1