aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAldy Hernandez <aldyh@redhat.com>2004-11-18 15:51:18 +0000
committerAldy Hernandez <aldyh@gcc.gnu.org>2004-11-18 15:51:18 +0000
commit18f63bfae3cd06c0e376872cbd862c78dc3a389b (patch)
treed035c27dd8d7b842ad3944dac1e141bd397626ac
parenta73498160839a23ebcda694c117be41ddb197528 (diff)
downloadgcc-18f63bfae3cd06c0e376872cbd862c78dc3a389b.zip
gcc-18f63bfae3cd06c0e376872cbd862c78dc3a389b.tar.gz
gcc-18f63bfae3cd06c0e376872cbd862c78dc3a389b.tar.bz2
rs6000.c (rs6000_complex_function_value): Revert previous change.
* config/rs6000/rs6000.c (rs6000_complex_function_value): Revert previous change. (rs6000_override_options): Likewise. (spe_build_register_parallel): Handle complex doubles on e500v2. (rs6000_spe_function_arg): Likewise. (function_arg): Likewise. (rs6000_function_value): Likewise. (rs6000_libcall_value): Likewise. [[Split portion of a mixed commit.]] From-SVN: r90868.2
-rw-r--r--gcc/ChangeLog11
-rw-r--r--gcc/config/rs6000/rs6000.c77
2 files changed, 50 insertions, 38 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 857a5a6..53126c6 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,14 @@
+2004-11-18 Aldy Hernandez <aldyh@redhat.com>
+
+ * config/rs6000/rs6000.c (rs6000_complex_function_value): Revert
+ previous change.
+ (rs6000_override_options): Likewise.
+ (spe_build_register_parallel): Handle complex doubles on e500v2.
+ (rs6000_spe_function_arg): Likewise.
+ (function_arg): Likewise.
+ (rs6000_function_value): Likewise.
+ (rs6000_libcall_value): Likewise.
+
2004-11-18 Andrew Pinski <pinskia@physics.uc.edu>
* ifcvt.c (find_if_block): Move the check for the number of edges
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index d67a857..5659195 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -1493,7 +1493,7 @@ rs6000_override_options (const char *default_cpu)
/* We should always be splitting complex arguments, but we can't break
Linux and Darwin ABIs at the moment. For now, only AIX is fixed. */
- if (DEFAULT_ABI != ABI_AIX && !TARGET_E500_DOUBLE)
+ if (DEFAULT_ABI != ABI_AIX)
targetm.calls.split_complex_arg = NULL;
/* Initialize rs6000_cost with the appropriate target costs. */
@@ -5018,23 +5018,32 @@ function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode,
static rtx
spe_build_register_parallel (enum machine_mode mode, int gregno)
{
- rtx r1, r2;
- enum machine_mode inner;
- unsigned int inner_bytes;
+ rtx r1, r2, r3, r4;
+ enum machine_mode inner = SImode;
if (mode == DFmode)
{
- inner = SImode;
- inner_bytes = 4;
+ r1 = gen_rtx_REG (inner, gregno);
+ r1 = gen_rtx_EXPR_LIST (SImode, r1, const0_rtx);
+ r2 = gen_rtx_REG (inner, gregno + 1);
+ r2 = gen_rtx_EXPR_LIST (SImode, r2, GEN_INT (4));
+ return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2));
+ }
+ else if (mode == DCmode)
+ {
+ r1 = gen_rtx_REG (inner, gregno);
+ r1 = gen_rtx_EXPR_LIST (SImode, r1, const0_rtx);
+ r2 = gen_rtx_REG (inner, gregno + 1);
+ r2 = gen_rtx_EXPR_LIST (SImode, r2, GEN_INT (4));
+ r3 = gen_rtx_REG (inner, gregno + 2);
+ r3 = gen_rtx_EXPR_LIST (SImode, r3, GEN_INT (8));
+ r4 = gen_rtx_REG (inner, gregno + 3);
+ r4 = gen_rtx_EXPR_LIST (SImode, r4, GEN_INT (12));
+ return gen_rtx_PARALLEL (mode, gen_rtvec (4, r1, r2, r3, r4));
}
- else
- abort ();
- r1 = gen_rtx_REG (inner, gregno);
- r1 = gen_rtx_EXPR_LIST (SImode, r1, const0_rtx);
- r2 = gen_rtx_REG (inner, gregno + 1);
- r2 = gen_rtx_EXPR_LIST (SImode, r2, GEN_INT (inner_bytes));
- return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2));
+ abort ();
+ return NULL_RTX;
}
/* Determine where to put a SIMD argument on the SPE. */
@@ -5046,7 +5055,7 @@ rs6000_spe_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
/* On E500 v2, double arithmetic is done on the full 64-bit GPR, but
are passed and returned in a pair of GPRs for ABI compatibility. */
- if (TARGET_E500_DOUBLE && mode == DFmode)
+ if (TARGET_E500_DOUBLE && (mode == DFmode || mode == DCmode))
{
/* Doubles go in an odd/even register pair (r5/r6, etc). */
gregno += (1 - gregno) & 1;
@@ -5380,7 +5389,8 @@ function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
}
else if (TARGET_SPE_ABI && TARGET_SPE
&& (SPE_VECTOR_MODE (mode)
- || (TARGET_E500_DOUBLE && mode == DFmode)))
+ || (TARGET_E500_DOUBLE && (mode == DFmode
+ || mode == DCmode))))
return rs6000_spe_function_arg (cum, mode, type);
else if (rs6000_darwin64_abi
@@ -18315,31 +18325,20 @@ rs6000_complex_function_value (enum machine_mode mode)
enum machine_mode inner = GET_MODE_INNER (mode);
unsigned int inner_bytes = GET_MODE_SIZE (inner);
- if (TARGET_E500_DOUBLE)
- {
- /* FIXME: This causes complex values to be returned in the full
- 64-bit GPR. It works, but is not ABI compatible with
- soft-float. Complex doubles should be returned in 4
- consecutive 32-bit GPRs. */
- regno = GP_ARG_RETURN;
- }
+ if (FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
+ regno = FP_ARG_RETURN;
else
{
- if (FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
- regno = FP_ARG_RETURN;
- else
- {
- regno = GP_ARG_RETURN;
-
- /* 32-bit is OK since it'll go in r3/r4. */
- if (TARGET_32BIT && inner_bytes >= 4)
- return gen_rtx_REG (mode, regno);
- }
+ regno = GP_ARG_RETURN;
- if (inner_bytes >= 8)
+ /* 32-bit is OK since it'll go in r3/r4. */
+ if (TARGET_32BIT && inner_bytes >= 4)
return gen_rtx_REG (mode, regno);
}
+ if (inner_bytes >= 8)
+ return gen_rtx_REG (mode, regno);
+
r1 = gen_rtx_EXPR_LIST (inner, gen_rtx_REG (inner, regno),
const0_rtx);
r2 = gen_rtx_EXPR_LIST (inner, gen_rtx_REG (inner, regno + 1),
@@ -18533,8 +18532,9 @@ rs6000_function_value (tree valtype, tree func ATTRIBUTE_UNUSED)
&& TARGET_ALTIVEC && TARGET_ALTIVEC_ABI
&& ALTIVEC_VECTOR_MODE(mode))
regno = ALTIVEC_ARG_RETURN;
- else if (TARGET_E500_DOUBLE && TARGET_HARD_FLOAT && mode == DFmode)
- return spe_build_register_parallel (DFmode, GP_ARG_RETURN);
+ else if (TARGET_E500_DOUBLE && TARGET_HARD_FLOAT
+ && (mode == DFmode || mode == DCmode))
+ return spe_build_register_parallel (mode, GP_ARG_RETURN);
else
regno = GP_ARG_RETURN;
@@ -18570,8 +18570,9 @@ rs6000_libcall_value (enum machine_mode mode)
regno = ALTIVEC_ARG_RETURN;
else if (COMPLEX_MODE_P (mode) && targetm.calls.split_complex_arg)
return rs6000_complex_function_value (mode);
- else if (TARGET_E500_DOUBLE && TARGET_HARD_FLOAT && mode == DFmode)
- return spe_build_register_parallel (DFmode, GP_ARG_RETURN);
+ else if (TARGET_E500_DOUBLE && TARGET_HARD_FLOAT
+ && (mode == DFmode || mode == DCmode))
+ return spe_build_register_parallel (mode, GP_ARG_RETURN);
else
regno = GP_ARG_RETURN;