aboutsummaryrefslogtreecommitdiff
path: root/gcc/calls.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/calls.c')
-rw-r--r--gcc/calls.c35
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