	Backport from FSF mainline:

	gcc/
	* config/arm/thumb2.md (*thumb2_addsi3_compare0): New.
	(*thumb2_addsi3_compare0_scratch): New.
	* config/arm/constraints.md (Pv): New.
	* config/arm/arm.md (*addsi3_compare0): Remove FIXME comment. Use
	for ARM mode only.
	(*addsi3_compare0_scratch): Likewise.

2010-07-26  Julian Brown  <julian@codesourcery.com>

 	Merge from Sourcery G++ 4.4:
 
 	2010-05-25  Julian Brown  <julian@codesourcery.com>

=== modified file 'gcc/config/arm/arm.md'
--- old/gcc/config/arm/arm.md	2010-08-12 13:35:39 +0000
+++ new/gcc/config/arm/arm.md	2010-08-12 16:47:21 +0000
@@ -701,7 +701,6 @@
   ""
 )
 
-;; ??? Make Thumb-2 variants which prefer low regs
 (define_insn "*addsi3_compare0"
   [(set (reg:CC_NOOV CC_REGNUM)
 	(compare:CC_NOOV
@@ -710,7 +709,7 @@
 	 (const_int 0)))
    (set (match_operand:SI 0 "s_register_operand" "=r,r")
 	(plus:SI (match_dup 1) (match_dup 2)))]
-  "TARGET_32BIT"
+  "TARGET_ARM"
   "@
    add%.\\t%0, %1, %2
    sub%.\\t%0, %1, #%n2"
@@ -723,7 +722,7 @@
 	 (plus:SI (match_operand:SI 0 "s_register_operand" "r, r")
 		  (match_operand:SI 1 "arm_add_operand"    "rI,L"))
 	 (const_int 0)))]
-  "TARGET_32BIT"
+  "TARGET_ARM"
   "@
    cmn%?\\t%0, %1
    cmp%?\\t%0, #%n1"

=== modified file 'gcc/config/arm/constraints.md'
--- old/gcc/config/arm/constraints.md	2010-07-29 16:58:56 +0000
+++ new/gcc/config/arm/constraints.md	2010-08-12 16:47:21 +0000
@@ -31,7 +31,7 @@
 ;; The following multi-letter normal constraints have been used:
 ;; in ARM/Thumb-2 state: Da, Db, Dc, Dn, Dl, DL, Dv, Dy, Di
 ;; in Thumb-1 state: Pa, Pb
-;; in Thumb-2 state: Ps, Pt
+;; in Thumb-2 state: Ps, Pt, Pv
 
 ;; The following memory constraints have been used:
 ;; in ARM/Thumb-2 state: Q, Ut, Uv, Uy, Un, Um, Us
@@ -158,6 +158,11 @@
   (and (match_code "const_int")
        (match_test "TARGET_THUMB2 && ival >= -7 && ival <= 7")))
 
+(define_constraint "Pv"
+  "@internal In Thumb-2 state a constant in the range -255 to 0"
+  (and (match_code "const_int")
+       (match_test "TARGET_THUMB2 && ival >= -255 && ival <= 0")))
+
 (define_constraint "G"
  "In ARM/Thumb-2 state a valid FPA immediate constant."
  (and (match_code "const_double")

=== modified file 'gcc/config/arm/thumb2.md'
--- old/gcc/config/arm/thumb2.md	2010-08-05 16:34:46 +0000
+++ new/gcc/config/arm/thumb2.md	2010-08-12 16:47:21 +0000
@@ -1241,6 +1241,56 @@
    (set_attr "length" "2")]
 )
 
+(define_insn "*thumb2_addsi3_compare0"
+  [(set (reg:CC_NOOV CC_REGNUM)
+	(compare:CC_NOOV
+	  (plus:SI (match_operand:SI 1 "s_register_operand" "l,  0, r")
+		   (match_operand:SI 2 "arm_add_operand"    "lPt,Ps,rIL"))
+	  (const_int 0)))
+   (set (match_operand:SI 0 "s_register_operand" "=l,l,r")
+	(plus:SI (match_dup 1) (match_dup 2)))]
+  "TARGET_THUMB2"
+  "*
+    HOST_WIDE_INT val;
+
+    if (GET_CODE (operands[2]) == CONST_INT)
+      val = INTVAL (operands[2]);
+    else
+      val = 0;
+
+    if (val < 0 && const_ok_for_arm (ARM_SIGN_EXTEND (-val)))
+      return \"subs\\t%0, %1, #%n2\";
+    else
+      return \"adds\\t%0, %1, %2\";
+  "
+  [(set_attr "conds" "set")
+   (set_attr "length" "2,2,4")]
+)
+
+(define_insn "*thumb2_addsi3_compare0_scratch"
+  [(set (reg:CC_NOOV CC_REGNUM)
+	(compare:CC_NOOV
+	  (plus:SI (match_operand:SI 0 "s_register_operand" "l,  r")
+		   (match_operand:SI 1 "arm_add_operand"    "lPv,rIL"))
+	  (const_int 0)))]
+  "TARGET_THUMB2"
+  "*
+    HOST_WIDE_INT val;
+
+    if (GET_CODE (operands[1]) == CONST_INT)
+      val = INTVAL (operands[1]);
+    else
+      val = 0;
+
+    if (val < 0 && const_ok_for_arm (ARM_SIGN_EXTEND (-val)))
+      return \"cmp\\t%0, #%n1\";
+    else
+      return \"cmn\\t%0, %1\";
+  "
+  [(set_attr "conds" "set")
+   (set_attr "length" "2,4")]
+)
+
 ;; 16-bit encodings of "muls" and "mul<c>".  We only use these when
 ;; optimizing for size since "muls" is slow on all known
 ;; implementations and since "mul<c>" will be generated by

