DONE;
})
+(define_expand "cstore_si_as_di"
+ [(use (match_operator 1 "unsigned_comparison_operator"
+ [(match_operand:SI 2 "gpc_reg_operand")
+ (match_operand:SI 3 "reg_or_short_operand")]))
+ (clobber (match_operand:SI 0 "register_operand"))]
+ ""
+{
+ int uns_flag = unsigned_comparison_operator (operands[1], VOIDmode) ? 1 : 0;
+ enum rtx_code cond_code = signed_condition (GET_CODE (operands[1]));
+
+ rtx op1 = gen_reg_rtx (DImode);
+ rtx op2 = gen_reg_rtx (DImode);
+ convert_move (op1, operands[2], uns_flag);
+ convert_move (op2, operands[3], uns_flag);
+
+ if (cond_code == GT || cond_code == LE)
+ {
+ cond_code = swap_condition (cond_code);
+ std::swap (op1, op2);
+ }
+
+ rtx tmp = gen_reg_rtx (DImode);
+ rtx tmp2 = gen_reg_rtx (DImode);
+ emit_insn (gen_subdi3 (tmp, op1, op2));
+ emit_insn (gen_lshrdi3 (tmp2, tmp, GEN_INT (63)));
+
+ rtx tmp3;
+ switch (cond_code)
+ {
+ default:
+ gcc_unreachable ();
+ case LT:
+ tmp3 = tmp2;
+ break;
+ case GE:
+ tmp3 = gen_reg_rtx (DImode);
+ emit_insn (gen_xordi3 (tmp3, tmp2, const1_rtx));
+ break;
+ }
+
+ convert_move (operands[0], tmp3, 1);
+
+ DONE;
+})
+
(define_expand "cstore<mode>4_signed_imm"
[(use (match_operator 1 "signed_comparison_operator"
[(match_operand:GPR 2 "gpc_reg_operand")
emit_insn (gen_cstore<mode>4_unsigned (operands[0], operands[1],
operands[2], operands[3]));
+ /* For comparisons smaller than Pmode we can cheaply do things in Pmode. */
+ else if (<MODE>mode == SImode && Pmode == DImode)
+ emit_insn (gen_cstore_si_as_di (operands[0], operands[1],
+ operands[2], operands[3]));
+
/* For signed comparisons against a constant, we can do some simple
bit-twiddling. */
else if (signed_comparison_operator (operands[1], VOIDmode)