diff options
author | Aldy Hernandez <aldyh@redhat.com> | 2004-11-18 15:51:18 +0000 |
---|---|---|
committer | Aldy Hernandez <aldyh@gcc.gnu.org> | 2004-11-18 15:51:18 +0000 |
commit | 18f63bfae3cd06c0e376872cbd862c78dc3a389b (patch) | |
tree | d035c27dd8d7b842ad3944dac1e141bd397626ac | |
parent | a73498160839a23ebcda694c117be41ddb197528 (diff) | |
download | gcc-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/ChangeLog | 11 | ||||
-rw-r--r-- | gcc/config/rs6000/rs6000.c | 77 |
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; |