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 and neg patterns


Hi
This patch should fill in the last gap in SSE code generation by neg patterns.

Honza

Wed Apr 25 21:33:15 CEST 2001  Jan Hubicka  <jh@suse.cz>
	* i386.md (negsf2, negdf2 expander): Emit to pattern with
	negative zero constant if SSE is enabled.
	(negsf2_memory, negsf2_ifs, negdf2_memory, negdf2_ifs): New pattern.
Index: config/i386/i386.md
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/i386/i386.md,v
retrieving revision 1.264
diff -c -3 -p -r1.264 i386.md
*** i386.md	2001/04/16 00:12:44	1.264
--- i386.md	2001/04/25 19:32:30
***************
*** 9308,9315 ****
  		   (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))
  	      (clobber (reg:CC 17))])]
    "TARGET_80387"
!   "ix86_expand_unary_operator (NEG, SFmode, operands); DONE;")
  
  ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
  ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
  ;; to itself.
--- 9308,9390 ----
  		   (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))
  	      (clobber (reg:CC 17))])]
    "TARGET_80387"
!   "if (TARGET_SSE)
!      {
!        /* In case operand is in memory,  we will not use SSE.  */
!        if (memory_operand (operands[0], VOIDmode)
! 	   && rtx_equal_p (operands[0], operands[1]))
! 	 emit_insn (gen_negsf2_memory (operands[0], operands[1]));
!        else
! 	{
! 	  /* Using SSE is tricky, since we need bitwise negation of -0
! 	     in register.  */
! 	  rtx reg = gen_reg_rtx (SFmode);
! 	  emit_move_insn (reg,
! 			  gen_lowpart (SFmode,
! 				       trunc_int_for_mode (0x80000000,
! 							   SImode)));
! 	  emit_insn (gen_negsf2_ifs (operands[0], operands[1], reg));
! 	}
!        DONE;
!      }
!    ix86_expand_unary_operator (NEG, SFmode, operands); DONE;")
! 
! (define_insn "negsf2_memory"
!   [(set (match_operand:SF 0 "memory_operand" "=m")
! 	(neg:SF (match_operand:SF 1 "memory_operand" "0")))
!    (clobber (reg:CC 17))]
!   "ix86_unary_operator_ok (NEG, SFmode, operands)"
!   "#")
! 
! (define_insn "negsf2_ifs"
!   [(set (match_operand:SF 0 "nonimmediate_operand" "=x#fr,x#fr,f#xr,r#xf")
! 	(neg:SF (match_operand:SF 1 "nonimmediate_operand" "0,x#fr,0,0")))
!    (use (match_operand:SF 2 "nonmemory_operand" "x#x,0#x,*X#x,*X#x"))
!    (clobber (reg:CC 17))]
!   "TARGET_SSE"
!   "#")
! 
! (define_split
!   [(set (match_operand:SF 0 "memory_operand" "")
! 	(neg:SF (match_operand:SF 1 "memory_operand" "")))
!    (use (match_operand:SF 2 "" ""))
!    (clobber (reg:CC 17))]
!   ""
!   [(parallel [(set (match_dup 0)
! 		   (neg:SF (match_dup 1)))
! 	      (clobber (reg:CC 17))])])
! 
! (define_split
!   [(set (match_operand:SF 0 "register_operand" "")
! 	(neg:SF (match_operand:SF 1 "register_operand" "")))
!    (use (match_operand:SF 2 "" ""))
!    (clobber (reg:CC 17))]
!   "reload_completed && !SSE_REG_P (operands[0])"
!   [(parallel [(set (match_dup 0)
! 		   (neg:SF (match_dup 1)))
! 	      (clobber (reg:CC 17))])])
  
+ (define_split
+   [(set (match_operand:SF 0 "register_operand" "")
+ 	(neg:SF (match_operand:SF 1 "register_operand" "")))
+    (use (match_operand:SF 2 "register_operand" ""))
+    (clobber (reg:CC 17))]
+   "reload_completed && SSE_REG_P (operands[0])"
+   [(set (subreg:TI (match_dup 0) 0)
+ 	(xor:TI (subreg:TI (match_dup 1) 0)
+ 		(subreg:TI (match_dup 2) 0)))]
+   "
+ {
+   if (operands_match_p (operands[0], operands[2]))
+     {
+       rtx tmp;
+       tmp = operands[1];
+       operands[1] = operands[2];
+       operands[2] = tmp;
+     }
+ }")
+ 
+ 
  ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
  ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
  ;; to itself.
***************
*** 9317,9323 ****
    [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
  	(neg:SF (match_operand:SF 1 "nonimmediate_operand" "0,0")))
     (clobber (reg:CC 17))]
!   "TARGET_80387 && ix86_unary_operator_ok (NEG, SFmode, operands)"
    "#")
  
  (define_split
--- 9392,9399 ----
    [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
  	(neg:SF (match_operand:SF 1 "nonimmediate_operand" "0,0")))
     (clobber (reg:CC 17))]
!   "TARGET_80387 && !TARGET_SSE
!    && ix86_unary_operator_ok (NEG, SFmode, operands)"
    "#")
  
  (define_split
***************
*** 9363,9369 ****
  		   (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))
  	      (clobber (reg:CC 17))])]
    "TARGET_80387"
!   "ix86_expand_unary_operator (NEG, DFmode, operands); DONE;")
  
  ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
  ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
--- 9439,9521 ----
  		   (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))
  	      (clobber (reg:CC 17))])]
    "TARGET_80387"
!   "if (TARGET_SSE2)
!      {
!        /* In case operand is in memory,  we will not use SSE.  */
!        if (memory_operand (operands[0], VOIDmode)
! 	   && rtx_equal_p (operands[0], operands[1]))
! 	 emit_insn (gen_negdf2_memory (operands[0], operands[1]));
!        else
! 	{
! 	  /* Using SSE is tricky, since we need bitwise negation of -0
! 	     in register.  */
! 	  rtx reg = gen_reg_rtx (DFmode);
! #if HOST_BITS_PER_WIDE_INT >= 64
! 	  rtx imm = GEN_INT (0x80000000);
! #else
! 	  rtx imm = immed_double_const (0, 0x80000000, DImode);
! #endif
! 	  emit_move_insn (reg, gen_lowpart (DFmode, imm));
! 	  emit_insn (gen_negdf2_ifs (operands[0], operands[1], reg));
! 	}
!        DONE;
!      }
!    ix86_expand_unary_operator (NEG, DFmode, operands); DONE;")
! 
! (define_insn "negdf2_memory"
!   [(set (match_operand:DF 0 "memory_operand" "=m")
! 	(neg:DF (match_operand:DF 1 "memory_operand" "0")))
!    (clobber (reg:CC 17))]
!   "ix86_unary_operator_ok (NEG, DFmode, operands)"
!   "#")
! 
! (define_insn "negdf2_ifs"
!   [(set (match_operand:DF 0 "nonimmediate_operand" "=x#fr,x#fr,f#xr,r#xf")
! 	(neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,x#fr,0,0")))
!    (use (match_operand:DF 2 "nonmemory_operand" "x#x,0#x,*X#x,*X#x"))
!    (clobber (reg:CC 17))]
!   "TARGET_SSE2"
!   "#")
! 
! (define_split
!   [(set (match_operand:DF 0 "memory_operand" "")
! 	(neg:DF (match_operand:DF 1 "memory_operand" "")))
!    (use (match_operand:DF 2 "" ""))
!    (clobber (reg:CC 17))]
!   ""
!   [(parallel [(set (match_dup 0)
! 		   (neg:DF (match_dup 1)))
! 	      (clobber (reg:CC 17))])])
! 
! (define_split
!   [(set (match_operand:DF 0 "register_operand" "")
! 	(neg:DF (match_operand:DF 1 "register_operand" "")))
!    (use (match_operand:DF 2 "" ""))
!    (clobber (reg:CC 17))]
!   "reload_completed && !SSE_REG_P (operands[0])"
!   [(parallel [(set (match_dup 0)
! 		   (neg:DF (match_dup 1)))
! 	      (clobber (reg:CC 17))])])
! 
! (define_split
!   [(set (match_operand:DF 0 "register_operand" "")
! 	(neg:DF (match_operand:DF 1 "register_operand" "")))
!    (use (match_operand:DF 2 "register_operand" ""))
!    (clobber (reg:CC 17))]
!   "reload_completed && SSE_REG_P (operands[0])"
!   [(set (subreg:TI (match_dup 0) 0)
! 	(xor:TI (subreg:TI (match_dup 1) 0)
! 		(subreg:TI (match_dup 2) 0)))]
!   "
! {
!   if (operands_match_p (operands[0], operands[2]))
!     {
!       rtx tmp;
!       tmp = operands[1];
!       operands[1] = operands[2];
!       operands[2] = tmp;
!     }
! }")
  
  ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
  ;; because of secondary memory needed to reload from class FLOAT_INT_REGS


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