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]

mips patch for complex numbers


complex numbers are severely broken when floats are 32bits.  basically,
gcc ends up generating a subreg which purge_single_hard_subreg_set()
turns into consecutive registers.  This is invalid when floats are
32bits because we can't address odd registers.

it turns out FUNCTION_VALUE wasn't being set correctly for complex
numbers-- especially when the complex number was a float.

there seems to be comments all throughout the mips backend alluding to
the fact that complex support is incomplete, but this patch fixes at
least fixes all the complex failures.  but i don't doubt there are other
problems lurking around ;-)

fully tested.

ok to install?

-- 
Aldy Hernandez					E-mail: aldyh@redhat.com
Professional Gypsy and Camel Trader
Red Hat, Inc.

2001-08-23  Aldy Hernandez  <aldyh@redhat.com>

        * config/mips/mips.c (mips_function_value): Handle complex
return
	values.


Index: config/mips/mips.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/mips/mips.c,v
retrieving revision 1.138
diff -c -p -r1.138 mips.c
*** mips.c	2001/08/10 13:08:16	1.138
--- mips.c	2001/08/23 10:13:13
*************** mips_function_value (valtype, func)
*** 7786,7798 ****
       just as PROMOTE_MODE does.  */
    mode = promote_mode (valtype, mode, &unsignedp, 1);
  
!   /* ??? How should we return complex float?  */
!   if (mclass == MODE_FLOAT || mclass == MODE_COMPLEX_FLOAT)
      {
        if (TARGET_SINGLE_FLOAT
  	  && (mclass == MODE_FLOAT
  	      ? GET_MODE_SIZE (mode) > 4 : GET_MODE_SIZE (mode) / 2 > 4))
  	reg = GP_RETURN;
        else
  	reg = FP_RETURN;
      }
--- 7786,7824 ----
       just as PROMOTE_MODE does.  */
    mode = promote_mode (valtype, mode, &unsignedp, 1);
  
!   if (mclass == MODE_FLOAT)
      {
        if (TARGET_SINGLE_FLOAT
  	  && (mclass == MODE_FLOAT
  	      ? GET_MODE_SIZE (mode) > 4 : GET_MODE_SIZE (mode) / 2 > 4))
  	reg = GP_RETURN;
+       else
+ 	reg = FP_RETURN;
+     }
+ 
+   else if (mclass == MODE_COMPLEX_FLOAT)
+     {
+       if (TARGET_FLOAT64)
+ 	reg = FP_RETURN;
+       else if (mode == SCmode)
+ 	{
+ 	  /* When FP registers are 32 bits, we can't directly reference
+ 	     the odd numbered ones, so let's make a pair of evens.  */
+ 
+ 	  enum machine_mode cmode = TYPE_MODE (TREE_TYPE (valtype));
+ 
+ 	  return gen_rtx_PARALLEL
+ 	    (VOIDmode,
+ 	     gen_rtvec (2,
+ 			gen_rtx_EXPR_LIST (VOIDmode,
+ 					   gen_rtx_REG (cmode,
+ 							FP_RETURN),
+ 					   GEN_INT (0)),
+ 			gen_rtx_EXPR_LIST (VOIDmode,
+ 					   gen_rtx_REG (cmode,
+ 							FP_RETURN + 2),
+ 					   GEN_INT (4))));
+ 	}
        else
  	reg = FP_RETURN;
      }


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