This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
patch: e500v2 handle complex numbers
- From: Aldy Hernandez <aldyh at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Tue, 16 Nov 2004 22:17:51 -0400
- Subject: patch: e500v2 handle complex numbers
Complex numbers should behave as -msoft-float. A nice shortcut is to
use the SPLIT_COMPLEX_ARG machinery.
Complex function return values work, but is not ABI compatible. I'll
address this later.
Committed to mainline and 3_4-e500-branch.
* config/rs6000/rs6000.c (rs6000_override_options): Split e500v2
doubles.
(rs6000_complex_function_value): Handle e500 v2 variant.
Index: config/rs6000/rs6000.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/rs6000.c,v
retrieving revision 1.741
diff -c -p -r1.741 rs6000.c
*** config/rs6000/rs6000.c 11 Nov 2004 17:03:33 -0000 1.741
--- config/rs6000/rs6000.c 17 Nov 2004 02:14:03 -0000
*************** rs6000_override_options (const char *def
*** 1482,1488 ****
/* 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)
targetm.calls.split_complex_arg = NULL;
/* Initialize rs6000_cost with the appropriate target costs. */
--- 1482,1488 ----
/* 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)
targetm.calls.split_complex_arg = NULL;
/* Initialize rs6000_cost with the appropriate target costs. */
*************** rs6000_complex_function_value (enum mach
*** 18106,18125 ****
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
{
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);
}
- 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),
--- 18106,18136 ----
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;
+ }
+ 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);
! }
!
! 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),