Patch for IA64 32-bit function descriptors
Jessica Han
jessica@cup.hp.com
Tue Jun 4 14:28:00 GMT 2002
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.
----
Jessica Han
Open Source Tools
Hewlett-Packard
(408) 447-6154
Part 1. g++
2002-06-04 Jessica Han <jessica@cup.hp.com>
* config/ia64/hpux.h Use 4 word function descriptors, define
TARGET_VTABLE_ENTRY_ALIGN, TARGET_VTABLE_DATA_ENTRY_DISTANCE for
handling IA64 32-bit mode.
* defaults.h Define TARGET_VTABLE_ENTRY_ALIGN and
TARGET_VTABLE_DATA_ENTRY_DISTANCE.
* cp/class.c Make IA64 32-bit vtable looks the same as 64-bit.
* cp/rtti.c Make IA64 32-bit vtable looks 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 and
TARGET_VTABLE_DATA_ENTRY_DISTANCE.
--- hpux.h.1.8 Tue Jun 4 12:04:29 2002
+++ hpux.h Tue Jun 4 12:10:13 2002
@@ -121,3 +121,36 @@ Boston, MA 02111-1307, USA. */
#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 ? (POINTER_SIZE*2) :
POINTER_SIZE)
+
+/* at 32-bit mode, there are 4 bytes of zeros after each vtable entry */
+#undef TARGET_VTABLE_DATA_ENTRY_DISTANCE
+#define TARGET_VTABLE_DATA_ENTRY_DISTANCE ( TARGET_ILP32 ? 2 : 1)
+
+/* Output part N of a function descriptor for DECL. For ia64, both
+ words are emitted with a single relocation, so ignore N > 0. */
+
+#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.76 Tue Jun 4 12:11:17 2002
+++ defaults.h Tue Jun 4 12:17:09 2002
@@ -379,6 +379,20 @@ do { ASM_OUTPUT_LABEL(FILE,LABEL_ALTERNA
#define TARGET_VTABLE_USES_DESCRIPTORS 0
#endif
+/* By default, the vtable entries are void pointers, the alignment is the
same
+ as pointer alignment. The value of this macro says how many bites the
entries
+ should be aligned when special alignment is necessary. */
+#ifndef TARGET_VTABLE_ENTRY_ALIGN
+#define TARGET_VTABLE_ENTRY_ALIGN POINTER_SIZE
+#endif
+
+/* By default, a vtable entry is a void pointer, we can find the next
vtable
+ entry by adding the size of 1 pointer. The value of this macro says how
many
+ pointers we should pass to find the next valid vtable 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. */
--- class.c.1.449 Tue Jun 4 12:19:46 2002
+++ class.c Tue Jun 4 14:18:28 2002
@@ -7254,6 +7254,7 @@ build_ctor_vtbl_group (binfo, t)
constructing the addresses of secondary vtables in the
construction vtable group. */
vtbl = build_vtable (t, id, ptr_type_node);
+ DECL_ALIGN(vtbl) = TARGET_VTABLE_ENTRY_ALIGN;
list = build_tree_list (vtbl, NULL_TREE);
accumulate_vtbl_inits (binfo, TYPE_BINFO (TREE_TYPE (binfo)),
binfo, t, list);
@@ -7499,8 +7500,9 @@ build_vtbl_initializer (binfo, orig_binf
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);
+ /* The first vbase or vcall offset is at index -3 in the vtable at 64 bit
+ mode and -6 at IA64 32-bit mode because of the padding. */
+ vid.index = ssize_int (-3 * TARGET_VTABLE_DATA_ENTRY_DISTANCE);
/* Add entries to the vtable for RTTI. */
build_rtti_vtbl_entries (binfo, &vid);
@@ -7520,6 +7522,30 @@ build_vtbl_initializer (binfo, orig_binf
vbase = TREE_CHAIN (vbase))
CLEAR_BINFO_VTABLE_PATH_MARKED (TREE_VALUE (vbase));
+ /* HP Linker requires that vtable info 8-byte aligned on IA64 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_DATA_ENTRY_DISTANCE > 1)
+ {
+ 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);
@@ -7736,8 +7762,9 @@ build_vbase_offset_vtbl_entries (binfo,
abort ();
}
- /* The next vbase will come at a more negative offset. */
- vid->index = size_binop (MINUS_EXPR, vid->index, ssize_int (1));
+ /* The next vbase will come at a more negative offset. 1 vtable entry
+ at 64-bit mode, 2 vtable entries at IA64 32-bit mode */
+ 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
@@ -7958,8 +7985,10 @@ add_vcall_offset_vtbl_entries_1 (binfo,
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));
+ offset. 1 vtable entry at 64-bit mode, 2 vtable entries at IA64 32-bit
+ mode. */
+ vid->index = size_binop (MINUS_EXPR, vid->index,
+ ssize_int
(TARGET_VTABLE_DATA_ENTRY_DISTANCE));
/* Keep track of this function. */
VARRAY_PUSH_TREE (vid->fns, derived_virtuals);
--- rtti.c.1.133 Tue Jun 4 12:34:14 2002
+++ rtti.c Tue Jun 4 12:40:47 2002
@@ -101,8 +101,9 @@ build_headof (exp)
/* 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);
+ /* The offset-to-top field is at index -2 from the vptr at 64-bit mode,
+ -4 at IA64 32-bit mode. */
+ index = build_int_2 (-2 * TARGET_VTABLE_DATA_ENTRY_DISTANCE, -1);
offset = build_vtbl_ref (build_indirect_ref (exp, NULL), index);
@@ -180,8 +181,9 @@ get_tinfo_decl_dynamic (exp)
tree t;
tree index;
- /* The RTTI information is at index -1. */
- index = integer_minus_one_node;
+ /* The RTTI information is at index -1 at 64-bit mode, -2 at IA64
32-bit
+ mode. */
+ 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;
@@ -1184,7 +1186,7 @@ create_pseudo_type_info VPARAMS((const c
TREE_TYPE (vtable_decl),
vtable_decl,
size_binop (MULT_EXPR,
- size_int (2),
+ size_int (TARGET_VTABLE_DATA_ENTRY_DISTANCE * 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 Tue Jun 4 12:42:14 2002
@@ -130,8 +130,12 @@ void _ZN2S42s1Ev ();
// 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
@@ -145,18 +149,37 @@ int main ()
// 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);
@@ -166,19 +189,37 @@ int main ()
// 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.136 Tue Jun 4 12:55:53 2002
+++ tm.texi Tue Jun 4 13:00:46 2002
@@ -1694,6 +1694,21 @@ pointer to which the function's data is
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 bits.
+
+@findex TARGET_VTABLE_DATA_ENTRY_DISTANCE
+@item TARGET_VTABLE_DATA_ENTRY_DISTANCE
+Normally, the C++ compiler uses 1 void pointer for each vtable entry. This
+macro allows the target to use special padding in vtables. The default
value
+for this macro is 1, if it is greater than 1, it means there are
TARGET_VTABLE_DATA_ENTRY_DISTANCE-1 zero pointers after each entry.
+
@end table
@node Escape Sequences
--------------------------------------------------------------------------
Part 2 libstdc++
2002-06-04 Jessica Han <jessica@cup.hp.com>
* libsupc++/tinfo.cc Handle the 8 byte vtable entries in IA64 32-bit
mode.
--- tinfo.cc.1.9 Tue Apr 2 12:38:38 2002
+++ tinfo.cc Tue Jun 4 13:02:47 2002
@@ -95,7 +95,13 @@ using namespace abi;
// 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
};
More information about the Libstdc++
mailing list