This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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),


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]