pa.c (function_value): Handle small aggregates on 32-bit targets.

* pa.c (function_value): Handle small aggregates on 32-bit targets.
	(function_arg): Pass small aggregates in general registers on 32-bit
	targets.
	* som.h (MEMBER_TYPE_FORCES_BLK): Delete define.

From-SVN: r101646
This commit is contained in:
John David Anglin 2005-07-06 01:22:55 +00:00 committed by John David Anglin
parent 4bf8e11853
commit 2a04824b9f
3 changed files with 44 additions and 22 deletions

View File

@ -1,3 +1,10 @@
2005-07-05 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
* pa.c (function_value): Handle small aggregates on 32-bit targets.
(function_arg): Pass small aggregates in general registers on 32-bit
targets.
* som.h (MEMBER_TYPE_FORCES_BLK): Delete define.
2005-07-05 Andrew Pinski <pinskia@physics.uc.edu>
* Makefile.in (final.o): Fix dependencies.

View File

@ -8580,24 +8580,40 @@ function_value (tree valtype, tree func ATTRIBUTE_UNUSED)
{
enum machine_mode valmode;
/* Aggregates with a size less than or equal to 128 bits are returned
in GR 28(-29). They are left justified. The pad bits are undefined.
Larger aggregates are returned in memory. */
if (TARGET_64BIT && AGGREGATE_TYPE_P (valtype))
if (AGGREGATE_TYPE_P (valtype))
{
rtx loc[2];
int i, offset = 0;
int ub = int_size_in_bytes (valtype) <= UNITS_PER_WORD ? 1 : 2;
for (i = 0; i < ub; i++)
if (TARGET_64BIT)
{
loc[i] = gen_rtx_EXPR_LIST (VOIDmode,
gen_rtx_REG (DImode, 28 + i),
GEN_INT (offset));
offset += 8;
}
/* Aggregates with a size less than or equal to 128 bits are
returned in GR 28(-29). They are left justified. The pad
bits are undefined. Larger aggregates are returned in
memory. */
rtx loc[2];
int i, offset = 0;
int ub = int_size_in_bytes (valtype) <= UNITS_PER_WORD ? 1 : 2;
return gen_rtx_PARALLEL (BLKmode, gen_rtvec_v (ub, loc));
for (i = 0; i < ub; i++)
{
loc[i] = gen_rtx_EXPR_LIST (VOIDmode,
gen_rtx_REG (DImode, 28 + i),
GEN_INT (offset));
offset += 8;
}
return gen_rtx_PARALLEL (BLKmode, gen_rtvec_v (ub, loc));
}
else if (int_size_in_bytes (valtype) > UNITS_PER_WORD)
{
/* Aggregates 5 to 8 bytes in size are returned in general
registers r28-r29 in the same manner as other non
floating-point objects. The data is right-justified and
zero-extended to 64 bits. This is opposite to the normal
justification used on big endian targets and requires
special treatment. */
rtx loc = gen_rtx_EXPR_LIST (VOIDmode,
gen_rtx_REG (DImode, 28), const0_rtx);
return gen_rtx_PARALLEL (BLKmode, gen_rtvec (1, loc));
}
}
if ((INTEGRAL_TYPE_P (valtype)
@ -8608,6 +8624,7 @@ function_value (tree valtype, tree func ATTRIBUTE_UNUSED)
valmode = TYPE_MODE (valtype);
if (TREE_CODE (valtype) == REAL_TYPE
&& !AGGREGATE_TYPE_P (valtype)
&& TYPE_MODE (valtype) != TFmode
&& !TARGET_SOFT_FLOAT)
return gen_rtx_REG (valmode, 32);
@ -8733,12 +8750,12 @@ function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, tree type,
to 64 bits. This is opposite to the normal justification
used on big endian targets and requires special treatment.
We now define BLOCK_REG_PADDING to pad these objects. */
if (mode == BLKmode)
if (mode == BLKmode || (type && AGGREGATE_TYPE_P (type)))
{
rtx loc = gen_rtx_EXPR_LIST (VOIDmode,
gen_rtx_REG (DImode, gpr_reg_base),
const0_rtx);
return gen_rtx_PARALLEL (mode, gen_rtvec (1, loc));
return gen_rtx_PARALLEL (BLKmode, gen_rtvec (1, loc));
}
}
else
@ -8799,7 +8816,9 @@ function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, tree type,
&& cum->indirect)
/* If the parameter is not a floating point parameter, then
it belongs in GPRs. */
|| !FLOAT_MODE_P (mode))
|| !FLOAT_MODE_P (mode)
/* Structure with single SFmode field belongs in GPR. */
|| (type && AGGREGATE_TYPE_P (type)))
retval = gen_rtx_REG (mode, gpr_reg_base);
else
retval = gen_rtx_REG (mode, fpr_reg_base);

View File

@ -307,10 +307,6 @@ do { \
cannot be moved after installation using a symlink. */
#define ALWAYS_STRIP_DOTDOT 1
/* Aggregates with a single float or double field should be passed and
returned in the general registers. */
#define MEMBER_TYPE_FORCES_BLK(FIELD, MODE) (MODE==SFmode || MODE==DFmode)
/* If GAS supports weak, we can support weak when we have working linker
support for secondary definitions and are generating code for GAS. */
#ifdef HAVE_GAS_WEAK