diff options
Diffstat (limited to 'gcc/calls.c')
-rw-r--r-- | gcc/calls.c | 35 |
1 files changed, 24 insertions, 11 deletions
diff --git a/gcc/calls.c b/gcc/calls.c index 64f9f50..8ae9899 100644 --- a/gcc/calls.c +++ b/gcc/calls.c @@ -2002,6 +2002,8 @@ initialize_argument_information (int num_actuals ATTRIBUTE_UNUSED, args[i].unsignedp = unsignedp; args[i].mode = mode; + targetm.calls.warn_parameter_passing_abi (args_so_far, type); + args[i].reg = targetm.calls.function_arg (args_so_far, mode, type, argpos < n_named_args); @@ -5514,7 +5516,11 @@ store_one_arg (struct arg_data *arg, rtx argblock, int flags, Note that in C the default argument promotions will prevent such mismatches. */ - size = GET_MODE_SIZE (arg->mode); + if (TYPE_EMPTY_P (TREE_TYPE (pval))) + size = 0; + else + size = GET_MODE_SIZE (arg->mode); + /* Compute how much space the push instruction will push. On many machines, pushing a byte will advance the stack pointer by a halfword. */ @@ -5546,10 +5552,12 @@ store_one_arg (struct arg_data *arg, rtx argblock, int flags, /* This isn't already where we want it on the stack, so put it there. This can either be done with push or copy insns. */ - if (!emit_push_insn (arg->value, arg->mode, TREE_TYPE (pval), NULL_RTX, - parm_align, partial, reg, used - size, argblock, - ARGS_SIZE_RTX (arg->locate.offset), reg_parm_stack_space, - ARGS_SIZE_RTX (arg->locate.alignment_pad), true)) + if (used + && !emit_push_insn (arg->value, arg->mode, TREE_TYPE (pval), + NULL_RTX, parm_align, partial, reg, used - size, + argblock, ARGS_SIZE_RTX (arg->locate.offset), + reg_parm_stack_space, + ARGS_SIZE_RTX (arg->locate.alignment_pad), true)) sibcall_failure = 1; /* Unless this is a partially-in-register argument, the argument is now @@ -5582,9 +5590,9 @@ store_one_arg (struct arg_data *arg, rtx argblock, int flags, /* PUSH_ROUNDING has no effect on us, because emit_push_insn for BLKmode is careful to avoid it. */ excess = (arg->locate.size.constant - - int_size_in_bytes (TREE_TYPE (pval)) + - arg_int_size_in_bytes (TREE_TYPE (pval)) + partial); - size_rtx = expand_expr (size_in_bytes (TREE_TYPE (pval)), + size_rtx = expand_expr (arg_size_in_bytes (TREE_TYPE (pval)), NULL_RTX, TYPE_MODE (sizetype), EXPAND_NORMAL); } @@ -5660,10 +5668,12 @@ store_one_arg (struct arg_data *arg, rtx argblock, int flags, } } - emit_push_insn (arg->value, arg->mode, TREE_TYPE (pval), size_rtx, - parm_align, partial, reg, excess, argblock, - ARGS_SIZE_RTX (arg->locate.offset), reg_parm_stack_space, - ARGS_SIZE_RTX (arg->locate.alignment_pad), false); + if (!CONST_INT_P (size_rtx) || INTVAL (size_rtx) != 0) + emit_push_insn (arg->value, arg->mode, TREE_TYPE (pval), size_rtx, + parm_align, partial, reg, excess, argblock, + ARGS_SIZE_RTX (arg->locate.offset), + reg_parm_stack_space, + ARGS_SIZE_RTX (arg->locate.alignment_pad), false); /* Unless this is a partially-in-register argument, the argument is now in the stack. @@ -5741,6 +5751,9 @@ must_pass_in_stack_var_size_or_pad (machine_mode mode, const_tree type) if (TREE_ADDRESSABLE (type)) return true; + if (TYPE_EMPTY_P (type)) + return false; + /* If the padding and mode of the type is such that a copy into a register would put it into the wrong part of the register. */ if (mode == BLKmode |