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] Merge clear_upper32 patterns into "and" patterns


Richard Sandiford writes:
> Adam Nemet <anemet@caviumnetworks.com> writes:
> > + ;; The 0xffff_ffff case does not trigger with SI mode because we require
> > + ;; a 64-bit HOST_WIDE_INT and 0xffff_ffff wouldn't be a canonical
> > + ;; sign-extended SImode value.
> 
> You said this in the first paragraph, so let's drop this copy.

It's emacs' fault ;).

> OK with those changes.

Thanks.

> As a follow-up, it'd be good to update rtx_costs for the new ext-based
> alternative (specifically in mips_immediate_operand_p).

I added this to the list of follow-ups to this patch.  This is what I've
checked in after retesting as before.

Adam


Index: ChangeLog
===================================================================
*** ChangeLog	(revision 150656)
--- ChangeLog	(revision 150657)
***************
*** 1,5 ****
--- 1,25 ----
  2009-08-11  Adam Nemet  <anemet@caviumnetworks.com>
  
+ 	* config/mips/predicates.md (qi_mask_operand, hi_mask_operand,
+ 	si_mask_operand, and_load_operand, low_bitmask_operand,
+ 	and_reg_operand, and_operand): New predicates.
+ 	* config/mips/constraints.md (Yb, Yh, Yw, Yz): New constraints.
+ 	* config/mips/mips.c (and_operands_ok): New function.
+ 	* config/mips/mips-protos.h (and_operands_ok): Declare it.
+ 	* config/mips/mips.md (move_type): Add ext_ins and logical.
+ 	(type): Handle them.
+ 	(and<mode>3): Use and_reg_operand as the second operand's
+ 	predicate.
+ 	(*and<mode>3): Add alternatives for lbu, lhu, lwu, <d>ext and
+ 	shift_shift.  Remove commutative constraint modifier.
+ 	(*and<mode>3_mips16): Add alternatives for lbu, lhu, lwu and
+ 	shift_shift.
+ 	(*clear_upper32_dext): Remove define_insn_and_split.
+ 	(*clear_upper32): Turn this define_insn_and_split ...
+ 	(splitter for ANDing register with 0xffff_ffff): .. into this.
+ 
+ 2009-08-11  Adam Nemet  <anemet@caviumnetworks.com>
+ 
  	* combine.c (try_widen_shift_mode): Factor out code to check if an
          integer constant is a low-order bitmask from here ...
  	* rtlanal.c (low_bitmask_len): ... to here.
Index: testsuite/gcc.target/mips/ext-6.c
===================================================================
*** testsuite/gcc.target/mips/ext-6.c	(revision 0)
--- testsuite/gcc.target/mips/ext-6.c	(revision 150657)
***************
*** 0 ****
--- 1,11 ----
+ /* For MIPS64r2 use DEXT when ANDing with low-order bitmasks.  */
+ /* { dg-do compile } */
+ /* { dg-options "-O isa_rev>=2 -mgp64" } */
+ /* { dg-final { scan-assembler "\tdext\t" } } */
+ /* { dg-final { scan-assembler-not "\tandi?\t" } } */
+ 
+ NOMIPS16 unsigned long long
+ f (unsigned long long i)
+ {
+   return i & 0x7ffffffffff;
+ }
Index: testsuite/gcc.target/mips/extend-2.c
===================================================================
*** testsuite/gcc.target/mips/extend-2.c	(revision 0)
--- testsuite/gcc.target/mips/extend-2.c	(revision 150657)
***************
*** 0 ****
--- 1,12 ----
+ /* Check the shift_shift alternative of the AND patterns.  */
+ /* { dg-do compile } */
+ /* { dg-options "-O isa_rev<=1 -mgp64" } */
+ /* { dg-final { scan-assembler "\tdsrl\t" } } */
+ /* { dg-final { scan-assembler "\tdsll\t" } } */
+ /* { dg-final { scan-assembler-not "\td?ext\t" } } */
+ 
+ unsigned long long
+ f (unsigned long long i)
+ {
+   return i & 0xffffffff;
+ }
Index: testsuite/gcc.target/mips/ext-7.c
===================================================================
*** testsuite/gcc.target/mips/ext-7.c	(revision 0)
--- testsuite/gcc.target/mips/ext-7.c	(revision 150657)
***************
*** 0 ****
--- 1,11 ----
+ /* No need to use ext if we can use andi.  */
+ /* { dg-do compile } */
+ /* { dg-options "-O isa_rev>=2" } */
+ /* { dg-final { scan-assembler "\tandi\t" } } */
+ /* { dg-final { scan-assembler-not "\td?ext\t" } } */
+ 
+ NOMIPS16 unsigned
+ f (unsigned i)
+ {
+   return i & 0x7fff;
+ }
Index: testsuite/gcc.target/mips/ext-8.c
===================================================================
*** testsuite/gcc.target/mips/ext-8.c	(revision 0)
--- testsuite/gcc.target/mips/ext-8.c	(revision 150657)
***************
*** 0 ****
--- 1,11 ----
+ /* Also make sure we don't use ext for MIPS*r1.  */
+ /* { dg-do compile } */
+ /* { dg-options "-O isa_rev<=1" } */
+ /* { dg-final { scan-assembler "\tand\t" } } */
+ /* { dg-final { scan-assembler-not "\td?ext\t" } } */
+ 
+ unsigned
+ f (unsigned i)
+ {
+   return i & 0x7fffff;
+ }
Index: testsuite/gcc.target/mips/ext-5.c
===================================================================
*** testsuite/gcc.target/mips/ext-5.c	(revision 0)
--- testsuite/gcc.target/mips/ext-5.c	(revision 150657)
***************
*** 0 ****
--- 1,11 ----
+ /* For MIPS32r2 use EXT when ANDing with low-order bitmasks.  */
+ /* { dg-do compile } */
+ /* { dg-options "-O isa_rev>=2" } */
+ /* { dg-final { scan-assembler "\text\t" } } */
+ /* { dg-final { scan-assembler-not "\tandi?\t" } } */
+ 
+ NOMIPS16 unsigned
+ f (unsigned i)
+ {
+   return i & 0x7ffffff;
+ }
Index: testsuite/ChangeLog
===================================================================
*** testsuite/ChangeLog	(revision 150656)
--- testsuite/ChangeLog	(revision 150657)
***************
*** 1,3 ****
--- 1,11 ----
+ 2009-08-11  Adam Nemet  <anemet@caviumnetworks.com>
+ 
+ 	* gcc.target/mips/ext-5.c: New test.
+ 	* gcc.target/mips/ext-6.c: New test.
+ 	* gcc.target/mips/ext-7.c: New test.
+ 	* gcc.target/mips/ext-8.c: New test.
+ 	* gcc.target/mips/extend-2.c: New test.
+ 
  2009-08-10  Jason Merrill  <jason@redhat.com>
  
  	* g++.dg/other/linkage2.C: New test for types-without-linkage
Index: config/mips/constraints.md
===================================================================
*** config/mips/constraints.md	(revision 150656)
--- config/mips/constraints.md	(revision 150657)
*************** (define_constraint "YB"
*** 215,217 ****
--- 215,233 ----
     A signed 10-bit constant."
    (and (match_code "const_int")
         (match_test "IMM10_OPERAND (ival)")))
+ 
+ (define_constraint "Yb"
+    "@internal"
+    (match_operand 0 "qi_mask_operand"))
+ 
+ (define_constraint "Yh"
+    "@internal"
+     (match_operand 0 "hi_mask_operand"))
+ 
+ (define_constraint "Yw"
+    "@internal"
+     (match_operand 0 "si_mask_operand"))
+ 
+ (define_constraint "Yx"
+    "@internal"
+    (match_operand 0 "low_bitmask_operand"))
Index: config/mips/predicates.md
===================================================================
*** config/mips/predicates.md	(revision 150656)
--- config/mips/predicates.md	(revision 150657)
*************** (define_predicate "const_0_or_1_operand"
*** 76,81 ****
--- 76,114 ----
         (ior (match_test "op == CONST0_RTX (GET_MODE (op))")
  	    (match_test "op == CONST1_RTX (GET_MODE (op))"))))
  
+ (define_predicate "qi_mask_operand"
+   (and (match_code "const_int")
+        (match_test "UINTVAL (op) == 0xff")))
+ 
+ (define_predicate "hi_mask_operand"
+   (and (match_code "const_int")
+        (match_test "UINTVAL (op) == 0xffff")))
+ 
+ (define_predicate "si_mask_operand"
+   (and (match_code "const_int")
+        (match_test "UINTVAL (op) == 0xffffffff")))
+ 
+ (define_predicate "and_load_operand"
+   (ior (match_operand 0 "qi_mask_operand")
+        (match_operand 0 "hi_mask_operand")
+        (match_operand 0 "si_mask_operand")))
+ 
+ (define_predicate "low_bitmask_operand"
+   (and (match_test "ISA_HAS_EXT_INS")
+        (match_code "const_int")
+        (match_test "low_bitmask_len (mode, INTVAL (op)) > 16")))
+ 
+ (define_predicate "and_reg_operand"
+   (ior (match_operand 0 "register_operand")
+        (and (match_test "!TARGET_MIPS16")
+ 	    (match_operand 0 "const_uns_arith_operand"))
+        (match_operand 0 "low_bitmask_operand")
+        (match_operand 0 "si_mask_operand")))
+ 
+ (define_predicate "and_operand"
+   (ior (match_operand 0 "and_load_operand")
+        (match_operand 0 "and_reg_operand")))
+ 
  (define_predicate "d_operand"
    (and (match_code "reg")
         (match_test "TARGET_MIPS16
Index: config/mips/mips.md
===================================================================
*** config/mips/mips.md	(revision 150656)
--- config/mips/mips.md	(revision 150657)
*************** (define_attr "jal_macro" "no,yes"
*** 301,306 ****
--- 301,307 ----
  ;; sll0		"sll DEST,SRC,0", which on 64-bit targets is guaranteed
  ;;		to produce a sign-extended DEST, even if SRC is not
  ;;		properly sign-extended
+ ;; ext_ins	EXT, DEXT, INS or DINS instruction
  ;; andi		a single ANDI instruction
  ;; loadpool	move a constant into a MIPS16 register by loading it
  ;;		from the pool
*************** (define_attr "jal_macro" "no,yes"
*** 313,319 ****
  ;; scheduling type to be "multi" instead.
  (define_attr "move_type"
    "unknown,load,fpload,store,fpstore,mtc,mfc,mthilo,mfhilo,move,fmove,
!    const,constN,signext,arith,sll0,andi,loadpool,shift_shift,lui_movf"
    (const_string "unknown"))
  
  ;; Main data type used by the insn
--- 314,321 ----
  ;; scheduling type to be "multi" instead.
  (define_attr "move_type"
    "unknown,load,fpload,store,fpstore,mtc,mfc,mthilo,mfhilo,move,fmove,
!    const,constN,signext,ext_ins,logical,arith,sll0,andi,loadpool,
!    shift_shift,lui_movf"
    (const_string "unknown"))
  
  ;; Main data type used by the insn
*************** (define_attr "type"
*** 408,414 ****
--- 410,418 ----
  	 (eq_attr "move_type" "fmove") (const_string "fmove")
  	 (eq_attr "move_type" "loadpool") (const_string "load")
  	 (eq_attr "move_type" "signext") (const_string "signext")
+ 	 (eq_attr "move_type" "ext_ins") (const_string "arith")
  	 (eq_attr "move_type" "arith") (const_string "arith")
+ 	 (eq_attr "move_type" "logical") (const_string "logical")
  	 (eq_attr "move_type" "sll0") (const_string "shift")
  	 (eq_attr "move_type" "andi") (const_string "logical")
  
*************** (define_insn "one_cmpl<mode>2"
*** 2561,2591 ****
  (define_expand "and<mode>3"
    [(set (match_operand:GPR 0 "register_operand")
  	(and:GPR (match_operand:GPR 1 "register_operand")
! 		 (match_operand:GPR 2 "uns_arith_operand")))]
!   ""
! {
!   if (TARGET_MIPS16)
!     operands[2] = force_reg (<MODE>mode, operands[2]);
! })
  
  (define_insn "*and<mode>3"
!   [(set (match_operand:GPR 0 "register_operand" "=d,d")
! 	(and:GPR (match_operand:GPR 1 "register_operand" "%d,d")
! 		 (match_operand:GPR 2 "uns_arith_operand" "d,K")))]
!   "!TARGET_MIPS16"
!   "@
!    and\t%0,%1,%2
!    andi\t%0,%1,%x2"
!   [(set_attr "type" "logical")
     (set_attr "mode" "<MODE>")])
  
  (define_insn "*and<mode>3_mips16"
!   [(set (match_operand:GPR 0 "register_operand" "=d")
! 	(and:GPR (match_operand:GPR 1 "register_operand" "%0")
! 		 (match_operand:GPR 2 "register_operand" "d")))]
!   "TARGET_MIPS16"
!   "and\t%0,%2"
!   [(set_attr "type" "logical")
     (set_attr "mode" "<MODE>")])
  
  (define_expand "ior<mode>3"
--- 2565,2655 ----
  (define_expand "and<mode>3"
    [(set (match_operand:GPR 0 "register_operand")
  	(and:GPR (match_operand:GPR 1 "register_operand")
! 		 (match_operand:GPR 2 "and_reg_operand")))])
! 
! ;; The middle-end is not allowed to convert ANDing with 0xffff_ffff into a
! ;; zero_extendsidi2 because of TRULY_NOOP_TRUNCATION, so handle these here.
! ;; Note that this variant does not trigger for SI mode because we require
! ;; a 64-bit HOST_WIDE_INT and 0xffff_ffff wouldn't be a canonical
! ;; sign-extended SImode value.
! ;;
! ;; These are possible combinations for operand 1 and 2.  The table
! ;; includes both MIPS and MIPS16 cases.  (r=register, mem=memory,
! ;; 16=MIPS16, x=match, S=split):
! ;;
! ;;     \ op1    r/EXT   r/!EXT  mem   r/16   mem/16
! ;;  op2
! ;;
! ;;  andi           x     x
! ;;  0xff           x     x       x             x
! ;;  0xffff         x     x       x             x
! ;;  0xffff_ffff    x     S       x     S       x
! ;;  low-bitmask    x
! ;;  register       x     x
! ;;  register =op1                      x
  
  (define_insn "*and<mode>3"
!   [(set (match_operand:GPR 0 "register_operand" "=d,d,d,d,d,d,d")
! 	(and:GPR (match_operand:GPR 1 "nonimmediate_operand" "o,o,W,d,d,d,d")
! 		 (match_operand:GPR 2 "and_operand" "Yb,Yh,Yw,K,Yx,Yw,d")))]
!   "!TARGET_MIPS16 && and_operands_ok (<MODE>mode, operands[1], operands[2])"
! {
!   int len;
! 
!   switch (which_alternative)
!     {
!     case 0:
!       operands[1] = gen_lowpart (QImode, operands[1]);
!       return "lbu\t%0,%1";
!     case 1:
!       operands[1] = gen_lowpart (HImode, operands[1]);
!       return "lhu\t%0,%1";
!     case 2:
!       operands[1] = gen_lowpart (SImode, operands[1]);
!       return "lwu\t%0,%1";
!     case 3:
!       return "andi\t%0,%1,%x2";
!     case 4:
!       len = low_bitmask_len (<MODE>mode, INTVAL (operands[2]));
!       operands[2] = GEN_INT (len);
!       return "<d>ext\t%0,%1,0,%2";
!     case 5:
!       return "#";
!     case 6:
!       return "and\t%0,%1,%2";
!     default:
!       gcc_unreachable ();
!     }
! }
!   [(set_attr "move_type" "load,load,load,andi,ext_ins,shift_shift,logical")
     (set_attr "mode" "<MODE>")])
  
  (define_insn "*and<mode>3_mips16"
!   [(set (match_operand:GPR 0 "register_operand" "=d,d,d,d,d")
! 	(and:GPR (match_operand:GPR 1 "nonimmediate_operand" "%o,o,W,d,0")
! 		 (match_operand:GPR 2 "and_operand" "Yb,Yh,Yw,Yw,d")))]
!   "TARGET_MIPS16 && and_operands_ok (<MODE>mode, operands[1], operands[2])"
! {
!   switch (which_alternative)
!     {
!     case 0:
!       operands[1] = gen_lowpart (QImode, operands[1]);
!       return "lbu\t%0,%1";
!     case 1:
!       operands[1] = gen_lowpart (HImode, operands[1]);
!       return "lhu\t%0,%1";
!     case 2:
!       operands[1] = gen_lowpart (SImode, operands[1]);
!       return "lwu\t%0,%1";
!     case 3:
!       return "#";
!     case 4:
!       return "and\t%0,%2";
!     default:
!       gcc_unreachable ();
!     }
! }
!   [(set_attr "move_type" "load,load,load,shift_shift,logical")
     (set_attr "mode" "<MODE>")])
  
  (define_expand "ior<mode>3"
*************** (define_insn "*zero_extendsidi2_dext"
*** 2778,2821 ****
    [(set_attr "move_type" "arith,load")
     (set_attr "mode" "DI")])
  
! ;; Combine is not allowed to convert this insn into a zero_extendsidi2
! ;; because of TRULY_NOOP_TRUNCATION.
  
! (define_insn_and_split "*clear_upper32"
!   [(set (match_operand:DI 0 "register_operand" "=d,d")
!         (and:DI (match_operand:DI 1 "nonimmediate_operand" "d,W")
  		(const_int 4294967295)))]
!   "TARGET_64BIT && !ISA_HAS_EXT_INS"
! {
!   if (which_alternative == 0)
!     return "#";
! 
!   operands[1] = gen_lowpart (SImode, operands[1]);
!   return "lwu\t%0,%1";
! }
!   "&& reload_completed && REG_P (operands[1])"
    [(set (match_dup 0)
          (ashift:DI (match_dup 1) (const_int 32)))
     (set (match_dup 0)
!         (lshiftrt:DI (match_dup 0) (const_int 32)))]
!   ""
!   [(set_attr "move_type" "shift_shift,load")
!    (set_attr "mode" "DI")])
! 
! (define_insn "*clear_upper32_dext"
!   [(set (match_operand:DI 0 "register_operand" "=d,d")
!         (and:DI (match_operand:DI 1 "nonimmediate_operand" "d,W")
! 		(const_int 4294967295)))]
!   "TARGET_64BIT && ISA_HAS_EXT_INS"
! {
!   if (which_alternative == 0)
!     return "dext\t%0,%1,0,32";
! 
!   operands[1] = gen_lowpart (SImode, operands[1]);
!   return "lwu\t%0,%1";
! }
!   [(set_attr "move_type" "arith,load")
!    (set_attr "mode" "DI")])
  
  (define_expand "zero_extend<SHORT:mode><GPR:mode>2"
    [(set (match_operand:GPR 0 "register_operand")
--- 2842,2859 ----
    [(set_attr "move_type" "arith,load")
     (set_attr "mode" "DI")])
  
! ;; See the comment before the *and<mode>3 pattern why this is generated by
! ;; combine.
  
! (define_split
!   [(set (match_operand:DI 0 "register_operand")
!         (and:DI (match_operand:DI 1 "register_operand")
  		(const_int 4294967295)))]
!   "TARGET_64BIT && !ISA_HAS_EXT_INS && reload_completed"
    [(set (match_dup 0)
          (ashift:DI (match_dup 1) (const_int 32)))
     (set (match_dup 0)
!         (lshiftrt:DI (match_dup 0) (const_int 32)))])
  
  (define_expand "zero_extend<SHORT:mode><GPR:mode>2"
    [(set (match_operand:GPR 0 "register_operand")
Index: config/mips/mips-protos.h
===================================================================
*** config/mips/mips-protos.h	(revision 150656)
--- config/mips/mips-protos.h	(revision 150657)
*************** extern bool mips16e_save_restore_pattern
*** 316,321 ****
--- 316,322 ----
  
  extern bool mask_low_and_shift_p (enum machine_mode, rtx, rtx, int);
  extern int mask_low_and_shift_len (enum machine_mode, rtx, rtx);
+ extern bool and_operands_ok (enum machine_mode, rtx, rtx);
  
  union mips_gen_fn_ptrs
  {
Index: config/mips/mips.c
===================================================================
*** config/mips/mips.c	(revision 150656)
--- config/mips/mips.c	(revision 150657)
*************** mask_low_and_shift_p (enum machine_mode 
*** 6786,6791 ****
--- 6786,6803 ----
    return IN_RANGE (mask_low_and_shift_len (mode, mask, shift), 1, maxlen);
  }
  
+ /* Return true iff OP1 and OP2 are valid operands together for the
+    *and<MODE>3 and *and<MODE>3_mips16 patterns.  For the cases to consider,
+    see the table in the comment before the pattern.  */
+ 
+ bool
+ and_operands_ok (enum machine_mode mode, rtx op1, rtx op2)
+ {
+   return (memory_operand (op1, mode)
+ 	  ? and_load_operand (op2, mode)
+ 	  : and_reg_operand (op2, mode));
+ }
+ 
  /* The canonical form of a mask-low-and-shift-left operation is
     (and (ashift X SHIFT) MASK) where MASK has the lower SHIFT number of bits
     cleared.  Thus we need to shift MASK to the right before checking if it


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