OSDN Git Service

* config/sparc/sparc-protos.h (gen_compare_operator): Declare.
authorebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 21 Sep 2008 19:25:48 +0000 (19:25 +0000)
committerebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 21 Sep 2008 19:25:48 +0000 (19:25 +0000)
(sparc_emit_float_lib_cmp): Change return type.
* config/sparc/sparc.c (gen_compare_reg): Add comment about TFmode.
(gen_compare_operator): New function.
(sparc_emit_float_lib_cmp): Return the new operator to be used in
the comparison sequence.  Minor tweaks.
* config/sparc/sparc.md (seq, sne, sgt, slt, sge, sle): Assert
that the final operator and the result of sparc_emit_float_lib_cmp
match for software TFmode; use emit_insn in lieu of emit_jump_insn.
(beq, bne, bgt, blt, bge, ble, bunordered, bordered, bungt, bunlt,
buneq, bunge, bunle, bltgt): Assert that the final operator and the
result of sparc_emit_float_lib_cmp match for software TFmode.
(movqicc, movhicc, movsicc, movdicc): Merge into...
(mov<I:mode>cc): ...this.
(movsfcc, movdfcc, movtfcc): Merge into...
(mov<F:mode>cc): ...this.
(movqi_cc_sp64, movhi_cc_sp64, movsi_cc_sp64, movdi_cc_sp64): Merge
into...
(mov<I:mode>_cc_v9): ...this.
(movdi_cc_sp64_trunc): Delete.
(movqi_cc_reg_sp64, movhi_cc_reg_sp64, movsi_cc_reg_sp64,
movdi_cc_reg_sp64): Merge into...
(mov<I:mode>_cc_reg_sp64): ...this.
(movsf_cc_sp64): Rename into...
(movsf_cc_v9): ...this.
(movdf_cc_sp64): Rename into...
(movdf_cc_v9): ...this.
(movtf_cc_hq_sp64): Rename into...
(movtf_cc_hq_v9): ...this.
(movtf_cc_sp64): Rename into...
(movtf_cc_v9): ...this.  Adjust for renaming of movdf_cc_sp64.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@140530 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/config/sparc/sparc-protos.h
gcc/config/sparc/sparc.c
gcc/config/sparc/sparc.md

index ebb8875..8a1603e 100644 (file)
@@ -1,3 +1,37 @@
+2008-09-21  Eric Botcazou  <ebotcazou@adacore.com>
+
+       * config/sparc/sparc-protos.h (gen_compare_operator): Declare.
+       (sparc_emit_float_lib_cmp): Change return type.
+       * config/sparc/sparc.c (gen_compare_reg): Add comment about TFmode.
+       (gen_compare_operator): New function.
+       (sparc_emit_float_lib_cmp): Return the new operator to be used in
+       the comparison sequence.  Minor tweaks.
+       * config/sparc/sparc.md (seq, sne, sgt, slt, sge, sle): Assert
+       that the final operator and the result of sparc_emit_float_lib_cmp
+       match for software TFmode; use emit_insn in lieu of emit_jump_insn.
+       (beq, bne, bgt, blt, bge, ble, bunordered, bordered, bungt, bunlt,
+       buneq, bunge, bunle, bltgt): Assert that the final operator and the
+       result of sparc_emit_float_lib_cmp match for software TFmode.
+       (movqicc, movhicc, movsicc, movdicc): Merge into...
+       (mov<I:mode>cc): ...this.
+       (movsfcc, movdfcc, movtfcc): Merge into...
+       (mov<F:mode>cc): ...this.
+       (movqi_cc_sp64, movhi_cc_sp64, movsi_cc_sp64, movdi_cc_sp64): Merge
+       into...
+       (mov<I:mode>_cc_v9): ...this.
+       (movdi_cc_sp64_trunc): Delete.
+       (movqi_cc_reg_sp64, movhi_cc_reg_sp64, movsi_cc_reg_sp64,
+       movdi_cc_reg_sp64): Merge into...
+       (mov<I:mode>_cc_reg_sp64): ...this.
+       (movsf_cc_sp64): Rename into...
+       (movsf_cc_v9): ...this.
+       (movdf_cc_sp64): Rename into...
+       (movdf_cc_v9): ...this.
+       (movtf_cc_hq_sp64): Rename into...
+       (movtf_cc_hq_v9): ...this.
+       (movtf_cc_sp64): Rename into...
+       (movtf_cc_v9): ...this.  Adjust for renaming of movdf_cc_sp64.
+
 2008-09-21  Diego Novillo  <dnovillo@google.com>
 
        * doc/gccint.texi: Include generic.texi and gimple.texi.
index 7c56925..a15837f 100644 (file)
@@ -54,7 +54,8 @@ extern void sparc_output_scratch_registers (FILE *);
 extern enum machine_mode select_cc_mode (enum rtx_code, rtx, rtx);
 /* Define the function that build the compare insn for scc and bcc.  */
 extern rtx gen_compare_reg (enum rtx_code code);
-extern void sparc_emit_float_lib_cmp (rtx, rtx, enum rtx_code);
+extern rtx gen_compare_operator (enum rtx_code code);
+extern enum rtx_code sparc_emit_float_lib_cmp (rtx, rtx, enum rtx_code);
 extern void sparc_emit_floatunsdi (rtx [2], enum machine_mode);
 extern void sparc_emit_fixunsdi (rtx [2], enum machine_mode);
 extern void emit_tfmode_binop (enum rtx_code, rtx *);
index 0852cd9..fd56653 100644 (file)
@@ -2001,8 +2001,7 @@ select_cc_mode (enum rtx_code op, rtx x, rtx y ATTRIBUTE_UNUSED)
     }
 }
 
-/* X and Y are two things to compare using CODE.  Emit the compare insn and
-   return the rtx for the cc reg in the proper mode.  */
+/* Emit the compare insn and return the CC reg for a CODE comparison.  */
 
 rtx
 gen_compare_reg (enum rtx_code code)
@@ -2065,12 +2064,28 @@ gen_compare_reg (enum rtx_code code)
   else
     cc_reg = gen_rtx_REG (mode, SPARC_ICC_REG);
 
-  emit_insn (gen_rtx_SET (VOIDmode, cc_reg,
-                         gen_rtx_COMPARE (mode, x, y)));
+  /* We shouldn't get there for TFmode if !TARGET_HARD_QUAD.  If we do, this
+     will only result in an unrecognizable insn so no point in asserting.  */
+  emit_insn (gen_rtx_SET (VOIDmode, cc_reg, gen_rtx_COMPARE (mode, x, y)));
 
   return cc_reg;
 }
 
+/* Same as above but return the whole compare operator.  */
+
+rtx
+gen_compare_operator (enum rtx_code code)
+{
+  rtx cc_reg;
+
+  if (GET_MODE (sparc_compare_op0) == TFmode && !TARGET_HARD_QUAD)
+    code
+      = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, code);
+
+  cc_reg = gen_compare_reg (code);
+  return gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
+}
+
 /* This function is used for v9 only.
    CODE is the code for an Scc's comparison.
    OPERANDS[0] is the target of the Scc insn.
@@ -6099,41 +6114,45 @@ output_cbranch (rtx op, rtx dest, int label, int reversed, int annul,
 }
 
 /* Emit a library call comparison between floating point X and Y.
-   COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.).
+   COMPARISON is the operator to compare with (EQ, NE, GT, etc).
+   Return the new operator to be used in the comparison sequence.
+
    TARGET_ARCH64 uses _Qp_* functions, which use pointers to TFmode
    values as arguments instead of the TFmode registers themselves,
    that's why we cannot call emit_float_lib_cmp.  */
-void
+
+enum rtx_code
 sparc_emit_float_lib_cmp (rtx x, rtx y, enum rtx_code comparison)
 {
   const char *qpfunc;
   rtx slot0, slot1, result, tem, tem2;
   enum machine_mode mode;
+  enum rtx_code new_comparison;
 
   switch (comparison)
     {
     case EQ:
-      qpfunc = (TARGET_ARCH64) ? "_Qp_feq" : "_Q_feq";
+      qpfunc = (TARGET_ARCH64 ? "_Qp_feq" : "_Q_feq");
       break;
 
     case NE:
-      qpfunc = (TARGET_ARCH64) ? "_Qp_fne" : "_Q_fne";
+      qpfunc = (TARGET_ARCH64 ? "_Qp_fne" : "_Q_fne");
       break;
 
     case GT:
-      qpfunc = (TARGET_ARCH64) ? "_Qp_fgt" : "_Q_fgt";
+      qpfunc = (TARGET_ARCH64 ? "_Qp_fgt" : "_Q_fgt");
       break;
 
     case GE:
-      qpfunc = (TARGET_ARCH64) ? "_Qp_fge" : "_Q_fge";
+      qpfunc = (TARGET_ARCH64 ? "_Qp_fge" : "_Q_fge");
       break;
 
     case LT:
-      qpfunc = (TARGET_ARCH64) ? "_Qp_flt" : "_Q_flt";
+      qpfunc = (TARGET_ARCH64 ? "_Qp_flt" : "_Q_flt");
       break;
 
     case LE:
-      qpfunc = (TARGET_ARCH64) ? "_Qp_fle" : "_Q_fle";
+      qpfunc = (TARGET_ARCH64 ? "_Qp_fle" : "_Q_fle");
       break;
 
     case ORDERED:
@@ -6144,7 +6163,7 @@ sparc_emit_float_lib_cmp (rtx x, rtx y, enum rtx_code comparison)
     case UNGE:
     case UNLE:
     case LTGT:
-      qpfunc = (TARGET_ARCH64) ? "_Qp_cmp" : "_Q_cmp";
+      qpfunc = (TARGET_ARCH64 ? "_Qp_cmp" : "_Q_cmp");
       break;
 
     default:
@@ -6153,27 +6172,26 @@ sparc_emit_float_lib_cmp (rtx x, rtx y, enum rtx_code comparison)
 
   if (TARGET_ARCH64)
     {
-      if (GET_CODE (x) != MEM)
+      if (MEM_P (x))
+       slot0 = x;
+      else
        {
          slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
          emit_move_insn (slot0, x);
        }
-      else
-       slot0 = x;
 
-      if (GET_CODE (y) != MEM)
+      if (MEM_P (y))
+       slot1 = y;
+      else
        {
          slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
          emit_move_insn (slot1, y);
        }
-      else
-       slot1 = y;
 
       emit_library_call (gen_rtx_SYMBOL_REF (Pmode, qpfunc), LCT_NORMAL,
                         DImode, 2,
                         XEXP (slot0, 0), Pmode,
                         XEXP (slot1, 0), Pmode);
-
       mode = DImode;
     }
   else
@@ -6181,7 +6199,6 @@ sparc_emit_float_lib_cmp (rtx x, rtx y, enum rtx_code comparison)
       emit_library_call (gen_rtx_SYMBOL_REF (Pmode, qpfunc), LCT_NORMAL,
                         SImode, 2,
                         x, TFmode, y, TFmode);
-
       mode = SImode;
     }
 
@@ -6195,20 +6212,22 @@ sparc_emit_float_lib_cmp (rtx x, rtx y, enum rtx_code comparison)
   switch (comparison)
     {
     default:
-      emit_cmp_insn (result, const0_rtx, NE, NULL_RTX, mode, 0);
+      new_comparison = NE;
+      emit_cmp_insn (result, const0_rtx, new_comparison, NULL_RTX, mode, 0);
       break;
     case ORDERED:
     case UNORDERED:
-      emit_cmp_insn (result, GEN_INT(3), comparison == UNORDERED ? EQ : NE,
-                    NULL_RTX, mode, 0);
+      new_comparison = (comparison == UNORDERED ? EQ : NE);
+      emit_cmp_insn (result, GEN_INT(3), new_comparison, NULL_RTX, mode, 0);
       break;
     case UNGT:
     case UNGE:
-      emit_cmp_insn (result, const1_rtx,
-                    comparison == UNGT ? GT : NE, NULL_RTX, mode, 0);
+      new_comparison = (comparison == UNGT ? GT : NE);
+      emit_cmp_insn (result, const1_rtx, new_comparison, NULL_RTX, mode, 0);
       break;
     case UNLE:
-      emit_cmp_insn (result, const2_rtx, NE, NULL_RTX, mode, 0);
+      new_comparison = NE;
+      emit_cmp_insn (result, const2_rtx, new_comparison, NULL_RTX, mode, 0);
       break;
     case UNLT:
       tem = gen_reg_rtx (mode);
@@ -6216,7 +6235,8 @@ sparc_emit_float_lib_cmp (rtx x, rtx y, enum rtx_code comparison)
        emit_insn (gen_andsi3 (tem, result, const1_rtx));
       else
        emit_insn (gen_anddi3 (tem, result, const1_rtx));
-      emit_cmp_insn (tem, const0_rtx, NE, NULL_RTX, mode, 0);
+      new_comparison = NE;
+      emit_cmp_insn (tem, const0_rtx, new_comparison, NULL_RTX, mode, 0);
       break;
     case UNEQ:
     case LTGT:
@@ -6230,10 +6250,12 @@ sparc_emit_float_lib_cmp (rtx x, rtx y, enum rtx_code comparison)
        emit_insn (gen_andsi3 (tem2, tem, const2_rtx));
       else
        emit_insn (gen_anddi3 (tem2, tem, const2_rtx));
-      emit_cmp_insn (tem2, const0_rtx, comparison == UNEQ ? EQ : NE,
-                    NULL_RTX, mode, 0);
+      new_comparison = (comparison == UNEQ ? EQ : NE);
+      emit_cmp_insn (tem2, const0_rtx, new_comparison, NULL_RTX, mode, 0);
       break;
     }
+
+  return new_comparison;
 }
 
 /* Generate an unsigned DImode to FP conversion.  This is the same code
index bc29bcf..d0b7389 100644 (file)
     }
   else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
     {
-      sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, EQ);
-      emit_jump_insn (gen_sne (operands[0]));
+      enum rtx_code code
+        = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, EQ);
+      gcc_assert (code == NE);
+      emit_insn (gen_sne (operands[0]));
       DONE;
     }
   else if (TARGET_V9)
     }
   else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
     {
-      sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, NE);
-      emit_jump_insn (gen_sne (operands[0]));
+      enum rtx_code code
+        = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, NE);
+      gcc_assert (code == NE);
+      emit_insn (gen_sne (operands[0]));
       DONE;
     }
   else if (TARGET_V9)
 {
   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
     {
-      sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GT);
-      emit_jump_insn (gen_sne (operands[0]));
+      enum rtx_code code
+        = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GT);
+      gcc_assert (code == NE);
+      emit_insn (gen_sne (operands[0]));
       DONE;
     }
   else if (TARGET_V9)
 {
   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
     {
-      sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LT);
-      emit_jump_insn (gen_sne (operands[0]));
+      enum rtx_code code
+        = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LT);
+      gcc_assert (code == NE);
+      emit_insn (gen_sne (operands[0]));
       DONE;
     }
   else if (TARGET_V9)
 {
   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
     {
-      sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GE);
-      emit_jump_insn (gen_sne (operands[0]));
+      enum rtx_code code
+        = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GE);
+      gcc_assert (code == NE);
+      emit_insn (gen_sne (operands[0]));
       DONE;
     }
   else if (TARGET_V9)
 {
   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
     {
-      sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LE);
-      emit_jump_insn (gen_sne (operands[0]));
+      enum rtx_code code
+        = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LE);
+      gcc_assert (code == NE);
+      emit_insn (gen_sne (operands[0]));
       DONE;
     }
   else if (TARGET_V9)
     }
   else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
     {
-      sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, EQ);
+      enum rtx_code code
+        = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, EQ);
+      gcc_assert (code == NE);
       emit_jump_insn (gen_bne (operands[0]));
       DONE;
     }
     }
   else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
     {
-      sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, NE);
+      enum rtx_code code
+        = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, NE);
+      gcc_assert (code == NE);
       emit_jump_insn (gen_bne (operands[0]));
       DONE;
     }
     }
   else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
     {
-      sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GT);
+      enum rtx_code code
+        = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GT);
+      gcc_assert (code == NE);
       emit_jump_insn (gen_bne (operands[0]));
       DONE;
     }
     }
   else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
     {
-      sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LT);
+      enum rtx_code code
+        = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LT);
+      gcc_assert (code == NE);
       emit_jump_insn (gen_bne (operands[0]));
       DONE;
     }
     }
   else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
     {
-      sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GE);
+      enum rtx_code code
+        = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GE);
+      gcc_assert (code == NE);
       emit_jump_insn (gen_bne (operands[0]));
       DONE;
     }
     }
   else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
     {
-      sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LE);
+      enum rtx_code code
+        = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LE);
+      gcc_assert (code == NE);
       emit_jump_insn (gen_bne (operands[0]));
       DONE;
     }
 {
   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
     {
-      sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1,
-                               UNORDERED);
+      enum rtx_code code
+        = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNORDERED);
+      gcc_assert (code == EQ);
       emit_jump_insn (gen_beq (operands[0]));
       DONE;
     }
 {
   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
     {
-      sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, ORDERED);
+      enum rtx_code code
+        = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, ORDERED);
+      gcc_assert (code == NE);
       emit_jump_insn (gen_bne (operands[0]));
       DONE;
     }
 {
   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
     {
-      sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNGT);
+      enum rtx_code code
+        = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNGT);
+      gcc_assert (code == GT);
       emit_jump_insn (gen_bgt (operands[0]));
       DONE;
     }
 {
   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
     {
-      sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNLT);
+      enum rtx_code code
+        = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNLT);
+      gcc_assert (code == NE);
       emit_jump_insn (gen_bne (operands[0]));
       DONE;
     }
 {
   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
     {
-      sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNEQ);
+      enum rtx_code code
+        = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNEQ);
+      gcc_assert (code == EQ);
       emit_jump_insn (gen_beq (operands[0]));
       DONE;
     }
 {
   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
     {
-      sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNGE);
+      enum rtx_code code
+        = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNGE);
+      gcc_assert (code == NE);
       emit_jump_insn (gen_bne (operands[0]));
       DONE;
     }
 {
   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
     {
-      sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNLE);
+      enum rtx_code code
+        = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNLE);
+      gcc_assert (code == NE);
       emit_jump_insn (gen_bne (operands[0]));
       DONE;
     }
 {
   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
     {
-      sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LTGT);
+      enum rtx_code code
+        = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LTGT);
+      gcc_assert (code == NE);
       emit_jump_insn (gen_bne (operands[0]));
       DONE;
     }
 })
 
 
-;; SPARC-V9 conditional move instructions.
+;; SPARC-V9 conditional move instructions
 
 ;; We can handle larger constants here for some flavors, but for now we keep
 ;; it simple and only allow those constants supported by all flavors.
 ;; 3 contains the constant if one is present, but we handle either for
 ;; generality (sparc.c puts a constant in operand 2).
 
-(define_expand "movqicc"
-  [(set (match_operand:QI 0 "register_operand" "")
-       (if_then_else:QI (match_operand 1 "comparison_operator" "")
-                        (match_operand:QI 2 "arith10_operand" "")
-                        (match_operand:QI 3 "arith10_operand" "")))]
-  "TARGET_V9"
-{
-  enum rtx_code code = GET_CODE (operands[1]);
-
-  if (GET_MODE (sparc_compare_op0) == DImode
-      && ! TARGET_ARCH64)
-    FAIL;
-
-  if (sparc_compare_op1 == const0_rtx
-      && GET_CODE (sparc_compare_op0) == REG
-      && GET_MODE (sparc_compare_op0) == DImode
-      && v9_regcmp_p (code))
-    {
-      operands[1] = gen_rtx_fmt_ee (code, DImode,
-                            sparc_compare_op0, sparc_compare_op1);
-    }
-  else
-    {
-      rtx cc_reg = gen_compare_reg (code);
-      operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
-    }
-})
+(define_mode_iterator I [QI HI SI DI])
 
-(define_expand "movhicc"
-  [(set (match_operand:HI 0 "register_operand" "")
-       (if_then_else:HI (match_operand 1 "comparison_operator" "")
-                        (match_operand:HI 2 "arith10_operand" "")
-                        (match_operand:HI 3 "arith10_operand" "")))]
-  "TARGET_V9"
+(define_expand "mov<I:mode>cc"
+  [(set (match_operand:I 0 "register_operand" "")
+       (if_then_else:I (match_operand 1 "comparison_operator" "")
+                       (match_operand:I 2 "arith10_operand" "")
+                       (match_operand:I 3 "arith10_operand" "")))]
+  "TARGET_V9 && !(<I:MODE>mode == DImode && TARGET_ARCH32)"
 {
   enum rtx_code code = GET_CODE (operands[1]);
 
       && GET_CODE (sparc_compare_op0) == REG
       && GET_MODE (sparc_compare_op0) == DImode
       && v9_regcmp_p (code))
-    {
-      operands[1] = gen_rtx_fmt_ee (code, DImode,
-                            sparc_compare_op0, sparc_compare_op1);
-    }
-  else
-    {
-      rtx cc_reg = gen_compare_reg (code);
-      operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
-    }
-})
-
-(define_expand "movsicc"
-  [(set (match_operand:SI 0 "register_operand" "")
-       (if_then_else:SI (match_operand 1 "comparison_operator" "")
-                        (match_operand:SI 2 "arith10_operand" "")
-                        (match_operand:SI 3 "arith10_operand" "")))]
-  "TARGET_V9"
-{
-  enum rtx_code code = GET_CODE (operands[1]);
-  enum machine_mode op0_mode = GET_MODE (sparc_compare_op0);
-
-  if (sparc_compare_op1 == const0_rtx
-      && GET_CODE (sparc_compare_op0) == REG
-      && (TARGET_ARCH64 && op0_mode == DImode && v9_regcmp_p (code)))
-    {
-      operands[1] = gen_rtx_fmt_ee (code, op0_mode,
-                            sparc_compare_op0, sparc_compare_op1);
-    }
+    operands[1] = gen_rtx_fmt_ee (code, DImode, sparc_compare_op0, const0_rtx);
   else
-    {
-      rtx cc_reg = gen_compare_reg (code);
-      operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg),
-                                   cc_reg, const0_rtx);
-    }
+    operands[1] = gen_compare_operator (code);
 })
 
-(define_expand "movdicc"
-  [(set (match_operand:DI 0 "register_operand" "")
-       (if_then_else:DI (match_operand 1 "comparison_operator" "")
-                        (match_operand:DI 2 "arith10_operand" "")
-                        (match_operand:DI 3 "arith10_operand" "")))]
-  "TARGET_ARCH64"
-{
-  enum rtx_code code = GET_CODE (operands[1]);
-
-  if (sparc_compare_op1 == const0_rtx
-      && GET_CODE (sparc_compare_op0) == REG
-      && GET_MODE (sparc_compare_op0) == DImode
-      && v9_regcmp_p (code))
-    {
-      operands[1] = gen_rtx_fmt_ee (code, DImode,
-                            sparc_compare_op0, sparc_compare_op1);
-    }
-  else
-    {
-      rtx cc_reg = gen_compare_reg (code);
-      operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg),
-                                   cc_reg, const0_rtx);
-    }
-})
+(define_mode_iterator F [SF DF TF])
 
-(define_expand "movsfcc"
-  [(set (match_operand:SF 0 "register_operand" "")
-       (if_then_else:SF (match_operand 1 "comparison_operator" "")
-                        (match_operand:SF 2 "register_operand" "")
-                        (match_operand:SF 3 "register_operand" "")))]
+(define_expand "mov<F:mode>cc"
+  [(set (match_operand:F 0 "register_operand" "")
+       (if_then_else:F (match_operand 1 "comparison_operator" "")
+                       (match_operand:F 2 "register_operand" "")
+                       (match_operand:F 3 "register_operand" "")))]
   "TARGET_V9 && TARGET_FPU"
 {
   enum rtx_code code = GET_CODE (operands[1]);
       && GET_CODE (sparc_compare_op0) == REG
       && GET_MODE (sparc_compare_op0) == DImode
       && v9_regcmp_p (code))
-    {
-      operands[1] = gen_rtx_fmt_ee (code, DImode,
-                            sparc_compare_op0, sparc_compare_op1);
-    }
+    operands[1] = gen_rtx_fmt_ee (code, DImode, sparc_compare_op0, const0_rtx);
   else
-    {
-      rtx cc_reg = gen_compare_reg (code);
-      operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
-    }
+    operands[1] = gen_compare_operator (code);
 })
 
-(define_expand "movdfcc"
-  [(set (match_operand:DF 0 "register_operand" "")
-       (if_then_else:DF (match_operand 1 "comparison_operator" "")
-                        (match_operand:DF 2 "register_operand" "")
-                        (match_operand:DF 3 "register_operand" "")))]
-  "TARGET_V9 && TARGET_FPU"
-{
-  enum rtx_code code = GET_CODE (operands[1]);
-
-  if (GET_MODE (sparc_compare_op0) == DImode
-      && ! TARGET_ARCH64)
-    FAIL;
-
-  if (sparc_compare_op1 == const0_rtx
-      && GET_CODE (sparc_compare_op0) == REG
-      && GET_MODE (sparc_compare_op0) == DImode
-      && v9_regcmp_p (code))
-    {
-      operands[1] = gen_rtx_fmt_ee (code, DImode,
-                            sparc_compare_op0, sparc_compare_op1);
-    }
-  else
-    {
-      rtx cc_reg = gen_compare_reg (code);
-      operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
-    }
-})
-
-(define_expand "movtfcc"
-  [(set (match_operand:TF 0 "register_operand" "")
-       (if_then_else:TF (match_operand 1 "comparison_operator" "")
-                        (match_operand:TF 2 "register_operand" "")
-                        (match_operand:TF 3 "register_operand" "")))]
-  "TARGET_V9 && TARGET_FPU"
-{
-  enum rtx_code code = GET_CODE (operands[1]);
-
-  if (GET_MODE (sparc_compare_op0) == DImode
-      && ! TARGET_ARCH64)
-    FAIL;
-
-  if (sparc_compare_op1 == const0_rtx
-      && GET_CODE (sparc_compare_op0) == REG
-      && GET_MODE (sparc_compare_op0) == DImode
-      && v9_regcmp_p (code))
-    {
-      operands[1] = gen_rtx_fmt_ee (code, DImode,
-                            sparc_compare_op0, sparc_compare_op1);
-    }
-  else
-    {
-      rtx cc_reg = gen_compare_reg (code);
-      operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
-    }
-})
-
-;; Conditional move define_insns.
-
-(define_insn "*movqi_cc_sp64"
-  [(set (match_operand:QI 0 "register_operand" "=r,r")
-       (if_then_else:QI (match_operator 1 "comparison_operator"
-                               [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
-                                (const_int 0)])
-                         (match_operand:QI 3 "arith11_operand" "rL,0")
-                         (match_operand:QI 4 "arith11_operand" "0,rL")))]
-  "TARGET_V9"
-  "@
-   mov%C1\t%x2, %3, %0
-   mov%c1\t%x2, %4, %0"
-  [(set_attr "type" "cmove")])
-
-(define_insn "*movhi_cc_sp64"
-  [(set (match_operand:HI 0 "register_operand" "=r,r")
-       (if_then_else:HI (match_operator 1 "comparison_operator"
-                               [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
-                                (const_int 0)])
-                         (match_operand:HI 3 "arith11_operand" "rL,0")
-                         (match_operand:HI 4 "arith11_operand" "0,rL")))]
-  "TARGET_V9"
-  "@
-   mov%C1\t%x2, %3, %0
-   mov%c1\t%x2, %4, %0"
-  [(set_attr "type" "cmove")])
-
-(define_insn "*movsi_cc_sp64"
-  [(set (match_operand:SI 0 "register_operand" "=r,r")
-       (if_then_else:SI (match_operator 1 "comparison_operator"
-                               [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
-                                (const_int 0)])
-                         (match_operand:SI 3 "arith11_operand" "rL,0")
-                         (match_operand:SI 4 "arith11_operand" "0,rL")))]
-  "TARGET_V9"
-  "@
-   mov%C1\t%x2, %3, %0
-   mov%c1\t%x2, %4, %0"
-  [(set_attr "type" "cmove")])
+;; Conditional move define_insns
 
-(define_insn "*movdi_cc_sp64"
-  [(set (match_operand:DI 0 "register_operand" "=r,r")
-       (if_then_else:DI (match_operator 1 "comparison_operator"
-                               [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
-                                (const_int 0)])
-                         (match_operand:DI 3 "arith11_operand" "rL,0")
-                         (match_operand:DI 4 "arith11_operand" "0,rL")))]
-  "TARGET_ARCH64"
+(define_insn "*mov<I:mode>_cc_v9"
+  [(set (match_operand:I 0 "register_operand" "=r,r")
+       (if_then_else:I (match_operator 1 "comparison_operator"
+                              [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
+                               (const_int 0)])
+                       (match_operand:I 3 "arith11_operand" "rL,0")
+                       (match_operand:I 4 "arith11_operand" "0,rL")))]
+  "TARGET_V9 && !(<I:MODE>mode == DImode && TARGET_ARCH32)"
   "@
    mov%C1\t%x2, %3, %0
    mov%c1\t%x2, %4, %0"
   [(set_attr "type" "cmove")])
 
-(define_insn "*movdi_cc_sp64_trunc"
-  [(set (match_operand:SI 0 "register_operand" "=r,r")
-       (if_then_else:SI (match_operator 1 "comparison_operator"
-                               [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
+(define_insn "*mov<I:mode>_cc_reg_sp64"
+  [(set (match_operand:I 0 "register_operand" "=r,r")
+       (if_then_else:I (match_operator 1 "v9_register_compare_operator"
+                               [(match_operand:DI 2 "register_operand" "r,r")
                                 (const_int 0)])
-                         (match_operand:SI 3 "arith11_operand" "rL,0")
-                         (match_operand:SI 4 "arith11_operand" "0,rL")))]
+                       (match_operand:I 3 "arith10_operand" "rM,0")
+                       (match_operand:I 4 "arith10_operand" "0,rM")))]
   "TARGET_ARCH64"
   "@
-   mov%C1\t%x2, %3, %0
-   mov%c1\t%x2, %4, %0"
+   movr%D1\t%2, %r3, %0
+   movr%d1\t%2, %r4, %0"
   [(set_attr "type" "cmove")])
 
-(define_insn "*movsf_cc_sp64"
+(define_insn "*movsf_cc_v9"
   [(set (match_operand:SF 0 "register_operand" "=f,f")
        (if_then_else:SF (match_operator 1 "comparison_operator"
                                [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
                                 (const_int 0)])
-                         (match_operand:SF 3 "register_operand" "f,0")
-                         (match_operand:SF 4 "register_operand" "0,f")))]
+                        (match_operand:SF 3 "register_operand" "f,0")
+                        (match_operand:SF 4 "register_operand" "0,f")))]
   "TARGET_V9 && TARGET_FPU"
   "@
    fmovs%C1\t%x2, %3, %0
    fmovs%c1\t%x2, %4, %0"
   [(set_attr "type" "fpcmove")])
 
-(define_insn "movdf_cc_sp64"
+(define_insn "*movsf_cc_reg_sp64"
+  [(set (match_operand:SF 0 "register_operand" "=f,f")
+       (if_then_else:SF (match_operator 1 "v9_register_compare_operator"
+                               [(match_operand:DI 2 "register_operand" "r,r")
+                                (const_int 0)])
+                        (match_operand:SF 3 "register_operand" "f,0")
+                        (match_operand:SF 4 "register_operand" "0,f")))]
+  "TARGET_ARCH64 && TARGET_FPU"
+  "@
+   fmovrs%D1\t%2, %3, %0
+   fmovrs%d1\t%2, %4, %0"
+  [(set_attr "type" "fpcrmove")])
+
+;; Named because invoked by movtf_cc_v9
+(define_insn "movdf_cc_v9"
   [(set (match_operand:DF 0 "register_operand" "=e,e")
        (if_then_else:DF (match_operator 1 "comparison_operator"
                                [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
                                 (const_int 0)])
-                         (match_operand:DF 3 "register_operand" "e,0")
-                         (match_operand:DF 4 "register_operand" "0,e")))]
+                        (match_operand:DF 3 "register_operand" "e,0")
+                        (match_operand:DF 4 "register_operand" "0,e")))]
   "TARGET_V9 && TARGET_FPU"
   "@
    fmovd%C1\t%x2, %3, %0
   [(set_attr "type" "fpcmove")
    (set_attr "fptype" "double")])
 
-(define_insn "*movtf_cc_hq_sp64"
+;; Named because invoked by movtf_cc_reg_sp64
+(define_insn "movdf_cc_reg_sp64"
+  [(set (match_operand:DF 0 "register_operand" "=e,e")
+       (if_then_else:DF (match_operator 1 "v9_register_compare_operator"
+                               [(match_operand:DI 2 "register_operand" "r,r")
+                                (const_int 0)])
+                        (match_operand:DF 3 "register_operand" "e,0")
+                        (match_operand:DF 4 "register_operand" "0,e")))]
+  "TARGET_ARCH64 && TARGET_FPU"
+  "@
+   fmovrd%D1\t%2, %3, %0
+   fmovrd%d1\t%2, %4, %0"
+  [(set_attr "type" "fpcrmove")
+   (set_attr "fptype" "double")])
+
+(define_insn "*movtf_cc_hq_v9"
   [(set (match_operand:TF 0 "register_operand" "=e,e")
        (if_then_else:TF (match_operator 1 "comparison_operator"
                                [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
                                 (const_int 0)])
-                         (match_operand:TF 3 "register_operand" "e,0")
-                         (match_operand:TF 4 "register_operand" "0,e")))]
+                        (match_operand:TF 3 "register_operand" "e,0")
+                        (match_operand:TF 4 "register_operand" "0,e")))]
   "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
   "@
    fmovq%C1\t%x2, %3, %0
    fmovq%c1\t%x2, %4, %0"
   [(set_attr "type" "fpcmove")])
 
-(define_insn_and_split "*movtf_cc_sp64"
+(define_insn "*movtf_cc_reg_hq_sp64"
+  [(set (match_operand:TF 0 "register_operand" "=e,e")
+       (if_then_else:TF (match_operator 1 "v9_register_compare_operator"
+                               [(match_operand:DI 2 "register_operand" "r,r")
+                                (const_int 0)])
+                        (match_operand:TF 3 "register_operand" "e,0")
+                        (match_operand:TF 4 "register_operand" "0,e")))]
+  "TARGET_ARCH64 && TARGET_FPU && TARGET_HARD_QUAD"
+  "@
+   fmovrq%D1\t%2, %3, %0
+   fmovrq%d1\t%2, %4, %0"
+  [(set_attr "type" "fpcrmove")])
+
+(define_insn_and_split "*movtf_cc_v9"
   [(set (match_operand:TF 0 "register_operand" "=e,e")
        (if_then_else:TF (match_operator 1 "comparison_operator"
                            [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
                             (const_int 0)])
-                         (match_operand:TF 3 "register_operand" "e,0")
-                         (match_operand:TF 4 "register_operand" "0,e")))]
+                        (match_operand:TF 3 "register_operand" "e,0")
+                        (match_operand:TF 4 "register_operand" "0,e")))]
   "TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD"
   "#"
   "&& reload_completed"
   if ((third && reg_overlap_mentioned_p (dest1, srcb2))
       || (!third && reg_overlap_mentioned_p (dest1, srca2)))
     {
-      emit_insn (gen_movdf_cc_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
-      emit_insn (gen_movdf_cc_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
+      emit_insn (gen_movdf_cc_v9 (dest2, operands[1], operands[2], srca2, srcb2));
+      emit_insn (gen_movdf_cc_v9 (dest1, operands[1], operands[2], srca1, srcb1));
     }
   else
     {
-      emit_insn (gen_movdf_cc_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
-      emit_insn (gen_movdf_cc_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
+      emit_insn (gen_movdf_cc_v9 (dest1, operands[1], operands[2], srca1, srcb1));
+      emit_insn (gen_movdf_cc_v9 (dest2, operands[1], operands[2], srca2, srcb2));
     }
   DONE;
 }
   [(set_attr "length" "2")])
 
-(define_insn "*movqi_cc_reg_sp64"
-  [(set (match_operand:QI 0 "register_operand" "=r,r")
-       (if_then_else:QI (match_operator 1 "v9_register_compare_operator"
-                               [(match_operand:DI 2 "register_operand" "r,r")
-                                (const_int 0)])
-                         (match_operand:QI 3 "arith10_operand" "rM,0")
-                         (match_operand:QI 4 "arith10_operand" "0,rM")))]
-  "TARGET_ARCH64"
-  "@
-   movr%D1\t%2, %r3, %0
-   movr%d1\t%2, %r4, %0"
-  [(set_attr "type" "cmove")])
-
-(define_insn "*movhi_cc_reg_sp64"
-  [(set (match_operand:HI 0 "register_operand" "=r,r")
-       (if_then_else:HI (match_operator 1 "v9_register_compare_operator"
-                               [(match_operand:DI 2 "register_operand" "r,r")
-                                (const_int 0)])
-                         (match_operand:HI 3 "arith10_operand" "rM,0")
-                         (match_operand:HI 4 "arith10_operand" "0,rM")))]
-  "TARGET_ARCH64"
-  "@
-   movr%D1\t%2, %r3, %0
-   movr%d1\t%2, %r4, %0"
-  [(set_attr "type" "cmove")])
-
-(define_insn "*movsi_cc_reg_sp64"
-  [(set (match_operand:SI 0 "register_operand" "=r,r")
-       (if_then_else:SI (match_operator 1 "v9_register_compare_operator"
-                               [(match_operand:DI 2 "register_operand" "r,r")
-                                (const_int 0)])
-                         (match_operand:SI 3 "arith10_operand" "rM,0")
-                         (match_operand:SI 4 "arith10_operand" "0,rM")))]
-  "TARGET_ARCH64"
-  "@
-   movr%D1\t%2, %r3, %0
-   movr%d1\t%2, %r4, %0"
-  [(set_attr "type" "cmove")])
-
-(define_insn "*movdi_cc_reg_sp64"
-  [(set (match_operand:DI 0 "register_operand" "=r,r")
-       (if_then_else:DI (match_operator 1 "v9_register_compare_operator"
-                               [(match_operand:DI 2 "register_operand" "r,r")
-                                (const_int 0)])
-                         (match_operand:DI 3 "arith10_operand" "rM,0")
-                         (match_operand:DI 4 "arith10_operand" "0,rM")))]
-  "TARGET_ARCH64"
-  "@
-   movr%D1\t%2, %r3, %0
-   movr%d1\t%2, %r4, %0"
-  [(set_attr "type" "cmove")])
-
-(define_insn "*movsf_cc_reg_sp64"
-  [(set (match_operand:SF 0 "register_operand" "=f,f")
-       (if_then_else:SF (match_operator 1 "v9_register_compare_operator"
-                               [(match_operand:DI 2 "register_operand" "r,r")
-                                (const_int 0)])
-                         (match_operand:SF 3 "register_operand" "f,0")
-                         (match_operand:SF 4 "register_operand" "0,f")))]
-  "TARGET_ARCH64 && TARGET_FPU"
-  "@
-   fmovrs%D1\t%2, %3, %0
-   fmovrs%d1\t%2, %4, %0"
-  [(set_attr "type" "fpcrmove")])
-
-(define_insn "movdf_cc_reg_sp64"
-  [(set (match_operand:DF 0 "register_operand" "=e,e")
-       (if_then_else:DF (match_operator 1 "v9_register_compare_operator"
-                               [(match_operand:DI 2 "register_operand" "r,r")
-                                (const_int 0)])
-                         (match_operand:DF 3 "register_operand" "e,0")
-                         (match_operand:DF 4 "register_operand" "0,e")))]
-  "TARGET_ARCH64 && TARGET_FPU"
-  "@
-   fmovrd%D1\t%2, %3, %0
-   fmovrd%d1\t%2, %4, %0"
-  [(set_attr "type" "fpcrmove")
-   (set_attr "fptype" "double")])
-
-(define_insn "*movtf_cc_reg_hq_sp64"
-  [(set (match_operand:TF 0 "register_operand" "=e,e")
-       (if_then_else:TF (match_operator 1 "v9_register_compare_operator"
-                               [(match_operand:DI 2 "register_operand" "r,r")
-                                (const_int 0)])
-                         (match_operand:TF 3 "register_operand" "e,0")
-                         (match_operand:TF 4 "register_operand" "0,e")))]
-  "TARGET_ARCH64 && TARGET_FPU && TARGET_HARD_QUAD"
-  "@
-   fmovrq%D1\t%2, %3, %0
-   fmovrq%d1\t%2, %4, %0"
-  [(set_attr "type" "fpcrmove")])
-
 (define_insn_and_split "*movtf_cc_reg_sp64"
   [(set (match_operand:TF 0 "register_operand" "=e,e")
        (if_then_else:TF (match_operator 1 "v9_register_compare_operator"
                                [(match_operand:DI 2 "register_operand" "r,r")
                                 (const_int 0)])
-                         (match_operand:TF 3 "register_operand" "e,0")
-                         (match_operand:TF 4 "register_operand" "0,e")))]
+                        (match_operand:TF 3 "register_operand" "e,0")
+                        (match_operand:TF 4 "register_operand" "0,e")))]
   "TARGET_ARCH64 && TARGET_FPU && ! TARGET_HARD_QUAD"
   "#"
   "&& reload_completed"