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]

fix sparc -mhard-quad-float (c/4331)


The code expanders for -mhard-quad-float are completely broken.
Particularly at -O0, they quite regularly generate invalid code
which is then not recognized, followed directly by an ice.

This is probably not a regression as such, in that it has probably
never worked, but I'm given to understand that e.g. freebsd does
not implement the software routines, and so must use hard-quad.

Ok for 3.1?


r~


	* config/sparc/sparc.c (emit_soft_tfmode_libcall,
	emit_soft_tfmode_binop, emit_soft_tfmode_unop, emit_soft_tfmode_cvt,
	emit_hard_tfmode_operation, emit_tfmode_binop, emit_tfmode_unop,
	emit_tfmode_cvt): New.
	* config/sparc/sparc.md (extendsftf2, extenddftf2, trunctfsf2,
	trunctfdf2, floatsitf2, floatunssitf2, floatditf2, floatunsditf2,
	fix_trunctfsi2, fixuns_trunctfsi2, fix_trunctfdi2, fixuns_trunctfdi2,
	addtf3, subtf3, multf3, divtf3, sqrttf2): Use them.
	* config/sparc/sparc-protos.h: Update.

Index: sparc-protos.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/sparc/sparc-protos.h,v
retrieving revision 1.17.8.7
diff -c -p -d -r1.17.8.7 sparc-protos.h
*** sparc-protos.h	15 Apr 2002 10:08:51 -0000	1.17.8.7
--- sparc-protos.h	29 Apr 2002 20:25:44 -0000
*************** extern enum machine_mode select_cc_mode 
*** 74,79 ****
--- 74,82 ----
  extern rtx gen_compare_reg PARAMS ((enum rtx_code code, rtx, rtx));
  extern void sparc_emit_float_lib_cmp PARAMS ((rtx, rtx, enum rtx_code));
  extern void sparc_emit_floatunsdi PARAMS ((rtx [2]));
+ extern void emit_tfmode_binop PARAMS ((enum rtx_code, rtx *));
+ extern void emit_tfmode_unop PARAMS ((enum rtx_code, rtx *));
+ extern void emit_tfmode_cvt PARAMS ((enum rtx_code, rtx *));
  /* This function handles all v9 scc insns */
  extern int gen_v9_scc PARAMS ((enum rtx_code, rtx *));
  extern void sparc_initialize_trampoline PARAMS ((rtx, rtx, rtx));
Index: sparc.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/sparc/sparc.c,v
retrieving revision 1.185.2.19
diff -c -p -d -r1.185.2.19 sparc.c
*** sparc.c	17 Apr 2002 08:16:48 -0000	1.185.2.19
--- sparc.c	29 Apr 2002 20:25:45 -0000
*************** static int sparc_issue_rate PARAMS ((voi
*** 178,183 ****
--- 178,189 ----
  static int sparc_variable_issue PARAMS ((FILE *, int, rtx, int));
  static void sparc_sched_init PARAMS ((FILE *, int, int));
  static int sparc_sched_reorder PARAMS ((FILE *, int, rtx *, int *, int));
+ 
+ static void emit_soft_tfmode_libcall PARAMS ((const char *, int, rtx *));
+ static void emit_soft_tfmode_binop PARAMS ((enum rtx_code, rtx *));
+ static void emit_soft_tfmode_unop PARAMS ((enum rtx_code, rtx *));
+ static void emit_soft_tfmode_cvt PARAMS ((enum rtx_code, rtx *));
+ static void emit_hard_tfmode_operation PARAMS ((enum rtx_code, rtx *));
  
  /* Option handling.  */
  
*************** gen_df_reg (reg, low)
*** 2456,2461 ****
--- 2462,2765 ----
    if ((WORDS_BIG_ENDIAN == 0) ^ (low != 0))
      regno += (TARGET_ARCH64 && regno < 32) ? 1 : 2;
    return gen_rtx_REG (DFmode, regno);
+ }
+ 
+ /* Generate a call to FUNC with OPERANDS.  Operand 0 is the return value.
+    Unlike normal calls, TFmode operands are passed by reference.  It is
+    assumed that no more than 3 operands are required.  */
+ 
+ static void
+ emit_soft_tfmode_libcall (func_name, nargs, operands)
+      const char *func_name;
+      int nargs;
+      rtx *operands;
+ {
+   rtx ret_slot = NULL, arg[3], func_sym;
+   int i;
+ 
+   /* We only expect to be called for conversions, unary, and binary ops.  */
+   if (nargs < 2 || nargs > 3)
+     abort ();
+ 
+   for (i = 0; i < nargs; ++i)
+     {
+       rtx this_arg = operands[i];
+       rtx this_slot;
+ 
+       /* TFmode arguments and return values are passed by reference.  */
+       if (GET_MODE (this_arg) == TFmode)
+ 	{
+ 	  if (GET_CODE (this_arg) == MEM)
+ 	    this_arg = XEXP (this_arg, 0);
+ 	  else if (CONSTANT_P (arg[i]))
+ 	    {
+ 	      this_slot = force_const_mem (TFmode, this_arg);
+ 	      this_arg = XEXP (this_slot, 0);
+ 	    }
+ 	  else
+ 	    {
+ 	      this_slot = assign_stack_temp (TFmode, GET_MODE_SIZE (TFmode), 0);
+ 
+ 	      /* Operand 0 is the return value.  We'll copy it out later.  */
+ 	      if (i > 0)
+ 		emit_move_insn (this_slot, this_arg);
+ 	      else
+ 		ret_slot = this_slot;
+ 
+ 	      this_arg = XEXP (this_slot, 0);
+ 	    }
+ 	}
+ 
+       arg[i] = this_arg;
+     }
+ 
+   func_sym = gen_rtx_SYMBOL_REF (Pmode, func_name);
+ 
+   if (GET_MODE (operands[0]) == TFmode)
+     {
+       if (nargs == 2)
+ 	emit_library_call (func_sym, LCT_NORMAL, VOIDmode, 2,
+ 			   arg[0], GET_MODE (arg[0]),
+ 			   arg[1], GET_MODE (arg[1]));
+       else
+ 	emit_library_call (func_sym, LCT_NORMAL, VOIDmode, 3,
+ 			   arg[0], GET_MODE (arg[0]),
+ 			   arg[1], GET_MODE (arg[1]),
+ 			   arg[2], GET_MODE (arg[2]));
+ 
+       if (ret_slot)
+ 	emit_move_insn (operands[0], ret_slot);
+     }
+   else
+     {
+       rtx ret;
+ 
+       if (nargs != 2)
+ 	abort ();
+ 
+       ret = emit_library_call_value (func_sym, operands[0], LCT_NORMAL,
+ 				     GET_MODE (operands[0]), 1,
+ 				     arg[1], GET_MODE (arg[1]));
+ 
+       if (ret != operands[0])
+ 	emit_move_insn (operands[0], ret);
+     }
+ }
+ 
+ /* Expand soft-float TFmode calls to sparc abi routines.  */
+ 
+ static void
+ emit_soft_tfmode_binop (code, operands)
+      enum rtx_code code;
+      rtx *operands;
+ {
+   const char *func;
+ 
+   switch (code)
+     {
+     case PLUS:
+       func = "_Qp_add";
+       break;
+     case MINUS:
+       func = "_Qp_sub";
+       break;
+     case MULT:
+       func = "_Qp_mul";
+       break;
+     case DIV:
+       func = "_Qp_div";
+       break;
+     default:
+       abort ();
+     }
+ 
+   emit_soft_tfmode_libcall (func, 3, operands);
+ }
+ 
+ static void
+ emit_soft_tfmode_unop (code, operands)
+      enum rtx_code code;
+      rtx *operands;
+ {
+   const char *func;
+ 
+   switch (code)
+     {
+     case SQRT:
+       func = "_Qp_sqrt";
+       break;
+     default:
+       abort ();
+     }
+ 
+   emit_soft_tfmode_libcall (func, 2, operands);
+ }
+ 
+ static void
+ emit_soft_tfmode_cvt (code, operands)
+      enum rtx_code code;
+      rtx *operands;
+ {
+   const char *func;
+ 
+   switch (code)
+     {
+     case FLOAT_EXTEND:
+       switch (GET_MODE (operands[1]))
+ 	{
+ 	case SFmode:
+ 	  func = "_Qp_stoq";
+ 	  break;
+ 	case DFmode:
+ 	  func = "_Qp_dtoq";
+ 	  break;
+ 	default:
+ 	  abort ();
+ 	}
+       break;
+ 
+     case FLOAT_TRUNCATE:
+       switch (GET_MODE (operands[0]))
+ 	{
+ 	case SFmode:
+ 	  func = "_Qp_qtos";
+ 	  break;
+ 	case DFmode:
+ 	  func = "_Qp_qtod";
+ 	  break;
+ 	default:
+ 	  abort ();
+ 	}
+       break;
+ 
+     case FLOAT:
+       switch (GET_MODE (operands[1]))
+ 	{
+ 	case SImode:
+ 	  func = "_Qp_itoq";
+ 	  break;
+ 	case DImode:
+ 	  func = "_Qp_xtoq";
+ 	  break;
+ 	default:
+ 	  abort ();
+ 	}
+       break;
+ 
+     case UNSIGNED_FLOAT:
+       switch (GET_MODE (operands[1]))
+ 	{
+ 	case SImode:
+ 	  func = "_Qp_uitoq";
+ 	  break;
+ 	case DImode:
+ 	  func = "_Qp_uxtoq";
+ 	  break;
+ 	default:
+ 	  abort ();
+ 	}
+       break;
+ 
+     case FIX:
+       switch (GET_MODE (operands[1]))
+ 	{
+ 	case SImode:
+ 	  func = "_Qp_qtoi";
+ 	  break;
+ 	case DImode:
+ 	  func = "_Qp_qtox";
+ 	  break;
+ 	default:
+ 	  abort ();
+ 	}
+       break;
+ 
+     case UNSIGNED_FIX:
+       switch (GET_MODE (operands[1]))
+ 	{
+ 	case SImode:
+ 	  func = "_Qp_qtoui";
+ 	  break;
+ 	case DImode:
+ 	  func = "_Qp_qtoux";
+ 	  break;
+ 	default:
+ 	  abort ();
+ 	}
+       break;
+ 
+     default:
+       abort ();
+     }
+ 
+   emit_soft_tfmode_libcall (func, 2, operands);
+ }
+ 
+ /* Expand a hard-float tfmode operation.  All arguments must be in
+    registers.  */
+ 
+ static void
+ emit_hard_tfmode_operation (code, operands)
+      enum rtx_code code;
+      rtx *operands;
+ {
+   rtx op, dest;
+ 
+   if (GET_RTX_CLASS (code) == '1')
+     {
+       operands[1] = force_reg (GET_MODE (operands[1]), operands[1]);
+       op = gen_rtx_fmt_e (code, GET_MODE (operands[0]), operands[1]);
+     }
+   else
+     {
+       operands[1] = force_reg (GET_MODE (operands[1]), operands[1]);
+       operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
+       op = gen_rtx_fmt_ee (code, GET_MODE (operands[0]),
+ 			   operands[1], operands[2]);
+     }
+ 
+   if (register_operand (operands[0], VOIDmode))
+     dest = operands[0];
+   else
+     dest = gen_reg_rtx (GET_MODE (operands[0]));
+ 
+   emit_insn (gen_rtx_SET (VOIDmode, dest, op));
+ 
+   if (dest != operands[0])
+     emit_move_insn (operands[0], dest);
+ }
+ 
+ void
+ emit_tfmode_binop (code, operands)
+      enum rtx_code code;
+      rtx *operands;
+ {
+   if (TARGET_HARD_QUAD)
+     emit_hard_tfmode_operation (code, operands);
+   else
+     emit_soft_tfmode_binop (code, operands);
+ }
+ 
+ void
+ emit_tfmode_unop (code, operands)
+      enum rtx_code code;
+      rtx *operands;
+ {
+   if (TARGET_HARD_QUAD)
+     emit_hard_tfmode_operation (code, operands);
+   else
+     emit_soft_tfmode_unop (code, operands);
+ }
+ 
+ void
+ emit_tfmode_cvt (code, operands)
+      enum rtx_code code;
+      rtx *operands;
+ {
+   if (TARGET_HARD_QUAD)
+     emit_hard_tfmode_operation (code, operands);
+   else
+     emit_soft_tfmode_cvt (code, operands);
  }
  
  /* Return nonzero if a return peephole merging return with
Index: sparc.md
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/sparc/sparc.md,v
retrieving revision 1.148.2.12
diff -c -p -d -r1.148.2.12 sparc.md
*** sparc.md	29 Apr 2002 05:26:07 -0000	1.148.2.12
--- sparc.md	29 Apr 2002 20:25:45 -0000
***************
*** 5023,5053 ****
     (set_attr "fptype" "double")])
  
  (define_expand "extendsftf2"
!   [(set (match_operand:TF 0 "register_operand" "=e")
  	(float_extend:TF
! 	 (match_operand:SF 1 "register_operand" "f")))]
    "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
!   "
! {
!   if (! TARGET_HARD_QUAD)
!     {
!       rtx slot0;
! 
!       if (GET_CODE (operands[0]) != MEM)
! 	slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
!       else
! 	slot0 = operands[0];
! 
!       emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_stoq\"), LCT_NORMAL,
! 			 VOIDmode, 2,
! 			 XEXP (slot0, 0), Pmode,
! 			 operands[1], SFmode);
! 
!       if (GET_CODE (operands[0]) != MEM)
! 	emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
!       DONE;
!     }
! }")
  
  (define_insn "*extendsftf2_hq"
    [(set (match_operand:TF 0 "register_operand" "=e")
--- 5023,5033 ----
     (set_attr "fptype" "double")])
  
  (define_expand "extendsftf2"
!   [(set (match_operand:TF 0 "nonimmediate_operand" "")
  	(float_extend:TF
! 	 (match_operand:SF 1 "register_operand" "")))]
    "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
!   "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
  
  (define_insn "*extendsftf2_hq"
    [(set (match_operand:TF 0 "register_operand" "=e")
***************
*** 5058,5088 ****
    [(set_attr "type" "fp")])
  
  (define_expand "extenddftf2"
!   [(set (match_operand:TF 0 "register_operand" "=e")
  	(float_extend:TF
! 	 (match_operand:DF 1 "register_operand" "e")))]
    "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
!   "
! {
!   if (! TARGET_HARD_QUAD)
!     {
!       rtx slot0;
! 
!       if (GET_CODE (operands[0]) != MEM)
! 	slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
!       else
! 	slot0 = operands[0];
! 
!       emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_dtoq\"), LCT_NORMAL,
! 			 VOIDmode, 2,
! 			 XEXP (slot0, 0), Pmode,
! 			 operands[1], DFmode);
! 
!       if (GET_CODE (operands[0]) != MEM)
! 	emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
!       DONE;
!     }
! }")
  
  (define_insn "*extenddftf2_hq"
    [(set (match_operand:TF 0 "register_operand" "=e")
--- 5038,5048 ----
    [(set_attr "type" "fp")])
  
  (define_expand "extenddftf2"
!   [(set (match_operand:TF 0 "nonimmediate_operand" "")
  	(float_extend:TF
! 	 (match_operand:DF 1 "register_operand" "")))]
    "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
!   "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
  
  (define_insn "*extenddftf2_hq"
    [(set (match_operand:TF 0 "register_operand" "=e")
***************
*** 5102,5131 ****
     (set_attr "fptype" "double")])
  
  (define_expand "trunctfsf2"
!   [(set (match_operand:SF 0 "register_operand" "=f")
  	(float_truncate:SF
! 	 (match_operand:TF 1 "register_operand" "e")))]
    "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
!   "
! {
!   if (! TARGET_HARD_QUAD)
!     {
!       rtx slot0;
! 
!       if (GET_CODE (operands[1]) != MEM)
! 	{
! 	  slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
! 	  emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
! 	}
!       else
! 	slot0 = operands[1];
! 
!       emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtos\"),
! 			       operands[0], LCT_NORMAL, SFmode, 1,
! 			       XEXP (slot0, 0), Pmode);
!       DONE;
!     }
! }")
  
  (define_insn "*trunctfsf2_hq"
    [(set (match_operand:SF 0 "register_operand" "=f")
--- 5062,5072 ----
     (set_attr "fptype" "double")])
  
  (define_expand "trunctfsf2"
!   [(set (match_operand:SF 0 "register_operand" "")
  	(float_truncate:SF
! 	 (match_operand:TF 1 "general_operand" "")))]
    "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
!   "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
  
  (define_insn "*trunctfsf2_hq"
    [(set (match_operand:SF 0 "register_operand" "=f")
***************
*** 5136,5165 ****
    [(set_attr "type" "fp")])
  
  (define_expand "trunctfdf2"
!   [(set (match_operand:DF 0 "register_operand" "=f")
  	(float_truncate:DF
! 	 (match_operand:TF 1 "register_operand" "e")))]
    "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
!   "
! {
!   if (! TARGET_HARD_QUAD)
!     {
!       rtx slot0;
! 
!       if (GET_CODE (operands[1]) != MEM)
! 	{
! 	  slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
! 	  emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
! 	}
!       else
! 	slot0 = operands[1];
! 
!       emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtod\"),
! 			       operands[0], LCT_NORMAL, DFmode, 1,
! 			       XEXP (slot0, 0), Pmode);
!       DONE;
!     }
! }")
  
  (define_insn "*trunctfdf2_hq"
    [(set (match_operand:DF 0 "register_operand" "=e")
--- 5077,5087 ----
    [(set_attr "type" "fp")])
  
  (define_expand "trunctfdf2"
!   [(set (match_operand:DF 0 "register_operand" "")
  	(float_truncate:DF
! 	 (match_operand:TF 1 "general_operand" "")))]
    "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
!   "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
  
  (define_insn "*trunctfdf2_hq"
    [(set (match_operand:DF 0 "register_operand" "=e")
***************
*** 5188,5217 ****
     (set_attr "fptype" "double")])
  
  (define_expand "floatsitf2"
!   [(set (match_operand:TF 0 "register_operand" "=e")
! 	(float:TF (match_operand:SI 1 "register_operand" "f")))]
    "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
!   "
! {
!   if (! TARGET_HARD_QUAD)
!     {
!       rtx slot0;
! 
!       if (GET_CODE (operands[1]) != MEM)
! 	slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
!       else
! 	slot0 = operands[1];
! 
!       emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_itoq\"), 0,
! 			 VOIDmode, 2,
! 			 XEXP (slot0, 0), Pmode,
! 			 operands[1], SImode);
! 
!       if (GET_CODE (operands[0]) != MEM)
! 	emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
!       DONE;
!     }
! }")
  
  (define_insn "*floatsitf2_hq"
    [(set (match_operand:TF 0 "register_operand" "=e")
--- 5110,5119 ----
     (set_attr "fptype" "double")])
  
  (define_expand "floatsitf2"
!   [(set (match_operand:TF 0 "nonimmediate_operand" "")
! 	(float:TF (match_operand:SI 1 "register_operand" "")))]
    "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
!   "emit_tfmode_cvt (FLOAT, operands); DONE;")
  
  (define_insn "*floatsitf2_hq"
    [(set (match_operand:TF 0 "register_operand" "=e")
***************
*** 5221,5247 ****
    [(set_attr "type" "fp")])
  
  (define_expand "floatunssitf2"
!   [(set (match_operand:TF 0 "register_operand" "=e")
! 	(unsigned_float:TF (match_operand:SI 1 "register_operand" "e")))]
    "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
!   "
! {
!   rtx slot0;
! 
!   if (GET_CODE (operands[1]) != MEM)
!     slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
!   else
!     slot0 = operands[1];
! 
!   emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_uitoq\"), 0,
! 		     VOIDmode, 2,
! 		     XEXP (slot0, 0), Pmode,
! 		     operands[1], SImode);
! 
!   if (GET_CODE (operands[0]) != MEM)
!     emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
!   DONE;
! }")
  
  ;; Now the same for 64 bit sources.
  
--- 5123,5132 ----
    [(set_attr "type" "fp")])
  
  (define_expand "floatunssitf2"
!   [(set (match_operand:TF 0 "nonimmediate_operand" "")
! 	(unsigned_float:TF (match_operand:SI 1 "register_operand" "")))]
    "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
!   "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
  
  ;; Now the same for 64 bit sources.
  
***************
*** 5274,5303 ****
    "sparc_emit_floatunsdi (operands); DONE;")
  
  (define_expand "floatditf2"
!   [(set (match_operand:TF 0 "register_operand" "=e")
! 	(float:TF (match_operand:DI 1 "register_operand" "e")))]
    "TARGET_FPU && TARGET_V9 && (TARGET_HARD_QUAD || TARGET_ARCH64)"
!   "
! {
!   if (! TARGET_HARD_QUAD)
!     {
!       rtx slot0;
! 
!       if (GET_CODE (operands[1]) != MEM)
! 	slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
!       else
! 	slot0 = operands[1];
! 
!       emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_xtoq\"), 0,
! 			 VOIDmode, 2,
! 			 XEXP (slot0, 0), Pmode,
! 			 operands[1], DImode);
! 
!       if (GET_CODE (operands[0]) != MEM)
! 	emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
!       DONE;
!     }
! }")
  
  (define_insn "*floatditf2_hq"
    [(set (match_operand:TF 0 "register_operand" "=e")
--- 5159,5168 ----
    "sparc_emit_floatunsdi (operands); DONE;")
  
  (define_expand "floatditf2"
!   [(set (match_operand:TF 0 "nonimmediate_operand" "")
! 	(float:TF (match_operand:DI 1 "register_operand" "")))]
    "TARGET_FPU && TARGET_V9 && (TARGET_HARD_QUAD || TARGET_ARCH64)"
!   "emit_tfmode_cvt (FLOAT, operands); DONE;")
  
  (define_insn "*floatditf2_hq"
    [(set (match_operand:TF 0 "register_operand" "=e")
***************
*** 5307,5333 ****
    [(set_attr "type" "fp")])
  
  (define_expand "floatunsditf2"
!   [(set (match_operand:TF 0 "register_operand" "=e")
! 	(unsigned_float:TF (match_operand:DI 1 "register_operand" "e")))]
    "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
!   "
! {
!   rtx slot0;
! 
!   if (GET_CODE (operands[1]) != MEM)
!     slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
!   else
!     slot0 = operands[1];
! 
!   emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_uxtoq\"), 0,
! 		     VOIDmode, 2,
! 		     XEXP (slot0, 0), Pmode,
! 		     operands[1], DImode);
! 
!   if (GET_CODE (operands[0]) != MEM)
!     emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
!   DONE;
! }")
  
  ;; Convert a float to an actual integer.
  ;; Truncation is performed as part of the conversion.
--- 5172,5181 ----
    [(set_attr "type" "fp")])
  
  (define_expand "floatunsditf2"
!   [(set (match_operand:TF 0 "nonimmediate_operand" "")
! 	(unsigned_float:TF (match_operand:DI 1 "register_operand" "")))]
    "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
!   "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
  
  ;; Convert a float to an actual integer.
  ;; Truncation is performed as part of the conversion.
***************
*** 5349,5406 ****
     (set_attr "fptype" "double")])
  
  (define_expand "fix_trunctfsi2"
!   [(set (match_operand:SI 0 "register_operand" "=f")
! 	(fix:SI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
    "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
!   "
! {
!   if (! TARGET_HARD_QUAD)
!     {
!       rtx slot0;
! 
!       if (GET_CODE (operands[1]) != MEM)
! 	{
! 	  slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
! 	  emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
! 	}
!       else
! 	slot0 = operands[1];
! 
!       emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtoi\"),
! 			       operands[0], LCT_NORMAL, SImode, 1,
! 			       XEXP (slot0, 0), Pmode);
!       DONE;
!     }
! }")
  
  (define_insn "*fix_trunctfsi2_hq"
    [(set (match_operand:SI 0 "register_operand" "=f")
! 	(fix:SI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
    "TARGET_FPU && TARGET_HARD_QUAD"
    "fqtoi\\t%1, %0"
    [(set_attr "type" "fp")])
  
  (define_expand "fixuns_trunctfsi2"
!   [(set (match_operand:SI 0 "register_operand" "=f")
! 	(unsigned_fix:SI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
    "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
!   "
! {
!   rtx slot0;
! 
!   if (GET_CODE (operands[1]) != MEM)
!     {
!       slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
!       emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
!     }
!   else
!     slot0 = operands[1];
! 
!   emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtoui\"),
! 			   operands[0], LCT_NORMAL, SImode, 1,
! 			   XEXP (slot0, 0), Pmode);
!   DONE;
! }")
  
  ;; Now the same, for V9 targets
  
--- 5197,5219 ----
     (set_attr "fptype" "double")])
  
  (define_expand "fix_trunctfsi2"
!   [(set (match_operand:SI 0 "register_operand" "")
! 	(fix:SI (match_operand:TF 1 "general_operand" "")))]
    "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
!   "emit_tfmode_cvt (FIX, operands); DONE;")
  
  (define_insn "*fix_trunctfsi2_hq"
    [(set (match_operand:SI 0 "register_operand" "=f")
! 	(fix:SI (match_operand:TF 1 "register_operand" "e")))]
    "TARGET_FPU && TARGET_HARD_QUAD"
    "fqtoi\\t%1, %0"
    [(set_attr "type" "fp")])
  
  (define_expand "fixuns_trunctfsi2"
!   [(set (match_operand:SI 0 "register_operand" "")
! 	(unsigned_fix:SI (match_operand:TF 1 "general_operand" "")))]
    "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
!   "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
  
  ;; Now the same, for V9 targets
  
***************
*** 5421,5479 ****
     (set_attr "fptype" "double")])
  
  (define_expand "fix_trunctfdi2"
!   [(set (match_operand:DI 0 "register_operand" "=e")
! 	(fix:DI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
    "TARGET_V9 && TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
!   "
! {
!   if (! TARGET_HARD_QUAD)
!     {
!       rtx slot0;
! 
!       if (GET_CODE (operands[1]) != MEM)
! 	{
! 	  slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
! 	  emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
! 	}
!       else
! 	slot0 = operands[1];
! 
!       emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtox\"),
! 			       operands[0], LCT_NORMAL, DImode, 1,
! 			       XEXP (slot0, 0), Pmode);
!       DONE;
!     }
! }")
  
  (define_insn "*fix_trunctfdi2_hq"
    [(set (match_operand:DI 0 "register_operand" "=e")
! 	(fix:DI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
    "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
    "fqtox\\t%1, %0"
    [(set_attr "type" "fp")])
  
  (define_expand "fixuns_trunctfdi2"
!   [(set (match_operand:DI 0 "register_operand" "=f")
! 	(unsigned_fix:DI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
    "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
!   "
! {
!   rtx slot0;
! 
!   if (GET_CODE (operands[1]) != MEM)
!     {
!       slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
!       emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
!     }
!   else
!     slot0 = operands[1];
! 
!   emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtoux\"),
! 			   operands[0], LCT_NORMAL, DImode, 1,
! 			   XEXP (slot0, 0), Pmode);
!   DONE;
! }")
! 
  
  ;;- arithmetic instructions
  
--- 5234,5256 ----
     (set_attr "fptype" "double")])
  
  (define_expand "fix_trunctfdi2"
!   [(set (match_operand:DI 0 "register_operand" "")
! 	(fix:DI (match_operand:TF 1 "general_operand" "")))]
    "TARGET_V9 && TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
!   "emit_tfmode_cvt (FIX, operands); DONE;")
  
  (define_insn "*fix_trunctfdi2_hq"
    [(set (match_operand:DI 0 "register_operand" "=e")
! 	(fix:DI (match_operand:TF 1 "register_operand" "e")))]
    "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
    "fqtox\\t%1, %0"
    [(set_attr "type" "fp")])
  
  (define_expand "fixuns_trunctfdi2"
!   [(set (match_operand:DI 0 "register_operand" "")
! 	(unsigned_fix:DI (match_operand:TF 1 "general_operand" "")))]
    "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
!   "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
  
  ;;- arithmetic instructions
  
***************
*** 7373,7414 ****
  	(plus:TF (match_operand:TF 1 "general_operand" "")
  		 (match_operand:TF 2 "general_operand" "")))]
    "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
!   "
! {
!   if (! TARGET_HARD_QUAD)
!     {
!       rtx slot0, slot1, slot2;
! 
!       if (GET_CODE (operands[0]) != MEM)
! 	slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
!       else
! 	slot0 = operands[0];
!       if (GET_CODE (operands[1]) != MEM)
! 	{
! 	  slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
! 	  emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1]));
! 	}
!       else
! 	slot1 = operands[1];
!       if (GET_CODE (operands[2]) != MEM)
! 	{
! 	  slot2 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
! 	  emit_insn (gen_rtx_SET (VOIDmode, slot2, operands[2]));
! 	}
!       else
! 	slot2 = operands[2];
! 
!       emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_add\"), 0,
! 			 VOIDmode, 3,
! 			 XEXP (slot0, 0), Pmode,
! 			 XEXP (slot1, 0), Pmode,
! 			 XEXP (slot2, 0), Pmode);
! 
!       if (GET_CODE (operands[0]) != MEM)
! 	emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
!       DONE;
!     }
! }")
  
  (define_insn "*addtf3_hq"
    [(set (match_operand:TF 0 "register_operand" "=e")
--- 7150,7156 ----
  	(plus:TF (match_operand:TF 1 "general_operand" "")
  		 (match_operand:TF 2 "general_operand" "")))]
    "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
!   "emit_tfmode_binop (PLUS, operands); DONE;")
  
  (define_insn "*addtf3_hq"
    [(set (match_operand:TF 0 "register_operand" "=e")
***************
*** 7440,7481 ****
  	(minus:TF (match_operand:TF 1 "general_operand" "")
  		  (match_operand:TF 2 "general_operand" "")))]
    "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
!   "
! {
!   if (! TARGET_HARD_QUAD)
!     {
!       rtx slot0, slot1, slot2;
! 
!       if (GET_CODE (operands[0]) != MEM)
! 	slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
!       else
! 	slot0 = operands[0];
!       if (GET_CODE (operands[1]) != MEM)
! 	{
! 	  slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
! 	  emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1]));
! 	}
!       else
! 	slot1 = operands[1];
!       if (GET_CODE (operands[2]) != MEM)
! 	{
! 	  slot2 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
! 	  emit_insn (gen_rtx_SET (VOIDmode, slot2, operands[2]));
! 	}
!       else
! 	slot2 = operands[2];
! 
!       emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_sub\"), 0,
! 			 VOIDmode, 3,
! 			 XEXP (slot0, 0), Pmode,
! 			 XEXP (slot1, 0), Pmode,
! 			 XEXP (slot2, 0), Pmode);
! 
!       if (GET_CODE (operands[0]) != MEM)
! 	emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
!       DONE;
!     }
! }")
  
  (define_insn "*subtf3_hq"
    [(set (match_operand:TF 0 "register_operand" "=e")
--- 7182,7188 ----
  	(minus:TF (match_operand:TF 1 "general_operand" "")
  		  (match_operand:TF 2 "general_operand" "")))]
    "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
!   "emit_tfmode_binop (MINUS, operands); DONE;")
  
  (define_insn "*subtf3_hq"
    [(set (match_operand:TF 0 "register_operand" "=e")
***************
*** 7507,7548 ****
  	(mult:TF (match_operand:TF 1 "general_operand" "")
  		 (match_operand:TF 2 "general_operand" "")))]
    "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
!   "
! {
!   if (! TARGET_HARD_QUAD)
!     {
!       rtx slot0, slot1, slot2;
! 
!       if (GET_CODE (operands[0]) != MEM)
! 	slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
!       else
! 	slot0 = operands[0];
!       if (GET_CODE (operands[1]) != MEM)
! 	{
! 	  slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
! 	  emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1]));
! 	}
!       else
! 	slot1 = operands[1];
!       if (GET_CODE (operands[2]) != MEM)
! 	{
! 	  slot2 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
! 	  emit_insn (gen_rtx_SET (VOIDmode, slot2, operands[2]));
! 	}
!       else
! 	slot2 = operands[2];
! 
!       emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_mul\"), 0,
! 			 VOIDmode, 3,
! 			 XEXP (slot0, 0), Pmode,
! 			 XEXP (slot1, 0), Pmode,
! 			 XEXP (slot2, 0), Pmode);
! 
!       if (GET_CODE (operands[0]) != MEM)
! 	emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
!       DONE;
!     }
! }")
  
  (define_insn "*multf3_hq"
    [(set (match_operand:TF 0 "register_operand" "=e")
--- 7214,7220 ----
  	(mult:TF (match_operand:TF 1 "general_operand" "")
  		 (match_operand:TF 2 "general_operand" "")))]
    "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
!   "emit_tfmode_binop (MULT, operands); DONE;")
  
  (define_insn "*multf3_hq"
    [(set (match_operand:TF 0 "register_operand" "=e")
***************
*** 7591,7632 ****
  	(div:TF (match_operand:TF 1 "general_operand" "")
  		(match_operand:TF 2 "general_operand" "")))]
    "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
!   "
! {
!   if (! TARGET_HARD_QUAD)
!     {
!       rtx slot0, slot1, slot2;
! 
!       if (GET_CODE (operands[0]) != MEM)
! 	slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
!       else
! 	slot0 = operands[0];
!       if (GET_CODE (operands[1]) != MEM)
! 	{
! 	  slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
! 	  emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1]));
! 	}
!       else
! 	slot1 = operands[1];
!       if (GET_CODE (operands[2]) != MEM)
! 	{
! 	  slot2 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
! 	  emit_insn (gen_rtx_SET (VOIDmode, slot2, operands[2]));
! 	}
!       else
! 	slot2 = operands[2];
! 
!       emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_div\"), 0,
! 			 VOIDmode, 3,
! 			 XEXP (slot0, 0), Pmode,
! 			 XEXP (slot1, 0), Pmode,
! 			 XEXP (slot2, 0), Pmode);
! 
!       if (GET_CODE (operands[0]) != MEM)
! 	emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
!       DONE;
!     }
! }")
  
  ;; don't have timing for quad-prec. divide.
  (define_insn "*divtf3_hq"
--- 7263,7269 ----
  	(div:TF (match_operand:TF 1 "general_operand" "")
  		(match_operand:TF 2 "general_operand" "")))]
    "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
!   "emit_tfmode_binop (DIV, operands); DONE;")
  
  ;; don't have timing for quad-prec. divide.
  (define_insn "*divtf3_hq"
***************
*** 7875,7911 ****
    [(set_attr "type" "fpmove")])
  
  (define_expand "sqrttf2"
!   [(set (match_operand:TF 0 "register_operand" "=e")
! 	(sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
    "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
!   "
! {
!   if (! TARGET_HARD_QUAD)
!     {
!       rtx slot0, slot1;
! 
!       if (GET_CODE (operands[0]) != MEM)
! 	slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
!       else
! 	slot0 = operands[0];
!       if (GET_CODE (operands[1]) != MEM)
! 	{
! 	  slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
! 	  emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1]));
! 	}
!       else
! 	slot1 = operands[1];
! 
!       emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_sqrt\"), 0,
! 			 VOIDmode, 2,
! 			 XEXP (slot0, 0), Pmode,
! 			 XEXP (slot1, 0), Pmode);
! 
!       if (GET_CODE (operands[0]) != MEM)
! 	emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
!       DONE;
!     }
! }")
  
  (define_insn "*sqrttf2_hq"
    [(set (match_operand:TF 0 "register_operand" "=e")
--- 7512,7521 ----
    [(set_attr "type" "fpmove")])
  
  (define_expand "sqrttf2"
!   [(set (match_operand:TF 0 "nonimmediate_operand" "")
! 	(sqrt:TF (match_operand:TF 1 "general_operand" "")))]
    "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
!   "emit_tfmode_unop (SQRT, operands); DONE;")
  
  (define_insn "*sqrttf2_hq"
    [(set (match_operand:TF 0 "register_operand" "=e")


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