diff options
author | Richard Sandiford <richard.sandiford@linaro.org> | 2018-01-13 17:56:52 +0000 |
---|---|---|
committer | Richard Sandiford <rsandifo@gcc.gnu.org> | 2018-01-13 17:56:52 +0000 |
commit | dbc3af4fc620aeb6fbf088e961fe8658bbd959c7 (patch) | |
tree | cbbcda2f43cf257940616199a72d7b22c5d92a50 /libgcc/unwind-dw2.c | |
parent | 825b856cd08968694085aa13d0b937520b67a19d (diff) | |
download | gcc-dbc3af4fc620aeb6fbf088e961fe8658bbd959c7.zip gcc-dbc3af4fc620aeb6fbf088e961fe8658bbd959c7.tar.gz gcc-dbc3af4fc620aeb6fbf088e961fe8658bbd959c7.tar.bz2 |
SVE unwinding
This patch adds support for unwinding frames that use the SVE
pseudo VG register. We want this register to act like a normal
register if the CFI explicitly sets it, but want to provide a
default value otherwise. Computing the default value requires
an SVE target, so we only want to compute it on demand.
aarch64_vg uses a hard-coded .inst in order to avoid a build
dependency on binutils 2.28 or later.
2018-01-13 Richard Sandiford <richard.sandiford@linaro.org>
gcc/
* doc/tm.texi.in (DWARF_LAZY_REGISTER_VALUE): Document.
* doc/tm.texi: Regenerate.
libgcc/
* config/aarch64/value-unwind.h (aarch64_vg): New function.
(DWARF_LAZY_REGISTER_VALUE): Define.
* unwind-dw2.c (_Unwind_GetGR): Use DWARF_LAZY_REGISTER_VALUE
to provide a fallback register value.
gcc/testsuite/
* g++.target/aarch64/sve/aarch64-sve.exp: New harness.
* g++.target/aarch64/sve/catch_1.C: New test.
* g++.target/aarch64/sve/catch_2.C: Likewise.
* g++.target/aarch64/sve/catch_3.C: Likewise.
* g++.target/aarch64/sve/catch_4.C: Likewise.
* g++.target/aarch64/sve/catch_5.C: Likewise.
* g++.target/aarch64/sve/catch_6.C: Likewise.
Reviewed-by: James Greenhalgh <james.greenhalgh@arm.com>
From-SVN: r256615
Diffstat (limited to 'libgcc/unwind-dw2.c')
-rw-r--r-- | libgcc/unwind-dw2.c | 16 |
1 files changed, 12 insertions, 4 deletions
diff --git a/libgcc/unwind-dw2.c b/libgcc/unwind-dw2.c index a83ca2f..de9310f 100644 --- a/libgcc/unwind-dw2.c +++ b/libgcc/unwind-dw2.c @@ -216,12 +216,12 @@ _Unwind_IsExtendedContext (struct _Unwind_Context *context) || (context->flags & EXTENDED_CONTEXT_BIT)); } -/* Get the value of register INDEX as saved in CONTEXT. */ +/* Get the value of register REGNO as saved in CONTEXT. */ inline _Unwind_Word -_Unwind_GetGR (struct _Unwind_Context *context, int index) +_Unwind_GetGR (struct _Unwind_Context *context, int regno) { - int size; + int size, index; _Unwind_Context_Reg_Val val; #ifdef DWARF_ZERO_REG @@ -229,7 +229,7 @@ _Unwind_GetGR (struct _Unwind_Context *context, int index) return 0; #endif - index = DWARF_REG_TO_UNWIND_COLUMN (index); + index = DWARF_REG_TO_UNWIND_COLUMN (regno); gcc_assert (index < (int) sizeof(dwarf_reg_size_table)); size = dwarf_reg_size_table[index]; val = context->reg[index]; @@ -237,6 +237,14 @@ _Unwind_GetGR (struct _Unwind_Context *context, int index) if (_Unwind_IsExtendedContext (context) && context->by_value[index]) return _Unwind_Get_Unwind_Word (val); +#ifdef DWARF_LAZY_REGISTER_VALUE + { + _Unwind_Word value; + if (DWARF_LAZY_REGISTER_VALUE (regno, &value)) + return value; + } +#endif + /* This will segfault if the register hasn't been saved. */ if (size == sizeof(_Unwind_Ptr)) return * (_Unwind_Ptr *) (_Unwind_Internal_Ptr) val; |