Patch for IA64 32-bit function descriptors

Richard Henderson rth@redhat.com
Thu Jun 13 17:54:00 GMT 2002


On Tue, Jun 04, 2002 at 02:28:43PM -0700, Jessica Han wrote:
> I've updated the patch with Richard and Benjamin's comments. It contains two
> parts: part 1 is for g++, part 2 is for libstdc++-v3, they have to go
> together.   Pleaser review and check it in if ok. Thanks.

(1) Your mailer line-wrapped the patch, ruining it.

(2) The patch does not follow gnu style guidelines.

(3) The patch continues to be needlessly hpux specific.


I've re-written the patch and tested it for basic sanity on
ia64-linux.



r~

        * defaults.h (TARGET_VTABLE_ENTRY_ALIGN): New.
        (TARGET_VTABLE_DATA_ENTRY_DISTANCE): New.
        * doc/tm.texi: Document them.
        * config/ia64/ia64.h (TARGET_VTABLE_ENTRY_ALIGN): New.
        (TARGET_VTABLE_DATA_ENTRY_DISTANCE): New.
        (TARGET_VTABLE_USES_DESCRIPTORS): 4 word descriptors for 32-bit mode.
        (ASM_OUTPUT_FDESC): Likewise.

        * class.c (build_vtable): Use TARGET_VTABLE_ENTRY_ALIGN.
        (build_vtbl_initializer): Honor TARGET_VTABLE_DATA_ENTRY_DISTANCE.
        (build_vbase_offset_vtbl_entries): Likewise.
        * rtti.c (build_headof): Likewise.
        (get_tinfo_decl_dynamic): Likewise.
        (create_pseudo_type_info): Likewise.

        * g++.old-deja/g++.abi/vtable2.C (INC_VDATA): New.  Define for
        ia64 ilp32.

Index: defaults.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/defaults.h,v
retrieving revision 1.78
diff -c -p -d -r1.78 defaults.h
*** defaults.h	11 Jun 2002 21:34:30 -0000	1.78
--- defaults.h	13 Jun 2002 21:12:03 -0000
*************** do { ASM_OUTPUT_LABEL(FILE,LABEL_ALTERNA
*** 380,385 ****
--- 380,401 ----
  #define TARGET_VTABLE_USES_DESCRIPTORS 0
  #endif
  
+ /* By default, the vtable entries are void pointers, the so the alignment
+    is the same as pointer alignment.  The value of this macro specifies
+    the alignment of the vtable entry in bits.  It should be defined only
+    when special alignment is necessary. */
+ #ifndef TARGET_VTABLE_ENTRY_ALIGN
+ #define TARGET_VTABLE_ENTRY_ALIGN POINTER_SIZE
+ #endif
+ 
+ /* There are a few non-descriptor entries in the vtable at offsets below
+    zero.  If these entries must be padded (say, to preserve the alignment
+    specified by TARGET_VTABLE_ENTRY_ALIGN), set this to the number of
+    words in each data entry.  */
+ #ifndef TARGET_VTABLE_DATA_ENTRY_DISTANCE
+ #define TARGET_VTABLE_DATA_ENTRY_DISTANCE 1
+ #endif
+ 
  /* Select a format to encode pointers in exception handling data.  We
     prefer those that result in fewer dynamic relocations.  Assume no
     special support here and encode direct references.  */
Index: config/ia64/ia64.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/ia64/ia64.h,v
retrieving revision 1.120
diff -c -p -d -r1.120 ia64.h
*** config/ia64/ia64.h	12 Jun 2002 03:06:17 -0000	1.120
--- config/ia64/ia64.h	13 Jun 2002 21:12:03 -0000
*************** while (0)
*** 342,349 ****
     function descriptors instead.  The value of this macro says how
     many words wide the descriptor is (normally 2).  It is assumed
     that the address of a function descriptor may be treated as a
!    pointer to a function.  */
! #define TARGET_VTABLE_USES_DESCRIPTORS 2
  
  /* Layout of Source Language Data Types */
  
--- 342,362 ----
     function descriptors instead.  The value of this macro says how
     many words wide the descriptor is (normally 2).  It is assumed
     that the address of a function descriptor may be treated as a
!    pointer to a function.
! 
!    For reasons known only to HP, the vtable entries (as opposed to
!    normal function descriptors) are 16 bytes wide in 32-bit mode as
!    well, even though the 3rd and 4th words are unused.  */
! #define TARGET_VTABLE_USES_DESCRIPTORS (TARGET_ILP32 ? 4 : 2)
! 
! /* Due to silliness in the HPUX linker, vtable entries must be
!    8-byte aligned even in 32-bit mode.  Rather than create multiple
!    ABIs, force this restriction on everyone else too.  */
! #define TARGET_VTABLE_ENTRY_ALIGN  64
! 
! /* Due to the above, we need extra padding for the data entries below 0
!    to retain the alignment of the descriptors.  */
! #define TARGET_VTABLE_DATA_ENTRY_DISTANCE (TARGET_ILP32 ? 2 : 1)
  
  /* Layout of Source Language Data Types */
  
*************** do {									\
*** 1454,1462 ****
  do {									\
    if ((PART) == 0)							\
      {									\
!       fputs ("\tdata16.ua @iplt(", FILE);				\
        assemble_name (FILE, XSTR (XEXP (DECL_RTL (DECL), 0), 0));	\
        fputs (")\n", FILE);						\
      }									\
  } while (0)
  
--- 1467,1480 ----
  do {									\
    if ((PART) == 0)							\
      {									\
!       if (TARGET_ILP32)							\
!         fputs ("\tdata8.ua @iplt(", FILE);				\
!       else								\
!         fputs ("\tdata16.ua @iplt(", FILE);				\
        assemble_name (FILE, XSTR (XEXP (DECL_RTL (DECL), 0), 0));	\
        fputs (")\n", FILE);						\
+       if (TARGET_ILP32)							\
+ 	fputs ("\tdata8.ua 0\n", FILE);					\
      }									\
  } while (0)
  
Index: cp/class.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/class.c,v
retrieving revision 1.450
diff -c -p -d -r1.450 class.c
*** cp/class.c	4 Jun 2002 07:09:56 -0000	1.450
--- cp/class.c	13 Jun 2002 21:12:03 -0000
*************** build_vtable (class_type, name, vtable_t
*** 510,515 ****
--- 510,517 ----
    TREE_STATIC (decl) = 1;
    TREE_READONLY (decl) = 1;
    DECL_VIRTUAL_P (decl) = 1;
+   DECL_ALIGN (decl) = TARGET_VTABLE_ENTRY_ALIGN;
+ 
    import_export_vtable (decl, class_type, 0);
  
    return decl;
*************** build_vtbl_initializer (binfo, orig_binf
*** 7500,7506 ****
    vid.primary_vtbl_p = (binfo == TYPE_BINFO (t));
    vid.ctor_vtbl_p = !same_type_p (BINFO_TYPE (rtti_binfo), t);
    /* The first vbase or vcall offset is at index -3 in the vtable.  */
!   vid.index = ssize_int (-3);
  
    /* Add entries to the vtable for RTTI.  */
    build_rtti_vtbl_entries (binfo, &vid);
--- 7502,7508 ----
    vid.primary_vtbl_p = (binfo == TYPE_BINFO (t));
    vid.ctor_vtbl_p = !same_type_p (BINFO_TYPE (rtti_binfo), t);
    /* The first vbase or vcall offset is at index -3 in the vtable.  */
!   vid.index = ssize_int (-3 * TARGET_VTABLE_DATA_ENTRY_DISTANCE);
  
    /* Add entries to the vtable for RTTI.  */
    build_rtti_vtbl_entries (binfo, &vid);
*************** build_vtbl_initializer (binfo, orig_binf
*** 7518,7523 ****
--- 7520,7534 ----
         vbase = TREE_CHAIN (vbase))
      CLEAR_BINFO_VTABLE_PATH_MARKED (TREE_VALUE (vbase));
  
+   /* If the target requires padding between data entries, add that now.  */
+   if (TARGET_VTABLE_DATA_ENTRY_DISTANCE > 1)
+     {
+       tree cur, *prev;
+ 
+       for (prev = &vid.inits; (cur = *prev); prev = &TREE_CHAIN (cur))
+ 	*prev = tree_cons (NULL_TREE, null_pointer_node, cur);
+     }
+ 
    if (non_fn_entries_p)
      *non_fn_entries_p = list_length (vid.inits);
  
*************** build_vbase_offset_vtbl_entries (binfo, 
*** 7735,7741 ****
  	}
  
        /* The next vbase will come at a more negative offset.  */
!       vid->index = size_binop (MINUS_EXPR, vid->index, ssize_int (1));
  
        /* The initializer is the delta from BINFO to this virtual base.
  	 The vbase offsets go in reverse inheritance-graph order, and
--- 7746,7753 ----
  	}
  
        /* The next vbase will come at a more negative offset.  */
!       vid->index = size_binop (MINUS_EXPR, vid->index,
! 			       ssize_int (TARGET_VTABLE_DATA_ENTRY_DISTANCE));
  
        /* The initializer is the delta from BINFO to this virtual base.
  	 The vbase offsets go in reverse inheritance-graph order, and
Index: cp/rtti.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/rtti.c,v
retrieving revision 1.134
diff -c -p -d -r1.134 rtti.c
*** cp/rtti.c	16 May 2002 04:48:52 -0000	1.134
--- cp/rtti.c	13 Jun 2002 21:12:04 -0000
*************** build_headof (exp)
*** 102,108 ****
    exp = save_expr (exp);
  
    /* The offset-to-top field is at index -2 from the vptr.  */
!   index = build_int_2 (-2, -1);
  
    offset = build_vtbl_ref (build_indirect_ref (exp, NULL), index);
  
--- 102,108 ----
    exp = save_expr (exp);
  
    /* The offset-to-top field is at index -2 from the vptr.  */
!   index = build_int_2 (-2 * TARGET_VTABLE_DATA_ENTRY_DISTANCE, -1);
  
    offset = build_vtbl_ref (build_indirect_ref (exp, NULL), index);
  
*************** get_tinfo_decl_dynamic (exp)
*** 181,187 ****
        tree index;
  
        /* The RTTI information is at index -1.  */
!       index = integer_minus_one_node;
        t = build_vtbl_ref (exp, index);
        TREE_TYPE (t) = build_pointer_type (tinfo_decl_type);
        return t;
--- 181,187 ----
        tree index;
  
        /* The RTTI information is at index -1.  */
!       index = build_int_2 (-1 * TARGET_VTABLE_DATA_ENTRY_DISTANCE, -1);
        t = build_vtbl_ref (exp, index);
        TREE_TYPE (t) = build_pointer_type (tinfo_decl_type);
        return t;
*************** create_pseudo_type_info VPARAMS((const c
*** 1180,1191 ****
    vtable_decl = build_unary_op (ADDR_EXPR, vtable_decl, 0);
  
    /* We need to point into the middle of the vtable.  */
!   vtable_decl = build (PLUS_EXPR,
! 		       TREE_TYPE (vtable_decl),
! 		       vtable_decl,
! 		       size_binop (MULT_EXPR,
! 				   size_int (2),
! 				   TYPE_SIZE_UNIT (vtable_entry_type)));
    TREE_CONSTANT (vtable_decl) = 1;
  
    /* First field is the pseudo type_info base class. */
--- 1180,1190 ----
    vtable_decl = build_unary_op (ADDR_EXPR, vtable_decl, 0);
  
    /* We need to point into the middle of the vtable.  */
!   vtable_decl
!     = build (PLUS_EXPR, TREE_TYPE (vtable_decl), vtable_decl,
! 	     size_binop (MULT_EXPR,
! 			 size_int (2 * TARGET_VTABLE_DATA_ENTRY_DISTANCE),
! 			 TYPE_SIZE_UNIT (vtable_entry_type)));
    TREE_CONSTANT (vtable_decl) = 1;
  
    /* First field is the pseudo type_info base class. */
Index: doc/tm.texi
===================================================================
RCS file: /cvs/gcc/gcc/gcc/doc/tm.texi,v
retrieving revision 1.138
diff -c -p -d -r1.138 tm.texi
*** doc/tm.texi	11 Jun 2002 07:26:38 -0000	1.138
--- doc/tm.texi	13 Jun 2002 21:12:04 -0000
*************** pointer to which the function's data is 
*** 1695,1700 ****
--- 1695,1714 ----
  
  If vtables are used, the value of this macro should be the number
  of words that the function descriptor occupies.
+ 
+ @findex TARGET_VTABLE_ENTRY_ALIGN
+ @item TARGET_VTABLE_ENTRY_ALIGN
+ By default, the vtable entries are void pointers, the so the alignment
+ is the same as pointer alignment.  The value of this macro specifies
+ the alignment of the vtable entry in bits.  It should be defined only
+ when special alignment is necessary. */
+ 
+ @findex TARGET_VTABLE_DATA_ENTRY_DISTANCE
+ @item TARGET_VTABLE_DATA_ENTRY_DISTANCE
+ There are a few non-descriptor entries in the vtable at offsets below
+ zero.  If these entries must be padded (say, to preserve the alignment
+ specified by @code{TARGET_VTABLE_ENTRY_ALIGN}), set this to the number
+ of words in each data entry.
  @end table
  
  @node Escape Sequences
Index: testsuite/g++.old-deja/g++.abi/vtable2.C
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/g++.old-deja/g++.abi/vtable2.C,v
retrieving revision 1.5
diff -c -p -d -r1.5 vtable2.C
*** testsuite/g++.old-deja/g++.abi/vtable2.C	21 Sep 2001 16:58:22 -0000	1.5
--- testsuite/g++.old-deja/g++.abi/vtable2.C	13 Jun 2002 21:12:04 -0000
*************** void _ZN2S42s1Ev ();
*** 130,139 ****
--- 130,146 ----
  // IA-64 uses function descriptors not function pointers in its vtables.
  #if defined __ia64__
  #define CMP_VPTR(A, B)	(*(void **)(A) == *(void **)(B))
+ #ifdef _LP64
  #define INC_VPTR(A)	((A) += 2)
+ #define INC_VDATA(A,N)	((A) += (N))
+ #else
+ #define INC_VPTR(A)	((A) += 4)
+ #define INC_VDATA(A,N)	((A) += 2*(N))
+ #endif
  #else
  #define CMP_VPTR(A, B)	(*(A) == (ptrdiff_t)(B))
  #define INC_VPTR(A)	((A) += 1)
+ #define INC_VDATA(A,N)	((A) += (N))
  #endif
  
  int main ()
*************** int main ()
*** 145,162 ****
    // Set vtbl to point at the beginning of S4's primary vtable.
    vptr = (ptrdiff_t **) &s4;
    vtbl = *vptr;
!   vtbl -= 5;
  
!   if (*vtbl++ != ((char*) (S0*) &s4) - (char*) &s4)
      return 1;
!   if (*vtbl++ != ((char*) (S1*) &s4) - (char*) &s4)
      return 2;
!   if (*vtbl++ != ((char*) (S2*) &s4) - (char*) &s4)
      return 3;
!   if (*vtbl++ != 0)
      return 4;
    // Skip the RTTI entry.
!   vtbl++;
    if (! CMP_VPTR (vtbl, &_ZN2S32s3Ev))
      return 5;
    INC_VPTR (vtbl);
--- 152,173 ----
    // Set vtbl to point at the beginning of S4's primary vtable.
    vptr = (ptrdiff_t **) &s4;
    vtbl = *vptr;
!   INC_VDATA (vtbl, -5);
  
!   if (*vtbl != ((char*) (S0*) &s4) - (char*) &s4)
      return 1;
!   INC_VDATA (vtbl, 1);
!   if (*vtbl != ((char*) (S1*) &s4) - (char*) &s4)
      return 2;
!   INC_VDATA (vtbl, 1);
!   if (*vtbl != ((char*) (S2*) &s4) - (char*) &s4)
      return 3;
!   INC_VDATA (vtbl, 1);
!   if (*vtbl != 0)
      return 4;
+   INC_VDATA (vtbl, 1);
    // Skip the RTTI entry.
!   INC_VDATA (vtbl, 1);
    if (! CMP_VPTR (vtbl, &_ZN2S32s3Ev))
      return 5;
    INC_VPTR (vtbl);
*************** int main ()
*** 164,184 ****
      return 6;
    INC_VPTR (vtbl);
    // The S1 vbase offset.
!   if (*vtbl++ != 0)
      return 7;
    // The S4::s1 vcall offset is negative; once you convert to S2, you
    // have to convert to S4 to find the final overrider.
!   if (*vtbl++ != ((char*) &s4 - (char*) (S2*) &s4))
      return 8;
!   if (*vtbl++ != 0)
      return 9;
!   if (*vtbl++ != 0)
      return 10;
    // Now we're at the S2 offset to top entry.
!   if (*vtbl++ != ((char*) &s4 - (char*) (S2*) &s4))
      return 11;
    // Skip the RTTI entry.
!   vtbl++;
    // Skip the remaining virtual functions -- they are thunks.
    INC_VPTR (vtbl);
    INC_VPTR (vtbl);
--- 175,200 ----
      return 6;
    INC_VPTR (vtbl);
    // The S1 vbase offset.
!   if (*vtbl != 0)
      return 7;
+   INC_VDATA (vtbl, 1);
    // The S4::s1 vcall offset is negative; once you convert to S2, you
    // have to convert to S4 to find the final overrider.
!   if (*vtbl != ((char*) &s4 - (char*) (S2*) &s4))
      return 8;
!   INC_VDATA (vtbl, 1);
!   if (*vtbl != 0)
      return 9;
!   INC_VDATA (vtbl, 1);
!   if (*vtbl != 0)
      return 10;
+   INC_VDATA (vtbl, 1);
    // Now we're at the S2 offset to top entry.
!   if (*vtbl != ((char*) &s4 - (char*) (S2*) &s4))
      return 11;
+   INC_VDATA (vtbl, 1);
    // Skip the RTTI entry.
!   INC_VDATA (vtbl, 1);
    // Skip the remaining virtual functions -- they are thunks.
    INC_VPTR (vtbl);
    INC_VPTR (vtbl);



More information about the Gcc-patches mailing list