aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJohn David Anglin <dave.anglin@nrc-cnrc.gc.ca>2005-07-06 01:22:55 +0000
committerJohn David Anglin <danglin@gcc.gnu.org>2005-07-06 01:22:55 +0000
commit2a04824b9f21d6a57b655efb7fc531a80e6999b4 (patch)
tree3f5b8ea75be3c37f57e5430273873c2acd44499d /gcc
parent4bf8e1185372b64630d1c390c611474e474a39ae (diff)
downloadgcc-2a04824b9f21d6a57b655efb7fc531a80e6999b4.zip
gcc-2a04824b9f21d6a57b655efb7fc531a80e6999b4.tar.gz
gcc-2a04824b9f21d6a57b655efb7fc531a80e6999b4.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/config/pa/pa.c53
-rw-r--r--gcc/config/pa/som.h4
3 files changed, 43 insertions, 21 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 97919bd..c452f20 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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.
diff --git a/gcc/config/pa/pa.c b/gcc/config/pa/pa.c
index 54e08ed..969da83 100644
--- a/gcc/config/pa/pa.c
+++ b/gcc/config/pa/pa.c
@@ -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;
+ if (TARGET_64BIT)
+ {
+ /* 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;
+
+ for (i = 0; i < ub; i++)
+ {
+ loc[i] = gen_rtx_EXPR_LIST (VOIDmode,
+ gen_rtx_REG (DImode, 28 + i),
+ GEN_INT (offset));
+ offset += 8;
+ }
- for (i = 0; i < ub; i++)
+ return gen_rtx_PARALLEL (BLKmode, gen_rtvec_v (ub, loc));
+ }
+ else if (int_size_in_bytes (valtype) > UNITS_PER_WORD)
{
- loc[i] = gen_rtx_EXPR_LIST (VOIDmode,
- gen_rtx_REG (DImode, 28 + i),
- GEN_INT (offset));
- offset += 8;
+ /* 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));
}
-
- return gen_rtx_PARALLEL (BLKmode, gen_rtvec_v (ub, 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);
diff --git a/gcc/config/pa/som.h b/gcc/config/pa/som.h
index cac8dac..109e2a1 100644
--- a/gcc/config/pa/som.h
+++ b/gcc/config/pa/som.h
@@ -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