From a6f5e04831ee6d0aee3029d464a0929331e0c552 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Thu, 13 Jun 2002 17:50:34 -0700 Subject: [PATCH] defaults.h (TARGET_VTABLE_ENTRY_ALIGN): New. * 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 --- gcc/ChangeLog | 10 +++++ gcc/config/ia64/ia64.h | 24 ++++++++++-- gcc/cp/ChangeLog | 9 +++++ gcc/cp/class.c | 23 ++++++++++- gcc/cp/rtti.c | 15 ++++---- gcc/defaults.h | 16 ++++++++ gcc/doc/tm.texi | 14 +++++++ gcc/testsuite/ChangeLog | 5 +++ gcc/testsuite/g++.old-deja/g++.abi/vtable2.C | 40 ++++++++++++++------ 9 files changed, 131 insertions(+), 25 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 86344e93006..9f6d9006244 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2002-06-13 Jessica Han + + * 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 * diagnostic.c (output_format): Fix thinko. diff --git a/gcc/config/ia64/ia64.h b/gcc/config/ia64/ia64.h index 83da1644e7f..8aa8140d53b 100644 --- a/gcc/config/ia64/ia64.h +++ b/gcc/config/ia64/ia64.h @@ -342,8 +342,21 @@ while (0) 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) /* Layout of Source Language Data Types */ @@ -1454,9 +1467,14 @@ do { \ 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) diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 0e2685c5934..bfbe11f6579 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,12 @@ +2002-06-13 Jessica Han + + * 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 * mpw-config.in: Remove file, no longer used. diff --git a/gcc/cp/class.c b/gcc/cp/class.c index 72f9faa0560..1be2897f2f9 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -510,6 +510,8 @@ build_vtable (class_type, name, vtable_type) 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; @@ -7500,7 +7502,7 @@ build_vtbl_initializer (binfo, orig_binfo, t, rtti_binfo, non_fn_entries_p) 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); @@ -7518,6 +7520,22 @@ build_vtbl_initializer (binfo, orig_binfo, t, rtti_binfo, non_fn_entries_p) 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); @@ -7735,7 +7753,8 @@ build_vbase_offset_vtbl_entries (binfo, vid) } /* 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 diff --git a/gcc/cp/rtti.c b/gcc/cp/rtti.c index 8e4e7a196dc..7d3027af14a 100644 --- a/gcc/cp/rtti.c +++ b/gcc/cp/rtti.c @@ -102,7 +102,7 @@ build_headof (exp) 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); @@ -181,7 +181,7 @@ get_tinfo_decl_dynamic (exp) 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; @@ -1180,12 +1180,11 @@ create_pseudo_type_info VPARAMS((const char *real_name, int ident, ...)) 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. */ diff --git a/gcc/defaults.h b/gcc/defaults.h index 8a57e2fb44b..9db7bfe9da8 100644 --- a/gcc/defaults.h +++ b/gcc/defaults.h @@ -380,6 +380,22 @@ do { ASM_OUTPUT_LABEL(FILE,LABEL_ALTERNATE_NAME (INSN)); } while (0) #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. */ diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi index 547c09a247f..cf08b12d149 100644 --- a/gcc/doc/tm.texi +++ b/gcc/doc/tm.texi @@ -1695,6 +1695,20 @@ pointer to which the function's data is relative. 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 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 0924d2d7721..ee641bc8715 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2002-06-13 Richard Henderson + + * g++.old-deja/g++.abi/vtable2.C (INC_VDATA): New. Define for + ia64 ilp32. + 2002-06-12 Kriang Lerdsuwanakij * g++.dg/template/typename2.C: Update error message. diff --git a/gcc/testsuite/g++.old-deja/g++.abi/vtable2.C b/gcc/testsuite/g++.old-deja/g++.abi/vtable2.C index 9847a15a8b8..47afa15e807 100644 --- a/gcc/testsuite/g++.old-deja/g++.abi/vtable2.C +++ b/gcc/testsuite/g++.old-deja/g++.abi/vtable2.C @@ -130,10 +130,17 @@ 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) +#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 () @@ -145,18 +152,22 @@ 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); @@ -164,21 +175,26 @@ int main () 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); -- 2.30.2