Commit 37ea0b7e by Joseph Myers Committed by Joseph Myers

target.h (init_dwarf_reg_sizes_extra): New target hook.

	* target.h (init_dwarf_reg_sizes_extra): New target hook.
	* target-def.h (TARGET_INIT_DWARF_REG_SIZES_EXTRA): New default.
	* doc/tm.texi (TARGET_INIT_DWARF_REG_SIZES_EXTRA): Document.
	* dwarf2out.c (expand_builtin_init_dwarf_reg_sizes): Call this
	hook.
	* config/rs6000/rs6000.c (TARGET_INIT_DWARF_REG_SIZES_EXTRA,
	rs6000_init_dwarf_reg_sizes_extra): New.
	* config/rs6000/linux-unwind.h (ppc_fallback_frame_state): Support
	SPE register high parts.

testsuite:
	* gcc.target/powerpc/spe-unwind-1.c, g++.dg/eh/simd-5.C: New
	tests.

From-SVN: r122468
parent 9c4d2493
2007-03-02 Joseph Myers <joseph@codesourcery.com>
* target.h (init_dwarf_reg_sizes_extra): New target hook.
* target-def.h (TARGET_INIT_DWARF_REG_SIZES_EXTRA): New default.
* doc/tm.texi (TARGET_INIT_DWARF_REG_SIZES_EXTRA): Document.
* dwarf2out.c (expand_builtin_init_dwarf_reg_sizes): Call this
hook.
* config/rs6000/rs6000.c (TARGET_INIT_DWARF_REG_SIZES_EXTRA,
rs6000_init_dwarf_reg_sizes_extra): New.
* config/rs6000/linux-unwind.h (ppc_fallback_frame_state): Support
SPE register high parts.
2007-03-01 Brooks Moses <brooks.moses@codesourcery.com> 2007-03-01 Brooks Moses <brooks.moses@codesourcery.com>
* Makefile.in: Add install-pdf target as * Makefile.in: Add install-pdf target as
......
...@@ -301,6 +301,17 @@ ppc_fallback_frame_state (struct _Unwind_Context *context, ...@@ -301,6 +301,17 @@ ppc_fallback_frame_state (struct _Unwind_Context *context,
fs->regs.reg[VRSAVE_REGNO].loc.offset = (long) &vregs->vsave - new_cfa; fs->regs.reg[VRSAVE_REGNO].loc.offset = (long) &vregs->vsave - new_cfa;
} }
/* If we have SPE register high-parts... we check at compile-time to
avoid expanding the code for all other PowerPC. */
#ifdef __SPE__
for (i = 0; i < 32; i++)
{
fs->regs.reg[i + FIRST_PSEUDO_REGISTER - 1].how = REG_SAVED_OFFSET;
fs->regs.reg[i + FIRST_PSEUDO_REGISTER - 1].loc.offset
= (long) &regs->vregs - new_cfa + 4 * i;
}
#endif
return _URC_NO_REASON; return _URC_NO_REASON;
} }
......
...@@ -765,6 +765,7 @@ static rtx generate_set_vrsave (rtx, rs6000_stack_t *, int); ...@@ -765,6 +765,7 @@ static rtx generate_set_vrsave (rtx, rs6000_stack_t *, int);
int easy_vector_constant (rtx, enum machine_mode); int easy_vector_constant (rtx, enum machine_mode);
static bool rs6000_is_opaque_type (tree); static bool rs6000_is_opaque_type (tree);
static rtx rs6000_dwarf_register_span (rtx); static rtx rs6000_dwarf_register_span (rtx);
static void rs6000_init_dwarf_reg_sizes_extra (tree);
static rtx rs6000_legitimize_tls_address (rtx, enum tls_model); static rtx rs6000_legitimize_tls_address (rtx, enum tls_model);
static void rs6000_output_dwarf_dtprel (FILE *, int, rtx) ATTRIBUTE_UNUSED; static void rs6000_output_dwarf_dtprel (FILE *, int, rtx) ATTRIBUTE_UNUSED;
static rtx rs6000_tls_get_addr (void); static rtx rs6000_tls_get_addr (void);
...@@ -1028,6 +1029,9 @@ static const char alt_reg_names[][8] = ...@@ -1028,6 +1029,9 @@ static const char alt_reg_names[][8] =
#undef TARGET_DWARF_REGISTER_SPAN #undef TARGET_DWARF_REGISTER_SPAN
#define TARGET_DWARF_REGISTER_SPAN rs6000_dwarf_register_span #define TARGET_DWARF_REGISTER_SPAN rs6000_dwarf_register_span
#undef TARGET_INIT_DWARF_REG_SIZES_EXTRA
#define TARGET_INIT_DWARF_REG_SIZES_EXTRA rs6000_init_dwarf_reg_sizes_extra
/* On rs6000, function arguments are promoted, as are function return /* On rs6000, function arguments are promoted, as are function return
values. */ values. */
#undef TARGET_PROMOTE_FUNCTION_ARGS #undef TARGET_PROMOTE_FUNCTION_ARGS
...@@ -20657,6 +20661,30 @@ rs6000_dwarf_register_span (rtx reg) ...@@ -20657,6 +20661,30 @@ rs6000_dwarf_register_span (rtx reg)
gen_rtx_REG (SImode, regno + 1200))); gen_rtx_REG (SImode, regno + 1200)));
} }
/* Fill in sizes for SPE register high parts in table used by unwinder. */
static void
rs6000_init_dwarf_reg_sizes_extra (tree address)
{
if (TARGET_SPE)
{
int i;
enum machine_mode mode = TYPE_MODE (char_type_node);
rtx addr = expand_expr (address, NULL_RTX, VOIDmode, 0);
rtx mem = gen_rtx_MEM (BLKmode, addr);
rtx value = gen_int_mode (4, mode);
for (i = 1201; i < 1232; i++)
{
int column = DWARF_REG_TO_UNWIND_COLUMN (i);
HOST_WIDE_INT offset
= DWARF_FRAME_REGNUM (column) * GET_MODE_SIZE (mode);
emit_move_insn (adjust_address (mem, mode, offset), value);
}
}
}
/* Map internal gcc register numbers to DWARF2 register numbers. */ /* Map internal gcc register numbers to DWARF2 register numbers. */
unsigned int unsigned int
......
...@@ -8168,6 +8168,15 @@ register in Dwarf. Otherwise, this hook should return @code{NULL_RTX}. ...@@ -8168,6 +8168,15 @@ register in Dwarf. Otherwise, this hook should return @code{NULL_RTX}.
If not defined, the default is to return @code{NULL_RTX}. If not defined, the default is to return @code{NULL_RTX}.
@end deftypefn @end deftypefn
@deftypefn {Target Hook} void TARGET_INIT_DWARF_REG_SIZES_EXTRA (tree @var{address})
If some registers are represented in Dwarf-2 unwind information in
multiple pieces, define this hook to fill in information about the
sizes of those pieces in the table used by the unwinder at runtime.
It will be called by @code{expand_builtin_init_dwarf_reg_sizes} after
filling in a single size corresponding to each hard register;
@var{address} is the address of the table.
@end deftypefn
@deftypefn {Target Hook} bool TARGET_ASM_TTYPE (rtx @var{sym}) @deftypefn {Target Hook} bool TARGET_ASM_TTYPE (rtx @var{sym})
This hook is used to output a reference from a frame unwinding table to This hook is used to output a reference from a frame unwinding table to
the type_info object identified by @var{sym}. It should return @code{true} the type_info object identified by @var{sym}. It should return @code{true}
......
...@@ -498,6 +498,8 @@ expand_builtin_init_dwarf_reg_sizes (tree address) ...@@ -498,6 +498,8 @@ expand_builtin_init_dwarf_reg_sizes (tree address)
#ifdef DWARF_ALT_FRAME_RETURN_COLUMN #ifdef DWARF_ALT_FRAME_RETURN_COLUMN
init_return_column_size (mode, mem, DWARF_ALT_FRAME_RETURN_COLUMN); init_return_column_size (mode, mem, DWARF_ALT_FRAME_RETURN_COLUMN);
#endif #endif
targetm.init_dwarf_reg_sizes_extra (address);
} }
/* Convert a DWARF call frame info. operation to its string name */ /* Convert a DWARF call frame info. operation to its string name */
......
...@@ -190,6 +190,7 @@ Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ...@@ -190,6 +190,7 @@ Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#endif #endif
#define TARGET_DWARF_REGISTER_SPAN hook_rtx_rtx_null #define TARGET_DWARF_REGISTER_SPAN hook_rtx_rtx_null
#define TARGET_INIT_DWARF_REG_SIZES_EXTRA hook_void_tree
#ifndef TARGET_ASM_FILE_START #ifndef TARGET_ASM_FILE_START
#define TARGET_ASM_FILE_START default_file_start #define TARGET_ASM_FILE_START default_file_start
...@@ -688,6 +689,7 @@ Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ...@@ -688,6 +689,7 @@ Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
TARGET_ADDRESS_COST, \ TARGET_ADDRESS_COST, \
TARGET_ALLOCATE_INITIAL_VALUE, \ TARGET_ALLOCATE_INITIAL_VALUE, \
TARGET_DWARF_REGISTER_SPAN, \ TARGET_DWARF_REGISTER_SPAN, \
TARGET_INIT_DWARF_REG_SIZES_EXTRA, \
TARGET_FIXED_CONDITION_CODE_REGS, \ TARGET_FIXED_CONDITION_CODE_REGS, \
TARGET_CC_MODES_COMPATIBLE, \ TARGET_CC_MODES_COMPATIBLE, \
TARGET_MACHINE_DEPENDENT_REORG, \ TARGET_MACHINE_DEPENDENT_REORG, \
......
...@@ -601,6 +601,12 @@ struct gcc_target ...@@ -601,6 +601,12 @@ struct gcc_target
hook should return NULL_RTX. */ hook should return NULL_RTX. */
rtx (* dwarf_register_span) (rtx); rtx (* dwarf_register_span) (rtx);
/* If expand_builtin_init_dwarf_reg_sizes needs to fill in table
entries not corresponding directly to registers below
FIRST_PSEUDO_REGISTER, this hook should generate the necessary
code, given the address of the table. */
void (* init_dwarf_reg_sizes_extra) (tree);
/* Fetch the fixed register(s) which hold condition codes, for /* Fetch the fixed register(s) which hold condition codes, for
targets where it makes sense to look for duplicate assignments to targets where it makes sense to look for duplicate assignments to
the condition codes. This should return true if there is such a the condition codes. This should return true if there is such a
......
2007-03-02 Joseph Myers <joseph@codesourcery.com>
* gcc.target/powerpc/spe-unwind-1.c, g++.dg/eh/simd-5.C: New
tests.
2007-03-01 Zdenek Dvorak <dvorakz@suse.cz> 2007-03-01 Zdenek Dvorak <dvorakz@suse.cz>
* gcc.dg/tree-ssa/prefetch-4.c: New test. * gcc.dg/tree-ssa/prefetch-4.c: New test.
// Test EH with V2SI SIMD registers actually restores correct values.
// Origin: Joseph Myers <joseph@codesourcery.com>
// { dg-options "-O" }
// { dg-do run { target powerpc_spe } }
extern "C" void abort (void);
extern "C" int memcmp (const void *, const void *, __SIZE_TYPE__);
typedef int __attribute__((vector_size (8))) v2si;
v2si a = { 1, 2 };
v2si b = { 3, 4 };
v2si c = { 4, 6 };
volatile v2si r;
v2si r2;
void
f ()
{
register v2si v asm("r15");
v = __builtin_spe_evaddw (b, c);
asm volatile ("" : "+r" (v));
r = v;
throw 1;
}
int
main ()
{
register v2si v asm("r15");
v = __builtin_spe_evaddw (a, b);
asm volatile ("" : "+r" (v));
try
{
f ();
}
catch (int)
{
r = v;
r2 = r;
if (memcmp (&r2, &c, sizeof (v2si)))
abort ();
}
return 0;
}
/* Verify that unwinding can find SPE registers in signal frames. */
/* Origin: Joseph Myers <joseph@codesourcery.com> */
/* { dg-do run { target { powerpc*-*-linux* && powerpc_spe } } } */
/* { dg-options "-fexceptions -fnon-call-exceptions -O2" } */
#include <unwind.h>
#include <stdlib.h>
#include <signal.h>
#include <string.h>
int count;
char *null;
int found_reg;
typedef int v2si __attribute__((__vector_size__(8)));
v2si v1 = { 123, 234 };
v2si v2 = { 345, 456 };
static _Unwind_Reason_Code
force_unwind_stop (int version, _Unwind_Action actions,
_Unwind_Exception_Class exc_class,
struct _Unwind_Exception *exc_obj,
struct _Unwind_Context *context,
void *stop_parameter)
{
unsigned int reg;
if (actions & _UA_END_OF_STACK)
abort ();
if (_Unwind_GetGR (context, 1215) == 123)
found_reg = 1;
return _URC_NO_REASON;
}
static void force_unwind ()
{
struct _Unwind_Exception *exc = malloc (sizeof (*exc));
memset (&exc->exception_class, 0, sizeof (exc->exception_class));
exc->exception_cleanup = 0;
#ifndef __USING_SJLJ_EXCEPTIONS__
_Unwind_ForcedUnwind (exc, force_unwind_stop, 0);
#else
_Unwind_SjLj_ForcedUnwind (exc, force_unwind_stop, 0);
#endif
abort ();
}
static void counter (void *p __attribute__((unused)))
{
++count;
}
static void handler (void *p __attribute__((unused)))
{
if (count != 2)
abort ();
if (!found_reg)
abort ();
exit (0);
}
static int __attribute__((noinline)) fn5 ()
{
char dummy __attribute__((cleanup (counter)));
force_unwind ();
return 0;
}
static void fn4 (int sig)
{
char dummy __attribute__((cleanup (counter)));
/* Clobber high part without compiler's knowledge so the only saved
copy is from the signal frame. */
asm volatile ("evmergelo 15,15,15");
fn5 ();
null = NULL;
}
static void fn3 ()
{
abort ();
}
static int __attribute__((noinline)) fn2 ()
{
register v2si r15 asm("r15");
r15 = v1;
asm volatile ("" : "+r" (r15));
*null = 0;
fn3 ();
return 0;
}
static int __attribute__((noinline)) fn1 ()
{
signal (SIGSEGV, fn4);
signal (SIGBUS, fn4);
fn2 ();
return 0;
}
static int __attribute__((noinline)) fn0 ()
{
char dummy __attribute__((cleanup (handler)));
fn1 ();
null = 0;
return 0;
}
int main()
{
fn0 ();
abort ();
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment