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

login
register
mail settings
Submitter Richard Henderson
Date Aug. 10, 2012, 2:31 a.m.
Message ID <1344565921-27852-2-git-send-email-rth@redhat.com>
Download mbox | patch
Permalink /patch/176335/
State New
Headers show

Comments

Richard Henderson - Aug. 10, 2012, 2:31 a.m.
---
 gcc/config/s390/constraints.md |   11 ++++-
 gcc/config/s390/predicates.md  |    6 +++
 gcc/config/s390/s390.c         |   92 +++++++++++++++++++++++++++-------------
 gcc/config/s390/s390.md        |   48 +++++----------------
 4 files changed, 90 insertions(+), 67 deletions(-)
Andreas Krebbel - Nov. 6, 2012, 12:51 p.m.
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"

Patch

diff --git a/gcc/config/s390/constraints.md b/gcc/config/s390/constraints.md
index 8564b66..9d416ad 100644
--- a/gcc/config/s390/constraints.md
+++ b/gcc/config/s390/constraints.md
@@ -45,6 +45,8 @@ 
 ;;         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,8 +332,15 @@ 
   (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.
diff --git a/gcc/config/s390/predicates.md b/gcc/config/s390/predicates.md
index 9d619fb..333457d 100644
--- a/gcc/config/s390/predicates.md
+++ b/gcc/config/s390/predicates.md
@@ -154,6 +154,12 @@ 
   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
diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c
index d67c0eb..4e22100 100644
--- a/gcc/config/s390/s390.c
+++ b/gcc/config/s390/s390.c
@@ -5286,28 +5286,35 @@  print_operand_address (FILE *file, rtx addr)
     '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.
+    '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).
-    '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.
+    '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.  */
+    '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':
@@ -5486,30 +5493,57 @@  print_operand (FILE *file, rtx x, int code)
       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));
+      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:
diff --git a/gcc/config/s390/s390.md b/gcc/config/s390/s390.md
index b3d096c..76ec9c4 100644
--- a/gcc/config/s390/s390.md
+++ b/gcc/config/s390/s390.md
@@ -518,6 +518,10 @@ 
 ;; 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.
 ;;
@@ -3389,28 +3393,12 @@ 
 (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"))
+			  (match_operand:GPR 2 "contiguous_bitmask_operand" ""))
 		 (and:GPR (match_operand:GPR 3 "nonimmediate_operand" "0")
-			  (match_operand 4 "const_int_operand" "n"))))
+			  (match_operand:GPR 4 "const_int_operand" ""))))
    (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";
-}
+  "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")])
 
@@ -3418,25 +3406,11 @@ 
 (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 2 "contiguous_bitmask_operand" ""))
 		(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";
-}
+  "TARGET_Z10"
+  "rosbg\t%0,%1,%<bfstart>2,%<bfend>2,0"
   [(set_attr "op_type" "RIE")])
 
 (define_insn "*insv<mode>_mem_reg"