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]

Re: Conditional addition for i386


> On Tue, Jan 07, 2003 at 09:57:39PM +0100, Jan Hubicka wrote:
> > Hmm, there definitly was addcc expander calling the function.  I guess
> > i've killed it while I was splitting the patch into independent pieces.
> > Should I send updated patch?
> 
> Please.
OK, bootstrap in progress.  OK now? :)
Works in the testcase.

/* { dg-do compile { target i?86-*-* x86_64-*-* } } */
/* { dg-options "-O2 -march=athlon" } */
/* { dg-final { scan-assembler "sbb" } } */

/* Conditional increment is best done using sbb $-1, val.  */
int t[]={0,0,0,0,1,1,1,1,1,1};
q()
{
  int sum=0;
  int i;
  for (i=0;i<10;i++)
    if (t[i])
       sum++;
  if (sum != 6)
    abort ();
}
main()
{
  int i;
  for (i=0;i<10000000;i++)
    q();
}

Honza
Fri Nov 22 01:36:03 CET 2002  Jan Hubicka  <jh@suse.cz>
	* i386.md (adddi3_carry_rex64, subdi3_carry_rex64): Name pattern.
	(addhi3_carry, addqi3_carry, subhi3_carry, subqi3_carry): New patterns.
	(add??cc): New expanders.
	* i386.c (expand_int_addcc): New function.
	* i386-protos.h (expand_int_addcc): Declare.
Index: i386-protos.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/i386/i386-protos.h,v
retrieving revision 1.88
diff -c -3 -p -r1.88 i386-protos.h
*** i386-protos.h	19 Dec 2002 22:00:32 -0000	1.88
--- i386-protos.h	7 Jan 2003 21:18:21 -0000
*************** extern void ix86_expand_branch PARAMS ((
*** 141,146 ****
--- 141,147 ----
  extern int ix86_expand_setcc PARAMS ((enum rtx_code, rtx));
  extern int ix86_expand_int_movcc PARAMS ((rtx[]));
  extern int ix86_expand_fp_movcc PARAMS ((rtx[]));
+ extern int ix86_expand_int_addcc PARAMS ((rtx[]));
  extern void ix86_expand_call PARAMS ((rtx, rtx, rtx, rtx, rtx, int));
  extern void x86_initialize_trampoline PARAMS ((rtx, rtx, rtx));
  extern rtx ix86_zero_extend_to_Pmode PARAMS ((rtx));
Index: i386.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/i386/i386.c,v
retrieving revision 1.504
diff -c -3 -p -r1.504 i386.c
*** i386.c	7 Jan 2003 21:09:20 -0000	1.504
--- i386.c	7 Jan 2003 21:18:28 -0000
*************** ix86_expand_fp_movcc (operands)
*** 9981,9986 ****
--- 9981,10049 ----
    return 1;
  }
  
+ /* Expand conditional increment or decrement using adb/sbb instructions.
+    The default case using setcc followed by the conditional move can be
+    done by generic code.  */
+ int
+ ix86_expand_int_addcc (operands)
+      rtx operands[];
+ {
+   enum rtx_code code = GET_CODE (operands[1]);
+   rtx compare_op;
+   rtx val = const0_rtx;
+ 
+   if (operands[3] != const1_rtx
+       && operands[3] != constm1_rtx)
+     return 0;
+   if (!ix86_expand_carry_flag_compare (code, ix86_compare_op0,
+ 				       ix86_compare_op1, &compare_op))
+      return 0;
+   if (GET_CODE (compare_op) != LTU)
+     val = constm1_rtx;
+   if ((GET_CODE (compare_op) == LTU) == (operands[1] == const1_rtx))
+     {
+       switch (GET_MODE (operands[0]))
+ 	{
+ 	  case QImode:
+             emit_insn (gen_subqi3_carry (operands[0], operands[2], val));
+ 	    break;
+ 	  case HImode:
+             emit_insn (gen_subhi3_carry (operands[0], operands[2], val));
+ 	    break;
+ 	  case SImode:
+             emit_insn (gen_subsi3_carry (operands[0], operands[2], val));
+ 	    break;
+ 	  case DImode:
+             emit_insn (gen_subdi3_carry_rex64 (operands[0], operands[2], val));
+ 	    break;
+ 	  default:
+ 	    abort ();
+ 	}
+     }
+   else
+     {
+       switch (GET_MODE (operands[0]))
+ 	{
+ 	  case QImode:
+             emit_insn (gen_addqi3_carry (operands[0], operands[2], val));
+ 	    break;
+ 	  case HImode:
+             emit_insn (gen_addhi3_carry (operands[0], operands[2], val));
+ 	    break;
+ 	  case SImode:
+             emit_insn (gen_addsi3_carry (operands[0], operands[2], val));
+ 	    break;
+ 	  case DImode:
+             emit_insn (gen_adddi3_carry_rex64 (operands[0], operands[2], val));
+ 	    break;
+ 	  default:
+ 	    abort ();
+ 	}
+     }
+   return 1; /* DONE */
+ }
+ 
+ 
  /* Split operands 0 and 1 into SImode parts.  Similar to split_di, but
     works for floating pointer parameters and nonoffsetable memories.
     For pushes, it returns just stack offsets; the values will be saved
Index: i386.md
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/i386/i386.md,v
retrieving revision 1.408
diff -c -3 -p -r1.408 i386.md
*** i386.md	26 Dec 2002 18:45:03 -0000	1.408
--- i386.md	7 Jan 2003 21:18:38 -0000
***************
*** 4950,4956 ****
     split_di (operands+1, 1, operands+1, operands+4);
     split_di (operands+2, 1, operands+2, operands+5);")
  
! (define_insn "*adddi3_carry_rex64"
    [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
  	  (plus:DI (plus:DI (ltu:DI (reg:CC 17) (const_int 0))
  			    (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
--- 4950,4956 ----
     split_di (operands+1, 1, operands+1, operands+4);
     split_di (operands+2, 1, operands+2, operands+5);")
  
! (define_insn "adddi3_carry_rex64"
    [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
  	  (plus:DI (plus:DI (ltu:DI (reg:CC 17) (const_int 0))
  			    (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
***************
*** 4975,4981 ****
    [(set_attr "type" "alu")
     (set_attr "mode" "DI")])
  
! (define_insn "*addsi3_carry"
    [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
  	  (plus:SI (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
  			    (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
--- 4975,5007 ----
    [(set_attr "type" "alu")
     (set_attr "mode" "DI")])
  
! (define_insn "addqi3_carry"
!   [(set (match_operand:QI 0 "nonimmediate_operand" "=rm,r")
! 	  (plus:QI (plus:QI (ltu:QI (reg:CC 17) (const_int 0))
! 			    (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
! 		   (match_operand:QI 2 "general_operand" "ri,rm")))
!    (clobber (reg:CC 17))]
!   "ix86_binary_operator_ok (PLUS, QImode, operands)"
!   "adc{b}\t{%2, %0|%0, %2}"
!   [(set_attr "type" "alu")
!    (set_attr "pent_pair" "pu")
!    (set_attr "mode" "QI")
!    (set_attr "ppro_uops" "few")])
! 
! (define_insn "addhi3_carry"
!   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
! 	  (plus:HI (plus:HI (ltu:HI (reg:CC 17) (const_int 0))
! 			    (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
! 		   (match_operand:HI 2 "general_operand" "ri,rm")))
!    (clobber (reg:CC 17))]
!   "ix86_binary_operator_ok (PLUS, HImode, operands)"
!   "adc{w}\t{%2, %0|%0, %2}"
!   [(set_attr "type" "alu")
!    (set_attr "pent_pair" "pu")
!    (set_attr "mode" "HI")
!    (set_attr "ppro_uops" "few")])
! 
! (define_insn "addsi3_carry"
    [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
  	  (plus:SI (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
  			    (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
***************
*** 6652,6657 ****
--- 6678,6708 ----
    [(set_attr "type" "alu")
     (set_attr "mode" "DI")])
  
+ (define_insn "subqi3_carry"
+   [(set (match_operand:QI 0 "nonimmediate_operand" "=rm,r")
+ 	  (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
+ 	    (plus:QI (ltu:QI (reg:CC 17) (const_int 0))
+ 	       (match_operand:QI 2 "general_operand" "ri,rm"))))
+    (clobber (reg:CC 17))]
+   "ix86_binary_operator_ok (MINUS, QImode, operands)"
+   "sbb{q}\t{%2, %0|%0, %2}"
+   [(set_attr "type" "alu")
+    (set_attr "pent_pair" "pu")
+    (set_attr "ppro_uops" "few")
+    (set_attr "mode" "QI")])
+ 
+ (define_insn "subhi3_carry"
+   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
+ 	  (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
+ 	    (plus:HI (ltu:HI (reg:CC 17) (const_int 0))
+ 	       (match_operand:HI 2 "general_operand" "ri,rm"))))
+    (clobber (reg:CC 17))]
+   "ix86_binary_operator_ok (MINUS, HImode, operands)"
+   "sbb{w}\t{%2, %0|%0, %2}"
+   [(set_attr "type" "alu")
+    (set_attr "pent_pair" "pu")
+    (set_attr "ppro_uops" "few")
+    (set_attr "mode" "HI")])
  
  (define_insn "subsi3_carry"
    [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
***************
*** 16457,16462 ****
--- 16508,16546 ----
  			     (match_dup 2))
  			 (match_dup 1)
  			 (match_dup 2)))])
+ 
+ ;; Conditional addition patterns
+ (define_expand "addqicc"
+   [(match_operand:QI 0 "register_operand" "")
+    (match_operand 1 "comparison_operator" "")
+    (match_operand:QI 2 "register_operand" "")
+    (match_operand:QI 3 "const_int_operand" "")]
+   ""
+   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
+ 
+ (define_expand "addhicc"
+   [(match_operand:HI 0 "register_operand" "")
+    (match_operand 1 "comparison_operator" "")
+    (match_operand:HI 2 "register_operand" "")
+    (match_operand:HI 3 "const_int_operand" "")]
+   ""
+   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
+ 
+ (define_expand "addsicc"
+   [(match_operand:SI 0 "register_operand" "")
+    (match_operand 1 "comparison_operator" "")
+    (match_operand:SI 2 "register_operand" "")
+    (match_operand:SI 3 "const_int_operand" "")]
+   ""
+   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
+ 
+ (define_expand "adddicc"
+   [(match_operand:DI 0 "register_operand" "")
+    (match_operand 1 "comparison_operator" "")
+    (match_operand:DI 2 "register_operand" "")
+    (match_operand:DI 3 "const_int_operand" "")]
+   "TARGET_64BIT"
+   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
  
  ;; We can't represent the LT test directly.  Do this by swapping the operands.
  


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