rs6000 va_arg patch
David Edelsohn
dje@watson.ibm.com
Wed Mar 13 10:37:00 GMT 2002
When I started converting the AIX/Darwin va_arg function to
calculate the size with trees, I noticed that it is identical to
std_expand_bulitin_va_arg. The only uniqueness is when to pad down.
Given that ia64.h references a variable local to the
std_expand_bulitin_va_arg where PAD_VARARGS_DOWN is invoked, I wasn't
going to be proud...
David
2002-03-13 David Edelsohn <edelsohn@gnu.org>
* config/rs6000/rs6000.h (PAD_VARARGS_DOWN): Define.
* config/rs6000/rs6000.c (rs6000_va_arg): Use
std_expand_builtin_va_arg if not ABI_V4.
Index: rs6000.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/rs6000/rs6000.c,v
retrieving revision 1.297
diff -c -p -r1.297 rs6000.c
*** rs6000.c 2002/03/12 18:01:18 1.297
--- rs6000.c 2002/03/13 16:48:45
*************** rs6000_va_arg (valist, type)
*** 3096,3143 ****
int indirect_p, size, rsize, n_reg, sav_ofs, sav_scale;
rtx lab_false, lab_over, addr_rtx, r;
- /* For AIX, the rule is that structures are passed left-aligned in
- their stack slot. However, GCC does not presently do this:
- structures which are the same size as integer types are passed
- right-aligned, as if they were in fact integers. This only
- matters for structures of size 1 or 2, or 4 when TARGET_64BIT. */
if (DEFAULT_ABI != ABI_V4)
! {
! HOST_WIDE_INT align, rounded_size;
! enum machine_mode mode;
! tree addr_tree;
!
! /* Compute the rounded size of the type. */
! align = PARM_BOUNDARY / BITS_PER_UNIT;
! rounded_size = (((int_size_in_bytes (type) + align - 1) / align)
! * align);
!
! addr_tree = valist;
!
! mode = TYPE_MODE (type);
! if (mode != BLKmode)
! {
! HOST_WIDE_INT adj;
! adj = TREE_INT_CST_LOW (TYPE_SIZE (type)) / BITS_PER_UNIT;
! if (rounded_size > align)
! adj = rounded_size;
!
! addr_tree = build (PLUS_EXPR, TREE_TYPE (addr_tree), addr_tree,
! build_int_2 (rounded_size - adj, 0));
! }
!
! addr_rtx = expand_expr (addr_tree, NULL_RTX, Pmode, EXPAND_NORMAL);
! addr_rtx = copy_to_reg (addr_rtx);
!
! /* Compute new value for AP. */
! t = build (MODIFY_EXPR, TREE_TYPE (valist), valist,
! build (PLUS_EXPR, TREE_TYPE (valist), valist,
! build_int_2 (rounded_size, 0)));
! TREE_SIDE_EFFECTS (t) = 1;
! expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
!
! return addr_rtx;
! }
f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
f_fpr = TREE_CHAIN (f_gpr);
--- 3094,3101 ----
int indirect_p, size, rsize, n_reg, sav_ofs, sav_scale;
rtx lab_false, lab_over, addr_rtx, r;
if (DEFAULT_ABI != ABI_V4)
! return std_expand_builtin_va_arg (valist, type);
f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
f_fpr = TREE_CHAIN (f_gpr);
Index: rs6000.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/rs6000/rs6000.h,v
retrieving revision 1.194
diff -c -p -r1.194 rs6000.h
*** rs6000.h 2002/03/12 18:01:17 1.194
--- rs6000.h 2002/03/13 16:48:46
*************** typedef struct rs6000_args
*** 1697,1702 ****
--- 1697,1710 ----
#define EXPAND_BUILTIN_VA_ARG(valist, type) \
rs6000_va_arg (valist, type)
+ /* For AIX, the rule is that structures are passed left-aligned in
+ their stack slot. However, GCC does not presently do this:
+ structures which are the same size as integer types are passed
+ right-aligned, as if they were in fact integers. This only
+ matters for structures of size 1 or 2, or 4 when TARGET_64BIT.
+ ABI_V4 does not use std_expand_builtin_va_arg. */
+ #define PAD_VARARGS_DOWN (TYPE_MODE (type) != BLKmode)
+
/* Define this macro to be a nonzero value if the location where a function
argument is passed depends on whether or not it is a named argument. */
#define STRICT_ARGUMENT_NAMING 1
More information about the Gcc-patches
mailing list