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]

[RFA] PR/19653: fld used for reloads in sse mode


First of all, the `#' hints to regclass are removed. They seem to produce worst code only: without them, no fld's creep in before reload. Jan Hubicka's regclass tweak I had posted is not necessary.

The PREFERRED_RELOAD_CLASS macro in the i386 backend is modified to reject FLOAT_REGS when using SSE for math. To do so, I use an undocumented feature of find_reloads: if PREFERRED_RELOAD_CLASS returns NO_REGS, it is equivalent to adding a `?' to the constraint (but in a way that may be dependent on the target options and on the operands' RTL).

I'm documenting this feature in the patch, and extending it to PREFERRED_OUTPUT_RELOAD_CLASS.

I also add a PREFERRED_OUTPUT_RELOAD_CLASS macro to the i386 backend, similar to PREFERRED_RELOAD_CLASS. This macro needs to be careful because sometimes we need an output reload for

   (set (reg:SF st) (vec_select:SF (reg:V4SF xmm1)
                                   (parallel [(const_int 0)])))

and in this case it is unavoidable to put the vec_select's result in an SSE register, even if -mfpmath=387. This case seems general enough that I documented it in the manual, too.

This aforementioned feature of find_reloads, however, is incompatible with an assert in push_reload, even without my patch. So I made push_reload understand a return value of `NO_REGS' too: the back-end would not like the alternative that was chosen, but was not helpful enough to reload: so reload will proceed with the original regclass.

This patch produces an improvement of 3% on tramp3d if linked with Richard Guenther's libsse2 project (on top of the 5% improvement from libsse2 WRT libc's transcendental math functions: in total it is 8.2%).

Bootstrapped/regtested i686-pc-linux-gnu. Ok for mainline?

Paolo

2005-07-14  Paolo Bonzini  <bonzini@gnu.org>

	* reload.c (find_reloads): Take PREFERRED_OUTPUT_RELOAD_CLASS
	into account.
	(push_reload): Allow PREFERRED_*_RELOAD_CLASS to liberally
	return NO_REGS.
	* doc/tm.texi (Register Classes): Document what it means
	if PREFERRED_*_RELOAD_CLASS return NO_REGS.
	* config/i386/i386.c (ix86_preferred_reload_class): Force
	using SSE registers (and return NO_REGS for floating-point
	constants) if math is done with SSE.
	(ix86_preferred_output_reload_class): New.
	* config/i386/i386-protos.h (ix86_preferred_output_reload_class): New.
	* config/i386/i386.h (PREFERRED_OUTPUT_RELOAD_CLASS): New.
	* config/i386/i386.md: Remove # register preferences.

Index: reload.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/reload.c,v
retrieving revision 1.273
diff -c -r1.273 reload.c
*** reload.c	25 Jun 2005 02:00:53 -0000	1.273
--- reload.c	14 Jul 2005 08:07:56 -0000
***************
*** 1231,1245 ****
  
    /* Narrow down the class of register wanted if that is
       desirable on this machine for efficiency.  */
!   if (in != 0)
!     class = PREFERRED_RELOAD_CLASS (in, class);
  
    /* Output reloads may need analogous treatment, different in detail.  */
  #ifdef PREFERRED_OUTPUT_RELOAD_CLASS
!   if (out != 0)
!     class = PREFERRED_OUTPUT_RELOAD_CLASS (out, class);
  #endif
  
    /* Make sure we use a class that can handle the actual pseudo
       inside any subreg.  For example, on the 386, QImode regs
       can appear within SImode subregs.  Although GENERAL_REGS
--- 1231,1254 ----
  
    /* Narrow down the class of register wanted if that is
       desirable on this machine for efficiency.  */
!   {
!     enum reg_class preferred_class = class;
! 
!     if (in != 0)
!       preferred_class = PREFERRED_RELOAD_CLASS (in, class);
  
    /* Output reloads may need analogous treatment, different in detail.  */
  #ifdef PREFERRED_OUTPUT_RELOAD_CLASS
!     if (out != 0)
!       preferred_class = PREFERRED_OUTPUT_RELOAD_CLASS (out, preferred_class);
  #endif
  
+     /* Discard what the target said if we cannot do it.  */
+     if (preferred_class != NO_REGS
+ 	|| (optional && type == RELOAD_FOR_OUTPUT))
+       class = preferred_class;
+   }
+ 
    /* Make sure we use a class that can handle the actual pseudo
       inside any subreg.  For example, on the 386, QImode regs
       can appear within SImode subregs.  Although GENERAL_REGS
***************
*** 3443,3457 ****
  
  	      /* If we can't reload this value at all, reject this
  		 alternative.  Note that we could also lose due to
! 		 LIMIT_RELOAD_RELOAD_CLASS, but we don't check that
  		 here.  */
  
  	      if (! CONSTANT_P (operand)
! 		  && (enum reg_class) this_alternative[i] != NO_REGS
! 		  && (PREFERRED_RELOAD_CLASS (operand,
! 					      (enum reg_class) this_alternative[i])
! 		      == NO_REGS))
! 		bad = 1;
  
  	      /* Alternative loses if it requires a type of reload not
  		 permitted for this insn.  We can always reload SCRATCH
--- 3452,3477 ----
  
  	      /* If we can't reload this value at all, reject this
  		 alternative.  Note that we could also lose due to
! 		 LIMIT_RELOAD_CLASS, but we don't check that
  		 here.  */
  
  	      if (! CONSTANT_P (operand)
! 		  && (enum reg_class) this_alternative[i] != NO_REGS)
! 		{
! 		  if (PREFERRED_RELOAD_CLASS
! 			(operand, (enum reg_class) this_alternative[i])
! 		      == NO_REGS)
! 		    bad = 1;
! 
! #ifdef PREFERRED_OUTPUT_RELOAD_CLASS
! 		  if (operand_type[i] == RELOAD_FOR_OUTPUT
! 		      && PREFERRED_OUTPUT_RELOAD_CLASS
! 			   (operand, (enum reg_class) this_alternative[i])
! 		         == NO_REGS)
! 		    bad = 1;
! #endif
! 		}
! 
  
  	      /* Alternative loses if it requires a type of reload not
  		 permitted for this insn.  We can always reload SCRATCH
Index: doc/tm.texi
===================================================================
RCS file: /cvs/gcc/gcc/gcc/doc/tm.texi,v
retrieving revision 1.441
diff -p -u -r1.441 tm.texi
--- doc/tm.texi	13 Jul 2005 16:28:25 -0000	1.441
+++ doc/tm.texi	15 Jul 2005 14:13:49 -0000
@@ -2385,12 +2385,24 @@ register, so @code{PREFERRED_RELOAD_CLAS
 into any kind of register, code generation will be better if
 @code{LEGITIMATE_CONSTANT_P} makes the constant illegitimate instead
 of using @code{PREFERRED_RELOAD_CLASS}.
+
+If an insn has pseudos in it after register allocation, reload will go
+through the alternatives and call repeatedly @code{PREFERRED_RELOAD_CLASS}
+to find the best one.  Returning @code{NO_REGS}, in this case, makes
+reload add a @code{?} in front of the constraint: the x86 back-end uses
+this feature to discourage usage of 387 registers when math is done in
+the SSE registers (and vice versa).
 @end defmac
 
 @defmac PREFERRED_OUTPUT_RELOAD_CLASS (@var{x}, @var{class})
 Like @code{PREFERRED_RELOAD_CLASS}, but for output reloads instead of
 input reloads.  If you don't define this macro, the default is to use
 @var{class}, unchanged.
+
+You can also use @code{PREFERRED_RELOAD_CLASS} to discourage reload
+from using some of the insns.  In this case, however, be careful not
+to return @code{NO_REGS} when @code{x} is an hard register.
+Otherwise, it will be impossible to successfully reload the insn.
 @end defmac
 
 @defmac LIMIT_RELOAD_CLASS (@var{mode}, @var{class})
Index: config/i386/i386.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/i386/i386.c,v
retrieving revision 1.841
diff -c -r1.841 i386.c
*** config/i386/i386.c	11 Jul 2005 09:35:16 -0000	1.841
--- config/i386/i386.c	14 Jul 2005 08:07:55 -0000
***************
*** 15315,15329 ****
  enum reg_class
  ix86_preferred_reload_class (rtx x, enum reg_class class)
  {
    /* We're only allowed to return a subclass of CLASS.  Many of the 
       following checks fail for NO_REGS, so eliminate that early.  */
    if (class == NO_REGS)
      return NO_REGS;
  
    /* All classes can load zeros.  */
!   if (x == CONST0_RTX (GET_MODE (x)))
      return class;
  
    /* Floating-point constants need more complex checks.  */
    if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) != VOIDmode)
      {
--- 15315,15353 ----
  enum reg_class
  ix86_preferred_reload_class (rtx x, enum reg_class class)
  {
+   enum machine_mode mode = GET_MODE (x);
+   bool is_sse_math_mode;
+ 
    /* We're only allowed to return a subclass of CLASS.  Many of the 
       following checks fail for NO_REGS, so eliminate that early.  */
    if (class == NO_REGS)
      return NO_REGS;
  
    /* All classes can load zeros.  */
!   if (x == CONST0_RTX (mode))
      return class;
  
+   /* Reject this alternative if we are loading: a) a vector constant into
+      an MMX or SSE register b) a floating-point constant into an SSE register
+      that will be used for math.  This is because there are no MMX/SSE
+      load-from-constant instructions.  */
+ 
+   is_sse_math_mode =
+     TARGET_SSE_MATH && !TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (mode);
+ 
+   if (CONSTANT_P (x))
+     {
+       if (MAYBE_MMX_CLASS_P (class))
+         return NO_REGS;
+       if (MAYBE_SSE_CLASS_P (class)
+ 	  && (VECTOR_MODE_P (mode) || mode == TImode || is_sse_math_mode))
+         return NO_REGS;
+     }
+ 
+   /* Prefer SSE regs only, if we can use them for math.  */
+   if (is_sse_math_mode)
+     return SSE_CLASS_P (class) ? class : NO_REGS;
+ 
    /* Floating-point constants need more complex checks.  */
    if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) != VOIDmode)
      {
***************
*** 15335,15342 ****
  	 zero above.  We only want to wind up preferring 80387 registers if
  	 we plan on doing computation with them.  */
        if (TARGET_80387
- 	  && (TARGET_MIX_SSE_I387 
- 	      || !(TARGET_SSE_MATH && SSE_FLOAT_MODE_P (GET_MODE (x))))
  	  && standard_80387_constant_p (x))
  	{
  	  /* Limit class to non-sse.  */
--- 15359,15364 ----
***************
*** 15352,15361 ****
  
        return NO_REGS;
      }
-   if (MAYBE_MMX_CLASS_P (class) && CONSTANT_P (x))
-     return NO_REGS;
-   if (MAYBE_SSE_CLASS_P (class) && CONSTANT_P (x))
-     return NO_REGS;
  
    /* Generally when we see PLUS here, it's the function invariant
       (plus soft-fp const_int).  Which can only be computed into general
--- 15375,15380 ----
***************
*** 15376,15381 ****
--- 15395,15426 ----
  
    return class;
  }
+ 
+ /* Discourage putting floating-point values in SSE registers unless
+    SSE math is being used, and likewise for the 387 registers.  */
+ enum reg_class
+ ix86_preferred_output_reload_class (rtx x, enum reg_class class)
+ {
+   if (!FLOAT_MODE_P (GET_MODE (x)) || TARGET_MIX_SSE_I387)
+     return class;
+ 
+   /* Restrict the output reload class to the register bank that we are doing
+      math on.  If we would like not to return a subset of CLASS, reject this
+      alternative: if reload cannot do this, it will still use its choice.  */
+   if (TARGET_SSE_MATH && SSE_FLOAT_MODE_P (GET_MODE (x)))
+     return SSE_CLASS_P (class) ? class : NO_REGS;
+   else if (TARGET_80387)
+     {
+       if (class == FP_TOP_SSE_REGS)
+ 	return FP_TOP_REG;
+       else if (class == FP_SECOND_SSE_REGS)
+ 	return FP_SECOND_REG;
+       else
+ 	return FLOAT_CLASS_P (class) ? class : NO_REGS;
+     }
+   else
+     return NO_REGS;
+ }
  
  /* If we are copying between general and FP registers, we need a memory
     location. The same is true for SSE and MMX registers.
Index: config/i386/i386.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/i386/i386.h,v
retrieving revision 1.440
diff -c -r1.440 i386.h
*** config/i386/i386.h	26 Jun 2005 05:18:34 -0000	1.440
--- config/i386/i386.h	14 Jul 2005 08:07:55 -0000
***************
*** 1294,1299 ****
--- 1294,1305 ----
  #define PREFERRED_RELOAD_CLASS(X, CLASS) \
     ix86_preferred_reload_class ((X), (CLASS))
  
+ /* Discourage putting floating-point values in SSE registers unless
+    SSE math is being used, and likewise for the 387 registers.  */
+ 
+ #define PREFERRED_OUTPUT_RELOAD_CLASS(X, CLASS) \
+    ix86_preferred_output_reload_class ((X), (CLASS))
+ 
  /* If we are copying between general and FP registers, we need a memory
     location. The same is true for SSE and MMX registers.  */
  #define SECONDARY_MEMORY_NEEDED(CLASS1, CLASS2, MODE) \
Index: config/i386/i386-protos.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/i386/i386-protos.h,v
retrieving revision 1.143
diff -c -r1.143 i386-protos.h
*** config/i386/i386-protos.h	29 Jun 2005 17:27:16 -0000	1.143
--- config/i386/i386-protos.h	14 Jul 2005 08:07:55 -0000
***************
*** 188,193 ****
--- 188,194 ----
  extern bool ix86_cannot_change_mode_class (enum machine_mode,
  					   enum machine_mode, enum reg_class);
  extern enum reg_class ix86_preferred_reload_class (rtx, enum reg_class);
+ extern enum reg_class ix86_preferred_output_reload_class (rtx, enum reg_class);
  extern int ix86_memory_move_cost (enum machine_mode, enum reg_class, int);
  extern int ix86_mode_needed (int, rtx);
  extern void emit_i387_cw_initialization (int);
Index: config/i386/i386.md
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/i386/i386.md,v
retrieving revision 1.645
diff -c -r1.645 i386.md
*** config/i386/i386.md	12 Jul 2005 09:20:12 -0000	1.645
--- config/i386/i386.md	14 Jul 2005 21:22:24 -0000
***************
*** 946,953 ****
  
  (define_insn "*cmpfp_i_mixed"
    [(set (reg:CCFP FLAGS_REG)
! 	(compare:CCFP (match_operand 0 "register_operand" "f#x,x#f")
! 		      (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
    "TARGET_MIX_SSE_I387
     && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
     && GET_MODE (operands[0]) == GET_MODE (operands[1])"
--- 946,953 ----
  
  (define_insn "*cmpfp_i_mixed"
    [(set (reg:CCFP FLAGS_REG)
! 	(compare:CCFP (match_operand 0 "register_operand" "f,x")
! 		      (match_operand 1 "nonimmediate_operand" "f,xm")))]
    "TARGET_MIX_SSE_I387
     && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
     && GET_MODE (operands[0]) == GET_MODE (operands[1])"
***************
*** 995,1002 ****
  
  (define_insn "*cmpfp_iu_mixed"
    [(set (reg:CCFPU FLAGS_REG)
! 	(compare:CCFPU (match_operand 0 "register_operand" "f#x,x#f")
! 		       (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
    "TARGET_MIX_SSE_I387
     && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
     && GET_MODE (operands[0]) == GET_MODE (operands[1])"
--- 995,1002 ----
  
  (define_insn "*cmpfp_iu_mixed"
    [(set (reg:CCFPU FLAGS_REG)
! 	(compare:CCFPU (match_operand 0 "register_operand" "f,x")
! 		       (match_operand 1 "nonimmediate_operand" "f,xm")))]
    "TARGET_MIX_SSE_I387
     && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
     && GET_MODE (operands[0]) == GET_MODE (operands[1])"
***************
*** 2197,2203 ****
  
  (define_insn "*pushsf"
    [(set (match_operand:SF 0 "push_operand" "=<,<,<")
! 	(match_operand:SF 1 "general_no_elim_operand" "f#rx,rFm#fx,x#rf"))]
    "!TARGET_64BIT"
  {
    /* Anything else should be already split before reg-stack.  */
--- 2197,2203 ----
  
  (define_insn "*pushsf"
    [(set (match_operand:SF 0 "push_operand" "=<,<,<")
! 	(match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
    "!TARGET_64BIT"
  {
    /* Anything else should be already split before reg-stack.  */
***************
*** 2210,2216 ****
  
  (define_insn "*pushsf_rex64"
    [(set (match_operand:SF 0 "push_operand" "=X,X,X")
! 	(match_operand:SF 1 "nonmemory_no_elim_operand" "f#rx,rF#fx,x#rf"))]
    "TARGET_64BIT"
  {
    /* Anything else should be already split before reg-stack.  */
--- 2210,2216 ----
  
  (define_insn "*pushsf_rex64"
    [(set (match_operand:SF 0 "push_operand" "=X,X,X")
! 	(match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
    "TARGET_64BIT"
  {
    /* Anything else should be already split before reg-stack.  */
***************
*** 2250,2258 ****
  
  (define_insn "*movsf_1"
    [(set (match_operand:SF 0 "nonimmediate_operand"
! 	  "=f#xr,m   ,f#xr,r#xf  ,m    ,x#rf,x#rf,x#rf ,m   ,!*y,!rm,!*y")
  	(match_operand:SF 1 "general_operand"
! 	  "fm#rx,f#rx,G   ,rmF#fx,Fr#fx,C   ,x   ,xm#rf,x#rf,rm ,*y ,*y"))]
    "!(MEM_P (operands[0]) && MEM_P (operands[1]))
     && (reload_in_progress || reload_completed
         || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
--- 2250,2258 ----
  
  (define_insn "*movsf_1"
    [(set (match_operand:SF 0 "nonimmediate_operand"
! 	  "=f,m   ,f,r,m    ,x,x,x,m   ,!*y,!rm,!*y")
  	(match_operand:SF 1 "general_operand"
! 	  "fm,f,G   ,rmF,Fr,C   ,x   ,xm,x,rm ,*y ,*y"))]
    "!(MEM_P (operands[0]) && MEM_P (operands[1]))
     && (reload_in_progress || reload_completed
         || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
***************
*** 2365,2371 ****
  
  (define_insn "*pushdf_nointeger"
    [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
! 	(match_operand:DF 1 "general_no_elim_operand" "f#Y,Fo#fY,*r#fY,Y#f"))]
    "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
  {
    /* This insn should be already split before reg-stack.  */
--- 2365,2371 ----
  
  (define_insn "*pushdf_nointeger"
    [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
! 	(match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y"))]
    "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
  {
    /* This insn should be already split before reg-stack.  */
***************
*** 2377,2383 ****
  
  (define_insn "*pushdf_integer"
    [(set (match_operand:DF 0 "push_operand" "=<,<,<")
! 	(match_operand:DF 1 "general_no_elim_operand" "f#rY,rFo#fY,Y#rf"))]
    "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
  {
    /* This insn should be already split before reg-stack.  */
--- 2377,2383 ----
  
  (define_insn "*pushdf_integer"
    [(set (match_operand:DF 0 "push_operand" "=<,<,<")
! 	(match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y"))]
    "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
  {
    /* This insn should be already split before reg-stack.  */
***************
*** 2417,2425 ****
  
  (define_insn "*movdf_nointeger"
    [(set (match_operand:DF 0 "nonimmediate_operand"
! 			"=f#Y,m  ,f#Y,*r  ,o  ,Y*x#f,Y*x#f,Y*x#f  ,m    ")
  	(match_operand:DF 1 "general_operand"
! 			"fm#Y,f#Y,G  ,*roF,F*r,C    ,Y*x#f,HmY*x#f,Y*x#f"))]
    "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
     && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
     && (reload_in_progress || reload_completed
--- 2417,2425 ----
  
  (define_insn "*movdf_nointeger"
    [(set (match_operand:DF 0 "nonimmediate_operand"
! 			"=f,m  ,f,*r  ,o  ,Y*x,Y*x,Y*x,m    ")
  	(match_operand:DF 1 "general_operand"
! 			"fm,f,G  ,*roF,F*r,C    ,Y*x,HmY*x,Y*x"))]
    "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
     && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
     && (reload_in_progress || reload_completed
***************
*** 2537,2545 ****
  
  (define_insn "*movdf_integer"
    [(set (match_operand:DF 0 "nonimmediate_operand"
! 		"=f#Yr,m   ,f#Yr,r#Yf  ,o    ,Y*x#rf,Y*x#rf,Y*x#rf,m")
  	(match_operand:DF 1 "general_operand"
! 		"fm#Yr,f#Yr,G   ,roF#Yf,Fr#Yf,C     ,Y*x#rf,m     ,Y*x#rf"))]
    "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
     && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
     && (reload_in_progress || reload_completed
--- 2537,2545 ----
  
  (define_insn "*movdf_integer"
    [(set (match_operand:DF 0 "nonimmediate_operand"
! 		"=f,m   ,f,r,o    ,Y*x,Y*x,Y*x,m")
  	(match_operand:DF 1 "general_operand"
! 		"fm,f,G   ,roF,Fr,C     ,Y*x,m     ,Y*x"))]
    "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
     && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
     && (reload_in_progress || reload_completed
***************
*** 2712,2718 ****
  
  (define_insn "*pushxf_integer"
    [(set (match_operand:XF 0 "push_operand" "=<,<")
! 	(match_operand:XF 1 "general_no_elim_operand" "f#r,ro#f"))]
    "!optimize_size"
  {
    /* This insn should be already split before reg-stack.  */
--- 2712,2718 ----
  
  (define_insn "*pushxf_integer"
    [(set (match_operand:XF 0 "push_operand" "=<,<")
! 	(match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
    "!optimize_size"
  {
    /* This insn should be already split before reg-stack.  */
***************
*** 2784,2791 ****
     (set_attr "mode" "XF,XF,XF,SI,SI")])
  
  (define_insn "*movxf_integer"
!   [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
! 	(match_operand:XF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
    "!optimize_size
     && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
     && (reload_in_progress || reload_completed
--- 2784,2791 ----
     (set_attr "mode" "XF,XF,XF,SI,SI")])
  
  (define_insn "*movxf_integer"
!   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
! 	(match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
    "!optimize_size
     && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
     && (reload_in_progress || reload_completed
***************
*** 3508,3515 ****
  })
  
  (define_insn "*extendsfdf2_mixed"
!   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,m#fY,Y#f")
!         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm#Y,f#Y,mY#f")))]
    "TARGET_SSE2 && TARGET_MIX_SSE_I387
     && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
  {
--- 3508,3515 ----
  })
  
  (define_insn "*extendsfdf2_mixed"
!   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,Y")
!         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f,mY")))]
    "TARGET_SSE2 && TARGET_MIX_SSE_I387
     && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
  {
***************
*** 3824,3830 ****
  })
  
  (define_insn "*truncxfsf2_mixed"
!   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
  	(float_truncate:SF
  	 (match_operand:XF 1 "register_operand" "f,f,f,f")))
     (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
--- 3824,3830 ----
  })
  
  (define_insn "*truncxfsf2_mixed"
!   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?r,?x")
  	(float_truncate:SF
  	 (match_operand:XF 1 "register_operand" "f,f,f,f")))
     (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
***************
*** 3851,3857 ****
     (set_attr "mode" "SF")])
  
  (define_insn "*truncxfsf2_i387"
!   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#r,?r#f")
  	(float_truncate:SF
  	 (match_operand:XF 1 "register_operand" "f,f,f")))
     (clobber (match_operand:SF 2 "memory_operand" "=X,m,m"))]
--- 3851,3857 ----
     (set_attr "mode" "SF")])
  
  (define_insn "*truncxfsf2_i387"
!   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?r")
  	(float_truncate:SF
  	 (match_operand:XF 1 "register_operand" "f,f,f")))
     (clobber (match_operand:SF 2 "memory_operand" "=X,m,m"))]
***************
*** 3922,3928 ****
  })
  
  (define_insn "*truncxfdf2_mixed"
!   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#rY,?r#fY,?Y#rf")
  	(float_truncate:DF
  	 (match_operand:XF 1 "register_operand" "f,f,f,f")))
     (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
--- 3922,3928 ----
  })
  
  (define_insn "*truncxfdf2_mixed"
!   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?r,?Y")
  	(float_truncate:DF
  	 (match_operand:XF 1 "register_operand" "f,f,f,f")))
     (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
***************
*** 3949,3955 ****
     (set_attr "mode" "DF")])
  
  (define_insn "*truncxfdf2_i387"
!   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#r,?r#f")
  	(float_truncate:DF
  	 (match_operand:XF 1 "register_operand" "f,f,f")))
     (clobber (match_operand:DF 2 "memory_operand" "=X,m,m"))]
--- 3949,3955 ----
     (set_attr "mode" "DF")])
  
  (define_insn "*truncxfdf2_i387"
!   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?r")
  	(float_truncate:DF
  	 (match_operand:XF 1 "register_operand" "f,f,f")))
     (clobber (match_operand:DF 2 "memory_operand" "=X,m,m"))]
***************
*** 4423,4429 ****
    "")
  
  (define_insn "*floatsisf2_mixed"
!   [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
  	(float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
    "TARGET_MIX_SSE_I387"
    "@
--- 4423,4429 ----
    "")
  
  (define_insn "*floatsisf2_mixed"
!   [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
  	(float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
    "TARGET_MIX_SSE_I387"
    "@
***************
*** 4466,4472 ****
    "")
  
  (define_insn "*floatdisf2_mixed"
!   [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
  	(float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
    "TARGET_64BIT && TARGET_MIX_SSE_I387"
    "@
--- 4466,4472 ----
    "")
  
  (define_insn "*floatdisf2_mixed"
!   [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
  	(float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
    "TARGET_64BIT && TARGET_MIX_SSE_I387"
    "@
***************
*** 4534,4540 ****
    "")
  
  (define_insn "*floatsidf2_mixed"
!   [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
  	(float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
    "TARGET_SSE2 && TARGET_MIX_SSE_I387"
    "@
--- 4534,4540 ----
    "")
  
  (define_insn "*floatsidf2_mixed"
!   [(set (match_operand:DF 0 "register_operand" "=f,?f,Y,Y")
  	(float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
    "TARGET_SSE2 && TARGET_MIX_SSE_I387"
    "@
***************
*** 4577,4583 ****
    "")
  
  (define_insn "*floatdidf2_mixed"
!   [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
  	(float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
    "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387"
    "@
--- 4577,4583 ----
    "")
  
  (define_insn "*floatdidf2_mixed"
!   [(set (match_operand:DF 0 "register_operand" "=f,?f,Y,Y")
  	(float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
    "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387"
    "@
***************
*** 9383,9391 ****
    "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;")
  
  (define_insn "*absnegsf2_mixed"
!   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x#f,x#f,f#x,rm")
  	(match_operator:SF 3 "absneg_operator"
! 	  [(match_operand:SF 1 "nonimmediate_operand" "0   ,x#f,0  ,0")]))
     (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm  ,0  ,X  ,X"))
     (clobber (reg:CC FLAGS_REG))]
    "TARGET_SSE_MATH && TARGET_MIX_SSE_I387
--- 9383,9391 ----
    "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;")
  
  (define_insn "*absnegsf2_mixed"
!   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x,x,f,rm")
  	(match_operator:SF 3 "absneg_operator"
! 	  [(match_operand:SF 1 "nonimmediate_operand" "0   ,x,0  ,0")]))
     (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm  ,0  ,X  ,X"))
     (clobber (reg:CC FLAGS_REG))]
    "TARGET_SSE_MATH && TARGET_MIX_SSE_I387
***************
*** 9479,9487 ****
    "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;")
  
  (define_insn "*absnegdf2_mixed"
!   [(set (match_operand:DF 0 "nonimmediate_operand"    "=Y#f,Y#f,f#Y,rm")
  	(match_operator:DF 3 "absneg_operator"
! 	  [(match_operand:DF 1 "nonimmediate_operand" "0   ,Y#f,0  ,0")]))
     (use (match_operand:V2DF 2 "nonimmediate_operand"  "Ym  ,0  ,X  ,X"))
     (clobber (reg:CC FLAGS_REG))]
    "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
--- 9479,9487 ----
    "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;")
  
  (define_insn "*absnegdf2_mixed"
!   [(set (match_operand:DF 0 "nonimmediate_operand"    "=Y,Y,f,rm")
  	(match_operator:DF 3 "absneg_operator"
! 	  [(match_operand:DF 1 "nonimmediate_operand" "0   ,Y,0  ,0")]))
     (use (match_operand:V2DF 2 "nonimmediate_operand"  "Ym  ,0  ,X  ,X"))
     (clobber (reg:CC FLAGS_REG))]
    "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
***************
*** 12723,12730 ****
  (define_insn "*fp_jcc_1_mixed"
    [(set (pc)
  	(if_then_else (match_operator 0 "comparison_operator"
! 			[(match_operand 1 "register_operand" "f#x,x#f")
! 			 (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
  	  (label_ref (match_operand 3 "" ""))
  	  (pc)))
     (clobber (reg:CCFP FPSR_REG))
--- 12723,12730 ----
  (define_insn "*fp_jcc_1_mixed"
    [(set (pc)
  	(if_then_else (match_operator 0 "comparison_operator"
! 			[(match_operand 1 "register_operand" "f,x")
! 			 (match_operand 2 "nonimmediate_operand" "f,xm")])
  	  (label_ref (match_operand 3 "" ""))
  	  (pc)))
     (clobber (reg:CCFP FPSR_REG))
***************
*** 12768,12775 ****
  (define_insn "*fp_jcc_2_mixed"
    [(set (pc)
  	(if_then_else (match_operator 0 "comparison_operator"
! 			[(match_operand 1 "register_operand" "f#x,x#f")
! 			 (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
  	  (pc)
  	  (label_ref (match_operand 3 "" ""))))
     (clobber (reg:CCFP FPSR_REG))
--- 12768,12775 ----
  (define_insn "*fp_jcc_2_mixed"
    [(set (pc)
  	(if_then_else (match_operator 0 "comparison_operator"
! 			[(match_operand 1 "register_operand" "f,x")
! 			 (match_operand 2 "nonimmediate_operand" "f,xm")])
  	  (pc)
  	  (label_ref (match_operand 3 "" ""))))
     (clobber (reg:CCFP FPSR_REG))
***************
*** 13906,13915 ****
  ;; so use special patterns for add and mull.
  
  (define_insn "*fop_sf_comm_mixed"
!   [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
  	(match_operator:SF 3 "binary_fp_operator"
  			[(match_operand:SF 1 "nonimmediate_operand" "%0,0")
! 			 (match_operand:SF 2 "nonimmediate_operand" "fm#x,xm#f")]))]
    "TARGET_MIX_SSE_I387
     && COMMUTATIVE_ARITH_P (operands[3])
     && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
--- 13906,13915 ----
  ;; so use special patterns for add and mull.
  
  (define_insn "*fop_sf_comm_mixed"
!   [(set (match_operand:SF 0 "register_operand" "=f,x")
  	(match_operator:SF 3 "binary_fp_operator"
  			[(match_operand:SF 1 "nonimmediate_operand" "%0,0")
! 			 (match_operand:SF 2 "nonimmediate_operand" "fm,xm")]))]
    "TARGET_MIX_SSE_I387
     && COMMUTATIVE_ARITH_P (operands[3])
     && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
***************
*** 13958,13964 ****
    [(set (match_operand:SF 0 "register_operand" "=f,f,x")
  	(match_operator:SF 3 "binary_fp_operator"
  			[(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
! 			 (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm#f")]))]
    "TARGET_MIX_SSE_I387
     && !COMMUTATIVE_ARITH_P (operands[3])
     && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
--- 13958,13964 ----
    [(set (match_operand:SF 0 "register_operand" "=f,f,x")
  	(match_operator:SF 3 "binary_fp_operator"
  			[(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
! 			 (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm")]))]
    "TARGET_MIX_SSE_I387
     && !COMMUTATIVE_ARITH_P (operands[3])
     && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
***************
*** 14052,14061 ****
     (set_attr "mode" "<MODE>")])
  
  (define_insn "*fop_df_comm_mixed"
!   [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
  	(match_operator:DF 3 "binary_fp_operator"
  			[(match_operand:DF 1 "nonimmediate_operand" "%0,0")
! 			 (match_operand:DF 2 "nonimmediate_operand" "fm#Y,Ym#f")]))]
    "TARGET_SSE2 && TARGET_MIX_SSE_I387
     && COMMUTATIVE_ARITH_P (operands[3])
     && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
--- 14052,14061 ----
     (set_attr "mode" "<MODE>")])
  
  (define_insn "*fop_df_comm_mixed"
!   [(set (match_operand:DF 0 "register_operand" "=f,Y")
  	(match_operator:DF 3 "binary_fp_operator"
  			[(match_operand:DF 1 "nonimmediate_operand" "%0,0")
! 			 (match_operand:DF 2 "nonimmediate_operand" "fm,Ym")]))]
    "TARGET_SSE2 && TARGET_MIX_SSE_I387
     && COMMUTATIVE_ARITH_P (operands[3])
     && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
***************
*** 14101,14110 ****
     (set_attr "mode" "DF")])
  
  (define_insn "*fop_df_1_mixed"
!   [(set (match_operand:DF 0 "register_operand" "=f#Y,f#Y,Y#f")
  	(match_operator:DF 3 "binary_fp_operator"
  			[(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
! 			 (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym#f")]))]
    "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
     && !COMMUTATIVE_ARITH_P (operands[3])
     && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
--- 14101,14110 ----
     (set_attr "mode" "DF")])
  
  (define_insn "*fop_df_1_mixed"
!   [(set (match_operand:DF 0 "register_operand" "=f,f,Y")
  	(match_operator:DF 3 "binary_fp_operator"
  			[(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
! 			 (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym")]))]
    "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
     && !COMMUTATIVE_ARITH_P (operands[3])
     && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
***************
*** 14419,14426 ****
  })
  
  (define_insn "*sqrtsf2_mixed"
!   [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
! 	(sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0#x,xm#f")))]
    "TARGET_USE_FANCY_MATH_387 && TARGET_MIX_SSE_I387"
    "@
     fsqrt
--- 14419,14426 ----
  })
  
  (define_insn "*sqrtsf2_mixed"
!   [(set (match_operand:SF 0 "register_operand" "=f,x")
! 	(sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0,xm")))]
    "TARGET_USE_FANCY_MATH_387 && TARGET_MIX_SSE_I387"
    "@
     fsqrt
***************
*** 14457,14464 ****
  })
  
  (define_insn "*sqrtdf2_mixed"
!   [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
! 	(sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0#Y,Ym#f")))]
    "TARGET_USE_FANCY_MATH_387 && TARGET_SSE2 && TARGET_MIX_SSE_I387"
    "@
     fsqrt
--- 14457,14464 ----
  })
  
  (define_insn "*sqrtdf2_mixed"
!   [(set (match_operand:DF 0 "register_operand" "=f,Y")
! 	(sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0,Ym")))]
    "TARGET_USE_FANCY_MATH_387 && TARGET_SSE2 && TARGET_MIX_SSE_I387"
    "@
     fsqrt
***************
*** 17921,17931 ****
    "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
  
  (define_insn "*movsfcc_1_387"
!   [(set (match_operand:SF 0 "register_operand" "=f#r,f#r,r#f,r#f")
  	(if_then_else:SF (match_operator 1 "fcmov_comparison_operator" 
  				[(reg FLAGS_REG) (const_int 0)])
! 		      (match_operand:SF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
! 		      (match_operand:SF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
    "TARGET_80387 && TARGET_CMOVE
     && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
    "@
--- 17921,17931 ----
    "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
  
  (define_insn "*movsfcc_1_387"
!   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
  	(if_then_else:SF (match_operator 1 "fcmov_comparison_operator" 
  				[(reg FLAGS_REG) (const_int 0)])
! 		      (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
! 		      (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
    "TARGET_80387 && TARGET_CMOVE
     && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
    "@
***************
*** 17945,17955 ****
    "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
  
  (define_insn "*movdfcc_1"
!   [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,&r#f,&r#f")
  	(if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
  				[(reg FLAGS_REG) (const_int 0)])
! 		      (match_operand:DF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
! 		      (match_operand:DF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
    "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
     && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
    "@
--- 17945,17955 ----
    "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
  
  (define_insn "*movdfcc_1"
!   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
  	(if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
  				[(reg FLAGS_REG) (const_int 0)])
! 		      (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
! 		      (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
    "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
     && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
    "@
***************
*** 17961,17971 ****
     (set_attr "mode" "DF")])
  
  (define_insn "*movdfcc_1_rex64"
!   [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,r#f,r#f")
  	(if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
  				[(reg FLAGS_REG) (const_int 0)])
! 		      (match_operand:DF 2 "nonimmediate_operand" "f#r,0#r,rm#f,0#f")
! 		      (match_operand:DF 3 "nonimmediate_operand" "0#r,f#r,0#f,rm#f")))]
    "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
     && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
    "@
--- 17961,17971 ----
     (set_attr "mode" "DF")])
  
  (define_insn "*movdfcc_1_rex64"
!   [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
  	(if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
  				[(reg FLAGS_REG) (const_int 0)])
! 		      (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
! 		      (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
    "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
     && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
    "@

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