Commit 41f3a930 by Aldy Hernandez Committed by Aldy Hernandez

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
parent 8b8e6c64
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> 2003-03-11 Hans-Peter Nilsson <hp@axis.com>
* config/cris/cris.md: Remove lingering EGCS reference. * config/cris/cris.md: Remove lingering EGCS reference.
......
...@@ -10235,7 +10235,7 @@ spe_synthesize_frame_save (real) ...@@ -10235,7 +10235,7 @@ spe_synthesize_frame_save (real)
/* For the SPE, registers saved in 64-bits, get a PARALLEL for their /* For the SPE, registers saved in 64-bits, get a PARALLEL for their
frame related note. The parallel contains a set of the register 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. This is so we can differentiate between 64-bit and 32-bit saves.
Words cannot describe this nastiness. */ Words cannot describe this nastiness. */
...@@ -10249,7 +10249,7 @@ spe_synthesize_frame_save (real) ...@@ -10249,7 +10249,7 @@ spe_synthesize_frame_save (real)
(reg z)) (reg z))
into: into:
(set (mem (plus (reg x) (const y+4))) (set (mem (plus (reg x) (const y+4)))
(reg z+113)) (reg z+1200))
*/ */
real2 = copy_rtx (real); real2 = copy_rtx (real);
...@@ -10265,10 +10265,9 @@ spe_synthesize_frame_save (real) ...@@ -10265,10 +10265,9 @@ spe_synthesize_frame_save (real)
} }
reg = SET_SRC (synth); 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, 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); offset = XEXP (XEXP (SET_DEST (synth), 0), 1);
synth = replace_rtx (synth, offset, synth = replace_rtx (synth, offset,
......
...@@ -708,6 +708,16 @@ extern int rs6000_default_long_calls; ...@@ -708,6 +708,16 @@ extern int rs6000_default_long_calls;
synthetic registers are 113 through 145. */ synthetic registers are 113 through 145. */
#define DWARF_FRAME_REGISTERS (FIRST_PSEUDO_REGISTER + 32) #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 /* 1 for registers that have pervasive standard uses
and are not available for the register allocator. and are not available for the register allocator.
......
...@@ -3256,6 +3256,16 @@ for backward compatibility in pre GCC 3.0 compiled code. ...@@ -3256,6 +3256,16 @@ for backward compatibility in pre GCC 3.0 compiled code.
If this macro is not defined, it defaults to If this macro is not defined, it defaults to
@code{DWARF_FRAME_REGISTERS}. @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 @end table
@node Elimination @node Elimination
......
...@@ -50,6 +50,10 @@ ...@@ -50,6 +50,10 @@
#define PRE_GCC3_DWARF_FRAME_REGISTERS DWARF_FRAME_REGISTERS #define PRE_GCC3_DWARF_FRAME_REGISTERS DWARF_FRAME_REGISTERS
#endif #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 /* This is the register and unwind state for a particular frame. This
provides the information necessary to unwind up past a frame and return provides the information necessary to unwind up past a frame and return
to its caller. */ to its caller. */
...@@ -164,6 +168,7 @@ read_8s (const void *p) { const union unaligned *up = p; return up->s8; } ...@@ -164,6 +168,7 @@ read_8s (const void *p) { const union unaligned *up = p; return up->s8; }
inline _Unwind_Word inline _Unwind_Word
_Unwind_GetGR (struct _Unwind_Context *context, int index) _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. */ /* This will segfault if the register hasn't been saved. */
return * (_Unwind_Word *) context->reg[index]; return * (_Unwind_Word *) context->reg[index];
} }
...@@ -173,9 +178,28 @@ _Unwind_GetGR (struct _Unwind_Context *context, int index) ...@@ -173,9 +178,28 @@ _Unwind_GetGR (struct _Unwind_Context *context, int index)
inline void inline void
_Unwind_SetGR (struct _Unwind_Context *context, int index, _Unwind_Word val) _Unwind_SetGR (struct _Unwind_Context *context, int index, _Unwind_Word val)
{ {
index = DWARF_REG_TO_UNWIND_COLUMN (index);
* (_Unwind_Word *) context->reg[index] = val; * (_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. */ /* Retrieve the return address for CONTEXT. */
inline _Unwind_Ptr inline _Unwind_Ptr
...@@ -741,13 +765,14 @@ execute_cfa_program (const unsigned char *insn_ptr, ...@@ -741,13 +765,14 @@ execute_cfa_program (const unsigned char *insn_ptr,
reg = insn & 0x3f; reg = insn & 0x3f;
insn_ptr = read_uleb128 (insn_ptr, &utmp); insn_ptr = read_uleb128 (insn_ptr, &utmp);
offset = (_Unwind_Sword) utmp * fs->data_align; offset = (_Unwind_Sword) utmp * fs->data_align;
fs->regs.reg[reg].how = REG_SAVED_OFFSET; fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how
fs->regs.reg[reg].loc.offset = offset; = REG_SAVED_OFFSET;
fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].loc.offset = offset;
} }
else if ((insn & 0xc0) == DW_CFA_restore) else if ((insn & 0xc0) == DW_CFA_restore)
{ {
reg = insn & 0x3f; 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) else switch (insn)
{ {
...@@ -773,13 +798,14 @@ execute_cfa_program (const unsigned char *insn_ptr, ...@@ -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, &reg);
insn_ptr = read_uleb128 (insn_ptr, &utmp); insn_ptr = read_uleb128 (insn_ptr, &utmp);
offset = (_Unwind_Sword) utmp * fs->data_align; offset = (_Unwind_Sword) utmp * fs->data_align;
fs->regs.reg[reg].how = REG_SAVED_OFFSET; fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how
fs->regs.reg[reg].loc.offset = offset; = REG_SAVED_OFFSET;
fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].loc.offset = offset;
break; break;
case DW_CFA_restore_extended: case DW_CFA_restore_extended:
insn_ptr = read_uleb128 (insn_ptr, &reg); 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; break;
case DW_CFA_undefined: case DW_CFA_undefined:
...@@ -795,8 +821,8 @@ execute_cfa_program (const unsigned char *insn_ptr, ...@@ -795,8 +821,8 @@ execute_cfa_program (const unsigned char *insn_ptr,
_Unwind_Word reg2; _Unwind_Word reg2;
insn_ptr = read_uleb128 (insn_ptr, &reg); insn_ptr = read_uleb128 (insn_ptr, &reg);
insn_ptr = read_uleb128 (insn_ptr, &reg2); insn_ptr = read_uleb128 (insn_ptr, &reg2);
fs->regs.reg[reg].how = REG_SAVED_REG; fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how = REG_SAVED_REG;
fs->regs.reg[reg].loc.reg = reg2; fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].loc.reg = reg2;
} }
break; break;
...@@ -853,8 +879,8 @@ execute_cfa_program (const unsigned char *insn_ptr, ...@@ -853,8 +879,8 @@ execute_cfa_program (const unsigned char *insn_ptr,
case DW_CFA_expression: case DW_CFA_expression:
insn_ptr = read_uleb128 (insn_ptr, &reg); insn_ptr = read_uleb128 (insn_ptr, &reg);
insn_ptr = read_uleb128 (insn_ptr, &utmp); insn_ptr = read_uleb128 (insn_ptr, &utmp);
fs->regs.reg[reg].how = REG_SAVED_EXP; fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how = REG_SAVED_EXP;
fs->regs.reg[reg].loc.exp = insn_ptr; fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].loc.exp = insn_ptr;
insn_ptr += utmp; insn_ptr += utmp;
break; break;
...@@ -863,8 +889,9 @@ execute_cfa_program (const unsigned char *insn_ptr, ...@@ -863,8 +889,9 @@ execute_cfa_program (const unsigned char *insn_ptr,
insn_ptr = read_uleb128 (insn_ptr, &reg); insn_ptr = read_uleb128 (insn_ptr, &reg);
insn_ptr = read_sleb128 (insn_ptr, &stmp); insn_ptr = read_sleb128 (insn_ptr, &stmp);
offset = stmp * fs->data_align; offset = stmp * fs->data_align;
fs->regs.reg[reg].how = REG_SAVED_OFFSET; fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how
fs->regs.reg[reg].loc.offset = offset; = REG_SAVED_OFFSET;
fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].loc.offset = offset;
break; break;
case DW_CFA_def_cfa_sf: case DW_CFA_def_cfa_sf:
...@@ -897,8 +924,9 @@ execute_cfa_program (const unsigned char *insn_ptr, ...@@ -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, &reg);
insn_ptr = read_uleb128 (insn_ptr, &utmp); insn_ptr = read_uleb128 (insn_ptr, &utmp);
offset = (_Unwind_Word) utmp * fs->data_align; offset = (_Unwind_Word) utmp * fs->data_align;
fs->regs.reg[reg].how = REG_SAVED_OFFSET; fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how
fs->regs.reg[reg].loc.offset = -offset; = REG_SAVED_OFFSET;
fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].loc.offset = -offset;
break; break;
default: default:
...@@ -1052,7 +1080,7 @@ uw_update_context_1 (struct _Unwind_Context *context, _Unwind_FrameState *fs) ...@@ -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 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 stored, so it has no saved address in the context. What we do
have is the CFA from the previous stack frame. */ 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; cfa = context->cfa;
else else
cfa = (void *) (_Unwind_Ptr) _Unwind_GetGR (context, fs->cfa_reg); 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) ...@@ -1086,10 +1114,12 @@ uw_update_context_1 (struct _Unwind_Context *context, _Unwind_FrameState *fs)
case REG_UNSAVED: case REG_UNSAVED:
break; break;
case REG_SAVED_OFFSET: 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; break;
case REG_SAVED_REG: 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; break;
case REG_SAVED_EXP: case REG_SAVED_EXP:
{ {
...@@ -1100,7 +1130,7 @@ uw_update_context_1 (struct _Unwind_Context *context, _Unwind_FrameState *fs) ...@@ -1100,7 +1130,7 @@ uw_update_context_1 (struct _Unwind_Context *context, _Unwind_FrameState *fs)
exp = read_uleb128 (exp, &len); exp = read_uleb128 (exp, &len);
val = execute_stack_op (exp, exp + len, &orig_context, val = execute_stack_op (exp, exp + len, &orig_context,
(_Unwind_Ptr) cfa); (_Unwind_Ptr) cfa);
context->reg[i] = (void *) val; _Unwind_SetGRPtr (context, i, (void *) val);
} }
break; break;
} }
...@@ -1205,6 +1235,7 @@ uw_install_context_1 (struct _Unwind_Context *current, ...@@ -1205,6 +1235,7 @@ uw_install_context_1 (struct _Unwind_Context *current,
{ {
void *c = current->reg[i]; void *c = current->reg[i];
void *t = target->reg[i]; void *t = target->reg[i];
if (t && c && t != c) if (t && c && t != c)
memcpy (c, t, dwarf_reg_size_table[i]); memcpy (c, t, dwarf_reg_size_table[i]);
} }
......
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