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]

SSE move tweeks


Hi,
This adds support for using "pxor" to load zero into SSE register.
It also cleans up little bit the SSE moves and detecting of i387 standard
constant.

Bootrapped/regtested with -msse2
Honza

Tue Feb 27 13:32:07 CET 2001  Jan Hubicka  <jh@suse.cz>
	* i386.md (attribute mode): Add "TI".
	(movsf_1): Add pxor support; remove constant propagation splitter.
	(movdf_integer): Likewise.
	(movdf_nointeger): Likewise.
	(movxf constant prop splitter): Handle all modes; update for SSE.
	* i386.h (CONST_DOUBLE_OK_FOR_LETTER): Add 'H' for SSE constants.
	* i386.c (standard_80387_constant_p): Rewrite.
	(standard_sse_constant_p): New.
	* i386-protos.h (standard_sse_constant_p): New.
Index: i386.md
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/i386/i386.md,v
retrieving revision 1.220
diff -c -3 -p -r1.220 i386.md
*** i386.md	2001/02/25 13:33:59	1.220
--- i386.md	2001/02/27 12:28:42
***************
*** 107,113 ****
    (const_string "other"))
  
  ;; Main data type used by the insn
! (define_attr "mode" "unknown,none,QI,HI,SI,DI,unknownfp,SF,DF,XF"
    (const_string "unknown"))
  
  ;; Set for i387 operations.
--- 107,113 ----
    (const_string "other"))
  
  ;; Main data type used by the insn
! (define_attr "mode" "unknown,none,QI,HI,SI,DI,unknownfp,SF,DF,XF,TI"
    (const_string "unknown"))
  
  ;; Set for i387 operations.
***************
*** 2198,2205 ****
     (set (mem:SF (reg:SI 7)) (match_dup 1))])
  
  (define_insn "*movsf_1"
!   [(set (match_operand:SF 0 "nonimmediate_operand" "=f#xr,m,f#xr,r#xf,m,x#rf,m")
! 	(match_operand:SF 1 "general_operand" "fm#rx,f#rx,G,rmF#fx,Fr#fx,xm#rf,x#rf"))]
    "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
     && (reload_in_progress || reload_completed
         || GET_CODE (operands[1]) != CONST_DOUBLE
--- 2198,2205 ----
     (set (mem:SF (reg:SI 7)) (match_dup 1))])
  
  (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")
! 	(match_operand:SF 1 "general_operand" "fm#rx,f#rx,G,rmF#fx,Fr#fx,H,x,xm#rf,x#rf"))]
    "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
     && (reload_in_progress || reload_completed
         || GET_CODE (operands[1]) != CONST_DOUBLE
***************
*** 2237,2269 ****
      case 4:
        return \"mov{l}\\t{%1, %0|%0, %1}\";
      case 5:
      case 6:
        return \"movss\\t{%1, %0|%0, %1}\";
  
      default:
        abort();
      }
  }"
!   [(set_attr "type" "fmov,fmov,fmov,imov,imov,sse,sse")
!    (set_attr "mode" "SF,SF,SF,SI,SI,SF,SF")])
  
- (define_split
-   [(set (match_operand:SF 0 "nonimmediate_operand" "")
- 	(match_operand:SF 1 "memory_operand" ""))]
-   "reload_completed
-    && GET_CODE (operands[1]) == MEM
-    && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
-    && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))
-    && !(SSE_REG_P (operands[0]) 
-         || (GET_CODE (operands[0]) == SUBREG && SSE_REG_P (operands[0])))
-    && (!(FP_REG_P (operands[0]) || 
- 	 (GET_CODE (operands[0]) == SUBREG
- 	  && FP_REG_P (SUBREG_REG (operands[0]))))
-        || standard_80387_constant_p (get_pool_constant (XEXP (operands[1], 0))))"
-   [(set (match_dup 0)
- 	(match_dup 1))]
-   "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
- 
  (define_insn "*swapsf"
    [(set (match_operand:SF 0 "register_operand" "+f")
  	(match_operand:SF 1 "register_operand" "+f"))
--- 2237,2259 ----
      case 4:
        return \"mov{l}\\t{%1, %0|%0, %1}\";
      case 5:
+       return \"pxor\\t%0, %0\";
      case 6:
+       if (TARGET_PARTIAL_REG_DEPENDENCY)
+ 	return \"movaps\\t{%1, %0|%0, %1}\";
+       else
+ 	return \"movss\\t{%1, %0|%0, %1}\";
+     case 7:
+     case 8:
        return \"movss\\t{%1, %0|%0, %1}\";
  
      default:
        abort();
      }
  }"
!   [(set_attr "type" "fmov,fmov,fmov,imov,imov,sse,sse,sse,sse")
!    (set_attr "mode" "SF,SF,SF,SI,SI,TI,SF,SF,SF")])
  
  (define_insn "*swapsf"
    [(set (match_operand:SF 0 "register_operand" "+f")
  	(match_operand:SF 1 "register_operand" "+f"))
***************
*** 2371,2378 ****
  ;; when optimizing for size.
  
  (define_insn "*movdf_nointeger"
!   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,m,f#Y,*r,o,Y#f,m")
! 	(match_operand:DF 1 "general_operand" "fm#Y,f#Y,G,*roF,F*r,Ym#f,Y#f"))]
    "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
     && (optimize_size || !TARGET_INTEGER_DFMODE_MOVES)
     && (reload_in_progress || reload_completed
--- 2361,2368 ----
  ;; when optimizing for size.
  
  (define_insn "*movdf_nointeger"
!   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,m,f#Y,*r,o,Y#f,Y#f,Y#f,m")
! 	(match_operand:DF 1 "general_operand" "fm#Y,f#Y,G,*roF,F*r,H,Y#f,YHm#f,Y#f"))]
    "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
     && (optimize_size || !TARGET_INTEGER_DFMODE_MOVES)
     && (reload_in_progress || reload_completed
***************
*** 2411,2429 ****
      case 4:
        return \"#\";
      case 5:
      case 6:
        return \"movsd\\t{%1, %0|%0, %1}\";
  
      default:
        abort();
      }
  }"
!   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sse,sse")
!    (set_attr "mode" "DF,DF,DF,SI,SI,DF,DF")])
  
  (define_insn "*movdf_integer"
!   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Yr,m,f#Yr,r#Yf,o,Y#rf,m")
! 	(match_operand:DF 1 "general_operand" "fm#Yr,f#Yr,G,roF#Yf,Fr#Yf,Ym#rf,Y#rf"))]
    "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
     && !optimize_size && TARGET_INTEGER_DFMODE_MOVES
     && (reload_in_progress || reload_completed
--- 2401,2426 ----
      case 4:
        return \"#\";
      case 5:
+       return \"pxor\\t%0, %0\";
      case 6:
+       if (TARGET_PARTIAL_REG_DEPENDENCY)
+ 	return \"movapd\\t{%1, %0|%0, %1}\";
+       else
+ 	return \"movsd\\t{%1, %0|%0, %1}\";
+     case 7:
+     case 8:
        return \"movsd\\t{%1, %0|%0, %1}\";
  
      default:
        abort();
      }
  }"
!   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sse,sse,sse,sse")
!    (set_attr "mode" "DF,DF,DF,SI,SI,TI,DF,DF,DF")])
  
  (define_insn "*movdf_integer"
!   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Yr,m,f#Yr,r#Yf,o,Y#rf,Y#rf,Y#rf,m")
! 	(match_operand:DF 1 "general_operand" "fm#Yr,f#Yr,G,roF#Yf,Fr#Yf,H,Y#rf,Ym#rf,Y#rf"))]
    "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
     && !optimize_size && TARGET_INTEGER_DFMODE_MOVES
     && (reload_in_progress || reload_completed
***************
*** 2463,2477 ****
        return \"#\";
  
      case 5:
      case 6:
        return \"movsd\\t{%1, %0|%0, %1}\";
  
      default:
        abort();
      }
  }"
!   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sse,sse")
!    (set_attr "mode" "DF,DF,DF,SI,SI,DF,DF")])
  
  (define_split
    [(set (match_operand:DF 0 "nonimmediate_operand" "")
--- 2460,2482 ----
        return \"#\";
  
      case 5:
+       return \"pxor\\t%0, %0\";
      case 6:
+       if (TARGET_PARTIAL_REG_DEPENDENCY)
+ 	return \"movapd\\t{%1, %0|%0, %1}\";
+       else
+ 	return \"movsd\\t{%1, %0|%0, %1}\";
+       return \"movsd\\t{%1, %0|%0, %1}\";
+     case 7:
+     case 8:
        return \"movsd\\t{%1, %0|%0, %1}\";
  
      default:
        abort();
      }
  }"
!   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sse,sse,sse,sse")
!    (set_attr "mode" "DF,DF,DF,SI,SI,TI,DF,DF,DF")])
  
  (define_split
    [(set (match_operand:DF 0 "nonimmediate_operand" "")
***************
*** 2488,2507 ****
     (set (match_dup 3) (match_dup 6))]
    "if (ix86_split_long_move (operands)) DONE;")
  
- (define_split
-   [(set (match_operand:DF 0 "register_operand" "")
- 	(match_operand:DF 1 "memory_operand" ""))]
-   "reload_completed
-    && GET_CODE (operands[1]) == MEM
-    && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
-    && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))
-    && !(SSE_REG_P (operands[0]) 
-         || (GET_CODE (operands[0]) == SUBREG && SSE_REG_P (operands[0])))
-    && standard_80387_constant_p (get_pool_constant (XEXP (operands[1], 0)))"
-   [(set (match_dup 0)
- 	(match_dup 1))]
-   "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
- 
  (define_insn "*swapdf"
    [(set (match_operand:DF 0 "register_operand" "+f")
  	(match_operand:DF 1 "register_operand" "+f"))
--- 2493,2498 ----
***************
*** 2887,2896 ****
  	(match_operand 1 "memory_operand" ""))]
    "reload_completed
     && GET_CODE (operands[1]) == MEM
!    && (GET_MODE (operands[0]) == XFmode || GET_MODE (operands[0]) == TFmode)
     && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
     && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))
!    && standard_80387_constant_p (get_pool_constant (XEXP (operands[1], 0)))"
    [(set (match_dup 0)
  	(match_dup 1))]
    "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
--- 2878,2895 ----
  	(match_operand 1 "memory_operand" ""))]
    "reload_completed
     && GET_CODE (operands[1]) == MEM
!    && (GET_MODE (operands[0]) == XFmode || GET_MODE (operands[0]) == TFmode
!        || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
     && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
     && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))
!    && (!(SSE_REG_P (operands[0]) || 
! 	 (GET_CODE (operands[0]) == SUBREG
! 	  && SSE_REG_P (SUBREG_REG (operands[0]))))
!        || standard_sse_constant_p (get_pool_constant (XEXP (operands[1], 0))))
!    && (!(FP_REG_P (operands[0]) || 
! 	 (GET_CODE (operands[0]) == SUBREG
! 	  && FP_REG_P (SUBREG_REG (operands[0]))))
!        || standard_80387_constant_p (get_pool_constant (XEXP (operands[1], 0))))"
    [(set (match_dup 0)
  	(match_dup 1))]
    "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
Index: i386.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/i386/i386.h,v
retrieving revision 1.156
diff -c -3 -p -r1.156 i386.h
*** i386.h	2001/02/19 15:47:30	1.156
--- i386.h	2001/02/27 12:29:26
*************** enum reg_class
*** 1131,1137 ****
     load 0.0 into the function value register.  */
  
  #define CONST_DOUBLE_OK_FOR_LETTER_P(VALUE, C)  \
!   ((C) == 'G' ? standard_80387_constant_p (VALUE) : 0)
  
  /* Place additional restrictions on the register class to use when it
     is necessary to be able to hold a value of mode MODE in a reload
--- 1149,1156 ----
     load 0.0 into the function value register.  */
  
  #define CONST_DOUBLE_OK_FOR_LETTER_P(VALUE, C)  \
!   ((C) == 'G' ? standard_80387_constant_p (VALUE) \
!    : ((C) == 'H' ? standard_sse_constant_p (VALUE) : 0))
  
  /* Place additional restrictions on the register class to use when it
     is necessary to be able to hold a value of mode MODE in a reload
Index: i386.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/i386/i386.c,v
retrieving revision 1.224
diff -c -3 -p -r1.224 i386.c
*** i386.c	2001/02/25 16:35:48	1.224
--- i386.c	2001/02/27 12:29:44
*************** int
*** 1622,1661 ****
  standard_80387_constant_p (x)
       rtx x;
  {
!   if (GET_CODE (x) != CONST_DOUBLE)
      return -1;
! 
! #if ! defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
!   {
!     REAL_VALUE_TYPE d;
!     jmp_buf handler;
!     int is0, is1;
! 
!     if (setjmp (handler))
!       return 0;
! 
!     set_float_handler (handler);
!     REAL_VALUE_FROM_CONST_DOUBLE (d, x);
!     is0 = REAL_VALUES_EQUAL (d, dconst0) && !REAL_VALUE_MINUS_ZERO (d);
!     is1 = REAL_VALUES_EQUAL (d, dconst1);
!     set_float_handler (NULL_PTR);
! 
!     if (is0)
!       return 1;
! 
!     if (is1)
!       return 2;
! 
!     /* Note that on the 80387, other constants, such as pi,
!        are much slower to load as standard constants
!        than to load from doubles in memory!  */
!     /* ??? Not true on K6: all constants are equal cost.  */
!   }
! #endif
! 
    return 0;
  }
  
  /* Returns 1 if OP contains a symbol reference */
  
  int
--- 1715,1743 ----
  standard_80387_constant_p (x)
       rtx x;
  {
!   if (GET_CODE (x) != CONST_DOUBLE || !FLOAT_MODE_P (GET_MODE (x)))
      return -1;
!   /* Note that on the 80387, other constants, such as pi, that we should support
!      too.  On some machines, these are much slower to load as standard constant,
!      than to load from doubles in memory.  */
!   if (x == CONST0_RTX (GET_MODE (x)))
!     return 1;
!   if (x == CONST1_RTX (GET_MODE (x)))
!     return 2;
    return 0;
  }
  
+ /* Return 1 if X is FP constant we can load to SSE register w/o using memory.
+  */
+ int
+ standard_sse_constant_p (x)
+      rtx x;
+ {
+   if (GET_CODE (x) != CONST_DOUBLE)
+     return -1;
+   return (x == CONST0_RTX (GET_MODE (x)));
+ }
+ 
  /* Returns 1 if OP contains a symbol reference */
  
  int
Index: i386-protos.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/i386/i386-protos.h,v
retrieving revision 1.43
diff -c -3 -p -r1.43 i386-protos.h
*** i386-protos.h	2001/02/25 16:35:48	1.43
--- i386-protos.h	2001/02/27 12:31:39
*************** extern void ix86_output_block_profiler P
*** 40,45 ****
--- 40,46 ----
  extern int ix86_aligned_p PARAMS ((rtx));
  
  extern int standard_80387_constant_p PARAMS ((rtx));
+ extern int standard_sse_constant_p PARAMS ((rtx));
  extern int symbolic_reference_mentioned_p PARAMS ((rtx));
  
  extern int const_int_1_operand PARAMS ((rtx, enum machine_mode));


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