From 2a04824b9f21d6a57b655efb7fc531a80e6999b4 Mon Sep 17 00:00:00 2001 From: John David Anglin Date: Wed, 6 Jul 2005 01:22:55 +0000 Subject: [PATCH] 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 --- gcc/ChangeLog | 7 ++++++ gcc/config/pa/pa.c | 53 ++++++++++++++++++++++++++++++--------------- gcc/config/pa/som.h | 4 ---- 3 files changed, 43 insertions(+), 21 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 97919bd0b736..c452f207821d 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2005-07-05 John David Anglin + + * 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 * Makefile.in (final.o): Fix dependencies. diff --git a/gcc/config/pa/pa.c b/gcc/config/pa/pa.c index 54e08edc9961..969da837a014 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 cac8daca09b6..109e2a164764 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 -- 2.43.5