summaryrefslogtreecommitdiff
path: root/gcc/config/sh
diff options
context:
space:
mode:
authoramylaar <amylaar@138bc75d-0d04-0410-961f-82ee72b054a4>2002-04-24 22:12:32 +0000
committeramylaar <amylaar@138bc75d-0d04-0410-961f-82ee72b054a4>2002-04-24 22:12:32 +0000
commita3e17e8ceb646c36ce3d461909be087e27e36e70 (patch)
tree7e7fc1163c7db3f8fa05f975bc16677b82179d34 /gcc/config/sh
parent575fdeec28192d6fce18f5564250d018212ba391 (diff)
downloadgcc-a3e17e8ceb646c36ce3d461909be087e27e36e70.tar.gz
* sh.c (sh_va_arg): If argument was passed by reference,
dereference the pointer. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@52734 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/config/sh')
-rw-r--r--gcc/config/sh/sh.c19
1 files changed, 18 insertions, 1 deletions
diff --git a/gcc/config/sh/sh.c b/gcc/config/sh/sh.c
index d80801b54ee..43c70a29cc5 100644
--- a/gcc/config/sh/sh.c
+++ b/gcc/config/sh/sh.c
@@ -5293,11 +5293,16 @@ sh_va_arg (valist, type)
HOST_WIDE_INT size, rsize;
tree tmp, pptr_type_node;
rtx addr_rtx, r;
+ rtx result;
+ int pass_by_ref = MUST_PASS_IN_STACK (TYPE_MODE (type), type);
size = int_size_in_bytes (type);
rsize = (size + UNITS_PER_WORD - 1) & -UNITS_PER_WORD;
pptr_type_node = build_pointer_type (ptr_type_node);
+ if (pass_by_ref)
+ type = build_pointer_type (type);
+
if (! TARGET_SH5 && (TARGET_SH3E || TARGET_SH4) && ! TARGET_HITACHI)
{
tree f_next_o, f_next_o_limit, f_next_fp, f_next_fp_limit, f_next_stack;
@@ -5411,7 +5416,19 @@ sh_va_arg (valist, type)
/* ??? In va-sh.h, there had been code to make values larger than
size 8 indirect. This does not match the FUNCTION_ARG macros. */
- return std_expand_builtin_va_arg (valist, type);
+ result = std_expand_builtin_va_arg (valist, type);
+ if (pass_by_ref)
+ {
+#ifdef POINTERS_EXTEND_UNSIGNED
+ if (GET_MODE (addr) != Pmode)
+ addr = convert_memory_address (Pmode, result);
+#endif
+ result = gen_rtx_MEM (ptr_mode, force_reg (Pmode, result));
+ set_mem_alias_set (result, get_varargs_alias_set ());
+ }
+ /* ??? expand_builtin_va_arg will also set the alias set of the dereferenced
+ argument to the varargs alias set. */
+ return result;
}
/* Define the offset between two registers, one to be eliminated, and