mirror of git://gcc.gnu.org/git/gcc.git
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
This commit is contained in:
parent
9e990d1436
commit
3576f984e8
|
@ -1,3 +1,12 @@
|
||||||
|
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>
|
2011-09-22 Jan Hubicka <jh@suse.cz>
|
||||||
|
|
||||||
* ipa-inline-analysis.c: Fix overly long lines.
|
* ipa-inline-analysis.c: Fix overly long lines.
|
||||||
|
|
35
gcc/calls.c
35
gcc/calls.c
|
@ -3577,20 +3577,29 @@ emit_library_call_value_1 (int retval, rtx orgfun, rtx value,
|
||||||
argvec[count].partial
|
argvec[count].partial
|
||||||
= targetm.calls.arg_partial_bytes (args_so_far, mode, NULL_TREE, 1);
|
= targetm.calls.arg_partial_bytes (args_so_far, mode, NULL_TREE, 1);
|
||||||
|
|
||||||
locate_and_pad_parm (mode, NULL_TREE,
|
if (argvec[count].reg == 0
|
||||||
#ifdef STACK_PARMS_IN_REG_PARM_AREA
|
|| argvec[count].partial != 0
|
||||||
1,
|
|
||||||
#else
|
|
||||||
argvec[count].reg != 0,
|
|
||||||
#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)
|
|| reg_parm_stack_space > 0)
|
||||||
args_size.constant += argvec[count].locate.size.constant;
|
{
|
||||||
|
locate_and_pad_parm (mode, NULL_TREE,
|
||||||
|
#ifdef STACK_PARMS_IN_REG_PARM_AREA
|
||||||
|
1,
|
||||||
|
#else
|
||||||
|
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
|
||||||
|
|
||||||
targetm.calls.function_arg_advance (args_so_far, mode, (tree) 0, true);
|
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. */
|
aggregate types are placed in the lowest memory address. */
|
||||||
|
|
||||||
bool
|
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)
|
if (!TARGET_AAPCS_BASED)
|
||||||
return DEFAULT_FUNCTION_ARG_PADDING(mode, type) == upward;
|
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))
|
if (type && BYTES_BIG_ENDIAN && INTEGRAL_TYPE_P (type))
|
||||||
return false;
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Similarly, for use by BLOCK_REG_PADDING (MODE, TYPE, FIRST).
|
/* Similarly, for use by BLOCK_REG_PADDING (MODE, TYPE, FIRST).
|
||||||
For non-AAPCS, return !BYTES_BIG_ENDIAN if the least significant
|
Return !BYTES_BIG_ENDIAN if the least significant byte of the
|
||||||
byte of the register has useful data, and return the opposite if the
|
register has useful data, and return the opposite if the most
|
||||||
most significant byte does.
|
significant byte does. */
|
||||||
For AAPCS, small aggregates and small complex types are always padded
|
|
||||||
upwards. */
|
|
||||||
|
|
||||||
bool
|
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)
|
tree type, int first ATTRIBUTE_UNUSED)
|
||||||
{
|
{
|
||||||
if (TARGET_AAPCS_BASED
|
if (TARGET_AAPCS_BASED && BYTES_BIG_ENDIAN)
|
||||||
&& BYTES_BIG_ENDIAN
|
{
|
||||||
&& (AGGREGATE_TYPE_P (type) || TREE_CODE (type) == COMPLEX_TYPE
|
/* For AAPCS, small aggregates, small fixed-point types,
|
||||||
|| FIXED_POINT_TYPE_P (type))
|
and small complex types are always padded upwards. */
|
||||||
&& int_size_in_bytes (type) <= 4)
|
if (type)
|
||||||
return true;
|
{
|
||||||
|
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. */
|
/* Otherwise, use default padding. */
|
||||||
return !BYTES_BIG_ENDIAN;
|
return !BYTES_BIG_ENDIAN;
|
||||||
|
|
Loading…
Reference in New Issue