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]

i386 arithmetics+comparison patterns fix



Hi
Here is updated patch that attempts to track the problem in way I mentioned
in previous email.  It does have some problems, but I've decided to stop
here, since otherwise I will end up with too long patch - I believe that
now thinkins are not worse than in current code and the bug is fixed.

The problems are:
 1)  It don't handle constants in the add patterns.  This is especially tricky,
     since combine reverses the condition code etc.
 2)  CCNOmode is never used for adds even when we should use it - the i386.c
     depends on fact that second operand is zero - we will need probably to
     split it to CCNOmode and CCNO0mode, where the first will indicate only
     the presence of good comparison operator.
 3)  Combine don't canonicalize the negs, so they may appear at both
     arms of plus - I am sending separate patch for this.
     Until that these patterns will be rarely generated, since the second
     ("noncanonical") form is more common.

Honza

Tue Sep 12 00:52:16 MET DST 2000  Jan Hubicka  <jh@suse.cz>
	* i386.md (add?i_3, add?i_5): New.
	(add?i_4): Rename from add?i_3;  Fix compare pattern.
	(sub?i_3, xor?i_3, ior?i_3): New.
*** i386.md.old	Mon Aug 28 12:17:54 2000
--- i386.md	Mon Sep 11 23:36:03 2000
***************
*** 3967,3976 ****
     (set_attr "mode" "SI")])
  
  (define_insn "*addsi_3"
    [(set (reg:CC 17)
! 	(compare:CC (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
! 			     (match_operand:SI 2 "general_operand" "rmni,rni"))
! 		    (const_int 0)))			
     (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
  	(plus:SI (match_dup 1) (match_dup 2)))]
    "ix86_binary_operator_ok (PLUS, SImode, operands)
--- 3965,4019 ----
     (set_attr "mode" "SI")])
  
  (define_insn "*addsi_3"
+   [(set (reg 17)
+ 	(compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
+ 		 (match_operand:SI 1 "nonimmediate_operand" "%0")))
+    (clobber (match_scratch:SI 0 "=r"))]
+   "ix86_match_ccmode (insn, CCNOmode)
+    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
+    /* Current assemblers are broken and do not allow @GOTOFF in
+       ought but a memory context. */
+    && ! pic_symbolic_operand (operands[2], VOIDmode)"
+   "*
+ {
+   switch (get_attr_type (insn))
+     {
+     case TYPE_INCDEC:
+       if (! rtx_equal_p (operands[0], operands[1]))
+ 	abort ();
+       if (operands[2] == const1_rtx)
+         return \"inc{l}\\t%0\";
+       else if (operands[2] == constm1_rtx)
+         return \"dec{l}\\t%0\";
+       else
+ 	abort();
+ 
+     default:
+       if (! rtx_equal_p (operands[0], operands[1]))
+ 	abort ();
+       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
+ 	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
+       if (GET_CODE (operands[2]) == CONST_INT
+           && (INTVAL (operands[2]) == 128
+ 	      || (INTVAL (operands[2]) < 0
+ 		  && INTVAL (operands[2]) != -128)))
+         {
+           operands[2] = GEN_INT (-INTVAL (operands[2]));
+           return \"sub{l}\\t{%2, %0|%0, %2}\";
+         }
+       return \"add{l}\\t{%2, %0|%0, %2}\";
+     }
+ }"
+   [(set (attr "type")
+      (if_then_else (match_operand:SI 2 "incdec_operand" "")
+ 	(const_string "incdec")
+ 	(const_string "alu")))
+    (set_attr "mode" "SI")])
+ 
+ (define_insn "*addsi_4"
    [(set (reg:CC 17)
! 	(compare:CC (neg:SI (match_operand:SI 2 "general_operand" "rmni,rni"))
! 		    (match_operand:SI 1 "nonimmediate_operand" "%0,0")))
     (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
  	(plus:SI (match_dup 1) (match_dup 2)))]
    "ix86_binary_operator_ok (PLUS, SImode, operands)
***************
*** 3981,3986 ****
--- 4024,4042 ----
    [(set_attr "type" "alu")
     (set_attr "mode" "SI")])
  
+ (define_insn "*addsi_5"
+   [(set (reg:CC 17)
+ 	(compare:CC (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
+ 		    (match_operand:SI 1 "nonimmediate_operand" "%0")))
+    (clobber (match_scratch:SI 0 "=r"))]
+   "(GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
+    /* Current assemblers are broken and do not allow @GOTOFF in
+       ought but a memory context. */
+    && ! pic_symbolic_operand (operands[2], VOIDmode)"
+   "add{l}\\t{%2, %0|%0, %2}"
+   [(set_attr "type" "alu")
+    (set_attr "mode" "SI")])
+ 
  (define_expand "addhi3"
    [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
  		   (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
***************
*** 4121,4130 ****
     (set_attr "mode" "HI")])
  
  (define_insn "*addhi_3"
    [(set (reg:CC 17)
! 	(compare:CC (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
! 			     (match_operand:HI 2 "general_operand" "rmni,rni"))
! 		    (const_int 0)))			
     (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
  	(plus:HI (match_dup 1) (match_dup 2)))]
    "ix86_binary_operator_ok (PLUS, HImode, operands)"
--- 4177,4225 ----
     (set_attr "mode" "HI")])
  
  (define_insn "*addhi_3"
+   [(set (reg 17)
+ 	(compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
+ 		 (match_operand:HI 1 "nonimmediate_operand" "%0")))
+    (clobber (match_scratch:HI 0 "=r"))]
+   "ix86_match_ccmode (insn, CCNOmode)
+    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
+   "*
+ {
+   switch (get_attr_type (insn))
+     {
+     case TYPE_INCDEC:
+       if (operands[2] == const1_rtx)
+ 	return \"inc{w}\\t%0\";
+       else if (operands[2] == constm1_rtx
+ 	       || (GET_CODE (operands[2]) == CONST_INT
+ 		   && INTVAL (operands[2]) == 65535))
+ 	return \"dec{w}\\t%0\";
+       abort();
+ 
+     default:
+       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
+ 	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
+       if (GET_CODE (operands[2]) == CONST_INT
+           && (INTVAL (operands[2]) == 128
+ 	      || (INTVAL (operands[2]) < 0
+ 		  && INTVAL (operands[2]) != -128)))
+ 	{
+ 	  operands[2] = GEN_INT (-INTVAL (operands[2]));
+ 	  return \"sub{w}\\t{%2, %0|%0, %2}\";
+ 	}
+       return \"add{w}\\t{%2, %0|%0, %2}\";
+     }
+ }"
+   [(set (attr "type")
+      (if_then_else (match_operand:HI 2 "incdec_operand" "")
+ 	(const_string "incdec")
+ 	(const_string "alu")))
+    (set_attr "mode" "HI")])
+ 
+ (define_insn "*addhi_4"
    [(set (reg:CC 17)
! 	(compare:CC (neg:HI (match_operand:HI 2 "general_operand" "rmni,rni"))
! 		    (match_operand:HI 1 "nonimmediate_operand" "%0,0")))
     (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
  	(plus:HI (match_dup 1) (match_dup 2)))]
    "ix86_binary_operator_ok (PLUS, HImode, operands)"
***************
*** 4132,4137 ****
--- 4227,4242 ----
    [(set_attr "type" "alu")
     (set_attr "mode" "HI")])
  
+ (define_insn "*addhi_5"
+   [(set (reg:CC 17)
+ 	(compare:CC (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
+ 		    (match_operand:HI 1 "nonimmediate_operand" "%0")))
+    (clobber (match_scratch:HI 0 "=r"))]
+   "(GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
+   "add{w}\\t{%2, %0|%0, %2}"
+   [(set_attr "type" "alu")
+    (set_attr "mode" "HI")])
+ 
  (define_expand "addqi3"
    [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
  		   (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
***************
*** 4280,4289 ****
     (set_attr "mode" "QI")])
  
  (define_insn "*addqi_3"
    [(set (reg:CC 17)
! 	(compare:CC (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
! 			     (match_operand:QI 2 "general_operand" "qmni,qni"))
! 		    (const_int 0)))			
     (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
  	(plus:QI (match_dup 1) (match_dup 2)))]
    "ix86_binary_operator_ok (PLUS, QImode, operands)"
--- 4385,4430 ----
     (set_attr "mode" "QI")])
  
  (define_insn "*addqi_3"
+   [(set (reg 17)
+ 	(compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
+ 		 (match_operand:QI 1 "nonimmediate_operand" "%0")))
+    (clobber (match_scratch:QI 0 "=r"))]
+   "ix86_match_ccmode (insn, CCNOmode)
+    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
+   "*
+ {
+   switch (get_attr_type (insn))
+     {
+     case TYPE_INCDEC:
+       if (operands[2] == const1_rtx)
+ 	return \"inc{b}\\t%0\";
+       else if (operands[2] == constm1_rtx
+ 	       || (GET_CODE (operands[2]) == CONST_INT
+ 		   && INTVAL (operands[2]) == 255))
+ 	return \"dec{b}\\t%0\";
+       abort();
+ 
+     default:
+       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
+       if (GET_CODE (operands[2]) == CONST_INT
+           && INTVAL (operands[2]) < 0)
+ 	{
+ 	  operands[2] = GEN_INT (-INTVAL (operands[2]));
+ 	  return \"sub{b}\\t{%2, %0|%0, %2}\";
+ 	}
+       return \"add{b}\\t{%2, %0|%0, %2}\";
+     }
+ }"
+   [(set (attr "type")
+      (if_then_else (match_operand:QI 2 "incdec_operand" "")
+ 	(const_string "incdec")
+ 	(const_string "alu")))
+    (set_attr "mode" "QI")])
+ 
+ (define_insn "*addqi_4"
    [(set (reg:CC 17)
! 	(compare:CC (neg:QI (match_operand:QI 2 "general_operand" "qmni,qni"))
! 		    (match_operand:QI 1 "nonimmediate_operand" "%0,0")))
     (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
  	(plus:QI (match_dup 1) (match_dup 2)))]
    "ix86_binary_operator_ok (PLUS, QImode, operands)"
***************
*** 4291,4296 ****
--- 4432,4447 ----
    [(set_attr "type" "alu")
     (set_attr "mode" "QI")])
  
+ (define_insn "*addqi_5"
+   [(set (reg:CC 17)
+ 	(compare:CC (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
+ 		    (match_operand:QI 1 "nonimmediate_operand" "%0")))
+    (clobber (match_scratch:QI 0 "=r"))]
+   "(GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
+   "add{b}\\t{%2, %0|%0, %2}"
+   [(set_attr "type" "alu")
+    (set_attr "mode" "QI")])
+ 
  
  (define_insn "addqi_ext_1"
    [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
***************
*** 4448,4453 ****
--- 4599,4616 ----
  	  (const_int 0)))
     (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
  	(minus:SI (match_dup 1) (match_dup 2)))]
+   "ix86_match_ccmode (insn, CCNOmode)
+    && ix86_binary_operator_ok (MINUS, SImode, operands)"
+   "sub{l}\\t{%2, %0|%0, %2}"
+   [(set_attr "type" "alu")
+    (set_attr "mode" "SI")])
+ 
+ (define_insn "*subsi_3"
+   [(set (reg 17)
+ 	(compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
+ 		 (match_operand:SI 2 "general_operand" "ri,rm")))
+    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
+ 	(minus:SI (match_dup 1) (match_dup 2)))]
    "ix86_match_ccmode (insn, CCmode)
     && ix86_binary_operator_ok (MINUS, SImode, operands)"
    "sub{l}\\t{%2, %0|%0, %2}"
***************
*** 4480,4485 ****
--- 4643,4660 ----
  	  (const_int 0)))
     (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
  	(minus:HI (match_dup 1) (match_dup 2)))]
+   "ix86_match_ccmode (insn, CCNOmode)
+    && ix86_binary_operator_ok (MINUS, HImode, operands)"
+   "sub{w}\\t{%2, %0|%0, %2}"
+   [(set_attr "type" "alu")
+    (set_attr "mode" "HI")])
+ 
+ (define_insn "*subhi_3"
+   [(set (reg 17)
+ 	(compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
+ 		 (match_operand:HI 2 "general_operand" "ri,rm")))
+    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
+ 	(minus:HI (match_dup 1) (match_dup 2)))]
    "ix86_match_ccmode (insn, CCmode)
     && ix86_binary_operator_ok (MINUS, HImode, operands)"
    "sub{w}\\t{%2, %0|%0, %2}"
***************
*** 4512,4517 ****
--- 4687,4704 ----
  	  (const_int 0)))
     (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
  	(minus:HI (match_dup 1) (match_dup 2)))]
+   "ix86_match_ccmode (insn, CCNOmode)
+    && ix86_binary_operator_ok (MINUS, QImode, operands)"
+   "sub{b}\\t{%2, %0|%0, %2}"
+   [(set_attr "type" "alu")
+    (set_attr "mode" "QI")])
+ 
+ (define_insn "*subqi_3"
+   [(set (reg 17)
+ 	(compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
+ 		 (match_operand:QI 2 "general_operand" "qi,qm")))
+    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
+ 	(minus:HI (match_dup 1) (match_dup 2)))]
    "ix86_match_ccmode (insn, CCmode)
     && ix86_binary_operator_ok (MINUS, QImode, operands)"
    "sub{b}\\t{%2, %0|%0, %2}"
***************
*** 5414,5419 ****
--- 5601,5618 ----
    [(set_attr "type" "alu")
     (set_attr "mode" "SI")])
  
+ (define_insn "*iorsi_3"
+   [(set (reg 17)
+ 	(compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
+ 			 (match_operand:SI 2 "general_operand" "rim"))
+ 		 (const_int 0)))
+    (clobber (match_scratch:SI 0 "=r"))]
+   "ix86_match_ccmode (insn, CCNOmode)
+    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
+   "or{l}\\t{%2, %0|%0, %2}"
+   [(set_attr "type" "alu")
+    (set_attr "mode" "SI")])
+ 
  (define_expand "iorhi3"
    [(set (match_operand:HI 0 "nonimmediate_operand" "")
  	(ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
***************
*** 5445,5450 ****
--- 5644,5661 ----
    [(set_attr "type" "alu")
     (set_attr "mode" "HI")])
  
+ (define_insn "*iorhi_3"
+   [(set (reg 17)
+ 	(compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
+ 			 (match_operand:HI 2 "general_operand" "rim"))
+ 		 (const_int 0)))
+    (clobber (match_scratch:HI 0 "=r"))]
+   "ix86_match_ccmode (insn, CCNOmode)
+    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
+   "or{w}\\t{%2, %0|%0, %2}"
+   [(set_attr "type" "alu")
+    (set_attr "mode" "HI")])
+ 
  (define_expand "iorqi3"
    [(set (match_operand:QI 0 "nonimmediate_operand" "")
  	(ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
***************
*** 5479,5484 ****
--- 5690,5708 ----
    "or{b}\\t{%2, %0|%0, %2}"
    [(set_attr "type" "alu")
     (set_attr "mode" "QI")])
+ 
+ (define_insn "*iorqi_3"
+   [(set (reg 17)
+ 	(compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
+ 			 (match_operand:QI 2 "general_operand" "qim"))
+ 		 (const_int 0)))
+    (clobber (match_scratch:QI 0 "=r"))]
+   "ix86_match_ccmode (insn, CCNOmode)
+    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
+   "or{b}\\t{%2, %0|%0, %2}"
+   [(set_attr "type" "alu")
+    (set_attr "mode" "QI")])
+ 
  
  ;; Logical XOR instructions
  
***************
*** 5516,5521 ****
--- 5740,5757 ----
    [(set_attr "type" "alu")
     (set_attr "mode" "SI")])
  
+ (define_insn "*xorsi_3"
+   [(set (reg 17)
+ 	(compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
+ 			 (match_operand:SI 2 "general_operand" "rim"))
+ 		 (const_int 0)))
+    (clobber (match_scratch:SI 0 "=r"))]
+   "ix86_match_ccmode (insn, CCNOmode)
+    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
+   "xor{l}\\t{%2, %0|%0, %2}"
+   [(set_attr "type" "alu")
+    (set_attr "mode" "SI")])
+ 
  (define_expand "xorhi3"
    [(set (match_operand:HI 0 "nonimmediate_operand" "")
  	(xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
***************
*** 5547,5552 ****
--- 5783,5800 ----
    [(set_attr "type" "alu")
     (set_attr "mode" "HI")])
  
+ (define_insn "*xorhi_3"
+   [(set (reg 17)
+ 	(compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
+ 			 (match_operand:HI 2 "general_operand" "rim"))
+ 		 (const_int 0)))
+    (clobber (match_scratch:HI 0 "=r"))]
+   "ix86_match_ccmode (insn, CCNOmode)
+    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
+   "xor{w}\\t{%2, %0|%0, %2}"
+   [(set_attr "type" "alu")
+    (set_attr "mode" "HI")])
+ 
  (define_expand "xorqi3"
    [(set (match_operand:QI 0 "nonimmediate_operand" "")
  	(xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
***************
*** 5601,5606 ****
--- 5849,5867 ----
    [(set_attr "type" "alu")
     (set_attr "mode" "QI")])
  
+ (define_insn "*xorqi_cc_2"
+   [(set (reg 17)
+ 	(compare
+ 	  (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
+ 		  (match_operand:QI 2 "general_operand" "qim"))
+ 	  (const_int 0)))
+    (clobber (match_scratch:QI 0 "=r"))]
+   "ix86_match_ccmode (insn, CCNOmode)
+    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
+   "xor{b}\\t{%2, %0|%0, %2}"
+   [(set_attr "type" "alu")
+    (set_attr "mode" "QI")])
+ 
  (define_insn "xorqi_cc_ext_1"
    [(set (reg:CCNO 17)
  	(compare:CCNO
*** i386.c.old	Mon Sep 11 18:53:12 2000
--- i386.c	Mon Sep 11 20:18:33 2000
*************** ix86_expand_strlensi_unroll_1 (out, alig
*** 5867,5874 ****
    rtx align_4_label = gen_label_rtx ();
    rtx end_0_label = gen_label_rtx ();
    rtx mem;
-   rtx no_flags = gen_rtx_REG (CCNOmode, FLAGS_REG);
-   rtx z_flags = gen_rtx_REG (CCNOmode, FLAGS_REG);
    rtx tmpreg = gen_reg_rtx (SImode);
  
    align = 0;
--- 5867,5872 ----

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