From c8c99a68775bacea4b8986024cca0d2b0e62b451 Mon Sep 17 00:00:00 2001 From: David Edelsohn Date: Wed, 29 Jan 2003 17:37:25 +0000 Subject: [PATCH] rs6000.c (function_arg_pass_by_reference): Return true for variable sized types. * config/rs6000/rs6000.c (function_arg_pass_by_reference): Return true for variable sized types. (rs6000_va_arg): Handle variable sized types passed by reference on non-SVR4 ABI. From-SVN: r62095 --- gcc/ChangeLog | 7 +++++++ gcc/config/rs6000/rs6000.c | 31 +++++++++++++++++++++++++++---- 2 files changed, 34 insertions(+), 4 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 744f12683d5..8d908ff23a6 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2003-01-29 David Edelsohn + + * config/rs6000/rs6000.c (function_arg_pass_by_reference): + Return true for variable sized types. + (rs6000_va_arg): Handle variable sized types passed by reference + on non-SVR4 ABI. + 2003-01-29 Richard Earnshaw * arm.c (arm_legtimize_address): New function. diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index 31eb55e2ec7..41284e87cc8 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -3314,7 +3314,10 @@ function_arg_partial_nregs (cum, mode, type, named) the argument itself. The pointer is passed in whatever way is appropriate for passing a pointer to that type. - Under V.4, structures and unions are passed by reference. */ + Under V.4, structures and unions are passed by reference. + + As an extension to all ABIs, variable sized types are passed by + reference. */ int function_arg_pass_by_reference (cum, mode, type, named) @@ -3332,8 +3335,7 @@ function_arg_pass_by_reference (cum, mode, type, named) return 1; } - - return 0; + return type && int_size_in_bytes (type) <= 0; } /* Perform any needed actions needed for a function that is receiving a @@ -3569,7 +3571,28 @@ rs6000_va_arg (valist, type) rtx lab_false, lab_over, addr_rtx, r; if (DEFAULT_ABI != ABI_V4) - return std_expand_builtin_va_arg (valist, type); + { + /* Variable sized types are passed by reference. */ + if (int_size_in_bytes (type) <= 0) + { + u = build_pointer_type (type); + + /* Args grow upward. */ + t = build (POSTINCREMENT_EXPR, TREE_TYPE (valist), valist, + build_int_2 (POINTER_SIZE / BITS_PER_UNIT, 0)); + TREE_SIDE_EFFECTS (t) = 1; + + t = build1 (NOP_EXPR, build_pointer_type (u), t); + TREE_SIDE_EFFECTS (t) = 1; + + t = build1 (INDIRECT_REF, u, t); + TREE_SIDE_EFFECTS (t) = 1; + + return expand_expr (t, NULL_RTX, VOIDmode, EXPAND_NORMAL); + } + else + return std_expand_builtin_va_arg (valist, type); + } f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node)); f_fpr = TREE_CHAIN (f_gpr);