Commit b2d04ecf by Alan Modra Committed by Alan Modra

rs6000.c (function_arg_boundary): Always align AltiVec vectors.

	* config/rs6000/rs6000.c (function_arg_boundary): Always align
	AltiVec vectors.
	(function_arg_advance): Pass TARGET_32BIT -mabi=no-altivec AltiVec
	vectors by refererence.  Align the same for TARGET_64BIT to a 16
	byte boundary.  Remove useless code.  Add function comment.
	(function_arg): Similarly.  Move gpr rs6000_mixed_function_arg
	call to where it belongs.
	(function_arg_partial_nregs): Return true for all TARGET_32BIT
	-mabi=no-altivec AltiVec vectors.  Fix debug output.
	(rs6000_va_arg): Adjust for AltiVec change.

From-SVN: r81666
parent b6685939
2004-05-10 Alan Modra <amodra@bigpond.net.au>
* config/rs6000/rs6000.c (function_arg_boundary): Always align
AltiVec vectors.
(function_arg_advance): Pass TARGET_32BIT -mabi=no-altivec AltiVec
vectors by refererence. Align the same for TARGET_64BIT to a 16
byte boundary. Remove useless code. Add function comment.
(function_arg): Similarly. Move gpr rs6000_mixed_function_arg
call to where it belongs.
(function_arg_partial_nregs): Return true for all TARGET_32BIT
-mabi=no-altivec AltiVec vectors. Fix debug output.
(rs6000_va_arg): Adjust for AltiVec change.
2004-05-10 Paul Brook <paul@codesourcery.com> 2004-05-10 Paul Brook <paul@codesourcery.com>
* config/arm/arm.c (arm_promote_prototypes): Use TARGET_AAPCS_BASED. * config/arm/arm.c (arm_promote_prototypes): Use TARGET_AAPCS_BASED.
......
...@@ -4192,7 +4192,7 @@ function_arg_boundary (enum machine_mode mode, tree type ATTRIBUTE_UNUSED) ...@@ -4192,7 +4192,7 @@ function_arg_boundary (enum machine_mode mode, tree type ATTRIBUTE_UNUSED)
return 64; return 64;
else if (SPE_VECTOR_MODE (mode)) else if (SPE_VECTOR_MODE (mode))
return 64; return 64;
else if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode)) else if (ALTIVEC_VECTOR_MODE (mode))
return 128; return 128;
else else
return PARM_BOUNDARY; return PARM_BOUNDARY;
...@@ -4218,7 +4218,11 @@ rs6000_arg_size (enum machine_mode mode, tree type) ...@@ -4218,7 +4218,11 @@ rs6000_arg_size (enum machine_mode mode, tree type)
/* Update the data in CUM to advance over an argument /* Update the data in CUM to advance over an argument
of mode MODE and data type TYPE. of mode MODE and data type TYPE.
(TYPE is null for libcalls where that information may not be available.) */ (TYPE is null for libcalls where that information may not be available.)
Note that for args passed by reference, function_arg will be called
with MODE and TYPE set to that of the pointer to the arg, not the arg
itself. */
void void
function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode, function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode,
...@@ -4295,18 +4299,9 @@ function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode, ...@@ -4295,18 +4299,9 @@ function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode,
} }
else else
{ {
int n_words; int n_words = rs6000_arg_size (mode, type);
int gregno = cum->sysv_gregno; int gregno = cum->sysv_gregno;
/* Aggregates, IEEE quad, and AltiVec vectors get passed by
reference. */
if ((type && AGGREGATE_TYPE_P (type))
|| mode == TFmode
|| ALTIVEC_VECTOR_MODE (mode))
n_words = 1;
else
n_words = rs6000_arg_size (mode, type);
/* Long long and SPE vectors are put in (r3,r4), (r5,r6), /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
(r7,r8) or (r9,r10). As does any other 2 word item such (r7,r8) or (r9,r10). As does any other 2 word item such
as complex int due to a historical mistake. */ as complex int due to a historical mistake. */
...@@ -4342,10 +4337,16 @@ function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode, ...@@ -4342,10 +4337,16 @@ function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode,
} }
else else
{ {
int align = (TARGET_32BIT && (cum->words & 1) != 0 int n_words = rs6000_arg_size (mode, type);
&& function_arg_boundary (mode, type) == 64) ? 1 : 0; int align = function_arg_boundary (mode, type) / PARM_BOUNDARY - 1;
cum->words += align + rs6000_arg_size (mode, type); /* The simple alignment calculation here works because
function_arg_boundary / PARM_BOUNDARY will only be 1 or 2.
If we ever want to handle alignments larger than 8 bytes for
32-bit or 16 bytes for 64-bit, then we'll need to take into
account the offset to the start of the parm save area. */
align &= cum->words;
cum->words += align + n_words;
if (GET_MODE_CLASS (mode) == MODE_FLOAT if (GET_MODE_CLASS (mode) == MODE_FLOAT
&& TARGET_HARD_FLOAT && TARGET_FPRS) && TARGET_HARD_FLOAT && TARGET_FPRS)
...@@ -4544,7 +4545,11 @@ rs6000_mixed_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, ...@@ -4544,7 +4545,11 @@ rs6000_mixed_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
both an FP and integer register (or possibly FP reg and stack). Library both an FP and integer register (or possibly FP reg and stack). Library
functions (when CALL_LIBCALL is set) always have the proper types for args, functions (when CALL_LIBCALL is set) always have the proper types for args,
so we can pass the FP value just in one register. emit_library_function so we can pass the FP value just in one register. emit_library_function
doesn't support PARALLEL anyway. */ doesn't support PARALLEL anyway.
Note that for args passed by reference, function_arg will be called
with MODE and TYPE set to that of the pointer to the arg, not the arg
itself. */
struct rtx_def * struct rtx_def *
function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
...@@ -4658,18 +4663,9 @@ function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, ...@@ -4658,18 +4663,9 @@ function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
} }
else else
{ {
int n_words; int n_words = rs6000_arg_size (mode, type);
int gregno = cum->sysv_gregno; int gregno = cum->sysv_gregno;
/* Aggregates, IEEE quad, and AltiVec vectors get passed by
reference. */
if ((type && AGGREGATE_TYPE_P (type))
|| mode == TFmode
|| ALTIVEC_VECTOR_MODE (mode))
n_words = 1;
else
n_words = rs6000_arg_size (mode, type);
/* Long long and SPE vectors are put in (r3,r4), (r5,r6), /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
(r7,r8) or (r9,r10). As does any other 2 word item such (r7,r8) or (r9,r10). As does any other 2 word item such
as complex int due to a historical mistake. */ as complex int due to a historical mistake. */
...@@ -4685,16 +4681,8 @@ function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, ...@@ -4685,16 +4681,8 @@ function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
} }
else else
{ {
int align = (TARGET_32BIT && (cum->words & 1) != 0 int align = function_arg_boundary (mode, type) / PARM_BOUNDARY - 1;
&& function_arg_boundary (mode, type) == 64) ? 1 : 0; int align_words = cum->words + (cum->words & align);
int align_words = cum->words + align;
if (type && TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
return NULL_RTX;
if (TARGET_32BIT && TARGET_POWERPC64
&& (mode == DImode || mode == BLKmode))
return rs6000_mixed_function_arg (cum, mode, type, align_words);
if (USE_FP_FOR_ARG_P (cum, mode, type)) if (USE_FP_FOR_ARG_P (cum, mode, type))
{ {
...@@ -4763,7 +4751,13 @@ function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, ...@@ -4763,7 +4751,13 @@ function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
return gen_rtx_PARALLEL (mode, gen_rtvec_v (n, r)); return gen_rtx_PARALLEL (mode, gen_rtvec_v (n, r));
} }
else if (align_words < GP_ARG_NUM_REG) else if (align_words < GP_ARG_NUM_REG)
return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words); {
if (TARGET_32BIT && TARGET_POWERPC64
&& (mode == DImode || mode == BLKmode))
return rs6000_mixed_function_arg (cum, mode, type, align_words);
return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
}
else else
return NULL_RTX; return NULL_RTX;
} }
...@@ -4810,7 +4804,10 @@ function_arg_partial_nregs (CUMULATIVE_ARGS *cum, enum machine_mode mode, ...@@ -4810,7 +4804,10 @@ function_arg_partial_nregs (CUMULATIVE_ARGS *cum, enum machine_mode mode,
the argument itself. The pointer is passed in whatever way is the argument itself. The pointer is passed in whatever way is
appropriate for passing a pointer to that type. appropriate for passing a pointer to that type.
Under V.4, structures and unions are passed by reference. Under V.4, aggregates and long double are passed by reference.
As an extension to all 32-bit ABIs, AltiVec vectors are passed by
reference unless the AltiVec vector extension ABI is in force.
As an extension to all ABIs, variable sized types are passed by As an extension to all ABIs, variable sized types are passed by
reference. */ reference. */
...@@ -4820,17 +4817,18 @@ function_arg_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED, ...@@ -4820,17 +4817,18 @@ function_arg_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED,
enum machine_mode mode ATTRIBUTE_UNUSED, enum machine_mode mode ATTRIBUTE_UNUSED,
tree type, int named ATTRIBUTE_UNUSED) tree type, int named ATTRIBUTE_UNUSED)
{ {
if (DEFAULT_ABI == ABI_V4 if ((DEFAULT_ABI == ABI_V4
&& ((type && AGGREGATE_TYPE_P (type)) && ((type && AGGREGATE_TYPE_P (type))
|| mode == TFmode || mode == TFmode))
|| (!TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode)))) || (TARGET_32BIT && !TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
|| (type && int_size_in_bytes (type) < 0))
{ {
if (TARGET_DEBUG_ARG) if (TARGET_DEBUG_ARG)
fprintf (stderr, "function_arg_pass_by_reference: aggregate\n"); fprintf (stderr, "function_arg_pass_by_reference\n");
return 1; return 1;
} }
return type && int_size_in_bytes (type) < 0; return 0;
} }
static void static void
...@@ -5081,8 +5079,12 @@ rs6000_va_arg (tree valist, tree type) ...@@ -5081,8 +5079,12 @@ rs6000_va_arg (tree valist, tree type)
if (DEFAULT_ABI != ABI_V4) if (DEFAULT_ABI != ABI_V4)
{ {
/* Variable sized types are passed by reference. */ /* Variable sized types are passed by reference, as are AltiVec
if (int_size_in_bytes (type) < 0) vectors when 32-bit and not using the AltiVec ABI extension. */
if (int_size_in_bytes (type) < 0
|| (TARGET_32BIT
&& !TARGET_ALTIVEC_ABI
&& ALTIVEC_VECTOR_MODE (TYPE_MODE (type))))
{ {
u = build_pointer_type (type); u = build_pointer_type (type);
......
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