/* 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. */
(reg z))
into:
(set (mem (plus (reg x) (const y+4)))
- (reg z+113))
+ (reg z+1200))
*/
real2 = copy_rtx (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,
#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. */
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];
}
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
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)
{
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:
_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;
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;
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:
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:
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);
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:
{
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;
}
{
void *c = current->reg[i];
void *t = target->reg[i];
+
if (t && c && t != c)
memcpy (c, t, dwarf_reg_size_table[i]);
}