tm.texi (Frame Registers): Document DWARF_REG_TO_UNWIND_COLUMN.
authorAldy Hernandez <aldyh@redhat.com>
Tue, 11 Mar 2003 20:40:54 +0000 (20:40 +0000)
committerAldy Hernandez <aldyh@gcc.gnu.org>
Tue, 11 Mar 2003 20:40:54 +0000 (20:40 +0000)
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

gcc/ChangeLog
gcc/config/rs6000/rs6000.c
gcc/config/rs6000/rs6000.h
gcc/doc/tm.texi
gcc/unwind-dw2.c

index 2d5e77776719f996426a93ff5f4923697355813e..d488b35612a74a9ab53e15e53a1ef44a9f7599fe 100644 (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.
index c1ed4764f0c84a9bdaf2fb21c74ae4fb09528d79..17997fd0f929bdf06ef55c3a3c9149ef8b520b02 100644 (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,
index 923adfb46c8005dbeb514a165fb5d768c3553c1e..e2c1f635180f9d52e4cf904a694dc6a2e343418f 100644 (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.
 
index 05689ef930bb1bfc798ab701d5f1f0a97d0f8b47..1723455535feadb168bb9fbaae96c1a509ab6903 100644 (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
index 6a44865d7c35669c2a389ebde05855b5e4cb0253..88d8d3047ded5aad3bf916627b1fdfbc4133cb38 100644 (file)
 #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]);
     }