OSDN Git Service

* sh.c (sh_va_arg): If argument was passed by reference,
authoramylaar <amylaar@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 24 Apr 2002 22:12:32 +0000 (22:12 +0000)
committeramylaar <amylaar@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 24 Apr 2002 22:12:32 +0000 (22:12 +0000)
dereference the pointer.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@52734 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/config/sh/sh.c

index a4933fe..23175ed 100644 (file)
@@ -1,4 +1,7 @@
-Wed Apr 24 21:35:11 2002  J"orn Rennecke <joern.rennecke@superh.com>
+Wed Apr 24 21:51:54 2002  J"orn Rennecke <joern.rennecke@superh.com>
+
+       * sh.c (sh_va_arg): If argument was passed by reference,
+       dereference the pointer.
 
        * sh.h (PIC_OFFSET_TABLE_REGNUM): Conditionalize on flag_pic.
 
index d80801b..43c70a2 100644 (file)
@@ -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