aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/config/rs6000/rs6000.c29
2 files changed, 26 insertions, 9 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index e548981..def3930 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2004-11-16 Aldy Hernandez <aldyh@redhat.com>
+
+ * config/rs6000/rs6000.c (rs6000_override_options): Split e500v2
+ doubles.
+ (rs6000_complex_function_value): Handle e500 v2 variant.
+
2004-11-16 Daniel Berlin <dberlin@dberlin.org>
Fix PR tree-optimization/18519
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index a0c607f..d67a857 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)
+ if (DEFAULT_ABI != ABI_AIX && !TARGET_E500_DOUBLE)
targetm.calls.split_complex_arg = NULL;
/* Initialize rs6000_cost with the appropriate target costs. */
@@ -18315,20 +18315,31 @@ 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 (FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
- regno = FP_ARG_RETURN;
- else
+ 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;
+ }
+ 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)
+ /* 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);
}
- 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),