OSDN Git Service

* ChangeLog: Follow spelling conventions.
[pf3gnuchains/gcc-fork.git] / gcc / calls.c
index 378c54f..d4e3f00 100644 (file)
@@ -91,7 +91,7 @@ struct arg_data
   /* Number of registers to use.  0 means put the whole arg in registers.
      Also 0 if not passed in registers.  */
   int partial;
-  /* Non-zero if argument must be passed on stack.
+  /* Nonzero if argument must be passed on stack.
      Note that some arguments may be passed on the stack
      even though pass_on_stack is zero, just because FUNCTION_ARG says so.
      pass_on_stack identifies arguments that *cannot* go in registers.  */
@@ -126,7 +126,7 @@ struct arg_data
   struct args_size alignment_pad;
 };
 
-/* A vector of one char per byte of stack space.  A byte if non-zero if
+/* A vector of one char per byte of stack space.  A byte if nonzero if
    the corresponding stack location has been used.
    This vector is used to prevent a function call within an argument from
    clobbering any stack already set up.  */
@@ -1965,7 +1965,7 @@ combine_pending_stack_adjustment_and_call (unadjusted_args_size,
 /* Scan X expression if it does not dereference any argument slots
    we already clobbered by tail call arguments (as noted in stored_args_map
    bitmap).
-   Return non-zero if X expression dereferences such argument slots,
+   Return nonzero if X expression dereferences such argument slots,
    zero otherwise.  */
 
 static int
@@ -2028,7 +2028,7 @@ check_sibcall_argument_overlap_1 (x)
 /* Scan sequence after INSN if it does not dereference any argument slots
    we already clobbered by tail call arguments (as noted in stored_args_map
    bitmap).  Add stack slots for ARG to stored_args_map bitmap afterwards.
-   Return non-zero if sequence after INSN dereferences such argument slots,
+   Return nonzero if sequence after INSN dereferences such argument slots,
    zero otherwise.  */
 
 static int
@@ -4148,9 +4148,9 @@ emit_library_call_value_1 (retval, orgfun, value, fn_type, outmode, nargs, p)
            emit_move_insn (value, mem_value);
        }
       else if (value != 0)
-       emit_move_insn (value, hard_libcall_value (outmode));
+       emit_move_insn (value, valreg);
       else
-       value = hard_libcall_value (outmode);
+       value = valreg;
     }
 
   if (ACCUMULATE_OUTGOING_ARGS)
@@ -4280,7 +4280,7 @@ emit_library_call_value VPARAMS((rtx orgfun, rtx value,
 
    FNDECL is the declaration of the function we are calling.
 
-   Return non-zero if this arg should cause sibcall failure,
+   Return nonzero if this arg should cause sibcall failure,
    zero otherwise.  */
 
 static int
@@ -4491,6 +4491,7 @@ store_one_arg (arg, argblock, flags, variable_size, reg_parm_stack_space)
     {
       /* BLKmode, at least partly to be pushed.  */
 
+      unsigned int parm_align;
       int excess;
       rtx size_rtx;
 
@@ -4516,6 +4517,23 @@ store_one_arg (arg, argblock, flags, variable_size, reg_parm_stack_space)
                                  NULL_RTX, TYPE_MODE (sizetype), 0);
        }
 
+      /* Some types will require stricter alignment, which will be
+        provided for elsewhere in argument layout.  */
+      parm_align = MAX (PARM_BOUNDARY, TYPE_ALIGN (TREE_TYPE (pval)));
+
+      /* When an argument is padded down, the block is aligned to
+        PARM_BOUNDARY, but the actual argument isn't.  */
+      if (FUNCTION_ARG_PADDING (arg->mode, TREE_TYPE (pval)) == downward)
+       {
+         if (arg->size.var)
+           parm_align = BITS_PER_UNIT;
+         else if (excess)
+           {
+             int excess_align = (excess & -excess) * BITS_PER_UNIT;
+             parm_align = MIN (parm_align, excess_align);
+           }
+       }
+
       if ((flags & ECF_SIBCALL) && GET_CODE (arg->value) == MEM)
        {
          /* emit_push_insn might not work properly if arg->value and
@@ -4573,8 +4591,7 @@ store_one_arg (arg, argblock, flags, variable_size, reg_parm_stack_space)
           {
            rtx size_rtx1 = GEN_INT (reg_parm_stack_space - arg->offset.constant);
            emit_push_insn (arg->value, arg->mode, TREE_TYPE (pval), size_rtx1,
-                           MAX (PARM_BOUNDARY, TYPE_ALIGN (TREE_TYPE (pval))),
-                           partial, reg, excess, argblock,
+                           parm_align, partial, reg, excess, argblock,
                            ARGS_SIZE_RTX (arg->offset), reg_parm_stack_space,
                            ARGS_SIZE_RTX (arg->alignment_pad));
          }
@@ -4582,8 +4599,7 @@ store_one_arg (arg, argblock, flags, variable_size, reg_parm_stack_space)
        
 
       emit_push_insn (arg->value, arg->mode, TREE_TYPE (pval), size_rtx,
-                     MAX (PARM_BOUNDARY, TYPE_ALIGN (TREE_TYPE (pval))),
-                     partial, reg, excess, argblock,
+                     parm_align, partial, reg, excess, argblock,
                      ARGS_SIZE_RTX (arg->offset), reg_parm_stack_space,
                      ARGS_SIZE_RTX (arg->alignment_pad));