* 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.
From-SVN: r54603
+2002-06-13 Jessica Han <jessica@cup.hp.com>
+
+ * 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.
+
2002-06-13 Eric Christopher <echristo@redhat.com>
* diagnostic.c (output_format): Fix thinko.
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
+ 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)
\f
/* Layout of Source Language Data Types */
do { \
if ((PART) == 0) \
{ \
- fputs ("\tdata16.ua @iplt(", FILE); \
+ 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)
\f
+2002-06-13 Jessica Han <jessica@cup.hp.com>
+
+ * 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.
+
2002-06-12 Stan Shebs <shebs@apple.com>
* mpw-config.in: Remove file, no longer used.
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;
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);
+ vid.index = ssize_int (-3 * TARGET_VTABLE_DATA_ENTRY_DISTANCE);
/* Add entries to the vtable for RTTI. */
build_rtti_vtbl_entries (binfo, &vid);
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))
+ {
+ tree add = cur;
+ int i;
+
+ for (i = 1; i < TARGET_VTABLE_DATA_ENTRY_DISTANCE; ++i)
+ add = tree_cons (NULL_TREE, null_pointer_node, add);
+ *prev = add;
+ }
+ }
+
if (non_fn_entries_p)
*non_fn_entries_p = list_length (vid.inits);
}
/* The next vbase will come at a more negative offset. */
- vid->index = size_binop (MINUS_EXPR, vid->index, ssize_int (1));
+ 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
exp = save_expr (exp);
/* The offset-to-top field is at index -2 from the vptr. */
- index = build_int_2 (-2, -1);
+ index = build_int_2 (-2 * TARGET_VTABLE_DATA_ENTRY_DISTANCE, -1);
offset = build_vtbl_ref (build_indirect_ref (exp, NULL), index);
tree index;
/* The RTTI information is at index -1. */
- index = integer_minus_one_node;
+ 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;
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)));
+ 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. */
#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. */
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
+2002-06-13 Richard Henderson <rth@redhat.com>
+
+ * g++.old-deja/g++.abi/vtable2.C (INC_VDATA): New. Define for
+ ia64 ilp32.
+
2002-06-12 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
* g++.dg/template/typename2.C: Update error message.
// 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 ()
// Set vtbl to point at the beginning of S4's primary vtable.
vptr = (ptrdiff_t **) &s4;
vtbl = *vptr;
- vtbl -= 5;
+ INC_VDATA (vtbl, -5);
- if (*vtbl++ != ((char*) (S0*) &s4) - (char*) &s4)
+ if (*vtbl != ((char*) (S0*) &s4) - (char*) &s4)
return 1;
- if (*vtbl++ != ((char*) (S1*) &s4) - (char*) &s4)
+ INC_VDATA (vtbl, 1);
+ if (*vtbl != ((char*) (S1*) &s4) - (char*) &s4)
return 2;
- if (*vtbl++ != ((char*) (S2*) &s4) - (char*) &s4)
+ INC_VDATA (vtbl, 1);
+ if (*vtbl != ((char*) (S2*) &s4) - (char*) &s4)
return 3;
- if (*vtbl++ != 0)
+ INC_VDATA (vtbl, 1);
+ if (*vtbl != 0)
return 4;
+ INC_VDATA (vtbl, 1);
// Skip the RTTI entry.
- vtbl++;
+ INC_VDATA (vtbl, 1);
if (! CMP_VPTR (vtbl, &_ZN2S32s3Ev))
return 5;
INC_VPTR (vtbl);
return 6;
INC_VPTR (vtbl);
// The S1 vbase offset.
- if (*vtbl++ != 0)
+ 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))
+ if (*vtbl != ((char*) &s4 - (char*) (S2*) &s4))
return 8;
- if (*vtbl++ != 0)
+ INC_VDATA (vtbl, 1);
+ if (*vtbl != 0)
return 9;
- if (*vtbl++ != 0)
+ 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))
+ if (*vtbl != ((char*) &s4 - (char*) (S2*) &s4))
return 11;
+ INC_VDATA (vtbl, 1);
// Skip the RTTI entry.
- vtbl++;
+ INC_VDATA (vtbl, 1);
// Skip the remaining virtual functions -- they are thunks.
INC_VPTR (vtbl);
INC_VPTR (vtbl);