diff options
author | David Edelsohn <edelsohn@gnu.org> | 2003-01-29 17:37:25 +0000 |
---|---|---|
committer | David Edelsohn <dje@gcc.gnu.org> | 2003-01-29 12:37:25 -0500 |
commit | c8c99a68775bacea4b8986024cca0d2b0e62b451 (patch) | |
tree | 61f6e6fb66454a09fc43b654799025f56490d708 /gcc | |
parent | ccf4d5128446c504efe2133f907f8b13181b0f3c (diff) | |
download | gcc-c8c99a68775bacea4b8986024cca0d2b0e62b451.zip gcc-c8c99a68775bacea4b8986024cca0d2b0e62b451.tar.gz gcc-c8c99a68775bacea4b8986024cca0d2b0e62b451.tar.bz2 |
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
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/config/rs6000/rs6000.c | 31 |
2 files changed, 34 insertions, 4 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 744f126..8d908ff 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2003-01-29 David Edelsohn <edelsohn@gnu.org> + + * 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 <rearnsha@arm.com> * arm.c (arm_legtimize_address): New function. diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index 31eb55e..41284e8 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); |