patch: dwarf handling of values spanning > 1 register

Aldy Hernandez aldyh@redhat.com
Wed Mar 5 21:08:00 GMT 2003


On Wednesday, March 5, 2003, at 12:36  PM, Richard Henderson wrote:

> On Wed, Mar 05, 2003 at 11:43:32AM -0800, Aldy Hernandez wrote:
>>> What about a hypothetical value which goes in two 64-bit SPE 
>>> registers
>>> (a synthesized 128-bit vector)?  I think something's at the wrong 
>>> level
>>> here.
>>
>> Well since GCC won't generate that, not even in the remote future, I
>> don't see a problem.
>
> Huh?  I thought Joern changed your synthetic vector stuff
> so that we already fall back on narrower vectors for
> implementing wider vectors.

Don't think so, at least not for SPE anyhow:

typedef int __attribute__((vector_size(16))) v2si;
extern void martes(v2si);
jorge(){
register v2si foofoo = {3,2,1,0};
martes(foofoo);
}

which yields...

        lwz 9,.LC0@l(7)
         lwz 10,4(8)
         lwz 11,8(8)
         lwz 6,12(8)
         mr 3,9
         mr 4,10
         mr 5,11
         bl martes

Richard commented on a few things on irc.  I fixed them all.  I also 
addressed the fixes Joseph suggested.  Here's the latest patch.


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.

Index: doc/tm.texi
===================================================================
RCS file: /cvs/gcc/gcc/gcc/doc/tm.texi,v
retrieving revision 1.204
diff -c -p -r1.204 tm.texi
*** doc/tm.texi	25 Feb 2003 17:06:40 -0000	1.204
--- doc/tm.texi	5 Mar 2003 21:03:35 -0000
*************** Default value is false if @code{EH_FRAME
*** 7600,7605 ****
--- 7600,7614 ----
   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: config/rs6000/rs6000.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/rs6000.c,v
retrieving revision 1.427
diff -c -p -r1.427 rs6000.c
*** config/rs6000/rs6000.c	25 Feb 2003 23:11:54 -0000	1.427
--- config/rs6000/rs6000.c	5 Mar 2003 21:03:38 -0000
*************** static rtx generate_set_vrsave PARAMS ((
*** 269,274 ****
--- 269,275 ----
   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.  */

*************** static const char alt_reg_names[][8] =
*** 424,429 ****
--- 425,433 ----
   #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;
   
   /* Override command line options.  Mostly we process the processor
*************** is_ev64_opaque_type (type)
*** 13609,13614 ****
--- 13613,13642 ----
   	  && DECL_NAME (TYPE_NAME (type))
   	  && strcmp (IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (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: hooks.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/hooks.c,v
retrieving revision 1.12
diff -c -p -r1.12 hooks.c
*** hooks.c	3 Feb 2003 19:40:57 -0000	1.12
--- hooks.c	5 Mar 2003 21:03:38 -0000
*************** hook_rtx_rtx_identity (x)
*** 157,159 ****
--- 157,166 ----
     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: hooks.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/hooks.h,v
retrieving revision 1.12
diff -c -p -r1.12 hooks.h
*** hooks.h	3 Feb 2003 19:40:57 -0000	1.12
--- hooks.h	5 Mar 2003 21:03:38 -0000
*************** bool default_can_output_mi_thunk_no_vcal
*** 46,50 ****
--- 46,51 ----
   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: target-def.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/target-def.h,v
retrieving revision 1.46
diff -c -p -r1.46 target-def.h
*** target-def.h	25 Feb 2003 17:06:39 -0000	1.46
--- target-def.h	5 Mar 2003 21:03:38 -0000
*************** Foundation, 59 Temple Place - Suite 330,
*** 140,145 ****
--- 140,147 ----
   #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
*************** Foundation, 59 Temple Place - Suite 330,
*** 310,315 ****
--- 312,318 ----
     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: target.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/target.h,v
retrieving revision 1.52
diff -c -p -r1.52 target.h
*** target.h	25 Feb 2003 17:06:39 -0000	1.52
--- target.h	5 Mar 2003 21:03:38 -0000
*************** struct gcc_target
*** 334,339 ****
--- 334,347 ----
        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.  */
Index: dwarf2out.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/dwarf2out.c,v
retrieving revision 1.401
diff -c -p -r1.401 dwarf2out.c
*** dwarf2out.c	20 Feb 2003 17:51:39 -0000	1.401
--- dwarf2out.c	5 Mar 2003 21:03:42 -0000
*************** static dw_die_ref modified_type_die	PARA
*** 3751,3756 ****
--- 3751,3758 ----
   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));
*************** reg_number (rtl)
*** 8145,8168 ****
   }

   /* Return a location descriptor that designates a machine register or
!    zero if there is no such.  */

   static dw_loc_descr_ref
   reg_loc_descriptor (rtl)
        rtx rtl;
   {
-   dw_loc_descr_ref loc_result = NULL;
     unsigned reg;

     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);
     else
!     loc_result = new_loc_descr (DW_OP_regx, reg, 0);

     return loc_result;
   }

--- 8147,8238 ----
   }

   /* Return a location descriptor that designates a machine register or
!    zero if there is none.  */

   static dw_loc_descr_ref
   reg_loc_descriptor (rtl)
        rtx rtl;
   {
     unsigned reg;
+   rtx regs;

     if (REGNO (rtl) >= FIRST_PSEUDO_REGISTER)
       return 0;

     reg = reg_number (rtl);
!   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
!     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 = one_reg_loc_descriptor (reg);
!       add_loc_descr (&loc_result, new_loc_descr (DW_OP_piece, size, 
0));
!       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 = one_reg_loc_descriptor (REGNO (XVECEXP (regs, 0, 0)));
+   add_loc_descr (&loc_result, new_loc_descr (DW_OP_piece, size, 0));
+
+   for (i = 1; 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;
   }



More information about the Gcc-patches mailing list