diff options
author | Richard Sandiford <rdsandiford@googlemail.com> | 2011-09-22 12:26:41 +0000 |
---|---|---|
committer | Richard Sandiford <rsandifo@gcc.gnu.org> | 2011-09-22 12:26:41 +0000 |
commit | 3576f984e8e8cc65385cffcba23f403632aa88c8 (patch) | |
tree | ea10f15658f10eca2def948025beed6db152833c | |
parent | 9e990d143674829b6583da2ab91030abbb8257dc (diff) | |
download | gcc-3576f984e8e8cc65385cffcba23f403632aa88c8.zip gcc-3576f984e8e8cc65385cffcba23f403632aa88c8.tar.gz gcc-3576f984e8e8cc65385cffcba23f403632aa88c8.tar.bz2 |
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
-rw-r--r-- | gcc/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/calls.c | 31 | ||||
-rw-r--r-- | gcc/config/arm/arm.c | 46 |
3 files changed, 53 insertions, 33 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 74482ed..ed624bb 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -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> * ipa-inline-analysis.c: Fix overly long lines. diff --git a/gcc/calls.c b/gcc/calls.c index 1413c8d..3fa70b5 100644 --- a/gcc/calls.c +++ b/gcc/calls.c @@ -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); } diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index b45f939..e730881 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -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; |