This is the mail archive of the
libstdc++@gcc.gnu.org
mailing list for the libstdc++ project.
Patch for IA64 32-bit function descriptors
- From: "Jessica Han" <jessica at cup dot hp dot com>
- To: <gcc-patches at gcc dot gnu dot org>, <libstdc++ at gcc dot gnu dot org>
- Date: Fri, 31 May 2002 14:35:51 -0700
- Subject: Patch for IA64 32-bit function descriptors
- Reply-to: <jessica at cup dot hp dot com>
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
};