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 store flag patterns


Hi
This patch adds store flag patterns needed for conditional move implementation.
It also cleans up the SSE conditional infratructure somehow.


Tue Feb 27 13:52:00 CET 2001  Jan Hubicka  <jh@suse.cz>
	* i386.md (sse_setccsf, sse_setccdf): New.
	(sse_cmp* patterns): Use '%D' instead of outputtting condition
	flag directly.
	* i386.c (sse_comparison_operator): Accept the supported unordered
	comparses; be ready for fast_math.
	* i386.md (print_operand): Support 'D'.
	
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:38:24
***************
*** 9315,9320 ****
--- 9443,9475 ----
    [(set_attr "type" "setcc")
     (set_attr "mode" "QI")])
  
+ ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
+ ;; subsequent logical operations are used to imitate conditional moves.
+ ;; 0xffffffff is NaN, but not in normalized form, se we can't represent
+ ;; it directly.  Futher holding this value in pseudo register might bring
+ ;; problem in implicit normalization in spill code.
+ ;; So we don't define FLOAT_STORE_FLAG_VALUE and create these
+ ;; instructions after reload by splitting the conditional move patterns.
+ 
+ (define_insn "*sse_setccsf"
+   [(set (match_operand:SF 0 "register_operand" "=x")
+ 	(match_operator:SF 1 "sse_comparison_operator"
+ 	  [(match_operand:SF 2 "register_operand" "0")
+ 	   (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
+   "TARGET_SSE && reload_completed"
+   "cmp%D1ss\\t{%3, %0|%0, %3}"
+   [(set_attr "type" "sse")
+    (set_attr "mode" "SF")])
+ 
+ (define_insn "*sse_setccdf"
+   [(set (match_operand:DF 0 "register_operand" "=Y")
+ 	(match_operator:DF 1 "sse_comparison_operator"
+ 	  [(match_operand:DF 2 "register_operand" "0")
+ 	   (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
+   "TARGET_SSE2 && reload_completed"
+   "cmp%D1sd\\t{%3, %0|%0, %3}"
+   [(set_attr "type" "sse")
+    (set_attr "mode" "DF")])
  
  ;; Basic conditional jump instructions.
  ;; We ignore the overflow flag for signed branch instructions.
***************
*** 13669,13690 ****
  			     [(match_operand:V4SF 1 "register_operand" "0")
  			      (match_operand:V4SF 2 "nonimmediate_operand" "x")]))]
    "TARGET_SSE"
!   "*
! {
!   switch (GET_CODE (operands[3]))
!     {
!     case EQ:
!       return \"cmpeqps\\t{%2, %0|%0, %2}\";
!     case LT:
!       return \"cmpltps\\t{%2, %0|%0, %2}\";
!     case LE:
!       return \"cmpleps\\t{%2, %0|%0, %2}\";
!     case UNORDERED:
!       return \"cmpunordps\\t{%2, %0|%0, %2}\";
!     default:
!       abort ();
!     }
! }"
    [(set_attr "type" "sse")])
  
  (define_insn "maskncmpv4sf3"
--- 14462,14468 ----
  			     [(match_operand:V4SF 1 "register_operand" "0")
  			      (match_operand:V4SF 2 "nonimmediate_operand" "x")]))]
    "TARGET_SSE"
!   "cmp%D3ps\\t{%2, %0|%0, %2}"
    [(set_attr "type" "sse")])
  
  (define_insn "maskncmpv4sf3"
***************
*** 13694,13715 ****
  			      [(match_operand:V4SF 1 "register_operand" "0")
  			       (match_operand:V4SF 2 "nonimmediate_operand" "x")])))]
    "TARGET_SSE"
!   "*
! {
!   switch (GET_CODE (operands[3]))
!     {
!     case EQ:
!       return \"cmpneqps\\t{%2, %0|%0, %2}\";
!     case LT:
!       return \"cmpnltps\\t{%2, %0|%0, %2}\";
!     case LE:
!       return \"cmpnleps\\t{%2, %0|%0, %2}\";
!     case UNORDERED:
!       return \"cmpordps\\t{%2, %0|%0, %2}\";
!     default:
!       abort ();
!     }
! }"
    [(set_attr "type" "sse")])
  
  (define_insn "vmmaskcmpv4sf3"
--- 14472,14478 ----
  			      [(match_operand:V4SF 1 "register_operand" "0")
  			       (match_operand:V4SF 2 "nonimmediate_operand" "x")])))]
    "TARGET_SSE"
!   "cmpn%D3ps\\t{%2, %0|%0, %2}"
    [(set_attr "type" "sse")])
  
  (define_insn "vmmaskcmpv4sf3"
***************
*** 13721,13742 ****
  	 (match_dup 1)
  	 (const_int 1)))]
    "TARGET_SSE"
!   "*
! {
!   switch (GET_CODE (operands[3]))
!     {
!     case EQ:
!       return \"cmpeqss\\t{%2, %0|%0, %2}\";
!     case LT:
!       return \"cmpltss\\t{%2, %0|%0, %2}\";
!     case LE:
!       return \"cmpless\\t{%2, %0|%0, %2}\";
!     case UNORDERED:
!       return \"cmpunordss\\t{%2, %0|%0, %2}\";
!     default:
!       abort ();
!     }
! }"
    [(set_attr "type" "sse")])
  
  (define_insn "vmmaskncmpv4sf3"
--- 14484,14490 ----
  	 (match_dup 1)
  	 (const_int 1)))]
    "TARGET_SSE"
!   "cmp%D3ss\\t{%2, %0|%0, %2}"
    [(set_attr "type" "sse")])
  
  (define_insn "vmmaskncmpv4sf3"
***************
*** 13749,13770 ****
  	 (subreg:V4SI (match_dup 1) 0)
  	 (const_int 1)))]
    "TARGET_SSE"
!   "*
! {
!   switch (GET_CODE (operands[3]))
!     {
!     case EQ:
!       return \"cmpneqss\\t{%2, %0|%0, %2}\";
!     case LT:
!       return \"cmpnltss\\t{%2, %0|%0, %2}\";
!     case LE:
!       return \"cmpnless\\t{%2, %0|%0, %2}\";
!     case UNORDERED:
!       return \"cmpordss\\t{%2, %0|%0, %2}\";
!     default:
!       abort ();
!     }
! }"
    [(set_attr "type" "sse")])
  
  (define_insn "sse_comi"
--- 14497,14503 ----
  	 (subreg:V4SI (match_dup 1) 0)
  	 (const_int 1)))]
    "TARGET_SSE"
!   "cmp%D3ss\\t{%2, %0|%0, %2}"
    [(set_attr "type" "sse")])
  
  (define_insn "sse_comi"
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:49:58
*************** sse_comparison_operator (op, mode)
*** 1318,1324 ****
       enum machine_mode mode ATTRIBUTE_UNUSED;
  {
    enum rtx_code code = GET_CODE (op);
!   return code == EQ || code == LT || code == LE || code == UNORDERED;
  }
  /* Return 1 if OP is a valid comparison operator in valid mode.  */
  int
--- 1359,1387 ----
       enum machine_mode mode ATTRIBUTE_UNUSED;
  {
    enum rtx_code code = GET_CODE (op);
!   switch (code)
!     {
!     /* Operations supported directly.  */
!     case EQ:
!     case LT:
!     case LE:
!     case UNORDERED:
!     case NE:
!     case UNGE:
!     case UNGT:
!     case ORDERED:
!       return 1;
!     /* These are equivalent to ones above in non-IEEE comparisons.  */
!     case UNEQ:
!     case UNLT:
!     case UNLE:
!     case LTGT:
!     case GE:
!     case GT:
!       return !TARGET_IEEE_FP;
!     default:
!       return 0;
!     }
  }
  /* Return 1 if OP is a valid comparison operator in valid mode.  */
  int
*************** print_reg (x, code, file)
*** 3326,3332 ****
     k --  likewise, print the SImode name of the register.
     h --  print the QImode name for a "high" register, either ah, bh, ch or dh.
     y --  print "st(0)" instead of "st" as a register.
!    m --  print "st(n)" as an mmx register.  */
  
  void
  print_operand (file, x, code)
--- 3489,3497 ----
     k --  likewise, print the SImode name of the register.
     h --  print the QImode name for a "high" register, either ah, bh, ch or dh.
     y --  print "st(0)" instead of "st" as a register.
!    m --  print "st(n)" as an mmx register.
!    D -- print condition for SSE cmp instruction.
!  */
  
  void
  print_operand (file, x, code)
*************** print_operand (file, x, code)
*** 3460,3465 ****
--- 3627,3673 ----
  	    }
  	  return;
  
+ 	case 'D':
+ 	  /* Little bit of braindamage here.  The SSE compare instructions
+ 	     does use completely different names for the comparisons that the
+ 	     fp conditional moves.  */
+ 	  switch (GET_CODE (x))
+ 	    {
+ 	    case EQ:
+ 	    case UNEQ:
+ 	      fputs ("eq", file);
+ 	      break;
+ 	    case LT:
+ 	    case UNLT:
+ 	      fputs ("lt", file);
+ 	      break;
+ 	    case LE:
+ 	    case UNLE:
+ 	      fputs ("le", file);
+ 	      break;
+ 	    case UNORDERED:
+ 	      fputs ("unord", file);
+ 	      break;
+ 	    case NE:
+ 	    case LTGT:
+ 	      fputs ("neq", file);
+ 	      break;
+ 	    case UNGE:
+ 	    case GE:
+ 	      fputs ("nlt", file);
+ 	      break;
+ 	    case UNGT:
+ 	    case GT:
+ 	      fputs ("nle", file);
+ 	      break;
+ 	    case ORDERED:
+ 	      fputs ("ord", file);
+ 	      break;
+ 	    default:
+ 	      abort ();
+ 	      break;
+ 	    }
+ 	  return;
  	case 'C':
  	  put_condition_code (GET_CODE (x), GET_MODE (XEXP (x, 0)), 0, 0, file);
  	  return;


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