Commit 36583fea by Jan Hubicka Committed by Richard Henderson

Jan Hubicka <hubicka@freesoft.cz>

        * i386.c (ix86_expand_int_movcc): Convert LEU and GTU comparisons
        to LTU and GEU.  Handle more cases using sbb.

From-SVN: r29743
parent ca285e07
Thu Sep 30 18:21:30 1999 Jan Hubicka <hubicka@freesoft.cz>
* i386.c (ix86_expand_int_movcc): Convert LEU and GTU comparisons
to LTU and GEU. Handle more cases using sbb.
Thu Sep 30 18:18:39 1999 Jan Hubicka <hubicka@freesoft.cz>
* i386.md (truncatexfdf splitters): Do not use subreg.
......
......@@ -4288,6 +4288,23 @@ ix86_expand_int_movcc (operands)
enum rtx_code code = GET_CODE (operands[1]), compare_code;
rtx compare_seq, compare_op;
/* When the compare code is not LTU or GEU, we can not use sbbl case.
In case comparsion is done with immediate, we can convert it to LTU or
GEU by altering the integer. */
if ((code == LEU || code == GTU)
&& GET_CODE (ix86_compare_op1) == CONST_INT
&& GET_MODE (operands[0]) != HImode
&& (unsigned int)INTVAL (ix86_compare_op1) != 0xffffffff
&& GET_CODE (operands[2]) == CONST_INT
&& GET_CODE (operands[3]) == CONST_INT)
{
if (code == LEU)
code = LTU;
else
code = GEU;
ix86_compare_op1 = GEN_INT (INTVAL (ix86_compare_op1) + 1);
}
start_sequence ();
compare_op = ix86_expand_compare (code, code == EQ || code == NE);
compare_seq = gen_sequence ();
......@@ -4307,27 +4324,23 @@ ix86_expand_int_movcc (operands)
HOST_WIDE_INT cf = INTVAL (operands[3]);
HOST_WIDE_INT diff;
/* Special cases: */
if (ct == 0)
if (compare_code == LTU || compare_code == GEU)
{
ct = cf;
cf = 0;
compare_code = reverse_condition (compare_code);
code = reverse_condition (code);
}
if (cf == 0 && ct == -1 && (compare_code == LTU || compare_code == GEU))
{
/*
* xorl dest,dest
* cmpl op0,op1
* sbbl dest,dest
*
* Size 6.
*/
/* Detect overlap between destination and compare sources. */
rtx tmp = out;
/* To simplify rest of code, restrict to the GEU case. */
if (compare_code == LTU)
{
int tmp = ct;
ct = cf;
cf = tmp;
compare_code = reverse_condition (compare_code);
code = reverse_condition (code);
}
diff = ct - cf;
if (reg_overlap_mentioned_p (out, ix86_compare_op0)
|| reg_overlap_mentioned_p (out, ix86_compare_op0))
tmp = gen_reg_rtx (SImode);
......@@ -4335,8 +4348,57 @@ ix86_expand_int_movcc (operands)
emit_insn (compare_seq);
emit_insn (gen_x86_movsicc_0_m1 (tmp));
if (compare_code == GEU)
emit_insn (gen_one_cmplsi2 (tmp, tmp));
if (diff == 1)
{
/*
* cmpl op0,op1
* sbbl dest,dest
* [addl dest, ct]
*
* Size 5 - 8.
*/
if (ct)
emit_insn (gen_addsi3 (out, out, GEN_INT (ct)));
}
else if (cf == -1)
{
/*
* cmpl op0,op1
* sbbl dest,dest
* orl $ct, dest
*
* Size 8.
*/
emit_insn (gen_iorsi3 (out, out, GEN_INT (ct)));
}
else if (diff == -1 && ct)
{
/*
* cmpl op0,op1
* sbbl dest,dest
* xorl $-1, dest
* [addl dest, cf]
*
* Size 8 - 11.
*/
emit_insn (gen_one_cmplsi2 (tmp, tmp));
if (cf)
emit_insn (gen_addsi3 (out, out, GEN_INT (cf)));
}
else
{
/*
* cmpl op0,op1
* sbbl dest,dest
* andl cf - ct, dest
* [addl dest, ct]
*
* Size 8 - 11.
*/
emit_insn (gen_andsi3 (out, out, GEN_INT (cf - ct)));
if (ct)
emit_insn (gen_addsi3 (out, out, GEN_INT (ct)));
}
if (tmp != out)
emit_move_insn (out, tmp);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment