tm.texi: Document TARGET_DWARF_REGISTER_SPAN.
authorAldy Hernandez <aldyh@redhat.com>
Wed, 5 Mar 2003 22:37:52 +0000 (22:37 +0000)
committerAldy Hernandez <aldyh@gcc.gnu.org>
Wed, 5 Mar 2003 22:37:52 +0000 (22:37 +0000)
2003-03-05  Aldy Hernandez  <aldyh@redhat.com>

        * doc/tm.texi: Document TARGET_DWARF_REGISTER_SPAN.

        * config/rs6000/rs6000.c (rs6000_dwarf_register_span): New.

        * hooks.c (hook_rtx_rtx_null): New.

        * hooks.h (hook_rtx_rtx_null): Protoize.

        * target-def.h (TARGET_DWARF_REGISTER_SPAN): New macro.
        (TARGET_INITIALIZER): Add TARGET_DWARF_REGISTER_SPAN.

        * target.h (struct gcc_target): Add dwarf_register_span.

        * dwarf2out.c (multiple_reg_loc_descriptor): New.
        (one_reg_loc_descriptor): New.
        (reg_loc_descriptor): Add support for values that span more than
        one register.

From-SVN: r63870

gcc/ChangeLog
gcc/config/rs6000/rs6000.c
gcc/doc/tm.texi
gcc/dwarf2out.c
gcc/hooks.c
gcc/hooks.h
gcc/target-def.h
gcc/target.h

index e3e5cb49af15e7684066a2198aecb7744b48391f..9d1c8801791c4bc8f092140bed48091beec9b338 100644 (file)
@@ -1,3 +1,23 @@
+2003-03-05  Aldy Hernandez  <aldyh@redhat.com>
+
+        * doc/tm.texi: Document TARGET_DWARF_REGISTER_SPAN.
+
+        * config/rs6000/rs6000.c (rs6000_dwarf_register_span): New.
+
+        * hooks.c (hook_rtx_rtx_null): New.
+
+        * hooks.h (hook_rtx_rtx_null): Protoize.
+
+        * target-def.h (TARGET_DWARF_REGISTER_SPAN): New macro.
+        (TARGET_INITIALIZER): Add TARGET_DWARF_REGISTER_SPAN.
+
+        * target.h (struct gcc_target): Add dwarf_register_span.
+
+        * dwarf2out.c (multiple_reg_loc_descriptor): New.
+        (one_reg_loc_descriptor): New.
+        (reg_loc_descriptor): Add support for values that span more than
+        one register.
+
 Wed Mar  5 23:16:57 CET 2003  Jan Hubicka  <jh@suse.cz>
 
        * Makefile.in (calls.o, toplev.o alias.o): Depend on cgraph.h
index ca99979e6f197f57c65ca96adb8e4f01469c9cbc..8f57f9497b4653a317a2a0600ece62d2064b884f 100644 (file)
@@ -268,6 +268,7 @@ static rtx generate_set_vrsave PARAMS ((rtx, rs6000_stack_t *, int));
 static void altivec_frame_fixup PARAMS ((rtx, rtx, HOST_WIDE_INT));
 static int easy_vector_constant PARAMS ((rtx));
 static bool is_ev64_opaque_type PARAMS ((tree));
+static rtx rs6000_dwarf_register_span PARAMS ((rtx));
 
 /* Hash table stuff for keeping track of TOC entries.  */
 
@@ -421,6 +422,9 @@ static const char alt_reg_names[][8] =
 #undef TARGET_VECTOR_OPAQUE_P
 #define TARGET_VECTOR_OPAQUE_P is_ev64_opaque_type
 
+#undef TARGET_DWARF_REGISTER_SPAN
+#define TARGET_DWARF_REGISTER_SPAN rs6000_dwarf_register_span
+
 struct gcc_target targetm = TARGET_INITIALIZER;
 \f
 /* Override command line options.  Mostly we process the processor
@@ -13601,4 +13605,28 @@ is_ev64_opaque_type (type)
                     "__ev64_opaque__") == 0);
 }
 
+static rtx
+rs6000_dwarf_register_span (reg)
+     rtx reg;
+{
+  unsigned regno;
+
+  if (!TARGET_SPE || !SPE_VECTOR_MODE (GET_MODE (reg)))
+    return NULL_RTX;
+
+  regno = REGNO (reg);
+
+  /* The duality of the SPE register size wreaks all kinds of havoc.
+     This is a way of distinguishing r0 in 32-bits from r0 in
+     64-bits.  */
+  return
+    gen_rtx_PARALLEL (VOIDmode,
+                     gen_rtvec (2,
+                                gen_rtx_REG (SImode, regno),
+                                /* Who, where, what?  1200?  This
+                                   will get changed to a sane value
+                                   when the SPE ABI finalizes.  */
+                                gen_rtx_REG (SImode, regno + 1200)));
+}
+
 #include "gt-rs6000.h"
index 2d20c4f568cd471289bf7ff9fdb2c9e9dd88a5ca..25db00595df9f9f8c5d1b1200d969d6b5d0e40b0 100644 (file)
@@ -7610,6 +7610,15 @@ Default value is false if @code{EH_FRAME_SECTION_NAME} is defined, and
 true otherwise.
 @end deftypevar
 
+@deftypefn {Target Hook} rtx TARGET_DWARF_REGISTER_SPAN (rtx @var{reg})
+Given a register, this hook should return a parallel of registers to
+represent where to find the register pieces.  Define this hook if the
+register and its mode are represented in Dwarf in non-contiguous
+locations, or if the register should be represented in more than one
+register in Dwarf.  Otherwise, this hook should return @code{NULL_RTX}.
+If not defined, the default is to return @code{NULL_RTX}.
+@end deftypefn
+
 @node Alignment Output
 @subsection Assembler Commands for Alignment
 
index b75481c2411fb8409c8d4d5e582c06e6e34a408d..5a515e3fb4166be40d6eb9233e027e98a2c9a605 100644 (file)
@@ -3752,6 +3752,8 @@ static dw_die_ref modified_type_die       PARAMS ((tree, int, int, dw_die_ref));
 static int type_is_enum                        PARAMS ((tree));
 static unsigned int reg_number         PARAMS ((rtx));
 static dw_loc_descr_ref reg_loc_descriptor PARAMS ((rtx));
+static dw_loc_descr_ref one_reg_loc_descriptor PARAMS ((unsigned int));
+static dw_loc_descr_ref multiple_reg_loc_descriptor PARAMS ((rtx, rtx));
 static dw_loc_descr_ref int_loc_descriptor PARAMS ((HOST_WIDE_INT));
 static dw_loc_descr_ref based_loc_descr        PARAMS ((unsigned, long));
 static int is_based_loc                        PARAMS ((rtx));
@@ -8155,24 +8157,90 @@ reg_number (rtl)
 }
 
 /* Return a location descriptor that designates a machine register or
-   zero if there is no such.  */
+   zero if there is none.  */
 
 static dw_loc_descr_ref
 reg_loc_descriptor (rtl)
      rtx rtl;
 {
-  dw_loc_descr_ref loc_result = NULL;
   unsigned reg;
+  rtx regs;
 
   if (REGNO (rtl) >= FIRST_PSEUDO_REGISTER)
     return 0;
 
   reg = reg_number (rtl);
-  if (reg <= 31)
-    loc_result = new_loc_descr (DW_OP_reg0 + reg, 0, 0);
+  regs = (*targetm.dwarf_register_span) (rtl);
+
+  if (HARD_REGNO_NREGS (reg, GET_MODE (rtl)) > 1
+      || regs)
+    return multiple_reg_loc_descriptor (rtl, regs);
+  else
+    return one_reg_loc_descriptor (reg);
+}
+
+/* Return a location descriptor that designates a machine register for
+   a given hard register number.  */
+
+static dw_loc_descr_ref
+one_reg_loc_descriptor (regno)
+     unsigned int regno;
+{
+  if (regno <= 31)
+    return new_loc_descr (DW_OP_reg0 + regno, 0, 0);
   else
-    loc_result = new_loc_descr (DW_OP_regx, reg, 0);
+    return new_loc_descr (DW_OP_regx, regno, 0);
+}
+
+/* Given an RTL of a register, return a location descriptor that
+   designates a value that spans more than one register.  */
+
+static dw_loc_descr_ref
+multiple_reg_loc_descriptor (rtl, regs)
+     rtx rtl, regs;
+{
+  int nregs, size, i;
+  unsigned reg;
+  dw_loc_descr_ref loc_result = NULL;
 
+  reg = reg_number (rtl);
+  nregs = HARD_REGNO_NREGS (reg, GET_MODE (rtl));
+
+  /* Simple, contiguous registers.  */
+  if (regs == NULL_RTX)
+    {
+      size = GET_MODE_SIZE (GET_MODE (rtl)) / nregs;
+
+      loc_result = NULL;
+      while (nregs--)
+       {
+         dw_loc_descr_ref t;
+
+         ++reg;
+         t = one_reg_loc_descriptor (reg);
+         add_loc_descr (&loc_result, t);
+         add_loc_descr (&loc_result, new_loc_descr (DW_OP_piece, size, 0));
+       }
+      return loc_result;
+    }
+
+  /* Now onto stupid register sets in non contiguous locations.  */
+
+  if (GET_CODE (regs) != PARALLEL)
+    abort ();
+
+  size = GET_MODE_SIZE (GET_MODE (XVECEXP (regs, 0, 0)));
+  loc_result = NULL;
+
+  for (i = 0; i < XVECLEN (regs, 0); ++i)
+    {
+      dw_loc_descr_ref t;
+
+      t = one_reg_loc_descriptor (REGNO (XVECEXP (regs, 0, i)));
+      add_loc_descr (&loc_result, t);
+      size = GET_MODE_SIZE (GET_MODE (XVECEXP (regs, 0, 0)));
+      add_loc_descr (&loc_result, new_loc_descr (DW_OP_piece, size, 0));
+    }
   return loc_result;
 }
 
index 8926638347ce8a6cbdafc8891bd646c12e822a85..1ec672585c2d76446a4ded4d06cf063af3eba2e2 100644 (file)
@@ -157,3 +157,10 @@ hook_rtx_rtx_identity (x)
   return x;
 }
 
+/* Generic hook that takes an rtx and returns NULL_RTX.  */
+rtx
+hook_rtx_rtx_null (x)
+     rtx x ATTRIBUTE_UNUSED;
+{
+  return 0;
+}
index f7a4d6d302073ac31006a6bb0bc216c422094a2d..5866da71bc90364a23a1354f3bf64670964e6ee1 100644 (file)
@@ -46,5 +46,6 @@ bool default_can_output_mi_thunk_no_vcall
 bool hook_bool_tree_tree_false PARAMS ((tree, tree));
 
 rtx hook_rtx_rtx_identity PARAMS ((rtx));
+rtx hook_rtx_rtx_null PARAMS ((rtx));
 
 #endif
index a7f84c165eb984926fcc57fa1be47b25c93a6627..86774c1d59ea8f220ee394fdf426cf036c7b6aa8 100644 (file)
@@ -140,6 +140,8 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 #endif
 #endif
 
+#define TARGET_DWARF_REGISTER_SPAN hook_rtx_rtx_null
+
 #ifndef TARGET_ASM_EXCEPTION_SECTION
 #define TARGET_ASM_EXCEPTION_SECTION default_exception_section
 #endif
@@ -310,6 +312,7 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
   TARGET_VECTOR_OPAQUE_P,                      \
   TARGET_RTX_COSTS,                            \
   TARGET_ADDRESS_COST,                         \
+  TARGET_DWARF_REGISTER_SPAN,                   \
   TARGET_HAVE_NAMED_SECTIONS,                  \
   TARGET_HAVE_CTORS_DTORS,                     \
   TARGET_HAVE_TLS,                             \
index 95c97b4e224eac2b6c96150b32be46509545e627..22558e9f7788c66d05910e0f486411c8e63982ea 100644 (file)
@@ -334,6 +334,14 @@ struct gcc_target
      invalid addresses.  */
   int (* address_cost) PARAMS ((rtx x));
 
+  /* Given a register, this hook should return a parallel of registers
+     to represent where to find the register pieces.  Define this hook
+     if the register and its mode are represented in Dwarf in
+     non-contiguous locations, or if the register should be
+     represented in more than one register in Dwarf.  Otherwise, this
+     hook should return NULL_RTX.  */
+  rtx (* dwarf_register_span) PARAMS ((rtx));
+
   /* Leave the boolean fields at the end.  */
 
   /* True if arbitrary sections are supported.  */