Commit 3576f984 by Richard Sandiford Committed by Richard Sandiford

re PR middle-end/50113 (soft-float MIPS64 compiler is miscompiling ggc-page.c)

gcc/
	PR middle-end/50113
	PR middle-end/50061
	* calls.c (emit_library_call_value_1): Use BLOCK_REG_PADDING to
	get the locate.where_pad value for register-only arguments.
	* config/arm/arm.c (arm_pad_arg_upward): Remove HFmode handling.
	(arm_pad_reg_upward): Handle null types.

From-SVN: r179085
parent 9e990d14
2011-09-22 Richard Sandiford <rdsandiford@googlemail.com>
PR middle-end/50113
PR middle-end/50061
* calls.c (emit_library_call_value_1): Use BLOCK_REG_PADDING to
get the locate.where_pad value for register-only arguments.
* config/arm/arm.c (arm_pad_arg_upward): Remove HFmode handling.
(arm_pad_reg_upward): Handle null types.
2011-09-22 Jan Hubicka <jh@suse.cz>
* ipa-inline-analysis.c: Fix overly long lines.
......@@ -3577,20 +3577,29 @@ emit_library_call_value_1 (int retval, rtx orgfun, rtx value,
argvec[count].partial
= targetm.calls.arg_partial_bytes (args_so_far, mode, NULL_TREE, 1);
locate_and_pad_parm (mode, NULL_TREE,
if (argvec[count].reg == 0
|| argvec[count].partial != 0
|| reg_parm_stack_space > 0)
{
locate_and_pad_parm (mode, NULL_TREE,
#ifdef STACK_PARMS_IN_REG_PARM_AREA
1,
1,
#else
argvec[count].reg != 0,
argvec[count].reg != 0,
#endif
argvec[count].partial,
NULL_TREE, &args_size, &argvec[count].locate);
args_size.constant += argvec[count].locate.size.constant;
gcc_assert (!argvec[count].locate.size.var);
}
#ifdef BLOCK_REG_PADDING
else
/* The argument is passed entirely in registers. See at which
end it should be padded. */
argvec[count].locate.where_pad =
BLOCK_REG_PADDING (mode, NULL_TREE,
GET_MODE_SIZE (mode) <= UNITS_PER_WORD);
#endif
argvec[count].partial,
NULL_TREE, &args_size, &argvec[count].locate);
gcc_assert (!argvec[count].locate.size.var);
if (argvec[count].reg == 0 || argvec[count].partial != 0
|| reg_parm_stack_space > 0)
args_size.constant += argvec[count].locate.size.constant;
targetm.calls.function_arg_advance (args_so_far, mode, (tree) 0, true);
}
......
......@@ -11573,7 +11573,7 @@ arm_must_pass_in_stack (enum machine_mode mode, const_tree type)
aggregate types are placed in the lowest memory address. */
bool
arm_pad_arg_upward (enum machine_mode mode, const_tree type)
arm_pad_arg_upward (enum machine_mode mode ATTRIBUTE_UNUSED, const_tree type)
{
if (!TARGET_AAPCS_BASED)
return DEFAULT_FUNCTION_ARG_PADDING(mode, type) == upward;
......@@ -11581,36 +11581,38 @@ arm_pad_arg_upward (enum machine_mode mode, const_tree type)
if (type && BYTES_BIG_ENDIAN && INTEGRAL_TYPE_P (type))
return false;
/* Half-float values are only passed to libcalls, not regular functions.
They should be passed and returned as "short"s (see RTABI). To achieve
that effect in big-endian mode, pad downwards so the value is passed in
the least-significant end of the register. ??? This needs to be here
rather than in arm_pad_reg_upward due to peculiarity in the handling of
libcall arguments. */
if (BYTES_BIG_ENDIAN && mode == HFmode)
return false;
return true;
}
/* Similarly, for use by BLOCK_REG_PADDING (MODE, TYPE, FIRST).
For non-AAPCS, return !BYTES_BIG_ENDIAN if the least significant
byte of the register has useful data, and return the opposite if the
most significant byte does.
For AAPCS, small aggregates and small complex types are always padded
upwards. */
Return !BYTES_BIG_ENDIAN if the least significant byte of the
register has useful data, and return the opposite if the most
significant byte does. */
bool
arm_pad_reg_upward (enum machine_mode mode ATTRIBUTE_UNUSED,
arm_pad_reg_upward (enum machine_mode mode,
tree type, int first ATTRIBUTE_UNUSED)
{
if (TARGET_AAPCS_BASED
&& BYTES_BIG_ENDIAN
&& (AGGREGATE_TYPE_P (type) || TREE_CODE (type) == COMPLEX_TYPE
|| FIXED_POINT_TYPE_P (type))
&& int_size_in_bytes (type) <= 4)
return true;
if (TARGET_AAPCS_BASED && BYTES_BIG_ENDIAN)
{
/* For AAPCS, small aggregates, small fixed-point types,
and small complex types are always padded upwards. */
if (type)
{
if ((AGGREGATE_TYPE_P (type)
|| TREE_CODE (type) == COMPLEX_TYPE
|| FIXED_POINT_TYPE_P (type))
&& int_size_in_bytes (type) <= 4)
return true;
}
else
{
if ((COMPLEX_MODE_P (mode) || ALL_FIXED_POINT_MODE_P (mode))
&& GET_MODE_SIZE (mode) <= 4)
return true;
}
}
/* Otherwise, use default padding. */
return !BYTES_BIG_ENDIAN;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment