]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
predicates.md (addsubx_operand): New.
authorBob Wilson <bob.wilson@acm.org>
Fri, 17 Nov 2006 23:10:48 +0000 (23:10 +0000)
committerBob Wilson <bwilson@gcc.gnu.org>
Fri, 17 Nov 2006 23:10:48 +0000 (23:10 +0000)
* config/xtensa/predicates.md (addsubx_operand): New.
* config/xtensa/xtensa.c (xtensa_emit_branch): New.
(xtensa_emit_bit_branch): New.
(xtensa_emit_movcc): New.
* config/xtensa/xtensa.md (any_minmax): New code macro.
(minmax): New code attribute.
(any_cond, any_scc, any_scc_sf): New code macros.
(*addx2, *addx4, *addx8): Delete.
(*addx): New.
(*subx2, *subx4, *subx8): Delete.
(*subx): New.
(sminsi3, uminsi3, smaxsi3, umaxsi3): Use any_minmax macro.
(beq, bne, bgt, bge, blt, ble, bgtu, bgeu, bltu, bleu): Use any_cond.
(*btrue, *bfalse, *ubtrue, *ubfalse): Use xtensa_emit_branch.
(*bittrue, *bitfalse): Use xtensa_emit_bit_branch.
(seq, sne, sgt, sge, slt, sle): Use any_scc macro.
(movsicc_internal0, movsicc_internal1): Use xtensa_emit_movcc.
(movsfcc_internal0, movsfcc_internal1): Likewise.
(seq_sf, slt_sf, sle_sf): Use any_scc_sf macro.
* config/xtensa/xtensa-protos.h: (xtensa_emit_branch): New.
(xtensa_emit_bit_branch): New.
(xtensa_emit_movcc): New.
(function_arg_boundary): Add missing prototype.

From-SVN: r118952

gcc/ChangeLog
gcc/config/xtensa/predicates.md
gcc/config/xtensa/xtensa-protos.h
gcc/config/xtensa/xtensa.c
gcc/config/xtensa/xtensa.md

index 41d4378cb56781373b88ebd720e801f60af95703..d2fbac95742c3b866e5c5c4b0e27388719aec4a1 100644 (file)
@@ -1,3 +1,29 @@
+2006-11-17  Bob Wilson  <bob.wilson@acm.org>
+
+       * config/xtensa/predicates.md (addsubx_operand): New.
+       * config/xtensa/xtensa.c (xtensa_emit_branch): New.
+       (xtensa_emit_bit_branch): New.
+       (xtensa_emit_movcc): New.
+       * config/xtensa/xtensa.md (any_minmax): New code macro.
+       (minmax): New code attribute.
+       (any_cond, any_scc, any_scc_sf): New code macros.
+       (*addx2, *addx4, *addx8): Delete.
+       (*addx): New.
+       (*subx2, *subx4, *subx8): Delete.
+       (*subx): New.
+       (sminsi3, uminsi3, smaxsi3, umaxsi3): Use any_minmax macro.
+       (beq, bne, bgt, bge, blt, ble, bgtu, bgeu, bltu, bleu): Use any_cond.
+       (*btrue, *bfalse, *ubtrue, *ubfalse): Use xtensa_emit_branch.
+       (*bittrue, *bitfalse): Use xtensa_emit_bit_branch.
+       (seq, sne, sgt, sge, slt, sle): Use any_scc macro.
+       (movsicc_internal0, movsicc_internal1): Use xtensa_emit_movcc.
+       (movsfcc_internal0, movsfcc_internal1): Likewise.
+       (seq_sf, slt_sf, sle_sf): Use any_scc_sf macro.
+       * config/xtensa/xtensa-protos.h: (xtensa_emit_branch): New.
+       (xtensa_emit_bit_branch): New.
+       (xtensa_emit_movcc): New.
+       (function_arg_boundary): Add missing prototype.
+
 2006-11-17  Bob Wilson  <bob.wilson@acm.org>
 
        * config/xtensa/xtensa.md (tstsi): Delete
index 2beceacd2e142f396d7d060085fc81c213b19b3a..92326a787e03fda9452ebefecb6a3ff14ed8b8a6 100644 (file)
@@ -1,5 +1,5 @@
 ;; Predicate definitions for Xtensa.
-;; Copyright (C) 2005 Free Software Foundation, Inc.
+;; Copyright (C) 2005, 2006 Free Software Foundation, Inc.
 ;;
 ;; This file is part of GCC.
 ;;
                         || xtensa_simm8x256 (INTVAL (op))"))
        (match_operand 0 "register_operand")))
 
+(define_predicate "addsubx_operand"
+  (and (match_code "const_int")
+       (match_test "INTVAL (op) == 2
+                   || INTVAL (op) == 4
+                   || INTVAL (op) == 8")))
+
 (define_predicate "arith_operand"
   (ior (and (match_code "const_int")
            (match_test "xtensa_simm8 (INTVAL (op))"))
index 95442ab6b20b86385dd4ad7f5823d32f72370379..7f8ad2e8065b9712c7034a28cc1e0cbca211b167 100644 (file)
@@ -50,6 +50,9 @@ extern int xtensa_emit_move_sequence (rtx *, enum machine_mode);
 extern rtx xtensa_copy_incoming_a7 (rtx);
 extern void xtensa_expand_nonlocal_goto (rtx *);
 extern void xtensa_emit_loop_end (rtx, rtx *);
+extern char *xtensa_emit_branch (bool, bool, rtx *);
+extern char *xtensa_emit_bit_branch (bool, bool, rtx *);
+extern char *xtensa_emit_movcc (bool, bool, bool, rtx *);
 extern char *xtensa_emit_call (int, rtx *);
 
 #ifdef TREE_CODE
@@ -71,6 +74,7 @@ extern enum reg_class xtensa_secondary_reload_class (enum reg_class,
 extern void function_arg_advance (CUMULATIVE_ARGS *, enum machine_mode, tree);
 extern struct rtx_def *function_arg (CUMULATIVE_ARGS *, enum machine_mode,
                                     tree, int);
+extern int function_arg_boundary (enum machine_mode, tree);
 #endif /* TREE_CODE */
 
 extern void xtensa_setup_frame_addresses (void);
index 32c3ff2edbf2ea93f8684823c5b0d838574ada54..fa5f08d2d2335e307b9e7eacd6c3e12a38c3aed5 100644 (file)
@@ -1368,6 +1368,101 @@ xtensa_emit_loop_end (rtx insn, rtx *operands)
 }
 
 
+char *
+xtensa_emit_branch (bool inverted, bool immed, rtx *operands)
+{
+  static char result[64];
+  enum rtx_code code;
+  const char *op;
+
+  code = GET_CODE (operands[3]);
+  switch (code)
+    {
+    case EQ:   op = inverted ? "ne" : "eq"; break;
+    case NE:   op = inverted ? "eq" : "ne"; break;
+    case LT:   op = inverted ? "ge" : "lt"; break;
+    case GE:   op = inverted ? "lt" : "ge"; break;
+    case LTU:  op = inverted ? "geu" : "ltu"; break;
+    case GEU:  op = inverted ? "ltu" : "geu"; break;
+    default:   gcc_unreachable ();
+    }
+
+  if (immed)
+    {
+      if (INTVAL (operands[1]) == 0)
+       sprintf (result, "b%sz%s\t%%0, %%2", op,
+                (TARGET_DENSITY && (code == EQ || code == NE)) ? ".n" : "");
+      else
+       sprintf (result, "b%si\t%%0, %%d1, %%2", op);
+    }
+  else
+    sprintf (result, "b%s\t%%0, %%1, %%2", op);
+
+  return result;
+}
+
+
+char *
+xtensa_emit_bit_branch (bool inverted, bool immed, rtx *operands)
+{
+  static char result[64];
+  const char *op;
+
+  switch (GET_CODE (operands[3]))
+    {
+    case EQ:   op = inverted ? "bs" : "bc"; break;
+    case NE:   op = inverted ? "bc" : "bs"; break;
+    default:   gcc_unreachable ();
+    }
+
+  if (immed)
+    {
+      unsigned bitnum = INTVAL (operands[1]) & 0x1f; 
+      operands[1] = GEN_INT (bitnum); 
+      sprintf (result, "b%si\t%%0, %%d1, %%2", op);
+    }
+  else
+    sprintf (result, "b%s\t%%0, %%1, %%2", op);
+
+  return result;
+}
+
+
+char *
+xtensa_emit_movcc (bool inverted, bool isfp, bool isbool, rtx *operands)
+{
+  static char result[64];
+  enum rtx_code code;
+  const char *op;
+
+  code = GET_CODE (operands[4]);
+  if (isbool)
+    {
+      switch (code)
+       {
+       case EQ:        op = inverted ? "t" : "f"; break;
+       case NE:        op = inverted ? "f" : "t"; break;
+       default:        gcc_unreachable ();
+       }
+    }
+  else
+    {
+      switch (code)
+       {
+       case EQ:        op = inverted ? "nez" : "eqz"; break;
+       case NE:        op = inverted ? "eqz" : "nez"; break;
+       case LT:        op = inverted ? "gez" : "ltz"; break;
+       case GE:        op = inverted ? "ltz" : "gez"; break;
+       default:        gcc_unreachable ();
+       }
+    }
+
+  sprintf (result, "mov%s%s\t%%0, %%%d, %%1",
+          op, isfp ? ".s" : "", inverted ? 3 : 2);
+  return result;
+}
+
+
 char *
 xtensa_emit_call (int callop, rtx *operands)
 {
index 41d2754d51375bd667f7f73ff0585ae2c1035f39..c3f38cb93e809a72561fcb88067a6a7e1b6ac8f0 100644 (file)
 ;; <su> is like <u>, but the signed form expands to "s" rather than "".
 (define_code_attr su [(sign_extend "s") (zero_extend "u")])
 
+;; This code macro allows four integer min/max operations to be
+;; generated from one template.
+(define_code_macro any_minmax [smin umin smax umax])
+
+;; <minmax> expands to the opcode name for any_minmax operations.
+(define_code_attr minmax [(smin "min") (umin "minu")
+                         (smax "max") (umax "maxu")])
+
+;; This code macro allows all branch instructions to be generated from
+;; a single define_expand template.
+(define_code_macro any_cond [eq ne gt ge lt le gtu geu ltu leu])
+
+;; This code macro is for setting a register from a comparison.
+(define_code_macro any_scc [eq ne gt ge lt le])
+
+;; This code macro is for floating-point comparisons.
+(define_code_macro any_scc_sf [eq lt le])
+
 \f
 ;; Attributes.
 
    (set_attr "mode"    "SI")
    (set_attr "length"  "2,2,3,3,3")])
 
-(define_insn "*addx2"
+(define_insn "*addx"
   [(set (match_operand:SI 0 "register_operand" "=a")
        (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
-                         (const_int 2))
+                         (match_operand:SI 3 "addsubx_operand" "i"))
                 (match_operand:SI 2 "register_operand" "r")))]
   "TARGET_ADDX"
-  "addx2\t%0, %1, %2"
-  [(set_attr "type"    "arith")
-   (set_attr "mode"    "SI")
-   (set_attr "length"  "3")])
-
-(define_insn "*addx4"
-  [(set (match_operand:SI 0 "register_operand" "=a")
-       (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
-                         (const_int 4))
-                (match_operand:SI 2 "register_operand" "r")))]
-  "TARGET_ADDX"
-  "addx4\t%0, %1, %2"
-  [(set_attr "type"    "arith")
-   (set_attr "mode"    "SI")
-   (set_attr "length"  "3")])
-
-(define_insn "*addx8"
-  [(set (match_operand:SI 0 "register_operand" "=a")
-       (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
-                         (const_int 8))
-                (match_operand:SI 2 "register_operand" "r")))]
-  "TARGET_ADDX"
-  "addx8\t%0, %1, %2"
+  "addx%3\t%0, %1, %2"
   [(set_attr "type"    "arith")
    (set_attr "mode"    "SI")
    (set_attr "length"  "3")])
    (set_attr "mode"    "SI")
    (set_attr "length"  "3")])
 
-(define_insn "*subx2"
-  [(set (match_operand:SI 0 "register_operand" "=a")
-       (minus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
-                          (const_int 2))
-                 (match_operand:SI 2 "register_operand" "r")))]
-  "TARGET_ADDX"
-  "subx2\t%0, %1, %2"
-  [(set_attr "type"    "arith")
-   (set_attr "mode"    "SI")
-   (set_attr "length"  "3")])
-
-(define_insn "*subx4"
+(define_insn "*subx"
   [(set (match_operand:SI 0 "register_operand" "=a")
        (minus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
-                          (const_int 4))
+                          (match_operand:SI 3 "addsubx_operand" "i"))
                  (match_operand:SI 2 "register_operand" "r")))]
   "TARGET_ADDX"
-  "subx4\t%0, %1, %2"
-  [(set_attr "type"    "arith")
-   (set_attr "mode"    "SI")
-   (set_attr "length"  "3")])
-
-(define_insn "*subx8"
-  [(set (match_operand:SI 0 "register_operand" "=a")
-       (minus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
-                          (const_int 8))
-                 (match_operand:SI 2 "register_operand" "r")))]
-  "TARGET_ADDX"
-  "subx8\t%0, %1, %2"
+  "subx%3\t%0, %1, %2"
   [(set_attr "type"    "arith")
    (set_attr "mode"    "SI")
    (set_attr "length"  "3")])
 \f
 ;; Min and max.
 
-(define_insn "sminsi3"
+(define_insn "<code>si3"
   [(set (match_operand:SI 0 "register_operand" "=a")
-        (smin:SI (match_operand:SI 1 "register_operand" "%r")
-                 (match_operand:SI 2 "register_operand" "r")))]
+        (any_minmax:SI (match_operand:SI 1 "register_operand" "%r")
+                      (match_operand:SI 2 "register_operand" "r")))]
   "TARGET_MINMAX"
-  "min\t%0, %1, %2"
-  [(set_attr "type"    "arith")
-   (set_attr "mode"    "SI")
-   (set_attr "length"  "3")])
-
-(define_insn "uminsi3"
-  [(set (match_operand:SI 0 "register_operand" "=a")
-        (umin:SI (match_operand:SI 1 "register_operand" "%r")
-                 (match_operand:SI 2 "register_operand" "r")))]
-  "TARGET_MINMAX"
-  "minu\t%0, %1, %2"
-  [(set_attr "type"    "arith")
-   (set_attr "mode"    "SI")
-   (set_attr "length"  "3")])
-
-(define_insn "smaxsi3"
-  [(set (match_operand:SI 0 "register_operand" "=a")
-        (smax:SI (match_operand:SI 1 "register_operand" "%r")
-                 (match_operand:SI 2 "register_operand" "r")))]
-  "TARGET_MINMAX"
-  "max\t%0, %1, %2"
-  [(set_attr "type"    "arith")
-   (set_attr "mode"    "SI")
-   (set_attr "length"  "3")])
-
-(define_insn "umaxsi3"
-  [(set (match_operand:SI 0 "register_operand" "=a")
-        (umax:SI (match_operand:SI 1 "register_operand" "%r")
-                 (match_operand:SI 2 "register_operand" "r")))]
-  "TARGET_MINMAX"
-  "maxu\t%0, %1, %2"
+  "<minmax>\t%0, %1, %2"
   [(set_attr "type"    "arith")
    (set_attr "mode"    "SI")
    (set_attr "length"  "3")])
 \f
 ;; Conditional branches.
 
-(define_expand "beq"
-  [(set (pc)
-       (if_then_else (eq (cc0) (const_int 0))
-                     (label_ref (match_operand 0 "" ""))
-                     (pc)))]
-  ""
-{
-  xtensa_expand_conditional_branch (operands, EQ);
-  DONE;
-})
-
-(define_expand "bne"
-  [(set (pc)
-       (if_then_else (ne (cc0) (const_int 0))
-                     (label_ref (match_operand 0 "" ""))
-                     (pc)))]
-  ""
-{
-  xtensa_expand_conditional_branch (operands, NE);
-  DONE;
-})
-
-(define_expand "bgt"
-  [(set (pc)
-       (if_then_else (gt (cc0) (const_int 0))
-                     (label_ref (match_operand 0 "" ""))
-                     (pc)))]
-  ""
-{
-  xtensa_expand_conditional_branch (operands, GT);
-  DONE;
-})
-
-(define_expand "bge"
-  [(set (pc)
-       (if_then_else (ge (cc0) (const_int 0))
-                     (label_ref (match_operand 0 "" ""))
-                     (pc)))]
-  ""
-{
-  xtensa_expand_conditional_branch (operands, GE);
-  DONE;
-})
-
-(define_expand "blt"
+(define_expand "b<code>"
   [(set (pc)
-       (if_then_else (lt (cc0) (const_int 0))
+       (if_then_else (any_cond (cc0) (const_int 0))
                      (label_ref (match_operand 0 "" ""))
                      (pc)))]
   ""
 {
-  xtensa_expand_conditional_branch (operands, LT);
-  DONE;
-})
-
-(define_expand "ble"
-  [(set (pc)
-       (if_then_else (le (cc0) (const_int 0))
-                     (label_ref (match_operand 0 "" ""))
-                     (pc)))]
-  ""
-{
-  xtensa_expand_conditional_branch (operands, LE);
-  DONE;
-})
-
-(define_expand "bgtu"
-  [(set (pc)
-       (if_then_else (gtu (cc0) (const_int 0))
-                     (label_ref (match_operand 0 "" ""))
-                     (pc)))]
-  ""
-{
-  xtensa_expand_conditional_branch (operands, GTU);
-  DONE;
-})
-
-(define_expand "bgeu"
-  [(set (pc)
-       (if_then_else (geu (cc0) (const_int 0))
-                     (label_ref (match_operand 0 "" ""))
-                     (pc)))]
-  ""
-{
-  xtensa_expand_conditional_branch (operands, GEU);
-  DONE;
-})
-
-(define_expand "bltu"
-  [(set (pc)
-       (if_then_else (ltu (cc0) (const_int 0))
-                     (label_ref (match_operand 0 "" ""))
-                     (pc)))]
-  ""
-{
-  xtensa_expand_conditional_branch (operands, LTU);
-  DONE;
-})
-
-(define_expand "bleu"
-  [(set (pc)
-       (if_then_else (leu (cc0) (const_int 0))
-                     (label_ref (match_operand 0 "" ""))
-                     (pc)))]
-  ""
-{
-  xtensa_expand_conditional_branch (operands, LEU);
+  xtensa_expand_conditional_branch (operands, <CODE>);
   DONE;
 })
 
 (define_insn "*btrue"
   [(set (pc)
        (if_then_else (match_operator 3 "branch_operator"
-                        [(match_operand:SI 0 "register_operand" "r,r")
-                         (match_operand:SI 1 "branch_operand" "K,r")])
+                      [(match_operand:SI 0 "register_operand" "r,r")
+                       (match_operand:SI 1 "branch_operand" "K,r")])
                      (label_ref (match_operand 2 "" ""))
                      (pc)))]
   ""
 {
-  if (which_alternative == 1)
-    {
-      switch (GET_CODE (operands[3]))
-       {
-       case EQ:        return "beq\t%0, %1, %2";
-       case NE:        return "bne\t%0, %1, %2";
-       case LT:        return "blt\t%0, %1, %2";
-       case GE:        return "bge\t%0, %1, %2";
-       default:        gcc_unreachable ();
-       }
-    }
-  else if (INTVAL (operands[1]) == 0)
-    {
-      switch (GET_CODE (operands[3]))
-       {
-       case EQ:        return (TARGET_DENSITY
-                               ? "beqz.n\t%0, %2"
-                               : "beqz\t%0, %2");
-       case NE:        return (TARGET_DENSITY
-                               ? "bnez.n\t%0, %2"
-                               : "bnez\t%0, %2");
-       case LT:        return "bltz\t%0, %2";
-       case GE:        return "bgez\t%0, %2";
-       default:        gcc_unreachable ();
-       }
-    }
-  else
-    {
-      switch (GET_CODE (operands[3]))
-       {
-       case EQ:        return "beqi\t%0, %d1, %2";
-       case NE:        return "bnei\t%0, %d1, %2";
-       case LT:        return "blti\t%0, %d1, %2";
-       case GE:        return "bgei\t%0, %d1, %2";
-       default:        gcc_unreachable ();
-       }
-    }
-  gcc_unreachable ();
+  return xtensa_emit_branch (false, which_alternative == 0, operands);
 }
   [(set_attr "type"    "jump,jump")
    (set_attr "mode"    "none")
 (define_insn "*bfalse"
   [(set (pc)
        (if_then_else (match_operator 3 "branch_operator"
-                        [(match_operand:SI 0 "register_operand" "r,r")
-                         (match_operand:SI 1 "branch_operand" "K,r")])
+                      [(match_operand:SI 0 "register_operand" "r,r")
+                       (match_operand:SI 1 "branch_operand" "K,r")])
                      (pc)
                      (label_ref (match_operand 2 "" ""))))]
   ""
 {
-  if (which_alternative == 1)
-    {
-      switch (GET_CODE (operands[3]))
-       {
-       case EQ:        return "bne\t%0, %1, %2";
-       case NE:        return "beq\t%0, %1, %2";
-       case LT:        return "bge\t%0, %1, %2";
-       case GE:        return "blt\t%0, %1, %2";
-       default:        gcc_unreachable ();
-       }
-    }
-  else if (INTVAL (operands[1]) == 0)
-    {
-      switch (GET_CODE (operands[3]))
-       {
-       case EQ:        return (TARGET_DENSITY
-                               ? "bnez.n\t%0, %2"
-                               : "bnez\t%0, %2");
-       case NE:        return (TARGET_DENSITY
-                               ? "beqz.n\t%0, %2"
-                               : "beqz\t%0, %2");
-       case LT:        return "bgez\t%0, %2";
-       case GE:        return "bltz\t%0, %2";
-       default:        gcc_unreachable ();
-       }
-    }
-  else
-    {
-      switch (GET_CODE (operands[3]))
-       {
-       case EQ:        return "bnei\t%0, %d1, %2";
-       case NE:        return "beqi\t%0, %d1, %2";
-       case LT:        return "bgei\t%0, %d1, %2";
-       case GE:        return "blti\t%0, %d1, %2";
-       default:        gcc_unreachable ();
-       }
-    }
-  gcc_unreachable ();
+  return xtensa_emit_branch (true, which_alternative == 0, operands);
 }
   [(set_attr "type"    "jump,jump")
    (set_attr "mode"    "none")
 (define_insn "*ubtrue"
   [(set (pc)
        (if_then_else (match_operator 3 "ubranch_operator"
-                        [(match_operand:SI 0 "register_operand" "r,r")
-                         (match_operand:SI 1 "ubranch_operand" "L,r")])
+                      [(match_operand:SI 0 "register_operand" "r,r")
+                       (match_operand:SI 1 "ubranch_operand" "L,r")])
                      (label_ref (match_operand 2 "" ""))
                      (pc)))]
   ""
 {
-  if (which_alternative == 1)
-    {
-      switch (GET_CODE (operands[3]))
-       {
-       case LTU:       return "bltu\t%0, %1, %2";
-       case GEU:       return "bgeu\t%0, %1, %2";
-       default:        gcc_unreachable ();
-       }
-    }
-  else
-    {
-      switch (GET_CODE (operands[3]))
-       {
-       case LTU:       return "bltui\t%0, %d1, %2";
-       case GEU:       return "bgeui\t%0, %d1, %2";
-       default:        gcc_unreachable ();
-       }
-    }
-  gcc_unreachable ();
+  return xtensa_emit_branch (false, which_alternative == 0, operands);
 }
   [(set_attr "type"    "jump,jump")
    (set_attr "mode"    "none")
                      (label_ref (match_operand 2 "" ""))))]
   ""
 {
-  if (which_alternative == 1)
-    {
-      switch (GET_CODE (operands[3]))
-       {
-       case LTU:       return "bgeu\t%0, %1, %2";
-       case GEU:       return "bltu\t%0, %1, %2";
-       default:        gcc_unreachable ();
-       }
-    }
-  else
-    {
-      switch (GET_CODE (operands[3]))
-       {
-       case LTU:       return "bgeui\t%0, %d1, %2";
-       case GEU:       return "bltui\t%0, %d1, %2";
-       default:        gcc_unreachable ();
-       }
-    }
-  gcc_unreachable ();
+  return xtensa_emit_branch (true, which_alternative == 0, operands);
 }
   [(set_attr "type"    "jump,jump")
    (set_attr "mode"    "none")
                      (pc)))]
   ""
 {
-  if (which_alternative == 0)
-    {
-      unsigned bitnum = INTVAL(operands[1]) & 0x1f;
-      operands[1] = GEN_INT(bitnum);
-      switch (GET_CODE (operands[3]))
-       {
-       case EQ:        return "bbci\t%0, %d1, %2";
-       case NE:        return "bbsi\t%0, %d1, %2";
-       default:        gcc_unreachable ();
-       }
-    }
-  else
-    {
-      switch (GET_CODE (operands[3]))
-       {
-       case EQ:        return "bbc\t%0, %1, %2";
-       case NE:        return "bbs\t%0, %1, %2";
-       default:        gcc_unreachable ();
-       }
-    }
-  gcc_unreachable ();
+  return xtensa_emit_bit_branch (false, which_alternative == 0, operands);
 }
   [(set_attr "type"    "jump")
    (set_attr "mode"    "none")
                      (label_ref (match_operand 2 "" ""))))]
   ""
 {
-  if (which_alternative == 0)
-    {
-      unsigned bitnum = INTVAL (operands[1]) & 0x1f;
-      operands[1] = GEN_INT (bitnum);
-      switch (GET_CODE (operands[3]))
-       {
-       case EQ:        return "bbsi\t%0, %d1, %2";
-       case NE:        return "bbci\t%0, %d1, %2";
-       default:        gcc_unreachable ();
-       }
-    }
-  else
-    {
-      switch (GET_CODE (operands[3]))
-       {
-       case EQ:        return "bbs\t%0, %1, %2";
-       case NE:        return "bbc\t%0, %1, %2";
-       default:        gcc_unreachable ();
-       }
-    }
-  gcc_unreachable ();
+  return xtensa_emit_bit_branch (true, which_alternative == 0, operands);
 }
   [(set_attr "type"    "jump")
    (set_attr "mode"    "none")
 \f
 ;; Setting a register from a comparison.
 
-(define_expand "seq"
+(define_expand "s<code>"
   [(set (match_operand:SI 0 "register_operand" "")
-       (match_dup 1))]
+       (any_scc:SI (match_dup 1)
+                   (match_dup 2)))]
   ""
 {
-  operands[1] = gen_rtx_EQ (SImode, branch_cmp[0], branch_cmp[1]);
-  if (!xtensa_expand_scc (operands))
-    FAIL;
-  DONE;
-})
-
-(define_expand "sne"
-  [(set (match_operand:SI 0 "register_operand" "")
-       (match_dup 1))]
-  ""
-{
-  operands[1] = gen_rtx_NE (SImode, branch_cmp[0], branch_cmp[1]);
-  if (!xtensa_expand_scc (operands))
-    FAIL;
-  DONE;
-})
-
-(define_expand "sgt"
-  [(set (match_operand:SI 0 "register_operand" "")
-       (match_dup 1))]
-  ""
-{
-  operands[1] = gen_rtx_GT (SImode, branch_cmp[0], branch_cmp[1]);
-  if (!xtensa_expand_scc (operands))
-    FAIL;
-  DONE;
-})
-
-(define_expand "sge"
-  [(set (match_operand:SI 0 "register_operand" "")
-       (match_dup 1))]
-  ""
-{
-  operands[1] = gen_rtx_GE (SImode, branch_cmp[0], branch_cmp[1]);
-  if (!xtensa_expand_scc (operands))
-    FAIL;
-  DONE;
-})
-
-(define_expand "slt"
-  [(set (match_operand:SI 0 "register_operand" "")
-       (match_dup 1))]
-  ""
-{
-  operands[1] = gen_rtx_LT (SImode, branch_cmp[0], branch_cmp[1]);
-  if (!xtensa_expand_scc (operands))
-    FAIL;
-  DONE;
-})
-
-(define_expand "sle"
-  [(set (match_operand:SI 0 "register_operand" "")
-       (match_dup 1))]
-  ""
-{
-  operands[1] = gen_rtx_LE (SImode, branch_cmp[0], branch_cmp[1]);
+  operands[1] = gen_rtx_<CODE> (SImode, branch_cmp[0], branch_cmp[1]);
   if (!xtensa_expand_scc (operands))
     FAIL;
   DONE;
                         (match_operand:SI 3 "register_operand" "0,r")))]
   ""
 {
-  if (which_alternative == 0)
-    {
-      switch (GET_CODE (operands[4]))
-       {
-       case EQ:        return "moveqz\t%0, %2, %1";
-       case NE:        return "movnez\t%0, %2, %1";
-       case LT:        return "movltz\t%0, %2, %1";
-       case GE:        return "movgez\t%0, %2, %1";
-       default:        gcc_unreachable ();
-       }
-    }
-  else
-    {
-      switch (GET_CODE (operands[4]))
-       {
-       case EQ:        return "movnez\t%0, %3, %1";
-       case NE:        return "moveqz\t%0, %3, %1";
-       case LT:        return "movgez\t%0, %3, %1";
-       case GE:        return "movltz\t%0, %3, %1";
-       default:        gcc_unreachable ();
-       }
-    }
-  gcc_unreachable ();
+  return xtensa_emit_movcc (which_alternative == 1, false, false, operands);
 }
   [(set_attr "type"    "move,move")
    (set_attr "mode"    "SI")
                         (match_operand:SI 3 "register_operand" "0,r")))]
   "TARGET_BOOLEANS"
 {
-  int isEq = (GET_CODE (operands[4]) == EQ);
-  switch (which_alternative)
-    {
-    case 0:
-      if (isEq) return "movf\t%0, %2, %1";
-      return "movt\t%0, %2, %1";
-    case 1:
-      if (isEq) return "movt\t%0, %3, %1";
-      return "movf\t%0, %3, %1";
-    default:
-      gcc_unreachable ();
-    }
+  return xtensa_emit_movcc (which_alternative == 1, false, true, operands);
 }
   [(set_attr "type"    "move,move")
    (set_attr "mode"    "SI")
                         (match_operand:SF 3 "register_operand" "0,r,0,f")))]
   ""
 {
-  switch (which_alternative)
-    {
-    case 0:
-      switch (GET_CODE (operands[4]))
-       {
-       case EQ:        return "moveqz\t%0, %2, %1";
-       case NE:        return "movnez\t%0, %2, %1";
-       case LT:        return "movltz\t%0, %2, %1";
-       case GE:        return "movgez\t%0, %2, %1";
-       default:        gcc_unreachable ();
-       }
-      break;
-    case 1:
-      switch (GET_CODE (operands[4]))
-       {
-       case EQ:        return "movnez\t%0, %3, %1";
-       case NE:        return "moveqz\t%0, %3, %1";
-       case LT:        return "movgez\t%0, %3, %1";
-       case GE:        return "movltz\t%0, %3, %1";
-       default:        gcc_unreachable ();
-       }
-      break;
-    case 2:
-      switch (GET_CODE (operands[4]))
-       {
-       case EQ:        return "moveqz.s %0, %2, %1";
-       case NE:        return "movnez.s %0, %2, %1";
-       case LT:        return "movltz.s %0, %2, %1";
-       case GE:        return "movgez.s %0, %2, %1";
-       default:        gcc_unreachable ();
-       }
-      break;
-    case 3:
-      switch (GET_CODE (operands[4]))
-       {
-       case EQ:        return "movnez.s %0, %3, %1";
-       case NE:        return "moveqz.s %0, %3, %1";
-       case LT:        return "movgez.s %0, %3, %1";
-       case GE:        return "movltz.s %0, %3, %1";
-       default:        gcc_unreachable ();
-       }
-      break;
-    default:
-      gcc_unreachable ();
-    }
-  gcc_unreachable ();
+  return xtensa_emit_movcc ((which_alternative & 1) == 1,
+                           which_alternative >= 2, false, operands);
 }
   [(set_attr "type"    "move,move,move,move")
    (set_attr "mode"    "SF")
                         (match_operand:SF 3 "register_operand" "0,r,0,f")))]
   "TARGET_BOOLEANS"
 {
-  int isEq = (GET_CODE (operands[4]) == EQ);
-  switch (which_alternative)
-    {
-    case 0:
-      if (isEq) return "movf\t%0, %2, %1";
-      return "movt\t%0, %2, %1";
-    case 1:
-      if (isEq) return "movt\t%0, %3, %1";
-      return "movf\t%0, %3, %1";
-    case 2:
-      if (isEq) return "movf.s\t%0, %2, %1";
-      return "movt.s\t%0, %2, %1";
-    case 3:
-      if (isEq) return "movt.s\t%0, %3, %1";
-      return "movf.s\t%0, %3, %1";
-    default:
-      gcc_unreachable ();
-    }
+  return xtensa_emit_movcc ((which_alternative & 1) == 1,
+                           which_alternative >= 2, true, operands);
 }
   [(set_attr "type"    "move,move,move,move")
    (set_attr "mode"    "SF")
 \f
 ;; Floating-point comparisons.
 
-(define_insn "seq_sf"
-  [(set (match_operand:CC 0 "register_operand" "=b")
-       (eq:CC (match_operand:SF 1 "register_operand" "f")
-              (match_operand:SF 2 "register_operand" "f")))]
-  "TARGET_HARD_FLOAT"
-  "oeq.s\t%0, %1, %2"
-  [(set_attr "type"    "farith")
-   (set_attr "mode"    "BL")
-   (set_attr "length"  "3")])
-
-(define_insn "slt_sf"
-  [(set (match_operand:CC 0 "register_operand" "=b")
-       (lt:CC (match_operand:SF 1 "register_operand" "f")
-              (match_operand:SF 2 "register_operand" "f")))]
-  "TARGET_HARD_FLOAT"
-  "olt.s\t%0, %1, %2"
-  [(set_attr "type"    "farith")
-   (set_attr "mode"    "BL")
-   (set_attr "length"  "3")])
-
-(define_insn "sle_sf"
+(define_insn "s<code>_sf"
   [(set (match_operand:CC 0 "register_operand" "=b")
-       (le:CC (match_operand:SF 1 "register_operand" "f")
-              (match_operand:SF 2 "register_operand" "f")))]
+       (any_scc_sf:CC (match_operand:SF 1 "register_operand" "f")
+                      (match_operand:SF 2 "register_operand" "f")))]
   "TARGET_HARD_FLOAT"
-  "ole.s\t%0, %1, %2"
+  "o<code>.s\t%0, %1, %2"
   [(set_attr "type"    "farith")
    (set_attr "mode"    "BL")
    (set_attr "length"  "3")])