From 36583feac4bd37503c798dc3d32652258ba14d76 Mon Sep 17 00:00:00 2001 From: Jan Hubicka Date: Fri, 1 Oct 1999 03:22:24 +0200 Subject: [PATCH] Jan Hubicka * i386.c (ix86_expand_int_movcc): Convert LEU and GTU comparisons to LTU and GEU. Handle more cases using sbb. From-SVN: r29743 --- gcc/ChangeLog | 5 +++ gcc/config/i386/i386.c | 98 ++++++++++++++++++++++++++++++++++++++++---------- 2 files changed, 85 insertions(+), 18 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index b38ff43..2a61039 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +Thu Sep 30 18:21:30 1999 Jan Hubicka + + * 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 * i386.md (truncatexfdf splitters): Do not use subreg. diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index f654db6..34a68a7 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -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); -- 2.7.4