+ return (rtx_cost (and_test, IF_THEN_ELSE, optimize_insn_for_speed_p ())
+ <= rtx_cost (shift_test, IF_THEN_ELSE, optimize_insn_for_speed_p ()));
+}
+
+/* Subroutine of do_jump, dealing with exploded comparisons of the type
+ OP0 CODE OP1 . IF_FALSE_LABEL and IF_TRUE_LABEL like in do_jump.
+ PROB is probability of jump to if_true_label, or -1 if unknown. */
+
+void
+do_jump_1 (enum tree_code code, tree op0, tree op1,
+ rtx if_false_label, rtx if_true_label, int prob)
+{
+ enum machine_mode mode;
+ rtx drop_through_label = 0;
+
+ switch (code)
+ {
+ case EQ_EXPR:
+ {
+ tree inner_type = TREE_TYPE (op0);
+
+ gcc_assert (GET_MODE_CLASS (TYPE_MODE (inner_type))
+ != MODE_COMPLEX_FLOAT);
+ gcc_assert (GET_MODE_CLASS (TYPE_MODE (inner_type))
+ != MODE_COMPLEX_INT);
+
+ if (integer_zerop (op1))
+ do_jump (op0, if_true_label, if_false_label, inv (prob));
+ else if (GET_MODE_CLASS (TYPE_MODE (inner_type)) == MODE_INT
+ && !can_compare_p (EQ, TYPE_MODE (inner_type), ccp_jump))
+ do_jump_by_parts_equality (op0, op1, if_false_label, if_true_label,
+ prob);
+ else
+ do_compare_and_jump (op0, op1, EQ, EQ, if_false_label, if_true_label,
+ prob);
+ break;
+ }
+
+ case NE_EXPR:
+ {
+ tree inner_type = TREE_TYPE (op0);
+
+ gcc_assert (GET_MODE_CLASS (TYPE_MODE (inner_type))
+ != MODE_COMPLEX_FLOAT);
+ gcc_assert (GET_MODE_CLASS (TYPE_MODE (inner_type))
+ != MODE_COMPLEX_INT);
+
+ if (integer_zerop (op1))
+ do_jump (op0, if_false_label, if_true_label, prob);
+ else if (GET_MODE_CLASS (TYPE_MODE (inner_type)) == MODE_INT
+ && !can_compare_p (NE, TYPE_MODE (inner_type), ccp_jump))
+ do_jump_by_parts_equality (op0, op1, if_true_label, if_false_label,
+ inv (prob));
+ else
+ do_compare_and_jump (op0, op1, NE, NE, if_false_label, if_true_label,
+ prob);
+ break;
+ }
+
+ case LT_EXPR:
+ mode = TYPE_MODE (TREE_TYPE (op0));
+ if (GET_MODE_CLASS (mode) == MODE_INT
+ && ! can_compare_p (LT, mode, ccp_jump))
+ do_jump_by_parts_greater (op0, op1, 1, if_false_label, if_true_label,
+ prob);
+ else
+ do_compare_and_jump (op0, op1, LT, LTU, if_false_label, if_true_label,
+ prob);
+ break;
+
+ case LE_EXPR:
+ mode = TYPE_MODE (TREE_TYPE (op0));
+ if (GET_MODE_CLASS (mode) == MODE_INT
+ && ! can_compare_p (LE, mode, ccp_jump))
+ do_jump_by_parts_greater (op0, op1, 0, if_true_label, if_false_label,
+ inv (prob));
+ else
+ do_compare_and_jump (op0, op1, LE, LEU, if_false_label, if_true_label,
+ prob);
+ break;
+
+ case GT_EXPR:
+ mode = TYPE_MODE (TREE_TYPE (op0));
+ if (GET_MODE_CLASS (mode) == MODE_INT
+ && ! can_compare_p (GT, mode, ccp_jump))
+ do_jump_by_parts_greater (op0, op1, 0, if_false_label, if_true_label,
+ prob);
+ else
+ do_compare_and_jump (op0, op1, GT, GTU, if_false_label, if_true_label,
+ prob);
+ break;
+
+ case GE_EXPR:
+ mode = TYPE_MODE (TREE_TYPE (op0));
+ if (GET_MODE_CLASS (mode) == MODE_INT
+ && ! can_compare_p (GE, mode, ccp_jump))
+ do_jump_by_parts_greater (op0, op1, 1, if_true_label, if_false_label,
+ inv (prob));
+ else
+ do_compare_and_jump (op0, op1, GE, GEU, if_false_label, if_true_label,
+ prob);
+ break;
+
+ case ORDERED_EXPR:
+ do_compare_and_jump (op0, op1, ORDERED, ORDERED,
+ if_false_label, if_true_label, prob);
+ break;
+
+ case UNORDERED_EXPR:
+ do_compare_and_jump (op0, op1, UNORDERED, UNORDERED,
+ if_false_label, if_true_label, prob);
+ break;
+
+ case UNLT_EXPR:
+ do_compare_and_jump (op0, op1, UNLT, UNLT, if_false_label, if_true_label,
+ prob);
+ break;
+
+ case UNLE_EXPR:
+ do_compare_and_jump (op0, op1, UNLE, UNLE, if_false_label, if_true_label,
+ prob);
+ break;
+
+ case UNGT_EXPR:
+ do_compare_and_jump (op0, op1, UNGT, UNGT, if_false_label, if_true_label,
+ prob);
+ break;
+
+ case UNGE_EXPR:
+ do_compare_and_jump (op0, op1, UNGE, UNGE, if_false_label, if_true_label,
+ prob);
+ break;
+
+ case UNEQ_EXPR:
+ do_compare_and_jump (op0, op1, UNEQ, UNEQ, if_false_label, if_true_label,
+ prob);
+ break;
+
+ case LTGT_EXPR:
+ do_compare_and_jump (op0, op1, LTGT, LTGT, if_false_label, if_true_label,
+ prob);
+ break;
+
+ case TRUTH_ANDIF_EXPR:
+ if (if_false_label == NULL_RTX)
+ {
+ drop_through_label = gen_label_rtx ();
+ do_jump (op0, drop_through_label, NULL_RTX, prob);
+ do_jump (op1, NULL_RTX, if_true_label, prob);
+ }
+ else
+ {
+ do_jump (op0, if_false_label, NULL_RTX, prob);
+ do_jump (op1, if_false_label, if_true_label, prob);
+ }
+ break;
+
+ case TRUTH_ORIF_EXPR:
+ if (if_true_label == NULL_RTX)
+ {
+ drop_through_label = gen_label_rtx ();
+ do_jump (op0, NULL_RTX, drop_through_label, prob);
+ do_jump (op1, if_false_label, NULL_RTX, prob);
+ }
+ else
+ {
+ do_jump (op0, NULL_RTX, if_true_label, prob);
+ do_jump (op1, if_false_label, if_true_label, prob);
+ }
+ break;
+
+ default:
+ gcc_unreachable ();
+ }
+
+ if (drop_through_label)
+ {
+ do_pending_stack_adjust ();
+ emit_label (drop_through_label);
+ }