[PATCH 1/7] s390: Constraints, predicates, and op letters for contiguous bitmasks

Andreas Krebbel andreas@de.ibm.com
Tue Nov 6 12:52:00 GMT 2012


Hi,

thanks for your patch. I've refreshed it to the latest revision and
have added patterns for risbgn (risbg without clobbering CC) which has
been added with zEC12.

I've tested the patch on s390x with -march=z196.  I think it is safe
for EC12 as well. However I'll run some tests there later on.

Feel free to apply.

Bye,

-Andreas-

 gcc/config/s390/constraints.md |   11 ++!!
 gcc/config/s390/predicates.md  |    6 ++
 gcc/config/s390/s390.c         |   92 ++-!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 gcc/config/s390/s390.md        |   74 +-!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 4 files changed, 21 insertions(+), 5 deletions(-), 157 modifications(!)

Index: gcc/config/s390/constraints.md
===================================================================
*** gcc/config/s390/constraints.md.orig
--- gcc/config/s390/constraints.md
***************
*** 45,50 ****
--- 45,52 ----
  ;;         H,Q:     mode of the part
  ;;         D,S,H:   mode of the containing operand
  ;;         0,F:     value of the other parts (F - all bits set)
+ ;;         --
+ ;;         xx[DS]q  satisfies s390_contiguous_bitmask_p for DImode or SImode
  ;;
  ;;         The constraint matches if the specified part of a constant
  ;;         has a value different from its other parts.  If the letter x
***************
*** 330,337 ****
    (and (match_code "const_int")
         (match_test "s390_N_constraint_str (\"xQH0\", ival)")))
  
  
! 
  
  ;;
  ;; Double-letter constraints starting with O follow.
--- 332,346 ----
    (and (match_code "const_int")
         (match_test "s390_N_constraint_str (\"xQH0\", ival)")))
  
+ (define_constraint "NxxDq"
+   "@internal"
+   (and (match_code "const_int")
+        (match_test "s390_contiguous_bitmask_p (ival, 64, NULL, NULL)")))
  
! (define_constraint "NxxSq"
!   "@internal"
!   (and (match_code "const_int")
!        (match_test "s390_contiguous_bitmask_p (ival, 32, NULL, NULL)")))
  
  ;;
  ;; Double-letter constraints starting with O follow.
Index: gcc/config/s390/predicates.md
===================================================================
*** gcc/config/s390/predicates.md.orig
--- gcc/config/s390/predicates.md
***************
*** 154,159 ****
--- 154,165 ----
    return false;
  })
  
+ (define_predicate "contiguous_bitmask_operand"
+   (match_code "const_int")
+ {
+   return s390_contiguous_bitmask_p (INTVAL (op), GET_MODE_BITSIZE (mode), NULL, NULL);
+ })
+ 
  ;; operators --------------------------------------------------------------
  
  ;; Return nonzero if OP is a valid comparison operator
Index: gcc/config/s390/s390.c
===================================================================
*** gcc/config/s390/s390.c.orig
--- gcc/config/s390/s390.c
*************** print_operand_address (FILE *file, rtx a
*** 5361,5388 ****
      'C': print opcode suffix for branch condition.
      'D': print opcode suffix for inverse branch condition.
      'E': print opcode suffix for branch on index instruction.
-     'J': print tls_load/tls_gdcall/tls_ldcall suffix
      'G': print the size of the operand in bytes.
      'O': print only the displacement of a memory reference.
      'R': print only the base register of a memory reference.
      'S': print S-type memory reference (base+displacement).
-     'N': print the second word of a DImode operand.
-     'M': print the second word of a TImode operand.
      'Y': print shift count operand.
  
      'b': print integer X as if it's an unsigned byte.
      'c': print integer X as if it's an signed byte.
!     'x': print integer X as if it's an unsigned halfword.
      'h': print integer X as if it's a signed halfword.
      'i': print the first nonzero HImode part of X.
      'j': print the first HImode part unequal to -1 of X.
      'k': print the first nonzero SImode part of X.
      'm': print the first SImode part unequal to -1 of X.
!     'o': print integer X as if it's an unsigned 32bit word.  */
  
  void
  print_operand (FILE *file, rtx x, int code)
  {
    switch (code)
      {
      case 'C':
--- 5361,5395 ----
      'C': print opcode suffix for branch condition.
      'D': print opcode suffix for inverse branch condition.
      'E': print opcode suffix for branch on index instruction.
      'G': print the size of the operand in bytes.
+     'J': print tls_load/tls_gdcall/tls_ldcall suffix
+     'M': print the second word of a TImode operand.
+     'N': print the second word of a DImode operand.
      'O': print only the displacement of a memory reference.
      'R': print only the base register of a memory reference.
      'S': print S-type memory reference (base+displacement).
      'Y': print shift count operand.
  
      'b': print integer X as if it's an unsigned byte.
      'c': print integer X as if it's an signed byte.
!     'e': "end" of DImode contiguous bitmask X.
!     'f': "end" of SImode contiguous bitmask X.
      'h': print integer X as if it's a signed halfword.
      'i': print the first nonzero HImode part of X.
      'j': print the first HImode part unequal to -1 of X.
      'k': print the first nonzero SImode part of X.
      'm': print the first SImode part unequal to -1 of X.
!     'o': print integer X as if it's an unsigned 32bit word.
!     's': "start" of DImode contiguous bitmask X.
!     't': "start" of SImode contiguous bitmask X.
!     'x': print integer X as if it's an unsigned halfword.
! */
  
  void
  print_operand (FILE *file, rtx x, int code)
  {
+   HOST_WIDE_INT ival;
+ 
    switch (code)
      {
      case 'C':
*************** print_operand (FILE *file, rtx x, int co
*** 5561,5590 ****
        break;
  
      case CONST_INT:
!       if (code == 'b')
!         fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) & 0xff);
!       else if (code == 'c')
!         fprintf (file, HOST_WIDE_INT_PRINT_DEC, ((INTVAL (x) & 0xff) ^ 0x80) - 0x80);
!       else if (code == 'x')
!         fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) & 0xffff);
!       else if (code == 'h')
!         fprintf (file, HOST_WIDE_INT_PRINT_DEC, ((INTVAL (x) & 0xffff) ^ 0x8000) - 0x8000);
!       else if (code == 'i')
! 	fprintf (file, HOST_WIDE_INT_PRINT_DEC,
! 		 s390_extract_part (x, HImode, 0));
!       else if (code == 'j')
! 	fprintf (file, HOST_WIDE_INT_PRINT_DEC,
! 		 s390_extract_part (x, HImode, -1));
!       else if (code == 'k')
!  	fprintf (file, HOST_WIDE_INT_PRINT_DEC,
!  		 s390_extract_part (x, SImode, 0));
!       else if (code == 'm')
!  	fprintf (file, HOST_WIDE_INT_PRINT_DEC,
!  		 s390_extract_part (x, SImode, -1));
!       else if (code == 'o')
! 	fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) & 0xffffffff);
!       else
!         fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x));
        break;
  
      case CONST_DOUBLE:
--- 5568,5624 ----
        break;
  
      case CONST_INT:
!       ival = INTVAL (x);
!       switch (code)
! 	{
! 	case 0:
! 	  break;
! 	case 'b':
! 	  ival &= 0xff;
! 	  break;
! 	case 'c':
! 	  ival = ((ival & 0xff) ^ 0x80) - 0x80;
! 	  break;
! 	case 'x':
! 	  ival &= 0xffff;
! 	  break;
! 	case 'h':
! 	  ival = ((ival & 0xffff) ^ 0x8000) - 0x8000;
! 	  break;
! 	case 'i':
! 	  ival = s390_extract_part (x, HImode, 0);
! 	  break;
! 	case 'j':
! 	  ival = s390_extract_part (x, HImode, -1);
! 	  break;
! 	case 'k':
! 	  ival = s390_extract_part (x, SImode, 0);
! 	  break;
! 	case 'm':
! 	  ival = s390_extract_part (x, SImode, -1);
! 	  break;
! 	case 'o':
! 	  ival &= 0xffffffff;
! 	  break;
! 	case 'e': case 'f':
! 	case 's': case 't':
! 	  {
! 	    int pos, len;
! 	    bool ok;
! 
! 	    len = (code == 's' || code == 'e' ? 64 : 32);
! 	    ok = s390_contiguous_bitmask_p (ival, len, &pos, &len);
! 	    gcc_assert (ok);
! 	    if (code == 's' || code == 't')
! 	      ival = 64 - pos - len;
! 	    else
! 	      ival = 64 - 1 - pos;
! 	  }
! 	  break;
! 	default:
! 	  output_operand_lossage ("invalid constant for output modifier '%c'", code);
! 	}
!       fprintf (file, HOST_WIDE_INT_PRINT_DEC, ival);
        break;
  
      case CONST_DOUBLE:
Index: gcc/config/s390/s390.md
===================================================================
*** gcc/config/s390/s390.md.orig
--- gcc/config/s390/s390.md
***************
*** 527,532 ****
--- 527,536 ----
  ;; Maximum unsigned integer that fits in MODE.
  (define_mode_attr max_uint [(HI "65535") (QI "255")])
  
+ ;; Start and end field computations for RISBG et al.
+ (define_mode_attr bfstart [(DI "s") (SI "t")])
+ (define_mode_attr bfend   [(DI "e") (SI "f")])
+ 
  ;;
  ;;- Compare instructions.
  ;;
***************
*** 3420,3475 ****
  (define_insn "*insv<mode>_zEC12_noshift"
    [(set (match_operand:GPR 0 "nonimmediate_operand" "=d")
  	(ior:GPR (and:GPR (match_operand:GPR 1 "nonimmediate_operand" "d")
! 			  (match_operand 2 "const_int_operand" "n"))
  		 (and:GPR (match_operand:GPR 3 "nonimmediate_operand" "0")
! 			  (match_operand 4 "const_int_operand" "n"))))]
!   "TARGET_ZEC12
!    && s390_contiguous_bitmask_p (INTVAL (operands[2]),
!                                  GET_MODE_BITSIZE (<MODE>mode), NULL, NULL)
!    && INTVAL (operands[2]) == ~(INTVAL (operands[4]))"
! 
! {
!   int start;
!   int size;
! 
!   s390_contiguous_bitmask_p (INTVAL (operands[2]),
!                              GET_MODE_BITSIZE (<MODE>mode), &start, &size);
! 
!   operands[5] = GEN_INT (64 - start - size); /* start bit position */
!   operands[6] = GEN_INT (64 - 1 - start);    /* end bit position */
!   operands[7] = const0_rtx;                  /* left shift count */
! 
!   return "risbgn\t%0,%1,%b5,%b6,%b7";
! }
    [(set_attr "op_type" "RIE")])
  
- ; and op1 with a mask being 1 for the selected bits and 0 for the rest
- ; and op3=op0 with a mask being 0 for the selected bits and 1 for the rest
  (define_insn "*insv<mode>_z10_noshift"
    [(set (match_operand:GPR 0 "nonimmediate_operand" "=d")
  	(ior:GPR (and:GPR (match_operand:GPR 1 "nonimmediate_operand" "d")
! 			  (match_operand 2 "const_int_operand" "n"))
  		 (and:GPR (match_operand:GPR 3 "nonimmediate_operand" "0")
! 			  (match_operand 4 "const_int_operand" "n"))))
     (clobber (reg:CC CC_REGNUM))]
!   "TARGET_Z10
!    && s390_contiguous_bitmask_p (INTVAL (operands[2]),
!                                  GET_MODE_BITSIZE (<MODE>mode), NULL, NULL)
!    && INTVAL (operands[2]) == ~(INTVAL (operands[4]))"
! 
! {
!   int start;
!   int size;
! 
!   s390_contiguous_bitmask_p (INTVAL (operands[2]),
!                              GET_MODE_BITSIZE (<MODE>mode), &start, &size);
! 
!   operands[5] = GEN_INT (64 - start - size); /* start bit position */
!   operands[6] = GEN_INT (64 - 1 - start);    /* end bit position */
!   operands[7] = const0_rtx;                  /* left shift count */
! 
!   return "risbg\t%0,%1,%b5,%b6,%b7";
! }
    [(set_attr "op_type" "RIE")
     (set_attr "z10prop" "z10_super_E1")])
  
--- 3424,3445 ----
  (define_insn "*insv<mode>_zEC12_noshift"
    [(set (match_operand:GPR 0 "nonimmediate_operand" "=d")
  	(ior:GPR (and:GPR (match_operand:GPR 1 "nonimmediate_operand" "d")
! 			  (match_operand:GPR 2 "contiguous_bitmask_operand" ""))
  		 (and:GPR (match_operand:GPR 3 "nonimmediate_operand" "0")
! 			  (match_operand:GPR 4 "const_int_operand" ""))))]
!   "TARGET_ZEC12 && INTVAL (operands[2]) == ~INTVAL (operands[4])"
!   "risbgn\t%0,%1,%<bfstart>2,%<bfend>2,0"
    [(set_attr "op_type" "RIE")])
  
  (define_insn "*insv<mode>_z10_noshift"
    [(set (match_operand:GPR 0 "nonimmediate_operand" "=d")
  	(ior:GPR (and:GPR (match_operand:GPR 1 "nonimmediate_operand" "d")
! 			  (match_operand:GPR 2 "contiguous_bitmask_operand" ""))
  		 (and:GPR (match_operand:GPR 3 "nonimmediate_operand" "0")
! 			  (match_operand:GPR 4 "const_int_operand" ""))))
     (clobber (reg:CC CC_REGNUM))]
!   "TARGET_Z10 && INTVAL (operands[2]) == ~INTVAL (operands[4])"
!   "risbg\t%0,%1,%<bfstart>2,%<bfend>2,0"
    [(set_attr "op_type" "RIE")
     (set_attr "z10prop" "z10_super_E1")])
  
***************
*** 3477,3501 ****
  (define_insn "*insv<mode>_or_z10_noshift"
    [(set (match_operand:GPR 0 "nonimmediate_operand" "=d")
  	(ior:GPR (and:GPR (match_operand:GPR 1 "nonimmediate_operand" "d")
! 			  (match_operand 2 "const_int_operand" "n"))
  		(match_operand:GPR 3 "nonimmediate_operand" "0")))
     (clobber (reg:CC CC_REGNUM))]
!   "TARGET_Z10
!    && s390_contiguous_bitmask_p (INTVAL (operands[2]),
!                                  GET_MODE_BITSIZE (<MODE>mode), NULL, NULL)"
! {
!   int start;
!   int size;
! 
!   s390_contiguous_bitmask_p (INTVAL (operands[2]),
!                              GET_MODE_BITSIZE (<MODE>mode), &start, &size);
! 
!   operands[4] = GEN_INT (64 - start - size); /* start bit position */
!   operands[5] = GEN_INT (64 - 1 - start);    /* end bit position */
!   operands[6] = const0_rtx;                  /* left shift count */
! 
!   return "rosbg\t%0,%1,%b4,%b5,%b6";
! }
    [(set_attr "op_type" "RIE")])
  
  (define_insn "*insv<mode>_mem_reg"
--- 3447,3457 ----
  (define_insn "*insv<mode>_or_z10_noshift"
    [(set (match_operand:GPR 0 "nonimmediate_operand" "=d")
  	(ior:GPR (and:GPR (match_operand:GPR 1 "nonimmediate_operand" "d")
! 			  (match_operand:GPR 2 "contiguous_bitmask_operand" ""))
  		(match_operand:GPR 3 "nonimmediate_operand" "0")))
     (clobber (reg:CC CC_REGNUM))]
!   "TARGET_Z10"
!   "rosbg\t%0,%1,%<bfstart>2,%<bfend>2,0"
    [(set_attr "op_type" "RIE")])
  
  (define_insn "*insv<mode>_mem_reg"



More information about the Gcc-patches mailing list