diff --git a/gcc/config/arm/predicates.md b/gcc/config/arm/predicates.md
index d169cb2..8248a79 100644
--- a/gcc/config/arm/predicates.md
+++ b/gcc/config/arm/predicates.md
@@ -246,6 +246,10 @@
   (and (match_code "plus,minus,ior,xor,and")
        (match_test "mode == GET_MODE (op)")))
 
+(define_special_predicate "shiftable_operator_strict_it"
+  (and (match_code "plus,and")
+       (match_test "mode == GET_MODE (op)")))
+
 ;; True for logical binary operators.
 (define_special_predicate "logical_binary_operator"
   (and (match_code "ior,xor,and")
diff --git a/gcc/config/arm/thumb2.md b/gcc/config/arm/thumb2.md
index ca4eedb..6a3caf5 100644
--- a/gcc/config/arm/thumb2.md
+++ b/gcc/config/arm/thumb2.md
@@ -34,14 +34,15 @@
   "TARGET_THUMB2"
   "bic%?\\t%0, %1, %2%S4"
   [(set_attr "predicable" "yes")
+   (set_attr "predicable_short_it" "no")
    (set_attr "shift" "2")
    (set_attr "type" "alu_shift")]
 )
 
 (define_insn_and_split "*thumb2_smaxsi3"
-  [(set (match_operand:SI          0 "s_register_operand" "=r,r,r")
-	(smax:SI (match_operand:SI 1 "s_register_operand"  "0,r,?r")
-		 (match_operand:SI 2 "arm_rhs_operand"    "rI,0,rI")))
+  [(set (match_operand:SI          0 "s_register_operand" "=r,r,r ,r,l")
+	(smax:SI (match_operand:SI 1 "s_register_operand"  "0,r,?r,0,0")
+		 (match_operand:SI 2 "arm_rhs_operand"    "rI,0,rI,r,Py")))
    (clobber (reg:CC CC_REGNUM))]
   "TARGET_THUMB2"
   "#"
@@ -57,13 +58,14 @@
                          (match_dup 2)))]
   ""
   [(set_attr "conds" "clob")
-   (set_attr "length" "10,10,14")]
+   (set_attr "enabled_for_depr_it" "no,yes,no,yes,yes")
+   (set_attr "length" "10,10,14,8,8")]
 )
 
 (define_insn_and_split "*thumb2_sminsi3"
-  [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
-	(smin:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
-		 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
+  [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r,l")
+	(smin:SI (match_operand:SI 1 "s_register_operand" "0,r,?r,0,0")
+		 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI,r,Py")))
    (clobber (reg:CC CC_REGNUM))]
   "TARGET_THUMB2"
   "#"
@@ -79,13 +81,14 @@
                          (match_dup 2)))]
   ""
   [(set_attr "conds" "clob")
-   (set_attr "length" "10,10,14")]
+   (set_attr "enabled_for_depr_it" "no,yes,no,yes,yes")
+   (set_attr "length" "10,10,14,8,8")]
 )
 
 (define_insn_and_split "*thumb32_umaxsi3"
-  [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
-	(umax:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
-		 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
+  [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r,l")
+	(umax:SI (match_operand:SI 1 "s_register_operand" "0,r,?r,0,0")
+		 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI,r,Py")))
    (clobber (reg:CC CC_REGNUM))]
   "TARGET_THUMB2"
   "#"
@@ -101,13 +104,14 @@
                          (match_dup 2)))]
   ""
   [(set_attr "conds" "clob")
-   (set_attr "length" "10,10,14")]
+   (set_attr "length" "10,10,14,8,8")
+   (set_attr "enabled_for_depr_it" "no,yes,no,yes,yes")]
 )
 
 (define_insn_and_split "*thumb2_uminsi3"
-  [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
-	(umin:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
-		 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
+  [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r,l")
+	(umin:SI (match_operand:SI 1 "s_register_operand" "0,r,?r,0,0")
+		 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI,r,Py")))
    (clobber (reg:CC CC_REGNUM))]
   "TARGET_THUMB2"
   "#"
@@ -123,7 +127,8 @@
                          (match_dup 2)))]
   ""
   [(set_attr "conds" "clob")
-   (set_attr "length" "10,10,14")]
+   (set_attr "length" "10,10,14,8,8")
+   (set_attr "enabled_for_depr_it" "no,yes,no,yes,yes")]
 )
 
 ;; Thumb-2 does not have rsc, so use a clever trick with shifter operands.
@@ -152,7 +157,7 @@
 )
 
 (define_insn_and_split "*thumb2_abssi2"
-  [(set (match_operand:SI         0 "s_register_operand" "=r,&r")
+  [(set (match_operand:SI         0 "s_register_operand" "=Ts,&r")
 	(abs:SI (match_operand:SI 1 "s_register_operand" "0,r")))
    (clobber (reg:CC CC_REGNUM))]
   "TARGET_THUMB2"
@@ -202,12 +207,13 @@
   [(set_attr "conds" "clob,*")
    (set_attr "shift" "1")
    (set_attr "predicable" "no, yes")
+   (set_attr "predicable_short_it" "no")
    (set_attr "ce_count" "2")
    (set_attr "length" "10,8")]
 )
 
 (define_insn_and_split "*thumb2_neg_abssi2"
-  [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
+  [(set (match_operand:SI 0 "s_register_operand" "=Ts,&r")
 	(neg:SI (abs:SI (match_operand:SI 1 "s_register_operand" "0,r"))))
    (clobber (reg:CC CC_REGNUM))]
   "TARGET_THUMB2"
@@ -257,6 +263,7 @@
   [(set_attr "conds" "clob,*")
    (set_attr "shift" "1")
    (set_attr "predicable" "no, yes")
+   (set_attr "predicable_short_it" "no")
    (set_attr "ce_count" "2")
    (set_attr "length" "10,8")]
 )
@@ -337,7 +344,7 @@
 )
 
 (define_insn_and_split "*thumb2_mov_scc"
-  [(set (match_operand:SI 0 "s_register_operand" "=r")
+  [(set (match_operand:SI 0 "s_register_operand" "=r, =l")
 	(match_operator:SI 1 "arm_comparison_operator"
 	 [(match_operand 2 "cc_register" "") (const_int 0)]))]
   "TARGET_THUMB2"
@@ -349,11 +356,12 @@
                          (const_int 0)))]
   ""
   [(set_attr "conds" "use")
-   (set_attr "length" "10")]
+   (set_attr "enabled_for_depr_it" "no,yes")
+   (set_attr "length" "10, 10")]
 )
 
 (define_insn_and_split "*thumb2_mov_negscc"
-  [(set (match_operand:SI 0 "s_register_operand" "=r")
+  [(set (match_operand:SI 0 "s_register_operand" "=r,=l")
 	(neg:SI (match_operator:SI 1 "arm_comparison_operator"
 		 [(match_operand 2 "cc_register" "") (const_int 0)])))]
   "TARGET_THUMB2"
@@ -367,14 +375,15 @@
     operands[3] = GEN_INT (~0);
   }
   [(set_attr "conds" "use")
-   (set_attr "length" "10")]
+   (set_attr "enabled_for_depr_it" "no,yes")
+   (set_attr "length" "10,8")]
 )
 
 (define_insn_and_split "*thumb2_mov_notscc"
   [(set (match_operand:SI 0 "s_register_operand" "=r")
 	(not:SI (match_operator:SI 1 "arm_comparison_operator"
 		 [(match_operand 2 "cc_register" "") (const_int 0)])))]
-  "TARGET_THUMB2"
+  "TARGET_THUMB2 && !arm_restrict_it"
   "#"   ; "ite\\t%D1\;mvn%D1\\t%0, #0\;mvn%d1\\t%0, #1"
   "TARGET_THUMB2"
   [(set (match_dup 0)
@@ -521,7 +531,7 @@
 	(ior:SI (match_operator:SI 1 "arm_comparison_operator"
 		 [(match_operand 2 "cc_register" "") (const_int 0)])
 		(match_operand:SI 3 "s_register_operand" "0,?r")))]
-  "TARGET_THUMB2"
+  "TARGET_THUMB2 && !arm_restrict_it"
   "@
    it\\t%d1\;orr%d1\\t%0, %3, #1
    #"
@@ -546,6 +556,19 @@
    (set_attr "length" "6,10")]
 )
 
+(define_insn "*thumb2_ior_scc_strict_it"
+  [(set (match_operand:SI 0 "s_register_operand" "=l,=l")
+	(ior:SI (match_operator:SI 2 "arm_comparison_operator"
+		 [(match_operand 3 "cc_register" "") (const_int 0)])
+		(match_operand:SI 1 "s_register_operand" "0,?l")))]
+  "TARGET_THUMB2 && arm_restrict_it"
+  "@
+   it\\t%d2\;mov%d2\\t%0, #1\;it\\t%d2\;orr%d2\\t%0, %1
+   mov\\t%0, #1\;orr\\t%0, %1\;it\\t%D2\;mov%D2\\t%0, %1"
+  [(set_attr "conds" "use")
+   (set_attr "length" "8")]
+)
+
 (define_insn "*thumb2_cond_move"
   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
 	(if_then_else:SI (match_operator 3 "equality_operator"
@@ -573,13 +596,20 @@
 	output_asm_insn (\"it\\t%D4\", operands);
 	break;
       case 2:
-	output_asm_insn (\"ite\\t%D4\", operands);
+	if (arm_restrict_it)
+	  output_asm_insn (\"it\\t%D4\", operands);
+	else
+	  output_asm_insn (\"ite\\t%D4\", operands);
 	break;
       default:
 	abort();
       }
     if (which_alternative != 0)
-      output_asm_insn (\"mov%D4\\t%0, %1\", operands);
+      {
+        output_asm_insn (\"mov%D4\\t%0, %1\", operands);
+        if (arm_restrict_it && which_alternative == 2)
+          output_asm_insn (\"it\\t%d4\", operands);
+      }
     if (which_alternative != 1)
       output_asm_insn (\"mov%d4\\t%0, %2\", operands);
     return \"\";
@@ -596,7 +626,7 @@
 	    (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
           (match_operand:SI 1 "s_register_operand" "0,?r")]))
    (clobber (reg:CC CC_REGNUM))]
-  "TARGET_THUMB2"
+  "TARGET_THUMB2 && !arm_restrict_it"
   "*
     if (GET_CODE (operands[4]) == LT && operands[3] == const0_rtx)
       return \"%i5\\t%0, %1, %2, lsr #31\";
@@ -625,9 +669,78 @@
    (set_attr "length" "14")]
 )
 
+(define_insn_and_split "*thumb2_cond_arith_strict_it"
+  [(set (match_operand:SI 0 "s_register_operand" "=l")
+        (match_operator:SI 5 "shiftable_operator_strict_it"
+	 [(match_operator:SI 4 "arm_comparison_operator"
+           [(match_operand:SI 2 "s_register_operand" "r")
+	    (match_operand:SI 3 "arm_rhs_operand" "rI")])
+          (match_operand:SI 1 "s_register_operand" "0")]))
+   (clobber (reg:CC CC_REGNUM))]
+  "TARGET_THUMB2 && arm_restrict_it"
+  "#"
+  "&& reload_completed"
+  [(const_int 0)]
+  {
+    if (GET_CODE (operands[4]) == LT && operands[3] == const0_rtx)
+      {
+        /*  %i5 %0, %1, %2, lsr #31  */
+        rtx shifted_op = gen_rtx_LSHIFTRT (SImode, operands[2], GEN_INT (31));
+        rtx op = NULL_RTX;
+
+        switch (GET_CODE (operands[5]))
+          {
+          case AND:
+            op = gen_rtx_AND (SImode, shifted_op, operands[1]);
+            break;
+           case PLUS:
+            op = gen_rtx_PLUS (SImode, shifted_op, operands[1]);
+            break;
+          default: gcc_unreachable ();
+          }
+        emit_insn (gen_rtx_SET (VOIDmode, operands[0], op));
+        DONE;
+      }
+
+    /*  "cmp  %2, %3"  */
+    emit_insn (gen_rtx_SET (VOIDmode,
+                               gen_rtx_REG (CCmode, CC_REGNUM),
+                               gen_rtx_COMPARE (CCmode, operands[2], operands[3])));
+
+    if (GET_CODE (operands[5]) == AND)
+      {
+        /*  %i5  %0, %1, #1
+            it%D4
+            mov%D4  %0, #0  */
+        enum rtx_code rc = reverse_condition (GET_CODE (operands[4]));
+        emit_insn (gen_rtx_SET (VOIDmode, operands[0], gen_rtx_AND (SImode, operands[1], GEN_INT (1))));
+        emit_insn (gen_rtx_COND_EXEC (VOIDmode,
+                                      gen_rtx_fmt_ee (rc, VOIDmode, gen_rtx_REG (CCmode, CC_REGNUM), const0_rtx),
+                                      gen_rtx_SET (VOIDmode, operands[0], const0_rtx)));
+        DONE;
+      }
+    else
+      {
+        /*  it\\t%d4
+            %i5%d4\\t%0, %1, #1   */
+        emit_insn (gen_rtx_COND_EXEC (VOIDmode, gen_rtx_fmt_ee (GET_CODE (operands[4]),
+                                                                VOIDmode,
+                                                                gen_rtx_REG (CCmode, CC_REGNUM), const0_rtx),
+                                                gen_rtx_SET(VOIDmode, operands[0],
+                                                            gen_rtx_PLUS (SImode,
+                                                                          operands[1],
+                                                                          GEN_INT (1)))));
+        DONE;
+      }
+     FAIL;
+  }
+  [(set_attr "conds" "clob")
+   (set_attr "length" "12")]
+)
+
 (define_insn "*thumb2_cond_sub"
-  [(set (match_operand:SI 0 "s_register_operand" "=r,r")
-        (minus:SI (match_operand:SI 1 "s_register_operand" "0,?r")
+  [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
+        (minus:SI (match_operand:SI 1 "s_register_operand" "0,?Ts")
 		  (match_operator:SI 4 "arm_comparison_operator"
                    [(match_operand:SI 2 "s_register_operand" "r,r")
 		    (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
@@ -637,8 +711,16 @@
     output_asm_insn (\"cmp\\t%2, %3\", operands);
     if (which_alternative != 0)
       {
-	output_asm_insn (\"ite\\t%D4\", operands);
-	output_asm_insn (\"mov%D4\\t%0, %1\", operands);
+	if (arm_restrict_it)
+	  {
+	    output_asm_insn (\"mov\\t%0, %1\", operands);
+	    output_asm_insn (\"it\\t%d4\", operands);
+	  }
+	else
+	{
+	  output_asm_insn (\"ite\\t%D4\", operands);
+	  output_asm_insn (\"mov%D4\\t%0, %1\", operands);
+	}
       }
     else
       output_asm_insn (\"it\\t%d4\", operands);
@@ -723,13 +805,13 @@
 )
 
 (define_insn "*thumb2_movcond"
-  [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
+  [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts,Ts")
 	(if_then_else:SI
 	 (match_operator 5 "arm_comparison_operator"
 	  [(match_operand:SI 3 "s_register_operand" "r,r,r")
 	   (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL")])
-	 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
-	 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
+	 (match_operand:SI 1 "arm_rhs_operand" "0,TsI,?TsI")
+	 (match_operand:SI 2 "arm_rhs_operand" "TsI,0,TsI")))
    (clobber (reg:CC CC_REGNUM))]
   "TARGET_THUMB2"
   "*
@@ -784,12 +866,18 @@
       output_asm_insn (\"it\\t%d5\", operands);
       break;
     case 2:
-      output_asm_insn (\"ite\\t%d5\", operands);
+      if (arm_restrict_it)
+        {
+          output_asm_insn (\"mov\\t%0, %1\", operands);
+          output_asm_insn (\"it\\t%D5\", operands);
+        }
+      else
+        output_asm_insn (\"ite\\t%d5\", operands);
       break;
     default:
       abort();
     }
-  if (which_alternative != 0)
+  if (which_alternative != 0 && !(arm_restrict_it && which_alternative == 2))
     output_asm_insn (\"mov%d5\\t%0, %1\", operands);
   if (which_alternative != 1)
     output_asm_insn (\"mov%D5\\t%0, %2\", operands);
@@ -812,6 +900,7 @@
    ldr%(sb%)\\t%0, %1"
   [(set_attr "type" "simple_alu_shift,load_byte")
    (set_attr "predicable" "yes")
+   (set_attr "predicable_short_it" "no")
    (set_attr "pool_range" "*,4094")
    (set_attr "neg_pool_range" "*,250")]
 )
@@ -825,6 +914,7 @@
    ldr%(h%)\\t%0, %1"
   [(set_attr "type" "simple_alu_shift,load_byte")
    (set_attr "predicable" "yes")
+   (set_attr "predicable_short_it" "no")
    (set_attr "pool_range" "*,4094")
    (set_attr "neg_pool_range" "*,250")]
 )
@@ -838,6 +928,7 @@
    ldr%(b%)\\t%0, %1\\t%@ zero_extendqisi2"
   [(set_attr "type" "simple_alu_shift,load_byte")
    (set_attr "predicable" "yes")
+   (set_attr "predicable_short_it" "no")
    (set_attr "pool_range" "*,4094")
    (set_attr "neg_pool_range" "*,250")]
 )
@@ -1162,7 +1253,8 @@
 		(match_operand:SI 1 "s_register_operand" "r")))]
   "TARGET_THUMB2"
   "orn%?\\t%0, %1, %2"
-  [(set_attr "predicable" "yes")]
+  [(set_attr "predicable" "yes")
+   (set_attr "predicable_short_it" "no")]
 )
 
 (define_insn "*orsi_not_shiftsi_si"
@@ -1174,6 +1266,7 @@
   "TARGET_THUMB2"
   "orn%?\\t%0, %1, %2%S4"
   [(set_attr "predicable" "yes")
+   (set_attr "predicable_short_it" "no")
    (set_attr "shift" "2")
    (set_attr "type" "alu_shift")]
 )
