mirror of git://gcc.gnu.org/git/gcc.git
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
This commit is contained in:
parent
b668593951
commit
b2d04ecff8
|
@ -1,3 +1,16 @@
|
||||||
|
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)
|
||||||
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)
|
||||||
|
|
||||||
/* 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,
|
||||||
}
|
}
|
||||||
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,
|
||||||
}
|
}
|
||||||
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,
|
||||||
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,
|
||||||
}
|
}
|
||||||
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,
|
||||||
}
|
}
|
||||||
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,
|
||||||
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,
|
||||||
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,
|
||||||
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)
|
||||||
|
|
||||||
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);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue