tm.texi (Frame Registers): Document DWARF_REG_TO_UNWIND_COLUMN.

2003-03-11  Aldy Hernandez  <aldyh@redhat.com>

        * doc/tm.texi (Frame Registers): Document DWARF_REG_TO_UNWIND_COLUMN.

        * unwind-dw2.c (DWARF_REG_TO_UNWIND_COLUMN): Define.
        (_Unwind_GetGR): Use DWARF_REG_TO_UNWIND_COLUMN.
        (_Unwind_SetGR): Same.
        (_Unwind_GetGRPtr): New.
        (_Unwind_SetGRPtr): New.
        (uw_update_context_1): Use accesor functions instead of accessing
        context->reg[] directly.
        (uw_install_context_1): Same.
        (execute_cfa_program): Same.
        (__frame_state_for): Same.

        * config/rs6000/rs6000.c (spe_synthesize_frame_save): Use 1200 as
        the synthetic register offset.

        * config/rs6000/rs6000.h (DWARF_REG_TO_UNWIND_COLUMN): New.

From-SVN: r64186
This commit is contained in:
Aldy Hernandez 2003-03-11 20:40:54 +00:00 committed by Aldy Hernandez
parent 8b8e6c64af
commit 41f3a9307a
5 changed files with 93 additions and 23 deletions

View File

@ -1,3 +1,23 @@
2003-03-11 Aldy Hernandez <aldyh@redhat.com>
* doc/tm.texi (Frame Registers): Document DWARF_REG_TO_UNWIND_COLUMN.
* unwind-dw2.c (DWARF_REG_TO_UNWIND_COLUMN): Define.
(_Unwind_GetGR): Use DWARF_REG_TO_UNWIND_COLUMN.
(_Unwind_SetGR): Same.
(_Unwind_GetGRPtr): New.
(_Unwind_SetGRPtr): New.
(uw_update_context_1): Use accesor functions instead of accessing
context->reg[] directly.
(uw_install_context_1): Same.
(execute_cfa_program): Same.
(__frame_state_for): Same.
* config/rs6000/rs6000.c (spe_synthesize_frame_save): Use 1200 as
the synthetic register offset.
* config/rs6000/rs6000.h (DWARF_REG_TO_UNWIND_COLUMN): New.
2003-03-11 Hans-Peter Nilsson <hp@axis.com>
* config/cris/cris.md: Remove lingering EGCS reference.

View File

@ -10235,7 +10235,7 @@ spe_synthesize_frame_save (real)
/* For the SPE, registers saved in 64-bits, get a PARALLEL for their
frame related note. The parallel contains a set of the register
being saved, and another set to a synthetic register (n+113).
being saved, and another set to a synthetic register (n+1200).
This is so we can differentiate between 64-bit and 32-bit saves.
Words cannot describe this nastiness. */
@ -10249,7 +10249,7 @@ spe_synthesize_frame_save (real)
(reg z))
into:
(set (mem (plus (reg x) (const y+4)))
(reg z+113))
(reg z+1200))
*/
real2 = copy_rtx (real);
@ -10265,10 +10265,9 @@ spe_synthesize_frame_save (real)
}
reg = SET_SRC (synth);
/* FIXME: the ABI says REGNO+1200, but this creates a huge hole
in the unwinder tables. I'm still unsure what to do. */
synth = replace_rtx (synth, reg,
gen_rtx_REG (SImode, REGNO (reg) + 113));
gen_rtx_REG (SImode, REGNO (reg) + 1200));
offset = XEXP (XEXP (SET_DEST (synth), 0), 1);
synth = replace_rtx (synth, offset,

View File

@ -708,6 +708,16 @@ extern int rs6000_default_long_calls;
synthetic registers are 113 through 145. */
#define DWARF_FRAME_REGISTERS (FIRST_PSEUDO_REGISTER + 32)
/* The SPE has an additional 32 synthetic registers starting at 1200.
We must map them here to sane values in the unwinder to avoid a
huge hole in the unwind tables.
FIXME: the AltiVec ABI has AltiVec registers being 1124-1155, and
the VRSAVE SPR (SPR256) assigned to register 356. When AltiVec EH
is verified to be working, this macro should be changed
accordingly. */
#define DWARF_REG_TO_UNWIND_COLUMN(r) ((r) > 1200 ? ((r) - 1200 + 113) : (r))
/* 1 for registers that have pervasive standard uses
and are not available for the register allocator.

View File

@ -3256,6 +3256,16 @@ for backward compatibility in pre GCC 3.0 compiled code.
If this macro is not defined, it defaults to
@code{DWARF_FRAME_REGISTERS}.
@findex DWARF_REG_TO_UNWIND_COLUMN
@item DWARF_REG_TO_UNWIND_COLUMN (@var{regno})
Define this macro if the target's representation for dwarf registers
is different than the internal representation for unwind column.
Given a dwarf register, this macro should return the interal unwind
column number to use instead.
See the PowerPC's SPE target for an example.
@end table
@node Elimination

View File

@ -50,6 +50,10 @@
#define PRE_GCC3_DWARF_FRAME_REGISTERS DWARF_FRAME_REGISTERS
#endif
#ifndef DWARF_REG_TO_UNWIND_COLUMN
#define DWARF_REG_TO_UNWIND_COLUMN(REGNO) (REGNO)
#endif
/* This is the register and unwind state for a particular frame. This
provides the information necessary to unwind up past a frame and return
to its caller. */
@ -164,6 +168,7 @@ read_8s (const void *p) { const union unaligned *up = p; return up->s8; }
inline _Unwind_Word
_Unwind_GetGR (struct _Unwind_Context *context, int index)
{
index = DWARF_REG_TO_UNWIND_COLUMN (index);
/* This will segfault if the register hasn't been saved. */
return * (_Unwind_Word *) context->reg[index];
}
@ -173,9 +178,28 @@ _Unwind_GetGR (struct _Unwind_Context *context, int index)
inline void
_Unwind_SetGR (struct _Unwind_Context *context, int index, _Unwind_Word val)
{
index = DWARF_REG_TO_UNWIND_COLUMN (index);
* (_Unwind_Word *) context->reg[index] = val;
}
/* Get the pointer to a register INDEX as saved in CONTEXT. */
static inline void *
_Unwind_GetGRPtr (struct _Unwind_Context *context, int index)
{
index = DWARF_REG_TO_UNWIND_COLUMN (index);
return context->reg[index];
}
/* Set the pointer to a register INDEX as saved in CONTEXT. */
static inline void
_Unwind_SetGRPtr (struct _Unwind_Context *context, int index, void *p)
{
index = DWARF_REG_TO_UNWIND_COLUMN (index);
context->reg[index] = p;
}
/* Retrieve the return address for CONTEXT. */
inline _Unwind_Ptr
@ -741,13 +765,14 @@ execute_cfa_program (const unsigned char *insn_ptr,
reg = insn & 0x3f;
insn_ptr = read_uleb128 (insn_ptr, &utmp);
offset = (_Unwind_Sword) utmp * fs->data_align;
fs->regs.reg[reg].how = REG_SAVED_OFFSET;
fs->regs.reg[reg].loc.offset = offset;
fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how
= REG_SAVED_OFFSET;
fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].loc.offset = offset;
}
else if ((insn & 0xc0) == DW_CFA_restore)
{
reg = insn & 0x3f;
fs->regs.reg[reg].how = REG_UNSAVED;
fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how = REG_UNSAVED;
}
else switch (insn)
{
@ -773,13 +798,14 @@ execute_cfa_program (const unsigned char *insn_ptr,
insn_ptr = read_uleb128 (insn_ptr, &reg);
insn_ptr = read_uleb128 (insn_ptr, &utmp);
offset = (_Unwind_Sword) utmp * fs->data_align;
fs->regs.reg[reg].how = REG_SAVED_OFFSET;
fs->regs.reg[reg].loc.offset = offset;
fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how
= REG_SAVED_OFFSET;
fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].loc.offset = offset;
break;
case DW_CFA_restore_extended:
insn_ptr = read_uleb128 (insn_ptr, &reg);
fs->regs.reg[reg].how = REG_UNSAVED;
fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN(reg)].how = REG_UNSAVED;
break;
case DW_CFA_undefined:
@ -795,8 +821,8 @@ execute_cfa_program (const unsigned char *insn_ptr,
_Unwind_Word reg2;
insn_ptr = read_uleb128 (insn_ptr, &reg);
insn_ptr = read_uleb128 (insn_ptr, &reg2);
fs->regs.reg[reg].how = REG_SAVED_REG;
fs->regs.reg[reg].loc.reg = reg2;
fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how = REG_SAVED_REG;
fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].loc.reg = reg2;
}
break;
@ -853,8 +879,8 @@ execute_cfa_program (const unsigned char *insn_ptr,
case DW_CFA_expression:
insn_ptr = read_uleb128 (insn_ptr, &reg);
insn_ptr = read_uleb128 (insn_ptr, &utmp);
fs->regs.reg[reg].how = REG_SAVED_EXP;
fs->regs.reg[reg].loc.exp = insn_ptr;
fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how = REG_SAVED_EXP;
fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].loc.exp = insn_ptr;
insn_ptr += utmp;
break;
@ -863,8 +889,9 @@ execute_cfa_program (const unsigned char *insn_ptr,
insn_ptr = read_uleb128 (insn_ptr, &reg);
insn_ptr = read_sleb128 (insn_ptr, &stmp);
offset = stmp * fs->data_align;
fs->regs.reg[reg].how = REG_SAVED_OFFSET;
fs->regs.reg[reg].loc.offset = offset;
fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how
= REG_SAVED_OFFSET;
fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].loc.offset = offset;
break;
case DW_CFA_def_cfa_sf:
@ -897,8 +924,9 @@ execute_cfa_program (const unsigned char *insn_ptr,
insn_ptr = read_uleb128 (insn_ptr, &reg);
insn_ptr = read_uleb128 (insn_ptr, &utmp);
offset = (_Unwind_Word) utmp * fs->data_align;
fs->regs.reg[reg].how = REG_SAVED_OFFSET;
fs->regs.reg[reg].loc.offset = -offset;
fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how
= REG_SAVED_OFFSET;
fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].loc.offset = -offset;
break;
default:
@ -1052,7 +1080,7 @@ uw_update_context_1 (struct _Unwind_Context *context, _Unwind_FrameState *fs)
one frame to the next. In this case, the stack pointer is never
stored, so it has no saved address in the context. What we do
have is the CFA from the previous stack frame. */
if (context->reg[fs->cfa_reg] == NULL)
if (_Unwind_GetGRPtr (context, fs->cfa_reg) == NULL)
cfa = context->cfa;
else
cfa = (void *) (_Unwind_Ptr) _Unwind_GetGR (context, fs->cfa_reg);
@ -1086,10 +1114,12 @@ uw_update_context_1 (struct _Unwind_Context *context, _Unwind_FrameState *fs)
case REG_UNSAVED:
break;
case REG_SAVED_OFFSET:
context->reg[i] = cfa + fs->regs.reg[i].loc.offset;
_Unwind_SetGRPtr (context, i, (void *) (cfa + fs->regs.reg[i].loc.offset));
break;
case REG_SAVED_REG:
context->reg[i] = orig_context.reg[fs->regs.reg[i].loc.reg];
_Unwind_SetGRPtr
(context, i,
_Unwind_GetGRPtr (&orig_context, fs->regs.reg[i].loc.reg));
break;
case REG_SAVED_EXP:
{
@ -1100,7 +1130,7 @@ uw_update_context_1 (struct _Unwind_Context *context, _Unwind_FrameState *fs)
exp = read_uleb128 (exp, &len);
val = execute_stack_op (exp, exp + len, &orig_context,
(_Unwind_Ptr) cfa);
context->reg[i] = (void *) val;
_Unwind_SetGRPtr (context, i, (void *) val);
}
break;
}
@ -1205,6 +1235,7 @@ uw_install_context_1 (struct _Unwind_Context *current,
{
void *c = current->reg[i];
void *t = target->reg[i];
if (t && c && t != c)
memcpy (c, t, dwarf_reg_size_table[i]);
}