aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorUlrich Weigand <uweigand@de.ibm.com>2013-11-14 18:40:12 +0000
committerUlrich Weigand <uweigand@gcc.gnu.org>2013-11-14 18:40:12 +0000
commit140f2c812c50fbe104c3a251c530454a2682c891 (patch)
tree352fd46734142ede2b538e30baf7ebe488007529
parent98eefff6bc1c3e497f961128240980e6758dec10 (diff)
downloadgcc-140f2c812c50fbe104c3a251c530454a2682c891.zip
gcc-140f2c812c50fbe104c3a251c530454a2682c891.tar.gz
gcc-140f2c812c50fbe104c3a251c530454a2682c891.tar.bz2
rs6000.c (rs6000_arg_partial_bytes): Simplify logic by making use of the fact that for vector / floating point...
2013-11-14 Ulrich Weigand <Ulrich.Weigand@de.ibm.com> * config/rs6000/rs6000.c (rs6000_arg_partial_bytes): Simplify logic by making use of the fact that for vector / floating point arguments passed both in VRs/FPRs and in the fixed parameter area, the partial bytes mechanism is in fact not used. From-SVN: r204807
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/config/rs6000/rs6000.c35
2 files changed, 31 insertions, 11 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index bf58d4b..6d83b32 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,12 @@
2013-11-14 Ulrich Weigand <Ulrich.Weigand@de.ibm.com>
+ * config/rs6000/rs6000.c (rs6000_arg_partial_bytes): Simplify logic
+ by making use of the fact that for vector / floating point arguments
+ passed both in VRs/FPRs and in the fixed parameter area, the partial
+ bytes mechanism is in fact not used.
+
+2013-11-14 Ulrich Weigand <Ulrich.Weigand@de.ibm.com>
+
* config/rs6000/rs6000.c (rs6000_psave_function_arg): New function.
(rs6000_finish_function_arg): Likewise.
(rs6000_function_arg): Use rs6000_psave_function_arg and
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index dd95494..039868a 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -9840,15 +9840,25 @@ rs6000_arg_partial_bytes (cumulative_args_t cum_v, enum machine_mode mode,
tree type, bool named)
{
CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
+ bool passed_in_gprs = true;
int ret = 0;
int align_words;
if (DEFAULT_ABI == ABI_V4)
return 0;
- if (USE_ALTIVEC_FOR_ARG_P (cum, mode, named)
- && cum->nargs_prototype >= 0)
- return 0;
+ if (USE_ALTIVEC_FOR_ARG_P (cum, mode, named))
+ {
+ /* If we are passing this arg in the fixed parameter save area
+ (gprs or memory) as well as VRs, we do not use the partial
+ bytes mechanism; instead, rs6000_function_arg will return a
+ PARALLEL including a memory element as necessary. */
+ if (TARGET_64BIT && ! cum->prototype)
+ return 0;
+
+ /* Otherwise, we pass in VRs only. No partial copy possible. */
+ passed_in_gprs = false;
+ }
/* In this complicated case we just disable the partial_nregs code. */
if (TARGET_MACHO && rs6000_darwin64_struct_check_p (mode, type))
@@ -9858,24 +9868,27 @@ rs6000_arg_partial_bytes (cumulative_args_t cum_v, enum machine_mode mode,
if (USE_FP_FOR_ARG_P (cum, mode))
{
+ unsigned long n_fpreg = (GET_MODE_SIZE (mode) + 7) >> 3;
+
/* If we are passing this arg in the fixed parameter save area
- (gprs or memory) as well as fprs, then this function should
- return the number of partial bytes passed in the parameter
- save area rather than partial bytes passed in fprs. */
+ (gprs or memory) as well as FPRs, we do not use the partial
+ bytes mechanism; instead, rs6000_function_arg will return a
+ PARALLEL including a memory element as necessary. */
if (type
&& (cum->nargs_prototype <= 0
|| (DEFAULT_ABI == ABI_AIX
&& TARGET_XL_COMPAT
&& align_words >= GP_ARG_NUM_REG)))
return 0;
- else if (cum->fregno + ((GET_MODE_SIZE (mode) + 7) >> 3)
- > FP_ARG_MAX_REG + 1)
+
+ /* Otherwise, we pass in FPRs only. Check for partial copies. */
+ passed_in_gprs = false;
+ if (cum->fregno + n_fpreg > FP_ARG_MAX_REG + 1)
ret = (FP_ARG_MAX_REG + 1 - cum->fregno) * 8;
- else if (cum->nargs_prototype >= 0)
- return 0;
}
- if (align_words < GP_ARG_NUM_REG
+ if (passed_in_gprs
+ && align_words < GP_ARG_NUM_REG
&& GP_ARG_NUM_REG < align_words + rs6000_arg_size (mode, type))
ret = (GP_ARG_NUM_REG - align_words) * (TARGET_32BIT ? 4 : 8);