This is the mail archive of the libstdc++@gcc.gnu.org mailing list for the libstdc++ project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Patch for IA64 32-bit function descriptors


I submitted the following patch a while ago, it hasn't been checked in yet.
Could somebody review it and check it in if that's okay? Thanks.

----
Jessica Han
Open Source Tools
Hewlett-Packard
(408) 447-6154

http://gcc.gnu.org/ml/gcc-patches/2002-04/msg00142.html

The vtable for IA64 is designed for 64-bit, the current vtable generated in
32-bit doesn't work on HP-UX. The HP linker requires function descriptors to
be 8 bytes aligned even in 32-bit mode. I've twisted the 32-bit vtable to
make it the same as 64-bit :all vtable entries are 8 bytes (a 4 byte data
followed by 4 byte zeros), the function descriptor is 16 bytes (a 8 bye data
followed by 8 byte zeros). Thus HP linker can read in function descriptors
properly. This change will only change vtable layout on 32-bit IA64, other
platform won't be affected.

2002-04-02 Jessica Han <jessica@cup.hp.com>
	* config/ia64/hpux.h Use 4 word function descriptors and define
        TARGET_VTABLE_ENTRY_ALIGN to be non-zero at 32-bit mode.
	* defaults.h Define TARGET_VTABLE_ENTRY_ALIGN.
	* cp/class.c Make 32-bit vtable the same as 64-bit.
	* cp/rtti.c  Make 32-bit vtable the same as 64-bit.
	* testsuite/g++.old-deja/g++.abi/vtabl2.C Test the IA64 32-bit vtable
        layout specially.
	* doc/tm.texi Define TARGET_VTABLE_ENTRY_ALIGN.
	* libsupc++/tinfo.cc  Handle the 8 byte vtable entries in IA64 32-bit
        mode.

*** hpux.h.1.6	Tue Apr  2 11:35:32 2002
--- hpux.h	Wed Apr  3 12:38:21 2002
*************** Boston, MA 02111-1307, USA.  */
*** 122,124 ****
--- 122,153 ----

  #undef PAD_VARARGS_DOWN
  #define PAD_VARARGS_DOWN (!AGGREGATE_TYPE_P (type))
+
+ /* Function descriptors are always 16 bytes */
+ #undef TARGET_VTABLE_USES_DESCRIPTORS
+ #define TARGET_VTABLE_USES_DESCRIPTORS  ((TARGET_ILP32)? 4:2)
+
+ /* vtable entries are 8 byte aligned at 32-bit mode */
+ #undef TARGET_VTABLE_ENTRY_ALIGN
+ #define TARGET_VTABLE_ENTRY_ALIGN ((TARGET_ILP32)? 8:0)
+
+ /* Output part N of a function descriptor for DECL.  For ia64, both
+    words are emitted with a single relocation, so ignore N > 0. Use
+    data8.ua at 32-bit and data16.ua at 64-bit. */
+
+ #undef ASM_OUTPUT_FDESC
+ #define ASM_OUTPUT_FDESC(FILE, DECL, PART)                              \
+ 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)
+
*** defaults.h.1.70	Wed Apr  3 12:45:58 2002
--- defaults.h	Wed Apr  3 12:31:55 2002
*************** do {								\
*** 388,393 ****
--- 388,400 ----
  #define TARGET_VTABLE_USES_DESCRIPTORS 0
  #endif

+ /* By default, the vtable entries are void pointers. Setting this non-zero
+    tells the compiler to have special aligned vtable.  The value of
+    this macro says how many byte the entries should be aligned. */
+ #ifndef TARGET_VTABLE_ENTRY_ALIGN
+ #define TARGET_VTABLE_ENTRY_ALIGN 0
+ #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.  */
*** class.c.1.443	Tue Apr  2 11:44:44 2002
--- class.c	Wed Apr  3 12:47:07 2002
*************** build_ctor_vtbl_group (binfo, t)
*** 7273,7278 ****
--- 7273,7281 ----
       constructing the addresses of secondary vtables in the
       construction vtable group.  */
    vtbl = build_vtable (t, id, ptr_type_node);
+   /* HP linker requires vtable info 8-byte aligned on both 32-bit mode and
+      64 bit mode */
+   DECL_ALIGN(vtbl) = MAX(TYPE_ALIGN (double_type_node),DECL_ALIGN(vtbl));
    list = build_tree_list (vtbl, NULL_TREE);
    accumulate_vtbl_inits (binfo, TYPE_BINFO (TREE_TYPE (binfo)),
  			 binfo, t, list);
*************** build_vtbl_initializer (binfo, orig_binf
*** 7518,7525 ****
    vid.last_init = &vid.inits;
    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);
--- 7521,7529 ----
    vid.last_init = &vid.inits;
    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 at 64
bit
!      mode and -6 at 32-bit mode because of the padding.  */
!   vid.index = ssize_int (TARGET_VTABLE_ENTRY_ALIGN ? -6 : -3);

    /* Add entries to the vtable for RTTI.  */
    build_rtti_vtbl_entries (binfo, &vid);
*************** build_vtbl_initializer (binfo, orig_binf
*** 7538,7544 ****
         vbase;
         vbase = TREE_CHAIN (vbase))
      CLEAR_BINFO_VTABLE_PATH_MARKED (TREE_VALUE (vbase));
!
    if (non_fn_entries_p)
      *non_fn_entries_p = list_length (vid.inits);

--- 7542,7570 ----
         vbase;
         vbase = TREE_CHAIN (vbase))
      CLEAR_BINFO_VTABLE_PATH_MARKED (TREE_VALUE (vbase));
!   /* HP Linker requires that vtable info 8-byte aligned at both 32-bit and
!      64 bit mode. We put a 4-byte zero after each entry of the vtable to
!      make gcc generate aCC like vtables at 32-bit, thus HP linker can
!      recognize them properly.
!    */
!   if (TARGET_VTABLE_ENTRY_ALIGN)
!   {
!     tree current = vid.inits;
!     tree prev ;
!     tree next;
!     prev = current;
!     while (current){
!       tree tt = build_tree_list(NULL_TREE, integer_zero_node);
!       next = TREE_CHAIN(current);
!       if (current != vid.inits)
!         TREE_CHAIN(prev) = tt;
!       else
!         vid.inits=tt;
!       TREE_CHAIN(tt)=current;
!       prev = current;
!       current = next;
!     }
!   }
    if (non_fn_entries_p)
      *non_fn_entries_p = list_length (vid.inits);

*************** build_vbase_offset_vtbl_entries (binfo,
*** 7755,7762 ****
  	    abort ();
  	}

!       /* 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
--- 7781,7789 ----
  	    abort ();
  	}

!       /* The next vbase will come at a more negative offset.  1 vtable
entry
!          at 64-bit mode, 2 vtable entries at 32-bit mode */
!       vid->index = size_binop (MINUS_EXPR, vid->index, ssize_int
(TARGET_VTABLE_ENTRY_ALIGN ? 2:1));

        /* The initializer is the delta from BINFO to this virtual base.
  	 The vbase offsets go in reverse inheritance-graph order, and
*************** add_vcall_offset_vtbl_entries_1 (binfo,
*** 7977,7984 ****
  	BV_VCALL_INDEX (derived_virtuals) = vid->index;

        /* The next vcall offset will be found at a more negative
! 	 offset.  */
!       vid->index = size_binop (MINUS_EXPR, vid->index, ssize_int (1));

        /* Keep track of this function.  */
        VARRAY_PUSH_TREE (vid->fns, derived_virtuals);
--- 8004,8012 ----
  	BV_VCALL_INDEX (derived_virtuals) = vid->index;

        /* The next vcall offset will be found at a more negative
! 	 offset, 1 vtable entry at 64-bit mode, 2 vtable entries at 32-bit mode
*/
!       vid->index = size_binop (MINUS_EXPR, vid->index,
!                                ssize_int (TARGET_VTABLE_ENTRY_ALIGN ? 2 :
1));

        /* Keep track of this function.  */
        VARRAY_PUSH_TREE (vid->fns, derived_virtuals);
*** rtti.c.1.129.4.1	Tue Apr  2 11:43:53 2002
--- rtti.c	Wed Apr  3 12:48:13 2002
*************** build_headof (exp)
*** 101,108 ****
    /* We use this a couple of times below, protect it.  */
    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);

--- 101,109 ----
    /* We use this a couple of times below, protect it.  */
    exp = save_expr (exp);

!   /* The offset-to-top field is at index -2 from the vptr at 64-bit mode,
!      -4 at 32-bit mode.  */
!   index = build_int_2 ((TARGET_VTABLE_ENTRY_ALIGN ? -4 : -2), -1);

    offset = build_vtbl_ref (build_indirect_ref (exp, NULL), index);

*************** get_tinfo_decl_dynamic (exp)
*** 180,187 ****
        tree t;
        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,188 ----
        tree t;
        tree index;

!       /* The RTTI information is at index -1 at 64-bit mode, -2 at 32-bit
mode.  */
!       index = (TARGET_VTABLE_ENTRY_ALIGN? build_int_2 (-2, -1) :
integer_minus_one_node);
        t = build_vtbl_ref (exp, index);
        TREE_TYPE (t) = build_pointer_type (tinfo_decl_type);
        return t;
*************** create_pseudo_type_info VPARAMS((const c
*** 1179,1185 ****
  		       TREE_TYPE (vtable_decl),
  		       vtable_decl,
  		       size_binop (MULT_EXPR,
! 				   size_int (2),
  				   TYPE_SIZE_UNIT (vtable_entry_type)));
    TREE_CONSTANT (vtable_decl) = 1;

--- 1180,1186 ----
  		       TREE_TYPE (vtable_decl),
  		       vtable_decl,
  		       size_binop (MULT_EXPR,
! 				   size_int (TARGET_VTABLE_ENTRY_ALIGN ? 4 : 2),
  				   TYPE_SIZE_UNIT (vtable_entry_type)));
    TREE_CONSTANT (vtable_decl) = 1;

*** vtable2.C.1.5	Tue Apr  2 12:29:39 2002
--- vtable2.C	Wed Apr  3 12:33:08 2002
*************** void _ZN2S42s1Ev ();
*** 130,137 ****
--- 130,141 ----
  // 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)
  #else
+ #define INC_VPTR(A)	((A) += 4)
+ #endif
+ #else
  #define CMP_VPTR(A, B)	(*(A) == (ptrdiff_t)(B))
  #define INC_VPTR(A)	((A) += 1)
  #endif
*************** int main ()
*** 145,162 ****
--- 149,185 ----
    // Set vtbl to point at the beginning of S4's primary vtable.
    vptr = (ptrdiff_t **) &s4;
    vtbl = *vptr;
+ #if !defined(_LP64) && defined (__ia64__)
+   vtbl -= 10;
+ #else
    vtbl -= 5;
+ #endif

    if (*vtbl++ != ((char*) (S0*) &s4) - (char*) &s4)
      return 1;
+ #if !defined(_LP64) && defined (__ia64__)
+   vtbl++;
+ #endif
    if (*vtbl++ != ((char*) (S1*) &s4) - (char*) &s4)
      return 2;
+ #if !defined(_LP64) && defined (__ia64__)
+   vtbl++;
+ #endif
    if (*vtbl++ != ((char*) (S2*) &s4) - (char*) &s4)
      return 3;
+ #if !defined(_LP64) && defined (__ia64__)
+   vtbl++;
+ #endif
    if (*vtbl++ != 0)
      return 4;
+ #if !defined(_LP64) && defined (__ia64__)
+   vtbl++;
+ #endif
    // Skip the RTTI entry.
    vtbl++;
+ #if !defined(_LP64) && defined (__ia64__)
+   vtbl++;
+ #endif
    if (! CMP_VPTR (vtbl, &_ZN2S32s3Ev))
      return 5;
    INC_VPTR (vtbl);
*************** int main ()
*** 166,184 ****
--- 189,225 ----
    // The S1 vbase offset.
    if (*vtbl++ != 0)
      return 7;
+ #if !defined(_LP64) && defined (__ia64__)
+   vtbl++;
+ #endif
    // 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 !defined(_LP64) && defined (__ia64__)
+   vtbl++;
+ #endif
    if (*vtbl++ != 0)
      return 9;
+ #if !defined(_LP64) && defined (__ia64__)
+   vtbl++;
+ #endif
    if (*vtbl++ != 0)
      return 10;
+ #if !defined(_LP64) && defined (__ia64__)
+   vtbl++;
+ #endif
    // Now we're at the S2 offset to top entry.
    if (*vtbl++ != ((char*) &s4 - (char*) (S2*) &s4))
      return 11;
+ #if !defined(_LP64) && defined (__ia64__)
+   vtbl++;
+ #endif
    // Skip the RTTI entry.
    vtbl++;
+ #if !defined(_LP64) && defined (__ia64__)
+   vtbl++;
+ #endif
    // Skip the remaining virtual functions -- they are thunks.
    INC_VPTR (vtbl);
    INC_VPTR (vtbl);
*** tm.texi.1.114	Wed Apr  3 12:51:19 2002
--- tm.texi	Wed Apr  3 12:31:48 2002
*************** pointer to which the function's data is
*** 1703,1708 ****
--- 1703,1716 ----

  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
+ Normally, the C++ compiler uses void pionter vtable entries. This macro
+ allows the target to use special alignment in vtables.
+
+ If the value of this macro is non-zero, it represents the alignment of
+ vtable entries in bytes.
  @end table

  @node Escape Sequences
*** tinfo.cc.1.9	Tue Apr  2 12:38:38 2002
--- tinfo.cc	Wed Apr  3 12:32:22 2002
*************** using namespace abi;
*** 95,101 ****
--- 95,107 ----
  // have to keep alignments consistent manually.
  struct vtable_prefix {
    ptrdiff_t whole_object;           // offset to most derived object
+ #if !defined(_LP64) && defined (__ia64__)
+   ptrdiff_t padding1;           // padding to the offset IA64 32-bit only
+ #endif
    const __class_type_info *whole_type;  // pointer to most derived
type_info
+ #if !defined(_LP64) && defined (__ia64__)
+   ptrdiff_t padding2;           // padding to the pointer IA64 32-bit only
+ #endif
    const void *origin;               // what a class's vptr points to
  };




Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]