Patch for IA64 32-bit function descriptors
Richard Henderson
rth@redhat.com
Thu Jun 13 17:54:00 GMT 2002
On Tue, Jun 04, 2002 at 02:28:43PM -0700, Jessica Han wrote:
> 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.
(1) Your mailer line-wrapped the patch, ruining it.
(2) The patch does not follow gnu style guidelines.
(3) The patch continues to be needlessly hpux specific.
I've re-written the patch and tested it for basic sanity on
ia64-linux.
r~
* 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.
Index: defaults.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/defaults.h,v
retrieving revision 1.78
diff -c -p -d -r1.78 defaults.h
*** defaults.h 11 Jun 2002 21:34:30 -0000 1.78
--- defaults.h 13 Jun 2002 21:12:03 -0000
*************** do { ASM_OUTPUT_LABEL(FILE,LABEL_ALTERNA
*** 380,385 ****
--- 380,401 ----
#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. */
Index: config/ia64/ia64.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/ia64/ia64.h,v
retrieving revision 1.120
diff -c -p -d -r1.120 ia64.h
*** config/ia64/ia64.h 12 Jun 2002 03:06:17 -0000 1.120
--- config/ia64/ia64.h 13 Jun 2002 21:12:03 -0000
*************** while (0)
*** 342,349 ****
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
/* Layout of Source Language Data Types */
--- 342,362 ----
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.
!
! 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 */
*************** do { \
*** 1454,1462 ****
do { \
if ((PART) == 0) \
{ \
! fputs ("\tdata16.ua @iplt(", FILE); \
assemble_name (FILE, XSTR (XEXP (DECL_RTL (DECL), 0), 0)); \
fputs (")\n", FILE); \
} \
} while (0)
--- 1467,1480 ----
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)
Index: cp/class.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/class.c,v
retrieving revision 1.450
diff -c -p -d -r1.450 class.c
*** cp/class.c 4 Jun 2002 07:09:56 -0000 1.450
--- cp/class.c 13 Jun 2002 21:12:03 -0000
*************** build_vtable (class_type, name, vtable_t
*** 510,515 ****
--- 510,517 ----
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;
*************** build_vtbl_initializer (binfo, orig_binf
*** 7500,7506 ****
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);
--- 7502,7508 ----
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 * TARGET_VTABLE_DATA_ENTRY_DISTANCE);
/* Add entries to the vtable for RTTI. */
build_rtti_vtbl_entries (binfo, &vid);
*************** build_vtbl_initializer (binfo, orig_binf
*** 7518,7523 ****
--- 7520,7534 ----
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))
+ *prev = tree_cons (NULL_TREE, null_pointer_node, cur);
+ }
+
if (non_fn_entries_p)
*non_fn_entries_p = list_length (vid.inits);
*************** build_vbase_offset_vtbl_entries (binfo,
*** 7735,7741 ****
}
/* 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
--- 7746,7753 ----
}
/* The next vbase will come at a more negative offset. */
! 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
Index: cp/rtti.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/rtti.c,v
retrieving revision 1.134
diff -c -p -d -r1.134 rtti.c
*** cp/rtti.c 16 May 2002 04:48:52 -0000 1.134
--- cp/rtti.c 13 Jun 2002 21:12:04 -0000
*************** build_headof (exp)
*** 102,108 ****
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);
--- 102,108 ----
exp = save_expr (exp);
/* The offset-to-top field is at index -2 from the vptr. */
! index = build_int_2 (-2 * TARGET_VTABLE_DATA_ENTRY_DISTANCE, -1);
offset = build_vtbl_ref (build_indirect_ref (exp, NULL), index);
*************** get_tinfo_decl_dynamic (exp)
*** 181,187 ****
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,187 ----
tree index;
/* The RTTI information is at index -1. */
! 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;
*************** create_pseudo_type_info VPARAMS((const c
*** 1180,1191 ****
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)));
TREE_CONSTANT (vtable_decl) = 1;
/* First field is the pseudo type_info base class. */
--- 1180,1190 ----
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 * 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. */
Index: doc/tm.texi
===================================================================
RCS file: /cvs/gcc/gcc/gcc/doc/tm.texi,v
retrieving revision 1.138
diff -c -p -d -r1.138 tm.texi
*** doc/tm.texi 11 Jun 2002 07:26:38 -0000 1.138
--- doc/tm.texi 13 Jun 2002 21:12:04 -0000
*************** pointer to which the function's data is
*** 1695,1700 ****
--- 1695,1714 ----
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
Index: testsuite/g++.old-deja/g++.abi/vtable2.C
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/g++.old-deja/g++.abi/vtable2.C,v
retrieving revision 1.5
diff -c -p -d -r1.5 vtable2.C
*** testsuite/g++.old-deja/g++.abi/vtable2.C 21 Sep 2001 16:58:22 -0000 1.5
--- testsuite/g++.old-deja/g++.abi/vtable2.C 13 Jun 2002 21:12:04 -0000
*************** void _ZN2S42s1Ev ();
*** 130,139 ****
--- 130,146 ----
// 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 ()
*************** int main ()
*** 145,162 ****
// Set vtbl to point at the beginning of S4's primary vtable.
vptr = (ptrdiff_t **) &s4;
vtbl = *vptr;
! vtbl -= 5;
! if (*vtbl++ != ((char*) (S0*) &s4) - (char*) &s4)
return 1;
! if (*vtbl++ != ((char*) (S1*) &s4) - (char*) &s4)
return 2;
! if (*vtbl++ != ((char*) (S2*) &s4) - (char*) &s4)
return 3;
! if (*vtbl++ != 0)
return 4;
// Skip the RTTI entry.
! vtbl++;
if (! CMP_VPTR (vtbl, &_ZN2S32s3Ev))
return 5;
INC_VPTR (vtbl);
--- 152,173 ----
// Set vtbl to point at the beginning of S4's primary vtable.
vptr = (ptrdiff_t **) &s4;
vtbl = *vptr;
! INC_VDATA (vtbl, -5);
! if (*vtbl != ((char*) (S0*) &s4) - (char*) &s4)
return 1;
! INC_VDATA (vtbl, 1);
! if (*vtbl != ((char*) (S1*) &s4) - (char*) &s4)
return 2;
! INC_VDATA (vtbl, 1);
! if (*vtbl != ((char*) (S2*) &s4) - (char*) &s4)
return 3;
! INC_VDATA (vtbl, 1);
! if (*vtbl != 0)
return 4;
+ INC_VDATA (vtbl, 1);
// Skip the RTTI entry.
! INC_VDATA (vtbl, 1);
if (! CMP_VPTR (vtbl, &_ZN2S32s3Ev))
return 5;
INC_VPTR (vtbl);
*************** int main ()
*** 164,184 ****
return 6;
INC_VPTR (vtbl);
// The S1 vbase offset.
! if (*vtbl++ != 0)
return 7;
// 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 (*vtbl++ != 0)
return 9;
! if (*vtbl++ != 0)
return 10;
// Now we're at the S2 offset to top entry.
! if (*vtbl++ != ((char*) &s4 - (char*) (S2*) &s4))
return 11;
// Skip the RTTI entry.
! vtbl++;
// Skip the remaining virtual functions -- they are thunks.
INC_VPTR (vtbl);
INC_VPTR (vtbl);
--- 175,200 ----
return 6;
INC_VPTR (vtbl);
// The S1 vbase offset.
! 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))
return 8;
! INC_VDATA (vtbl, 1);
! if (*vtbl != 0)
return 9;
! 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))
return 11;
+ INC_VDATA (vtbl, 1);
// Skip the RTTI entry.
! INC_VDATA (vtbl, 1);
// Skip the remaining virtual functions -- they are thunks.
INC_VPTR (vtbl);
INC_VPTR (vtbl);
More information about the Libstdc++
mailing list