(alpha_emit_conditional_move): Fix some bugs in previous change and do
authorRichard Kenner <kenner@gcc.gnu.org>
Wed, 17 Apr 1996 12:40:51 +0000 (08:40 -0400)
committerRichard Kenner <kenner@gcc.gnu.org>
Wed, 17 Apr 1996 12:40:51 +0000 (08:40 -0400)
some cleanup.

From-SVN: r11834

gcc/config/alpha/alpha.c

index e3edeca947074e0a1411e2bf0ca91a54f5c92c36..aa1f1e3d06e437921482140c60e952a6cf9bf443 100644 (file)
@@ -977,54 +977,54 @@ alpha_emit_conditional_move (cmp, mode)
      rtx cmp;
      enum machine_mode mode;
 {
+  enum rtx_code code = GET_CODE (cmp);
   rtx op0 = alpha_compare_op0;
   rtx op1 = alpha_compare_op1;
-  rtx zero = CONST0_RTX (mode);
-  rtx tmp;
-  enum rtx_code code = GET_CODE (cmp), code2;
+  enum machine_mode cmp_mode
+    = (GET_MODE (op0) == VOIDmode ? DImode : GET_MODE (op0));
+  enum machine_mode cmp_op_mode = alpha_compare_fp_p ? DFmode : DImode;
+  rtx tem;
 
-  if (alpha_compare_fp_p != FLOAT_MODE_P(mode))
+  if (alpha_compare_fp_p != FLOAT_MODE_P (mode))
     return 0;
 
   /* We may be able to use a conditional move directly.
      This avoids emitting spurious compares. */
-  if (signed_comparison_operator (cmp, mode) && (op0 == zero || op1 == zero))
-    return gen_rtx (code, mode, op0, op1);
+  if (signed_comparison_operator (cmp, cmp_op_mode)
+      && (op0 == CONST0_RTX (cmp_mode) || op1 == CONST0_RTX (cmp_mode)))
+    return gen_rtx (code, VOIDmode, op0, op1);
 
   /* We can't put the comparison insides a conditional move;
      emit a compare instruction and put that inside the
-     conditional move. */
+     conditional move.  Make sure we emit only comparisons we have;
+     swap or reverse as necessary.  */
 
-  /* The alpha does not have NE GE GT compares for any mode.  Avoid them. */
-  code2 = NE;
   switch (code)
     {
-    /* We have these compares: */
-    case EQ: case LE: case LT:
+    case EQ:  case LE:  case LT:  case LEU:  case LTU:
+      /* We have these compares: */
       break;
-    /* These must be inverted: */
+
     case NE:
-      code = code2 = EQ;
-      break;
-    case GE:
-      code = LE;
-      op0 = force_reg (mode, alpha_compare_op1);
-      op1 = alpha_compare_op0;
+      /* This must be reversed. */
+      code = reverse_condition (code);
       break;
-    case GT:
-      code = LT;
-      op0 = force_reg (mode, alpha_compare_op1);
-      op1 = alpha_compare_op0;
+
+    case GE:  case GT:  case GEU:  case GTU:
+      /* These must be swapped.  Make sure the new first operand is in
+        a register.  */
+      code = swap_condition (code);
+      tem = op0, op0 = op1, op1 = tem;
+      op0 = force_reg (cmp_mode, op0);
       break;
+
     default:
-      return 0;
+      abort ();
     }
 
-  cmp = gen_rtx (code, mode, op0, op1);
-  tmp = gen_reg_rtx (mode);
-  emit_insn (gen_rtx (SET, VOIDmode, tmp, cmp));
-  cmp = gen_rtx (code2, VOIDmode, tmp, zero);
-  return cmp;
+  tem = gen_reg_rtx (cmp_op_mode);
+  emit_move_insn (tem, gen_rtx (code, cmp_op_mode, op0, op1));
+  return gen_rtx (code == NE ? EQ : NE, VOIDmode, tem, CONST0_RTX (mode));
 }
 \f
 /* Adjust the cost of a scheduling dependency.  Return the new cost of