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"
