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:
parent
8b8e6c64af
commit
41f3a9307a
|
@ -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.
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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, ®);
|
||||
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, ®);
|
||||
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, ®);
|
||||
insn_ptr = read_uleb128 (insn_ptr, ®2);
|
||||
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, ®);
|
||||
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, ®);
|
||||
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, ®);
|
||||
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]);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue