diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 126309259da4bb777152a734f4db78a8fbb20fb1..e57b0d3787dbbcc884004d7b36be3d9b84a5cf4a 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,39 @@
+2008-04-03  Adam Nemet  <anemet@caviumnetworks.com>
+
+	* config/mips/mips.md (any_gt, any_ge, any_lt, any_le): New code
+	iterators.
+	(u): Add attribute values for gt, gtu, ge, geu, lt, ltu, le and
+	leu.
+	(sgt<u>): Merge sgt and sgtu into new expander.
+	(sgt, sgtu): Remove expanders.
+	(*sgt<u>_<mode>): Merge *sgt_<mode> and *sgtu_<mode> into new
+	pattern.
+	(*sgt_<mode>, *sgtu_<mode>): Remove patterns.
+	(*sgt<u>_<mode>_mips16): Merge *sgt_<mode>_mips16 and
+	*sgtu_<mode>_mips16 into new pattern.
+	(*sgt_<mode>_mips16, *sgtu_<mode>_mips16): Remove patterns.
+	(sge<u>): Merge sge and sgeu into new expander.
+	(sge, sgeu): Remove expanders.
+	(*sge<u>_<mode>): Merge *sge_<mode> and second *sge_<mode> into
+	new pattern.
+	(*sge_<mode>, second *sge_<mode>): Remove patterns.
+	(slt<u>): Merge slt and sltu into new expander.
+	(slt, sltu): Remove expanders.
+	(*slt<u>_<mode>): Merge *slt_<mode> and *sltu_<mode> into new
+	pattern.
+	(*slt_<mode>, *sltu_<mode>): Remove patterns.
+	(*slt<u>_<mode>_mips16): Merge *slt_<mode>_mips16 and
+	*sltu_<mode>_mips16 into new pattern.
+	(*slt_<mode>_mips16, *sltu_<mode>_mips16): Remove patterns.
+	(sle<u>): Merge sle and sleu into new expander.
+	(sle, sleu): Remove expanders.
+	(*sle<u>_<mode>): Merge *sle_<mode> and *sleu_<mode> into new
+	pattern.
+	(*sle_<mode>, *sleu_<mode>): Remove patterns.
+	(*sle<u>_<mode>_mips16): Merge *sle_<mode>_mips16 and
+	*sleu_<mode>_mips16 into new pattern.
+	(*sle_<mode>_mips16, *sleu_<mode>_mips16): Remove patterns.
+
 2008-04-03  Jan Hubicka  <jh@suse.cz>
 
 	PR tree-optimization/35795
diff --git a/gcc/config/mips/mips.md b/gcc/config/mips/mips.md
index b5c66622c2ac28b0799308fd333301c8f73a78b6..2083cb9ff50380b02201010f0d7589507a8a49d7 100644
--- a/gcc/config/mips/mips.md
+++ b/gcc/config/mips/mips.md
@@ -610,9 +610,20 @@
 ;; by swapping the operands.
 (define_code_iterator swapped_fcond [ge gt unge ungt])
 
+;; These code iterators allow the signed and unsigned scc operations to use
+;; the same template.
+(define_code_iterator any_gt [gt gtu])
+(define_code_iterator any_ge [ge geu])
+(define_code_iterator any_lt [lt ltu])
+(define_code_iterator any_le [le leu])
+
 ;; <u> expands to an empty string when doing a signed operation and
 ;; "u" when doing an unsigned operation.
-(define_code_attr u [(sign_extend "") (zero_extend "u")])
+(define_code_attr u [(sign_extend "") (zero_extend "u")
+		     (gt "") (gtu "u")
+		     (ge "") (geu "u")
+		     (lt "") (ltu "u")
+		     (le "") (leu "u")])
 
 ;; <su> is like <u>, but the signed form expands to "s" rather than "".
 (define_code_attr su [(sign_extend "s") (zero_extend "u")])
@@ -5098,174 +5109,69 @@
   [(set_attr "type" "slt")
    (set_attr "mode" "<MODE>")])
 
-(define_expand "sgt"
-  [(set (match_operand:SI 0 "register_operand")
-	(gt:SI (match_dup 1)
-	       (match_dup 2)))]
-  ""
-  { if (mips_expand_scc (GT, operands[0])) DONE; else FAIL; })
-
-(define_insn "*sgt_<mode>"
-  [(set (match_operand:GPR 0 "register_operand" "=d")
-	(gt:GPR (match_operand:GPR 1 "register_operand" "d")
-		(match_operand:GPR 2 "reg_or_0_operand" "dJ")))]
-  "!TARGET_MIPS16"
-  "slt\t%0,%z2,%1"
-  [(set_attr "type" "slt")
-   (set_attr "mode" "<MODE>")])
-
-(define_insn "*sgt_<mode>_mips16"
-  [(set (match_operand:GPR 0 "register_operand" "=t")
-	(gt:GPR (match_operand:GPR 1 "register_operand" "d")
-		(match_operand:GPR 2 "register_operand" "d")))]
-  "TARGET_MIPS16"
-  "slt\t%2,%1"
-  [(set_attr "type" "slt")
-   (set_attr "mode" "<MODE>")])
-
-(define_expand "sge"
-  [(set (match_operand:SI 0 "register_operand")
-	(ge:SI (match_dup 1)
-	       (match_dup 2)))]
-  ""
-  { if (mips_expand_scc (GE, operands[0])) DONE; else FAIL; })
-
-(define_insn "*sge_<mode>"
-  [(set (match_operand:GPR 0 "register_operand" "=d")
-	(ge:GPR (match_operand:GPR 1 "register_operand" "d")
-		(const_int 1)))]
-  "!TARGET_MIPS16"
-  "slt\t%0,%.,%1"
-  [(set_attr "type" "slt")
-   (set_attr "mode" "<MODE>")])
-
-(define_expand "slt"
-  [(set (match_operand:SI 0 "register_operand")
-	(lt:SI (match_dup 1)
-	       (match_dup 2)))]
-  ""
-  { if (mips_expand_scc (LT, operands[0])) DONE; else FAIL; })
-
-(define_insn "*slt_<mode>"
-  [(set (match_operand:GPR 0 "register_operand" "=d")
-	(lt:GPR (match_operand:GPR 1 "register_operand" "d")
-		(match_operand:GPR 2 "arith_operand" "dI")))]
-  "!TARGET_MIPS16"
-  "slt\t%0,%1,%2"
-  [(set_attr "type" "slt")
-   (set_attr "mode" "<MODE>")])
-
-(define_insn "*slt_<mode>_mips16"
-  [(set (match_operand:GPR 0 "register_operand" "=t,t")
-	(lt:GPR (match_operand:GPR 1 "register_operand" "d,d")
-		(match_operand:GPR 2 "arith_operand" "d,I")))]
-  "TARGET_MIPS16"
-  "slt\t%1,%2"
-  [(set_attr "type" "slt")
-   (set_attr "mode" "<MODE>")
-   (set_attr_alternative "length"
-		[(const_int 4)
-		 (if_then_else (match_operand 2 "m16_uimm8_1")
-			       (const_int 4)
-			       (const_int 8))])])
-
-(define_expand "sle"
-  [(set (match_operand:SI 0 "register_operand")
-	(le:SI (match_dup 1)
-	       (match_dup 2)))]
-  ""
-  { if (mips_expand_scc (LE, operands[0])) DONE; else FAIL; })
-
-(define_insn "*sle_<mode>"
-  [(set (match_operand:GPR 0 "register_operand" "=d")
-	(le:GPR (match_operand:GPR 1 "register_operand" "d")
-		(match_operand:GPR 2 "sle_operand" "")))]
-  "!TARGET_MIPS16"
-{
-  operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
-  return "slt\t%0,%1,%2";
-}
-  [(set_attr "type" "slt")
-   (set_attr "mode" "<MODE>")])
-
-(define_insn "*sle_<mode>_mips16"
-  [(set (match_operand:GPR 0 "register_operand" "=t")
-	(le:GPR (match_operand:GPR 1 "register_operand" "d")
-		(match_operand:GPR 2 "sle_operand" "")))]
-  "TARGET_MIPS16"
-{
-  operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
-  return "slt\t%1,%2";
-}
-  [(set_attr "type" "slt")
-   (set_attr "mode" "<MODE>")
-   (set (attr "length") (if_then_else (match_operand 2 "m16_uimm8_m1_1")
-				      (const_int 4)
-				      (const_int 8)))])
-
-(define_expand "sgtu"
+(define_expand "sgt<u>"
   [(set (match_operand:SI 0 "register_operand")
-	(gtu:SI (match_dup 1)
-		(match_dup 2)))]
+	(any_gt:SI (match_dup 1)
+		   (match_dup 2)))]
   ""
-  { if (mips_expand_scc (GTU, operands[0])) DONE; else FAIL; })
+  { if (mips_expand_scc (<CODE>, operands[0])) DONE; else FAIL; })
 
-(define_insn "*sgtu_<mode>"
+(define_insn "*sgt<u>_<mode>"
   [(set (match_operand:GPR 0 "register_operand" "=d")
-	(gtu:GPR (match_operand:GPR 1 "register_operand" "d")
-		 (match_operand:GPR 2 "reg_or_0_operand" "dJ")))]
+	(any_gt:GPR (match_operand:GPR 1 "register_operand" "d")
+		    (match_operand:GPR 2 "reg_or_0_operand" "dJ")))]
   "!TARGET_MIPS16"
-  "sltu\t%0,%z2,%1"
+  "slt<u>\t%0,%z2,%1"
   [(set_attr "type" "slt")
    (set_attr "mode" "<MODE>")])
 
-(define_insn "*sgtu_<mode>_mips16"
+(define_insn "*sgt<u>_<mode>_mips16"
   [(set (match_operand:GPR 0 "register_operand" "=t")
-	(gtu:GPR (match_operand:GPR 1 "register_operand" "d")
-		 (match_operand:GPR 2 "register_operand" "d")))]
+	(any_gt:GPR (match_operand:GPR 1 "register_operand" "d")
+		    (match_operand:GPR 2 "register_operand" "d")))]
   "TARGET_MIPS16"
-  "sltu\t%2,%1"
+  "slt<u>\t%2,%1"
   [(set_attr "type" "slt")
    (set_attr "mode" "<MODE>")])
 
-(define_expand "sgeu"
+(define_expand "sge<u>"
   [(set (match_operand:SI 0 "register_operand")
-        (geu:SI (match_dup 1)
-                (match_dup 2)))]
+	(any_ge:SI (match_dup 1)
+		   (match_dup 2)))]
   ""
-  { if (mips_expand_scc (GEU, operands[0])) DONE; else FAIL; })
+  { if (mips_expand_scc (<CODE>, operands[0])) DONE; else FAIL; })
 
-(define_insn "*sge_<mode>"
+(define_insn "*sge<u>_<mode>"
   [(set (match_operand:GPR 0 "register_operand" "=d")
-	(geu:GPR (match_operand:GPR 1 "register_operand" "d")
-	         (const_int 1)))]
+	(any_ge:GPR (match_operand:GPR 1 "register_operand" "d")
+		    (const_int 1)))]
   "!TARGET_MIPS16"
-  "sltu\t%0,%.,%1"
+  "slt<u>\t%0,%.,%1"
   [(set_attr "type" "slt")
    (set_attr "mode" "<MODE>")])
 
-(define_expand "sltu"
+(define_expand "slt<u>"
   [(set (match_operand:SI 0 "register_operand")
-	(ltu:SI (match_dup 1)
-		(match_dup 2)))]
+	(any_lt:SI (match_dup 1)
+		   (match_dup 2)))]
   ""
-  { if (mips_expand_scc (LTU, operands[0])) DONE; else FAIL; })
+  { if (mips_expand_scc (<CODE>, operands[0])) DONE; else FAIL; })
 
-(define_insn "*sltu_<mode>"
+(define_insn "*slt<u>_<mode>"
   [(set (match_operand:GPR 0 "register_operand" "=d")
-	(ltu:GPR (match_operand:GPR 1 "register_operand" "d")
-		 (match_operand:GPR 2 "arith_operand" "dI")))]
+	(any_lt:GPR (match_operand:GPR 1 "register_operand" "d")
+		    (match_operand:GPR 2 "arith_operand" "dI")))]
   "!TARGET_MIPS16"
-  "sltu\t%0,%1,%2"
+  "slt<u>\t%0,%1,%2"
   [(set_attr "type" "slt")
    (set_attr "mode" "<MODE>")])
 
-(define_insn "*sltu_<mode>_mips16"
+(define_insn "*slt<u>_<mode>_mips16"
   [(set (match_operand:GPR 0 "register_operand" "=t,t")
-	(ltu:GPR (match_operand:GPR 1 "register_operand" "d,d")
-		 (match_operand:GPR 2 "arith_operand" "d,I")))]
+	(any_lt:GPR (match_operand:GPR 1 "register_operand" "d,d")
+		    (match_operand:GPR 2 "arith_operand" "d,I")))]
   "TARGET_MIPS16"
-  "sltu\t%1,%2"
+  "slt<u>\t%1,%2"
   [(set_attr "type" "slt")
    (set_attr "mode" "<MODE>")
    (set_attr_alternative "length"
@@ -5274,33 +5180,33 @@
 			       (const_int 4)
 			       (const_int 8))])])
 
-(define_expand "sleu"
+(define_expand "sle<u>"
   [(set (match_operand:SI 0 "register_operand")
-	(leu:SI (match_dup 1)
-		(match_dup 2)))]
+	(any_le:SI (match_dup 1)
+		   (match_dup 2)))]
   ""
-  { if (mips_expand_scc (LEU, operands[0])) DONE; else FAIL; })
+  { if (mips_expand_scc (<CODE>, operands[0])) DONE; else FAIL; })
 
-(define_insn "*sleu_<mode>"
+(define_insn "*sle<u>_<mode>"
   [(set (match_operand:GPR 0 "register_operand" "=d")
-	(leu:GPR (match_operand:GPR 1 "register_operand" "d")
-	         (match_operand:GPR 2 "sleu_operand" "")))]
+	(any_le:GPR (match_operand:GPR 1 "register_operand" "d")
+		    (match_operand:GPR 2 "sle_operand" "")))]
   "!TARGET_MIPS16"
 {
   operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
-  return "sltu\t%0,%1,%2";
+  return "slt<u>\t%0,%1,%2";
 }
   [(set_attr "type" "slt")
    (set_attr "mode" "<MODE>")])
 
-(define_insn "*sleu_<mode>_mips16"
+(define_insn "*sle<u>_<mode>_mips16"
   [(set (match_operand:GPR 0 "register_operand" "=t")
-	(leu:GPR (match_operand:GPR 1 "register_operand" "d")
-	         (match_operand:GPR 2 "sleu_operand" "")))]
+	(any_le:GPR (match_operand:GPR 1 "register_operand" "d")
+		    (match_operand:GPR 2 "sle_operand" "")))]
   "TARGET_MIPS16"
 {
   operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
-  return "sltu\t%1,%2";
+  return "slt<u>\t%1,%2";
 }
   [(set_attr "type" "slt")
    (set_attr "mode" "<MODE>")
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 59bc95a8e9e826351d668c2d070e9d7dce013b90..22d1cecdaa83dcba3fbe7073c347965be11fb81d 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+2008-04-03  Adam Nemet  <anemet@caviumnetworks.com>
+
+	* gcc.target/mips/scc-1.c: New test.
+
 2008-04-03  Richard Guenther  <rguenther@suse.de>
 
 	* gcc.dg/tree-ssa/vrp43.c: New testcase.
diff --git a/gcc/testsuite/gcc.target/mips/scc-1.c b/gcc/testsuite/gcc.target/mips/scc-1.c
new file mode 100644
index 0000000000000000000000000000000000000000..443b0bf7d170897119a8c38a067e4d93fcd68e90
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/scc-1.c
@@ -0,0 +1,35 @@
+/* { dg-do compile } */
+/* { dg-mips-options "-O -mips32" } */
+
+/* { dg-final { scan-assembler-times {slt	\$2,\$5,\$4} 1 } } */
+/* { dg-final { scan-assembler-times {sltu	\$2,\$5,\$4} 1 } } */
+/* { dg-final { scan-assembler-times {slt	\$5,\$4} 1 } } */
+/* { dg-final { scan-assembler-times {sltu	\$5,\$4} 1 } } */
+
+/* { dg-final { scan-assembler-times {slt	\$2,\$0,\$4} 1 } } */
+/* { dg-final { scan-assembler-times {sltu	\$2,\$0,\$4} 1 } } */
+
+/* { dg-final { scan-assembler-times {slt	\$2,\$4,\$5} 1 } } */
+/* { dg-final { scan-assembler-times {sltu	\$2,\$4,\$5} 1 } } */
+/* { dg-final { scan-assembler-times {slt	\$4,\$5} 1 } } */
+/* { dg-final { scan-assembler-times {sltu	\$4,\$5} 1 } } */
+
+/* { dg-final { scan-assembler-times {slt	\$2,\$4,23}  1 } } */
+/* { dg-final { scan-assembler-times {sltu	\$2,\$4,23}  1 } } */
+/* { dg-final { scan-assembler-times {slt	\$4,23}  1 } } */
+/* { dg-final { scan-assembler-times {sltu	\$4,23}  1 } } */
+
+#define TEST(N, LHS, REL, RHS) \
+  NOMIPS16 int s##N (int a, int b) { return LHS REL RHS; } \
+  NOMIPS16 int u##N (unsigned a, unsigned b) { return LHS REL RHS; } \
+  MIPS16 int s##N##_16 (int a, int b) { return LHS REL RHS; } \
+  MIPS16 int u##N##_16 (unsigned a, unsigned b) { return LHS REL RHS; }
+
+#define TEST_NO16(N, LHS, REL, RHS) \
+  NOMIPS16 int s##N (int a, int b) { return LHS REL RHS; } \
+  NOMIPS16 int u##N (unsigned a, unsigned b) { return LHS REL RHS; }
+
+TEST (1, a, >, b);
+TEST_NO16 (2, a, >=, 1);
+TEST (3, a, <, b);
+TEST (4, a, <=, 22);