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: [PATCH, MIPS] Add bbit* Octeon instructions


Richard Sandiford wrote:
> OK, but it still seems odd to remove SImode stuff from 64-bit targets.
> They generally ought to allow both.  The concern isn't so much the number
> of bbit instructions, but the number of mode changes (and the effect they
> can have on optimisation).

OK.  I think the argument that even if the backend does not emit SI mode
zero_extract the middle end is free to do so is a convincing one.
Trying to be a minimalist, I was adding tests to try to catch this.

> The target can logically do both 32-bit and 64-bit ops, so I think the
> fallback position is to keep things simple and stick to :GPR.

Sure.  To describe the HW as having bbit SI is certainly more accurate.

> (define_delay (and (eq_attr "type" "branch")
> 		   (eq (symbol_ref "TARGET_MIPS16") (const_int 0))
> 		   (eq_attr "branch_likely" "yes"))
>   [(eq_attr "can_delay" "yes")
>    (nil)
>    (eq_attr "can_delay" "yes")])
> 
> ;; Branches that don't have likely variants do not annul on false.
> (define_delay (and (eq_attr "type" "branch")
> 		   (eq (symbol_ref "TARGET_MIPS16") (const_int 0))
> 		   (eq_attr "branch_likely" "no"))
>   [(eq_attr "can_delay" "yes")
>    (nil)
>    (nil)])
> 
> (I believe "and" can take more than 2 arguments in this context.)

Sure, it works.  Also for some reason I thought "and" was not completely
like in Lisp.

> OK with that change, if it works.

I had to remove const from the definition of branch_likely.  This is
what I committed after reboostrapping and retesting.

Adam

	* config/mips/mips.h (ISA_HAS_BBIT): New macro.
	* config/mips/mips.md (branch_likely): Remove const.  Fix
	comment formatting.
	(define_delay for type "branch"): Change to only apply for branch
	with likely variant.
	(define_delay for type "branch" and "branch_likely" no).  New delay
	definition.
	(equality_op): New code iterator.
	(bbv, bbinv): New code attributes.
	(*branch_bit<bbv><mode>, *branch_bit<bbv><mode>_inverted): New
	patterns.

testsuite/
	* gcc.target/mips/octeon-bbit-1.c: New test.
	* gcc.target/mips/octeon-bbit-2.c: New test.
	* gcc.target/mips/octeon-bbit-3.c: New test.

Index: gcc/config/mips/mips.h
===================================================================
*** gcc.orig/config/mips/mips.h	2008-08-28 16:46:50.000000000 -0700
--- gcc/config/mips/mips.h	2008-08-28 16:49:41.000000000 -0700
*************** enum mips_code_readable_setting {
*** 1006,1011 ****
--- 1006,1014 ----
     ? TARGET_LLSC && !TARGET_MIPS16	\
     : ISA_HAS_LL_SC)
  
+ /* ISA includes the bbit* instructions.  */
+ #define ISA_HAS_BBIT		TARGET_OCTEON
+ 
  /* ISA includes the pop instruction.  */
  #define ISA_HAS_POP		TARGET_OCTEON
  
Index: gcc/config/mips/mips.md
===================================================================
*** gcc.orig/config/mips/mips.md	2008-08-28 16:49:17.000000000 -0700
--- gcc/config/mips/mips.md	2008-08-28 16:53:59.000000000 -0700
***************
*** 599,610 ****
  		(const_string "yes")
  		(const_string "no")))
  
! ;; Attribute defining whether or not we can use the branch-likely instructions
  (define_attr "branch_likely" "no,yes"
!   (const
!    (if_then_else (ne (symbol_ref "GENERATE_BRANCHLIKELY") (const_int 0))
! 		 (const_string "yes")
! 		 (const_string "no"))))
  
  ;; True if an instruction might assign to hi or lo when reloaded.
  ;; This is used by the TUNE_MACC_CHAINS code.
--- 599,610 ----
  		(const_string "yes")
  		(const_string "no")))
  
! ;; Attribute defining whether or not we can use the branch-likely
! ;; instructions.
  (define_attr "branch_likely" "no,yes"
!   (if_then_else (ne (symbol_ref "GENERATE_BRANCHLIKELY") (const_int 0))
! 		(const_string "yes")
! 		(const_string "no")))
  
  ;; True if an instruction might assign to hi or lo when reloaded.
  ;; This is used by the TUNE_MACC_CHAINS code.
***************
*** 788,793 ****
--- 788,796 ----
  ;; by swapping the operands.
  (define_code_iterator swapped_fcond [ge gt unge ungt])
  
+ ;; Equality operators.
+ (define_code_iterator equality_op [eq ne])
+ 
  ;; These code iterators allow the signed and unsigned scc operations to use
  ;; the same template.
  (define_code_iterator any_gt [gt gtu])
***************
*** 848,853 ****
--- 851,862 ----
  				 (unge "ule")
  				 (ungt "ult")])
  
+ ;; The value of the bit when the branch is taken for branch_bit patterns.
+ ;; Comparison is always against zero so this depends on the operator.
+ (define_code_attr bbv [(eq "0") (ne "1")])
+ 
+ ;; This is the inverse value of bbv.
+ (define_code_attr bbinv [(eq "1") (ne "0")])
  
  ;; .........................
  ;;
***************
*** 856,866 ****
  ;; .........................
  
  (define_delay (and (eq_attr "type" "branch")
! 		   (eq (symbol_ref "TARGET_MIPS16") (const_int 0)))
    [(eq_attr "can_delay" "yes")
     (nil)
!    (and (eq_attr "branch_likely" "yes")
! 	(eq_attr "can_delay" "yes"))])
  
  (define_delay (eq_attr "type" "jump")
    [(eq_attr "can_delay" "yes")
--- 865,883 ----
  ;; .........................
  
  (define_delay (and (eq_attr "type" "branch")
! 		   (eq (symbol_ref "TARGET_MIPS16") (const_int 0))
! 		   (eq_attr "branch_likely" "yes"))
    [(eq_attr "can_delay" "yes")
     (nil)
!    (eq_attr "can_delay" "yes")])
! 
! ;; Branches that don't have likely variants do not annul on false.
! (define_delay (and (eq_attr "type" "branch")
! 		   (eq (symbol_ref "TARGET_MIPS16") (const_int 0))
! 		   (eq_attr "branch_likely" "no"))
!   [(eq_attr "can_delay" "yes")
!    (nil)
!    (nil)])
  
  (define_delay (eq_attr "type" "jump")
    [(eq_attr "can_delay" "yes")
***************
*** 5052,5057 ****
--- 5069,5118 ----
  	(if_then_else (match_operand 0)
  		      (label_ref (match_operand 1))
  		      (pc)))])
+ 
+ ;; Branch if bit is set/clear.
+ 
+ (define_insn "*branch_bit<bbv><mode>"
+   [(set (pc)
+ 	(if_then_else
+ 	 (equality_op (zero_extract:GPR
+ 		       (match_operand:GPR 1 "register_operand" "d")
+ 		       (const_int 1)
+ 		       (match_operand 2 "const_int_operand" ""))
+ 		      (const_int 0))
+ 	 (label_ref (match_operand 0 ""))
+ 	 (pc)))]
+   "ISA_HAS_BBIT && UINTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)"
+ {
+   return
+     mips_output_conditional_branch (insn, operands,
+ 				    MIPS_BRANCH ("bbit<bbv>", "%1,%2,%0"),
+ 				    MIPS_BRANCH ("bbit<bbinv>", "%1,%2,%0"));
+ }
+   [(set_attr "type"	     "branch")
+    (set_attr "mode"	     "none")
+    (set_attr "branch_likely" "no")])
+ 
+ (define_insn "*branch_bit<bbv><mode>_inverted"
+   [(set (pc)
+ 	(if_then_else
+ 	 (equality_op (zero_extract:GPR
+ 		       (match_operand:GPR 1 "register_operand" "d")
+ 		       (const_int 1)
+ 		       (match_operand 2 "const_int_operand" ""))
+ 		      (const_int 0))
+ 	 (pc)
+ 	 (label_ref (match_operand 0 ""))))]
+   "ISA_HAS_BBIT && UINTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)"
+ {
+   return
+     mips_output_conditional_branch (insn, operands,
+ 				    MIPS_BRANCH ("bbit<bbinv>", "%1,%2,%0"),
+ 				    MIPS_BRANCH ("bbit<bbv>", "%1,%2,%0"));
+ }
+   [(set_attr "type"	     "branch")
+    (set_attr "mode"	     "none")
+    (set_attr "branch_likely" "no")])
  
  ;;
  ;;  ....................
Index: gcc/testsuite/gcc.target/mips/octeon-bbit-1.c
===================================================================
*** /dev/null	1970-01-01 00:00:00.000000000 +0000
--- gcc/testsuite/gcc.target/mips/octeon-bbit-1.c	2008-08-28 16:49:41.000000000 -0700
***************
*** 0 ****
--- 1,55 ----
+ /* { dg-do compile } */
+ /* { dg-mips-options "-O2 -march=octeon" } */
+ /* { dg-final { scan-assembler-times "\tbbit1\t" 4 } } */
+ /* { dg-final { scan-assembler-times "\tbbit0\t" 2 } } */
+ /* { dg-final { scan-assembler-not "andi\t" } } */
+ 
+ NOMIPS16 void
+ f1 (long long i)
+ {
+   if (i & 0x80)
+     foo ();
+ }
+ 
+ NOMIPS16 void
+ f2 (int i)
+ {
+   if (!(i & 0x80))
+     foo ();
+ }
+ 
+ NOMIPS16 void
+ f3 (int i)
+ {
+   if (i % 2)
+     foo ();
+ }
+ 
+ NOMIPS16 void
+ f4 (int i)
+ {
+   if (i & 1)
+     foo ();
+ }
+ 
+ NOMIPS16 void
+ f5 (long long i)
+ {
+   if ((i >> 3) & 1)
+     foo ();
+ }
+ 
+ unsigned long long r;
+ 
+ NOMIPS16 static inline __attribute__((always_inline)) int
+ test_bit(unsigned long long nr, const unsigned long long *addr)
+ {
+   return 1UL & (addr[nr >> 6] >> (nr & 63ULL));
+ }
+ 
+ NOMIPS16 void
+ f6 ()
+ {
+   if (!test_bit(0, &r))
+     g ();
+ }
Index: gcc/testsuite/gcc.target/mips/octeon-bbit-2.c
===================================================================
*** /dev/null	1970-01-01 00:00:00.000000000 +0000
--- gcc/testsuite/gcc.target/mips/octeon-bbit-2.c	2008-08-28 16:49:41.000000000 -0700
***************
*** 0 ****
--- 1,24 ----
+ /* { dg-do compile } */
+ /* { dg-mips-options "-O2 -march=octeon -mbranch-likely" } */
+ /* { dg-final { scan-assembler "\tbbit\[01\]\t" } } */
+ /* { dg-final { scan-assembler-not "\tbbit\[01\]l\t" } } */
+ /* { dg-final { scan-assembler "\tbnel\t" } } */
+ /* { dg-final { scan-assembler-not "\tbne\t" } } */
+ 
+ NOMIPS16 int
+ f (int n, int i)
+ {
+   int s = 0;
+   for (; i & 1; i++)
+     s += i;
+   return s;
+ }
+ 
+ NOMIPS16 int
+ g (int n, int i)
+ {
+   int s = 0;
+   for (i = 0; i < n; i++)
+     s += i;
+   return s;
+ }
Index: gcc/testsuite/gcc.target/mips/octeon-bbit-3.c
===================================================================
*** /dev/null	1970-01-01 00:00:00.000000000 +0000
--- gcc/testsuite/gcc.target/mips/octeon-bbit-3.c	2008-08-28 16:49:41.000000000 -0700
***************
*** 0 ****
--- 1,31 ----
+ /* { dg-do compile } */
+ /* { dg-mips-options "-O2 -march=octeon" } */
+ /* { dg-final { scan-assembler-times "\tbbit\[01\]\t|\tbgez\t" 2 } } */
+ /* { dg-final { scan-assembler-not "ext\t" } } */
+ 
+ void abort (void);
+ void exit (int);
+ 
+ typedef unsigned long long ulong64;
+ 
+ typedef struct bitfield_s {
+   ulong64 a:1;
+   ulong64 b:29;
+   ulong64 c:1;
+   ulong64 d:15;
+   ulong64 f:18;
+ } bitfield_t;
+ 
+ bitfield_t bar;
+ 
+ NOMIPS16 void
+ f ()
+ {
+   foo(&bar);
+   if (bar.a != 0x1)
+     abort ();
+   else if (!bar.c)
+     abort ();
+   else
+     exit (0);
+ }

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