Commit 3a3677ff by Richard Henderson

genrecog.c (pred): Update comparison_operator for the unordered operators.

        * genrecog.c (pred): Update comparison_operator for the unordered
        operators.

        * config/i386/i386.c (no_comparison_operator): Disallow unordered
        operators.
        (fcmov_comparison_operator): Allow UNORDERED/ORDERED.
        (uno_comparison_operator): New.
        (put_condition_code): Handle UNORDERED/ORDERED.
        (unsigned_comparison): Likewise.
        (ix86_fp_compare_mode): Broken out of ix86_expand_fp_compare.
        (ix86_use_fcomi_compare, ix86_prepare_fp_compare_args): Likewise.
        (ix86_expand_fp_compare): Use them.  Take scratch as argument,
        update all callers.  Handle all 8 unordered operators.
        (ix86_expand_setcc): Lose the unordered argument, update all callers.
        (ix86_expand_branch): Likewise.  Don't fully expand fp branches.
        * config/i386/i386.h (PREDICATE_CODES): Update.
        * config/i386/i386-protos.h (ix86_expand_fp_compare): Declare.
        (ix86_expand_branch, ix86_expand_setcc): Update.
        * config/i386/i386.md (sunordered, sordered): New.
        (suneq, sunge, sungt, sunle, sunlt, sltgt): New.
        (bunordered, bordered): New.
        (buneq, bunge, bungt, bunle, bunlt, bltgt): New.
        (*fp_jcc_1, *fp_jcc_2, *fp_jcc_3, *fp_jcc_4): New.
        (*fp_jcc_5, *fp_jcc_6, and splitters): New.

From-SVN: r33046
parent 00fdafef
2000-04-09 Richard Henderson <rth@cygnus.com>
* genrecog.c (pred): Update comparison_operator for the unordered
operators.
* config/i386/i386.c (no_comparison_operator): Disallow unordered
operators.
(fcmov_comparison_operator): Allow UNORDERED/ORDERED.
(uno_comparison_operator): New.
(put_condition_code): Handle UNORDERED/ORDERED.
(unsigned_comparison): Likewise.
(ix86_fp_compare_mode): Broken out of ix86_expand_fp_compare.
(ix86_use_fcomi_compare, ix86_prepare_fp_compare_args): Likewise.
(ix86_expand_fp_compare): Use them. Take scratch as argument,
update all callers. Handle all 8 unordered operators.
(ix86_expand_setcc): Lose the unordered argument, update all callers.
(ix86_expand_branch): Likewise. Don't fully expand fp branches.
* config/i386/i386.h (PREDICATE_CODES): Update.
* config/i386/i386-protos.h (ix86_expand_fp_compare): Declare.
(ix86_expand_branch, ix86_expand_setcc): Update.
* config/i386/i386.md (sunordered, sordered): New.
(suneq, sunge, sungt, sunle, sunlt, sltgt): New.
(bunordered, bordered): New.
(buneq, bunge, bungt, bunle, bunlt, bltgt): New.
(*fp_jcc_1, *fp_jcc_2, *fp_jcc_3, *fp_jcc_4): New.
(*fp_jcc_5, *fp_jcc_6, and splitters): New.
2000-04-09 Philip Blundell <philb@gnu.org> 2000-04-09 Philip Blundell <philb@gnu.org>
* config/arm/arm.h (ARM_NAME_ENCODING_LENGTHS): Strip `*' too. * config/arm/arm.h (ARM_NAME_ENCODING_LENGTHS): Strip `*' too.
......
...@@ -97,8 +97,9 @@ extern void ix86_expand_unary_operator PARAMS ((enum rtx_code, enum machine_mode ...@@ -97,8 +97,9 @@ extern void ix86_expand_unary_operator PARAMS ((enum rtx_code, enum machine_mode
extern int ix86_unary_operator_ok PARAMS ((enum rtx_code, enum machine_mode, extern int ix86_unary_operator_ok PARAMS ((enum rtx_code, enum machine_mode,
rtx[])); rtx[]));
extern int ix86_match_ccmode PARAMS ((rtx, enum machine_mode)); extern int ix86_match_ccmode PARAMS ((rtx, enum machine_mode));
extern void ix86_expand_branch PARAMS ((enum rtx_code, int, rtx)); extern rtx ix86_expand_fp_compare PARAMS ((enum rtx_code, rtx, rtx, rtx));
extern int ix86_expand_setcc PARAMS ((enum rtx_code, int, rtx)); extern void ix86_expand_branch PARAMS ((enum rtx_code, rtx));
extern int ix86_expand_setcc PARAMS ((enum rtx_code, rtx));
extern int ix86_expand_int_movcc PARAMS ((rtx[])); extern int ix86_expand_int_movcc PARAMS ((rtx[]));
extern int ix86_expand_fp_movcc PARAMS ((rtx[])); extern int ix86_expand_fp_movcc PARAMS ((rtx[]));
extern int ix86_split_long_move PARAMS ((rtx[])); extern int ix86_split_long_move PARAMS ((rtx[]));
......
...@@ -384,8 +384,11 @@ static void put_condition_code PARAMS ((enum rtx_code, enum machine_mode, ...@@ -384,8 +384,11 @@ static void put_condition_code PARAMS ((enum rtx_code, enum machine_mode,
int, int, FILE *)); int, int, FILE *));
static enum rtx_code unsigned_comparison PARAMS ((enum rtx_code code)); static enum rtx_code unsigned_comparison PARAMS ((enum rtx_code code));
static rtx ix86_expand_int_compare PARAMS ((enum rtx_code, rtx, rtx)); static rtx ix86_expand_int_compare PARAMS ((enum rtx_code, rtx, rtx));
static rtx ix86_expand_fp_compare PARAMS ((enum rtx_code, rtx, rtx, int)); static enum machine_mode ix86_fp_compare_mode PARAMS ((enum rtx_code));
static rtx ix86_expand_compare PARAMS ((enum rtx_code, int)); static int ix86_use_fcomi_compare PARAMS ((enum rtx_code));
static enum rtx_code ix86_prepare_fp_compare_args PARAMS ((enum rtx_code,
rtx *, rtx *));
static rtx ix86_expand_compare PARAMS ((enum rtx_code));
static rtx gen_push PARAMS ((rtx)); static rtx gen_push PARAMS ((rtx));
static int memory_address_length PARAMS ((rtx addr)); static int memory_address_length PARAMS ((rtx addr));
static int ix86_flags_dependant PARAMS ((rtx, rtx, enum attr_type)); static int ix86_flags_dependant PARAMS ((rtx, rtx, enum attr_type));
...@@ -1235,10 +1238,19 @@ no_comparison_operator (op, mode) ...@@ -1235,10 +1238,19 @@ no_comparison_operator (op, mode)
register rtx op; register rtx op;
enum machine_mode mode; enum machine_mode mode;
{ {
return ((mode == VOIDmode || GET_MODE (op) == mode) if (mode != VOIDmode && GET_MODE (op) != mode)
&& GET_RTX_CLASS (GET_CODE (op)) == '<' return 0;
&& GET_CODE (op) != LE
&& GET_CODE (op) != GT); switch (GET_CODE (op))
{
case EQ: case NE:
case LT: case GE:
case LEU: case LTU: case GEU: case GTU:
return 1;
default:
return 0;
}
} }
/* Return 1 if OP is a comparison operator that can be issued by fcmov. */ /* Return 1 if OP is a comparison operator that can be issued by fcmov. */
...@@ -1248,9 +1260,42 @@ fcmov_comparison_operator (op, mode) ...@@ -1248,9 +1260,42 @@ fcmov_comparison_operator (op, mode)
register rtx op; register rtx op;
enum machine_mode mode; enum machine_mode mode;
{ {
return ((mode == VOIDmode || GET_MODE (op) == mode) if (mode != VOIDmode && GET_MODE (op) != mode)
&& GET_RTX_CLASS (GET_CODE (op)) == '<' return 0;
&& GET_CODE (op) == unsigned_condition (GET_CODE (op)));
switch (GET_CODE (op))
{
case EQ: case NE:
case LEU: case LTU: case GEU: case GTU:
case UNORDERED: case ORDERED:
return 1;
default:
return 0;
}
}
/* Return 1 if OP is any normal comparison operator plus {UN}ORDERED. */
int
uno_comparison_operator (op, mode)
register rtx op;
enum machine_mode mode;
{
if (mode != VOIDmode && GET_MODE (op) != mode)
return 0;
switch (GET_CODE (op))
{
case EQ: case NE:
case LE: case LT: case GE: case GT:
case LEU: case LTU: case GEU: case GTU:
case UNORDERED: case ORDERED:
return 1;
default:
return 0;
}
} }
/* Return 1 if OP is a binary operator that can be promoted to wider mode. */ /* Return 1 if OP is a binary operator that can be promoted to wider mode. */
...@@ -2970,6 +3015,12 @@ put_condition_code (code, mode, reverse, fp, file) ...@@ -2970,6 +3015,12 @@ put_condition_code (code, mode, reverse, fp, file)
case LEU: case LEU:
suffix = "be"; suffix = "be";
break; break;
case UNORDERED:
suffix = "p";
break;
case ORDERED:
suffix = "np";
break;
default: default:
abort (); abort ();
} }
...@@ -4386,6 +4437,8 @@ unsigned_comparison (code) ...@@ -4386,6 +4437,8 @@ unsigned_comparison (code)
case LTU: case LTU:
case GEU: case GEU:
case GTU: case GTU:
case UNORDERED:
case ORDERED:
break; break;
default: default:
abort (); abort ();
...@@ -4416,36 +4469,80 @@ ix86_expand_int_compare (code, op0, op1) ...@@ -4416,36 +4469,80 @@ ix86_expand_int_compare (code, op0, op1)
return gen_rtx_fmt_ee (code, VOIDmode, flags, const0_rtx); return gen_rtx_fmt_ee (code, VOIDmode, flags, const0_rtx);
} }
/* Generate insn patterns to do a floating point compare of OPERANDS. /* Figure out whether to use ordered or unordered fp comparisons.
If UNORDERED, allow for unordered compares. */ Return the appropriate mode to use. */
static rtx static enum machine_mode
ix86_expand_fp_compare (code, op0, op1, unordered) ix86_fp_compare_mode (code)
enum rtx_code code; enum rtx_code code;
rtx op0, op1;
int unordered;
{ {
enum machine_mode fpcmp_mode; int unordered;
enum machine_mode intcmp_mode;
rtx tmp;
/* When not doing IEEE compliant compares, disable unordered. */ switch (code)
if (! TARGET_IEEE_FP) {
case NE: case EQ:
/* When not doing IEEE compliant compares, fault on NaNs. */
unordered = (TARGET_IEEE_FP != 0);
break;
case LT: case LE: case GT: case GE:
unordered = 0; unordered = 0;
fpcmp_mode = unordered ? CCFPUmode : CCFPmode; break;
case UNORDERED: case ORDERED:
case UNEQ: case UNGE: case UNGT: case UNLE: case UNLT: case LTGT:
unordered = 1;
break;
default:
abort ();
}
/* ??? If we knew whether invalid-operand exceptions were masked, /* ??? If we knew whether invalid-operand exceptions were masked,
we could rely on fcom to raise an exception and take care of we could rely on fcom to raise an exception and take care of
NaNs. But we don't. We could know this from c9x math bits. */ NaNs. But we don't. We could know this from c99 math pragmas. */
if (TARGET_IEEE_FP) if (TARGET_IEEE_FP)
unordered = 1; unordered = 1;
return unordered ? CCFPUmode : CCFPmode;
}
/* Return true if we should use an FCOMI instruction for this fp comparison. */
static int
ix86_use_fcomi_compare (code)
enum rtx_code code;
{
return (TARGET_CMOVE
&& (code == ORDERED || code == UNORDERED
/* All other unordered compares require checking
multiple sets of bits. */
|| ix86_fp_compare_mode (code) == CCFPmode));
}
/* Swap, force into registers, or otherwise massage the two operands
to a fp comparison. The operands are updated in place; the new
comparsion code is returned. */
static enum rtx_code
ix86_prepare_fp_compare_args (code, pop0, pop1)
enum rtx_code code;
rtx *pop0, *pop1;
{
enum machine_mode fpcmp_mode = ix86_fp_compare_mode (code);
rtx op0 = *pop0, op1 = *pop1;
enum machine_mode op_mode = GET_MODE (op0);
/* All of the unordered compare instructions only work on registers. /* All of the unordered compare instructions only work on registers.
The same is true of the XFmode compare instructions. */ The same is true of the XFmode compare instructions. The same is
if (unordered || GET_MODE (op0) == XFmode) true of the fcomi compare instructions. */
if (fpcmp_mode == CCFPUmode
|| op_mode == XFmode
|| ix86_use_fcomi_compare (code))
{ {
op0 = force_reg (GET_MODE (op0), op0); op0 = force_reg (op_mode, op0);
op1 = force_reg (GET_MODE (op1), op1); op1 = force_reg (op_mode, op1);
} }
else else
{ {
...@@ -4464,33 +4561,46 @@ ix86_expand_fp_compare (code, op0, op1, unordered) ...@@ -4464,33 +4561,46 @@ ix86_expand_fp_compare (code, op0, op1, unordered)
} }
if (GET_CODE (op0) != REG) if (GET_CODE (op0) != REG)
op0 = force_reg (GET_MODE (op0), op0); op0 = force_reg (op_mode, op0);
if (CONSTANT_P (op1)) if (CONSTANT_P (op1))
{ {
if (standard_80387_constant_p (op1)) if (standard_80387_constant_p (op1))
op1 = force_reg (GET_MODE (op1), op1); op1 = force_reg (op_mode, op1);
else else
op1 = validize_mem (force_const_mem (GET_MODE (op1), op1)); op1 = validize_mem (force_const_mem (op_mode, op1));
} }
} }
*pop0 = op0;
*pop1 = op1;
return code;
}
/* Generate insn patterns to do a floating point compare of OPERANDS. */
rtx
ix86_expand_fp_compare (code, op0, op1, scratch)
enum rtx_code code;
rtx op0, op1, scratch;
{
enum machine_mode fpcmp_mode, intcmp_mode;
rtx tmp;
fpcmp_mode = ix86_fp_compare_mode (code);
code = ix86_prepare_fp_compare_args (code, &op0, &op1);
/* %%% fcomi is probably always faster, even when dealing with memory, /* %%% fcomi is probably always faster, even when dealing with memory,
since compare-and-branch would be three insns instead of four. */ since compare-and-branch would be three insns instead of four. */
if (TARGET_CMOVE && !unordered) if (ix86_use_fcomi_compare (code))
{ {
if (GET_CODE (op0) != REG)
op0 = force_reg (GET_MODE (op0), op0);
if (GET_CODE (op1) != REG)
op1 = force_reg (GET_MODE (op1), op1);
tmp = gen_rtx_COMPARE (fpcmp_mode, op0, op1); tmp = gen_rtx_COMPARE (fpcmp_mode, op0, op1);
tmp = gen_rtx_SET (VOIDmode, gen_rtx_REG (fpcmp_mode, FLAGS_REG), tmp); tmp = gen_rtx_SET (VOIDmode, gen_rtx_REG (fpcmp_mode, FLAGS_REG), tmp);
emit_insn (tmp); emit_insn (tmp);
/* The FP codes work out to act like unsigned. */ /* The FP codes work out to act like unsigned. */
code = unsigned_comparison (code); code = unsigned_comparison (code);
intcmp_mode = fpcmp_mode; intcmp_mode = CCmode;
} }
else else
{ {
...@@ -4499,10 +4609,11 @@ ix86_expand_fp_compare (code, op0, op1, unordered) ...@@ -4499,10 +4609,11 @@ ix86_expand_fp_compare (code, op0, op1, unordered)
rtx tmp2; rtx tmp2;
tmp = gen_rtx_COMPARE (fpcmp_mode, op0, op1); tmp = gen_rtx_COMPARE (fpcmp_mode, op0, op1);
tmp2 = gen_rtx_UNSPEC (HImode, gen_rtvec (1, tmp), 9); tmp2 = gen_rtx_UNSPEC (HImode, gen_rtvec (1, tmp), 9);
tmp = gen_reg_rtx (HImode); emit_insn (gen_rtx_SET (VOIDmode, scratch, tmp2));
emit_insn (gen_rtx_SET (VOIDmode, tmp, tmp2));
if (! unordered) if (fpcmp_mode == CCFPmode
|| code == ORDERED
|| code == UNORDERED)
{ {
/* We have two options here -- use sahf, or testing bits of ah /* We have two options here -- use sahf, or testing bits of ah
directly. On PPRO, they are equivalent, sahf being one byte directly. On PPRO, they are equivalent, sahf being one byte
...@@ -4512,10 +4623,10 @@ ix86_expand_fp_compare (code, op0, op1, unordered) ...@@ -4512,10 +4623,10 @@ ix86_expand_fp_compare (code, op0, op1, unordered)
if (TARGET_USE_SAHF || optimize_size) if (TARGET_USE_SAHF || optimize_size)
{ {
do_sahf: do_sahf:
emit_insn (gen_x86_sahf_1 (scratch));
/* The FP codes work out to act like unsigned. */ /* The FP codes work out to act like unsigned. */
code = unsigned_comparison (code); code = unsigned_comparison (code);
emit_insn (gen_x86_sahf_1 (tmp));
intcmp_mode = CCmode; intcmp_mode = CCmode;
} }
else else
...@@ -4559,11 +4670,20 @@ ix86_expand_fp_compare (code, op0, op1, unordered) ...@@ -4559,11 +4670,20 @@ ix86_expand_fp_compare (code, op0, op1, unordered)
mask = 0x40; mask = 0x40;
code = EQ; code = EQ;
break; break;
case UNORDERED:
mask = 0x04;
code = NE;
break;
case ORDERED:
mask = 0x04;
code = EQ;
break;
default: default:
abort (); abort ();
} }
emit_insn (gen_testqi_ext_ccno_0 (tmp, GEN_INT (mask))); emit_insn (gen_testqi_ext_ccno_0 (scratch, GEN_INT (mask)));
intcmp_mode = CCNOmode; intcmp_mode = CCNOmode;
} }
} }
...@@ -4578,37 +4698,74 @@ ix86_expand_fp_compare (code, op0, op1, unordered) ...@@ -4578,37 +4698,74 @@ ix86_expand_fp_compare (code, op0, op1, unordered)
switch (code) switch (code)
{ {
case GT: case GT:
emit_insn (gen_testqi_ext_ccno_0 (tmp, GEN_INT (0x45))); emit_insn (gen_testqi_ext_ccno_0 (scratch, GEN_INT (0x45)));
code = EQ; code = EQ;
break; break;
case LT: case LT:
emit_insn (gen_andqi_ext_0 (tmp, tmp, GEN_INT (0x45))); emit_insn (gen_andqi_ext_0 (scratch, scratch, GEN_INT (0x45)));
emit_insn (gen_cmpqi_ext_3 (tmp, GEN_INT (0x01))); emit_insn (gen_cmpqi_ext_3 (scratch, GEN_INT (0x01)));
intcmp_mode = CCmode; intcmp_mode = CCmode;
code = EQ; code = EQ;
break; break;
case GE: case GE:
emit_insn (gen_testqi_ext_ccno_0 (tmp, GEN_INT (0x05))); emit_insn (gen_testqi_ext_ccno_0 (scratch, GEN_INT (0x05)));
code = EQ; code = EQ;
break; break;
case LE: case LE:
emit_insn (gen_andqi_ext_0 (tmp, tmp, GEN_INT (0x45))); emit_insn (gen_andqi_ext_0 (scratch, scratch, GEN_INT (0x45)));
emit_insn (gen_addqi_ext_1 (tmp, tmp, constm1_rtx)); emit_insn (gen_addqi_ext_1 (scratch, scratch, constm1_rtx));
emit_insn (gen_cmpqi_ext_3 (tmp, GEN_INT (0x40))); emit_insn (gen_cmpqi_ext_3 (scratch, GEN_INT (0x40)));
intcmp_mode = CCmode; intcmp_mode = CCmode;
code = LTU; code = LTU;
break; break;
case EQ: case EQ:
emit_insn (gen_andqi_ext_0 (tmp, tmp, GEN_INT (0x45))); emit_insn (gen_andqi_ext_0 (scratch, scratch, GEN_INT (0x45)));
emit_insn (gen_cmpqi_ext_3 (tmp, GEN_INT (0x40))); emit_insn (gen_cmpqi_ext_3 (scratch, GEN_INT (0x40)));
intcmp_mode = CCmode; intcmp_mode = CCmode;
code = EQ; code = EQ;
break; break;
case NE: case NE:
emit_insn (gen_andqi_ext_0 (tmp, tmp, GEN_INT (0x45))); emit_insn (gen_andqi_ext_0 (scratch, scratch, GEN_INT (0x45)));
emit_insn (gen_xorqi_cc_ext_1 (tmp, tmp, GEN_INT (0x40))); emit_insn (gen_xorqi_cc_ext_1 (scratch, scratch, GEN_INT (0x40)));
code = NE;
break;
case UNORDERED:
emit_insn (gen_testqi_ext_ccno_0 (scratch, GEN_INT (0x04)));
code = NE;
break;
case ORDERED:
emit_insn (gen_testqi_ext_ccno_0 (scratch, GEN_INT (0x04)));
code = EQ;
break;
case UNEQ:
emit_insn (gen_testqi_ext_ccno_0 (scratch, GEN_INT (0x40)));
code = NE;
break;
case UNGE:
emit_insn (gen_andqi_ext_0 (scratch, scratch, GEN_INT (0x45)));
emit_insn (gen_xorqi_cc_ext_1 (scratch, scratch, GEN_INT (0x01)));
code = NE;
break;
case UNGT:
emit_insn (gen_andqi_ext_0 (scratch, scratch, GEN_INT (0x45)));
emit_insn (gen_addqi_ext_1 (scratch, scratch, constm1_rtx));
emit_insn (gen_cmpqi_ext_3 (scratch, GEN_INT (0x44)));
code = GEU;
break;
case UNLE:
emit_insn (gen_testqi_ext_ccno_0 (scratch, GEN_INT (0x45)));
code = NE;
break;
case UNLT:
emit_insn (gen_testqi_ext_ccno_0 (scratch, GEN_INT (0x01)));
code = NE; code = NE;
break; break;
case LTGT:
emit_insn (gen_testqi_ext_ccno_0 (scratch, GEN_INT (0x40)));
code = EQ;
break;
default: default:
abort (); abort ();
} }
...@@ -4623,16 +4780,15 @@ ix86_expand_fp_compare (code, op0, op1, unordered) ...@@ -4623,16 +4780,15 @@ ix86_expand_fp_compare (code, op0, op1, unordered)
} }
static rtx static rtx
ix86_expand_compare (code, unordered) ix86_expand_compare (code)
enum rtx_code code; enum rtx_code code;
int unordered;
{ {
rtx op0, op1, ret; rtx op0, op1, ret;
op0 = ix86_compare_op0; op0 = ix86_compare_op0;
op1 = ix86_compare_op1; op1 = ix86_compare_op1;
if (GET_MODE_CLASS (GET_MODE (op0)) == MODE_FLOAT) if (GET_MODE_CLASS (GET_MODE (op0)) == MODE_FLOAT)
ret = ix86_expand_fp_compare (code, op0, op1, unordered); ret = ix86_expand_fp_compare (code, op0, op1, gen_reg_rtx (HImode));
else else
ret = ix86_expand_int_compare (code, op0, op1); ret = ix86_expand_int_compare (code, op0, op1);
...@@ -4640,25 +4796,63 @@ ix86_expand_compare (code, unordered) ...@@ -4640,25 +4796,63 @@ ix86_expand_compare (code, unordered)
} }
void void
ix86_expand_branch (code, unordered, label) ix86_expand_branch (code, label)
enum rtx_code code; enum rtx_code code;
int unordered;
rtx label; rtx label;
{ {
rtx tmp, lo[2], hi[2], label2; rtx tmp;
enum rtx_code code1, code2, code3;
if (GET_MODE (ix86_compare_op0) != DImode) switch (GET_MODE (ix86_compare_op0))
{ {
tmp = ix86_expand_compare (code, unordered); case QImode:
case HImode:
case SImode:
tmp = ix86_expand_compare (code);
tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp, tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
gen_rtx_LABEL_REF (VOIDmode, label), gen_rtx_LABEL_REF (VOIDmode, label),
pc_rtx); pc_rtx);
emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp)); emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
return; return;
case SFmode:
case DFmode:
case XFmode:
/* Don't expand the comparison early, so that we get better code
when jump or whoever decides to reverse the comparison. */
{
rtvec vec;
int use_fcomi;
code = ix86_prepare_fp_compare_args (code, &ix86_compare_op0,
&ix86_compare_op1);
tmp = gen_rtx_fmt_ee (code, ix86_fp_compare_mode (code),
ix86_compare_op0, ix86_compare_op1);
tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
gen_rtx_LABEL_REF (VOIDmode, label),
pc_rtx);
tmp = gen_rtx_SET (VOIDmode, pc_rtx, tmp);
use_fcomi = ix86_use_fcomi_compare (code);
vec = rtvec_alloc (3 + !use_fcomi);
RTVEC_ELT (vec, 0) = tmp;
RTVEC_ELT (vec, 1)
= gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCFPmode, 18));
RTVEC_ELT (vec, 2)
= gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCFPmode, 17));
if (! use_fcomi)
RTVEC_ELT (vec, 3)
= gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (HImode));
emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, vec));
return;
} }
case DImode:
/* Expand DImode branch into multiple compare+branch. */ /* Expand DImode branch into multiple compare+branch. */
{
rtx lo[2], hi[2], label2;
enum rtx_code code1, code2, code3;
if (CONSTANT_P (ix86_compare_op0) && ! CONSTANT_P (ix86_compare_op1)) if (CONSTANT_P (ix86_compare_op0) && ! CONSTANT_P (ix86_compare_op1))
{ {
...@@ -4670,9 +4864,9 @@ ix86_expand_branch (code, unordered, label) ...@@ -4670,9 +4864,9 @@ ix86_expand_branch (code, unordered, label)
split_di (&ix86_compare_op0, 1, lo+0, hi+0); split_di (&ix86_compare_op0, 1, lo+0, hi+0);
split_di (&ix86_compare_op1, 1, lo+1, hi+1); split_di (&ix86_compare_op1, 1, lo+1, hi+1);
/* When comparing for equality, we can use (hi0^hi1)|(lo0^lo1) to avoid /* When comparing for equality, we can use (hi0^hi1)|(lo0^lo1) to
two branches. This costs one extra insn, so disable when optimizing avoid two branches. This costs one extra insn, so disable when
for size. */ optimizing for size. */
if ((code == EQ || code == NE) if ((code == EQ || code == NE)
&& (!optimize_size && (!optimize_size
...@@ -4682,24 +4876,20 @@ ix86_expand_branch (code, unordered, label) ...@@ -4682,24 +4876,20 @@ ix86_expand_branch (code, unordered, label)
xor1 = hi[0]; xor1 = hi[0];
if (hi[1] != const0_rtx) if (hi[1] != const0_rtx)
{
xor1 = expand_binop (SImode, xor_optab, xor1, hi[1], xor1 = expand_binop (SImode, xor_optab, xor1, hi[1],
NULL_RTX, 0, OPTAB_WIDEN); NULL_RTX, 0, OPTAB_WIDEN);
}
xor0 = lo[0]; xor0 = lo[0];
if (lo[1] != const0_rtx) if (lo[1] != const0_rtx)
{
xor0 = expand_binop (SImode, xor_optab, xor0, lo[1], xor0 = expand_binop (SImode, xor_optab, xor0, lo[1],
NULL_RTX, 0, OPTAB_WIDEN); NULL_RTX, 0, OPTAB_WIDEN);
}
tmp = expand_binop (SImode, ior_optab, xor1, xor0, tmp = expand_binop (SImode, ior_optab, xor1, xor0,
NULL_RTX, 0, OPTAB_WIDEN); NULL_RTX, 0, OPTAB_WIDEN);
ix86_compare_op0 = tmp; ix86_compare_op0 = tmp;
ix86_compare_op1 = const0_rtx; ix86_compare_op1 = const0_rtx;
ix86_expand_branch (code, unordered, label); ix86_expand_branch (code, label);
return; return;
} }
...@@ -4711,7 +4901,7 @@ ix86_expand_branch (code, unordered, label) ...@@ -4711,7 +4901,7 @@ ix86_expand_branch (code, unordered, label)
{ {
ix86_compare_op0 = hi[0]; ix86_compare_op0 = hi[0];
ix86_compare_op1 = hi[1]; ix86_compare_op1 = hi[1];
ix86_expand_branch (code, unordered, label); ix86_expand_branch (code, label);
return; return;
} }
...@@ -4752,22 +4942,27 @@ ix86_expand_branch (code, unordered, label) ...@@ -4752,22 +4942,27 @@ ix86_expand_branch (code, unordered, label)
ix86_compare_op1 = hi[1]; ix86_compare_op1 = hi[1];
if (code1 != NIL) if (code1 != NIL)
ix86_expand_branch (code1, unordered, label); ix86_expand_branch (code1, label);
if (code2 != NIL) if (code2 != NIL)
ix86_expand_branch (code2, unordered, label2); ix86_expand_branch (code2, label2);
ix86_compare_op0 = lo[0]; ix86_compare_op0 = lo[0];
ix86_compare_op1 = lo[1]; ix86_compare_op1 = lo[1];
ix86_expand_branch (code3, unordered, label); ix86_expand_branch (code3, label);
if (code2 != NIL) if (code2 != NIL)
emit_label (label2); emit_label (label2);
return;
}
default:
abort ();
}
} }
int int
ix86_expand_setcc (code, unordered, dest) ix86_expand_setcc (code, dest)
enum rtx_code code; enum rtx_code code;
int unordered;
rtx dest; rtx dest;
{ {
rtx ret, tmp; rtx ret, tmp;
...@@ -4796,7 +4991,7 @@ ix86_expand_setcc (code, unordered, dest) ...@@ -4796,7 +4991,7 @@ ix86_expand_setcc (code, unordered, dest)
if (type == 0) if (type == 0)
emit_move_insn (dest, const0_rtx); emit_move_insn (dest, const0_rtx);
ret = ix86_expand_compare (code, unordered); ret = ix86_expand_compare (code);
PUT_MODE (ret, QImode); PUT_MODE (ret, QImode);
tmp = dest; tmp = dest;
...@@ -4853,8 +5048,9 @@ ix86_expand_int_movcc (operands) ...@@ -4853,8 +5048,9 @@ ix86_expand_int_movcc (operands)
code = GEU; code = GEU;
ix86_compare_op1 = GEN_INT (INTVAL (ix86_compare_op1) + 1); ix86_compare_op1 = GEN_INT (INTVAL (ix86_compare_op1) + 1);
} }
start_sequence (); start_sequence ();
compare_op = ix86_expand_compare (code, code == EQ || code == NE); compare_op = ix86_expand_compare (code);
compare_seq = gen_sequence (); compare_seq = gen_sequence ();
end_sequence (); end_sequence ();
...@@ -5165,7 +5361,7 @@ ix86_expand_fp_movcc (operands) ...@@ -5165,7 +5361,7 @@ ix86_expand_fp_movcc (operands)
case GE: case GE:
case GT: case GT:
tmp = gen_reg_rtx (QImode); tmp = gen_reg_rtx (QImode);
ix86_expand_setcc (code, 0, tmp); ix86_expand_setcc (code, tmp);
code = NE; code = NE;
ix86_compare_op0 = tmp; ix86_compare_op0 = tmp;
ix86_compare_op1 = const0_rtx; ix86_compare_op1 = const0_rtx;
......
...@@ -2508,6 +2508,8 @@ do { long l; \ ...@@ -2508,6 +2508,8 @@ do { long l; \
{"non_q_regs_operand", {SUBREG, REG}}, \ {"non_q_regs_operand", {SUBREG, REG}}, \
{"no_comparison_operator", {EQ, NE, LT, GE, LTU, GTU, LEU, GEU}}, \ {"no_comparison_operator", {EQ, NE, LT, GE, LTU, GTU, LEU, GEU}}, \
{"fcmov_comparison_operator", {EQ, NE, LTU, GTU, LEU, GEU}}, \ {"fcmov_comparison_operator", {EQ, NE, LTU, GTU, LEU, GEU}}, \
{"uno_comparison_operator", {EQ, NE, LE, LT, GE, GT, LEU, LTU, GEU, \
GTU, UNORDERED, ORDERED}}, \
{"cmp_fp_expander_operand", {CONST_DOUBLE, SUBREG, REG, MEM}}, \ {"cmp_fp_expander_operand", {CONST_DOUBLE, SUBREG, REG, MEM}}, \
{"ext_register_operand", {SUBREG, REG}}, \ {"ext_register_operand", {SUBREG, REG}}, \
{"binary_fp_operator", {PLUS, MINUS, MULT, DIV}}, \ {"binary_fp_operator", {PLUS, MINUS, MULT, DIV}}, \
......
...@@ -6605,61 +6605,109 @@ ...@@ -6605,61 +6605,109 @@
[(set (match_operand:SI 0 "register_operand" "") [(set (match_operand:SI 0 "register_operand" "")
(eq:SI (reg:CC 17) (const_int 0)))] (eq:SI (reg:CC 17) (const_int 0)))]
"" ""
"if (ix86_expand_setcc (EQ, 1, operands[0])) DONE; else FAIL;") "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
(define_expand "sne" (define_expand "sne"
[(set (match_operand:SI 0 "register_operand" "") [(set (match_operand:SI 0 "register_operand" "")
(ne:SI (reg:CC 17) (const_int 0)))] (ne:SI (reg:CC 17) (const_int 0)))]
"" ""
"if (ix86_expand_setcc (NE, 1, operands[0])) DONE; else FAIL;") "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
(define_expand "sgt" (define_expand "sgt"
[(set (match_operand:SI 0 "register_operand" "") [(set (match_operand:SI 0 "register_operand" "")
(gt:SI (reg:CC 17) (const_int 0)))] (gt:SI (reg:CC 17) (const_int 0)))]
"" ""
"if (ix86_expand_setcc (GT, 0, operands[0])) DONE; else FAIL;") "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
(define_expand "sgtu" (define_expand "sgtu"
[(set (match_operand:SI 0 "register_operand" "") [(set (match_operand:SI 0 "register_operand" "")
(gtu:SI (reg:CC 17) (const_int 0)))] (gtu:SI (reg:CC 17) (const_int 0)))]
"" ""
"if (ix86_expand_setcc (GTU, 0, operands[0])) DONE; else FAIL;") "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
(define_expand "slt" (define_expand "slt"
[(set (match_operand:SI 0 "register_operand" "") [(set (match_operand:SI 0 "register_operand" "")
(lt:SI (reg:CC 17) (const_int 0)))] (lt:SI (reg:CC 17) (const_int 0)))]
"" ""
"if (ix86_expand_setcc (LT, 0, operands[0])) DONE; else FAIL;") "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
(define_expand "sltu" (define_expand "sltu"
[(set (match_operand:SI 0 "register_operand" "") [(set (match_operand:SI 0 "register_operand" "")
(ltu:SI (reg:CC 17) (const_int 0)))] (ltu:SI (reg:CC 17) (const_int 0)))]
"" ""
"if (ix86_expand_setcc (LTU, 0, operands[0])) DONE; else FAIL;") "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
(define_expand "sge" (define_expand "sge"
[(set (match_operand:SI 0 "register_operand" "") [(set (match_operand:SI 0 "register_operand" "")
(ge:SI (reg:CC 17) (const_int 0)))] (ge:SI (reg:CC 17) (const_int 0)))]
"" ""
"if (ix86_expand_setcc (GE, 0, operands[0])) DONE; else FAIL;") "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
(define_expand "sgeu" (define_expand "sgeu"
[(set (match_operand:SI 0 "register_operand" "") [(set (match_operand:SI 0 "register_operand" "")
(geu:SI (reg:CC 17) (const_int 0)))] (geu:SI (reg:CC 17) (const_int 0)))]
"" ""
"if (ix86_expand_setcc (GEU, 0, operands[0])) DONE; else FAIL;") "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
(define_expand "sle" (define_expand "sle"
[(set (match_operand:SI 0 "register_operand" "") [(set (match_operand:SI 0 "register_operand" "")
(le:SI (reg:CC 17) (const_int 0)))] (le:SI (reg:CC 17) (const_int 0)))]
"" ""
"if (ix86_expand_setcc (LE, 0, operands[0])) DONE; else FAIL;") "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
(define_expand "sleu" (define_expand "sleu"
[(set (match_operand:SI 0 "register_operand" "") [(set (match_operand:SI 0 "register_operand" "")
(leu:SI (reg:CC 17) (const_int 0)))] (leu:SI (reg:CC 17) (const_int 0)))]
"" ""
"if (ix86_expand_setcc (LEU, 0, operands[0])) DONE; else FAIL;") "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
(define_expand "sunordered"
[(set (match_operand:SI 0 "register_operand" "")
(unordered:SI (reg:CC 17) (const_int 0)))]
"TARGET_80387"
"if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
(define_expand "sordered"
[(set (match_operand:SI 0 "register_operand" "")
(ordered:SI (reg:CC 17) (const_int 0)))]
"TARGET_80387"
"if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
(define_expand "suneq"
[(set (match_operand:SI 0 "register_operand" "")
(uneq:SI (reg:CC 17) (const_int 0)))]
"TARGET_80387"
"if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
(define_expand "sunge"
[(set (match_operand:SI 0 "register_operand" "")
(unge:SI (reg:CC 17) (const_int 0)))]
"TARGET_80387"
"if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
(define_expand "sungt"
[(set (match_operand:SI 0 "register_operand" "")
(ungt:SI (reg:CC 17) (const_int 0)))]
"TARGET_80387"
"if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
(define_expand "sunle"
[(set (match_operand:SI 0 "register_operand" "")
(unle:SI (reg:CC 17) (const_int 0)))]
"TARGET_80387"
"if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
(define_expand "sunlt"
[(set (match_operand:SI 0 "register_operand" "")
(unlt:SI (reg:CC 17) (const_int 0)))]
"TARGET_80387"
"if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
(define_expand "sltgt"
[(set (match_operand:SI 0 "register_operand" "")
(ltgt:SI (reg:CC 17) (const_int 0)))]
"TARGET_80387"
"if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
(define_insn "*setcc_1" (define_insn "*setcc_1"
[(set (match_operand:QI 0 "nonimmediate_operand" "=qm") [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
...@@ -6679,7 +6727,7 @@ ...@@ -6679,7 +6727,7 @@
(define_insn "*setcc_3" (define_insn "*setcc_3"
[(set (match_operand:QI 0 "nonimmediate_operand" "=qm") [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
(match_operator:QI 1 "comparison_operator" (match_operator:QI 1 "uno_comparison_operator"
[(reg:CC 17) (const_int 0)]))] [(reg:CC 17) (const_int 0)]))]
"" ""
"set%C1\\t%0" "set%C1\\t%0"
...@@ -6687,7 +6735,7 @@ ...@@ -6687,7 +6735,7 @@
(define_insn "*setcc_4" (define_insn "*setcc_4"
[(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm")) [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
(match_operator:QI 1 "comparison_operator" (match_operator:QI 1 "uno_comparison_operator"
[(reg:CC 17) (const_int 0)]))] [(reg:CC 17) (const_int 0)]))]
"" ""
"set%C1\\t%0" "set%C1\\t%0"
...@@ -6705,7 +6753,7 @@ ...@@ -6705,7 +6753,7 @@
(label_ref (match_operand 0 "" "")) (label_ref (match_operand 0 "" ""))
(pc)))] (pc)))]
"" ""
"ix86_expand_branch (EQ, 1, operands[0]); DONE;") "ix86_expand_branch (EQ, operands[0]); DONE;")
(define_expand "bne" (define_expand "bne"
[(set (pc) [(set (pc)
...@@ -6713,7 +6761,7 @@ ...@@ -6713,7 +6761,7 @@
(label_ref (match_operand 0 "" "")) (label_ref (match_operand 0 "" ""))
(pc)))] (pc)))]
"" ""
"ix86_expand_branch (NE, 1, operands[0]); DONE;") "ix86_expand_branch (NE, operands[0]); DONE;")
(define_expand "bgt" (define_expand "bgt"
[(set (pc) [(set (pc)
...@@ -6721,7 +6769,7 @@ ...@@ -6721,7 +6769,7 @@
(label_ref (match_operand 0 "" "")) (label_ref (match_operand 0 "" ""))
(pc)))] (pc)))]
"" ""
"ix86_expand_branch (GT, 0, operands[0]); DONE;") "ix86_expand_branch (GT, operands[0]); DONE;")
(define_expand "bgtu" (define_expand "bgtu"
[(set (pc) [(set (pc)
...@@ -6729,7 +6777,7 @@ ...@@ -6729,7 +6777,7 @@
(label_ref (match_operand 0 "" "")) (label_ref (match_operand 0 "" ""))
(pc)))] (pc)))]
"" ""
"ix86_expand_branch (GTU, 0, operands[0]); DONE;") "ix86_expand_branch (GTU, operands[0]); DONE;")
(define_expand "blt" (define_expand "blt"
[(set (pc) [(set (pc)
...@@ -6737,7 +6785,7 @@ ...@@ -6737,7 +6785,7 @@
(label_ref (match_operand 0 "" "")) (label_ref (match_operand 0 "" ""))
(pc)))] (pc)))]
"" ""
"ix86_expand_branch (LT, 0, operands[0]); DONE;") "ix86_expand_branch (LT, operands[0]); DONE;")
(define_expand "bltu" (define_expand "bltu"
[(set (pc) [(set (pc)
...@@ -6745,7 +6793,7 @@ ...@@ -6745,7 +6793,7 @@
(label_ref (match_operand 0 "" "")) (label_ref (match_operand 0 "" ""))
(pc)))] (pc)))]
"" ""
"ix86_expand_branch (LTU, 0, operands[0]); DONE;") "ix86_expand_branch (LTU, operands[0]); DONE;")
(define_expand "bge" (define_expand "bge"
[(set (pc) [(set (pc)
...@@ -6753,7 +6801,7 @@ ...@@ -6753,7 +6801,7 @@
(label_ref (match_operand 0 "" "")) (label_ref (match_operand 0 "" ""))
(pc)))] (pc)))]
"" ""
"ix86_expand_branch (GE, 0, operands[0]); DONE;") "ix86_expand_branch (GE, operands[0]); DONE;")
(define_expand "bgeu" (define_expand "bgeu"
[(set (pc) [(set (pc)
...@@ -6761,7 +6809,7 @@ ...@@ -6761,7 +6809,7 @@
(label_ref (match_operand 0 "" "")) (label_ref (match_operand 0 "" ""))
(pc)))] (pc)))]
"" ""
"ix86_expand_branch (GEU, 0, operands[0]); DONE;") "ix86_expand_branch (GEU, operands[0]); DONE;")
(define_expand "ble" (define_expand "ble"
[(set (pc) [(set (pc)
...@@ -6769,7 +6817,7 @@ ...@@ -6769,7 +6817,7 @@
(label_ref (match_operand 0 "" "")) (label_ref (match_operand 0 "" ""))
(pc)))] (pc)))]
"" ""
"ix86_expand_branch (LE, 0, operands[0]); DONE;") "ix86_expand_branch (LE, operands[0]); DONE;")
(define_expand "bleu" (define_expand "bleu"
[(set (pc) [(set (pc)
...@@ -6777,7 +6825,71 @@ ...@@ -6777,7 +6825,71 @@
(label_ref (match_operand 0 "" "")) (label_ref (match_operand 0 "" ""))
(pc)))] (pc)))]
"" ""
"ix86_expand_branch (LEU, 0, operands[0]); DONE;") "ix86_expand_branch (LEU, operands[0]); DONE;")
(define_expand "bunordered"
[(set (pc)
(if_then_else (match_dup 1)
(label_ref (match_operand 0 "" ""))
(pc)))]
"TARGET_80387"
"ix86_expand_branch (UNORDERED, operands[0]); DONE;")
(define_expand "bordered"
[(set (pc)
(if_then_else (match_dup 1)
(label_ref (match_operand 0 "" ""))
(pc)))]
"TARGET_80387"
"ix86_expand_branch (ORDERED, operands[0]); DONE;")
(define_expand "buneq"
[(set (pc)
(if_then_else (match_dup 1)
(label_ref (match_operand 0 "" ""))
(pc)))]
"TARGET_80387"
"ix86_expand_branch (UNEQ, operands[0]); DONE;")
(define_expand "bunge"
[(set (pc)
(if_then_else (match_dup 1)
(label_ref (match_operand 0 "" ""))
(pc)))]
"TARGET_80387"
"ix86_expand_branch (UNGE, operands[0]); DONE;")
(define_expand "bungt"
[(set (pc)
(if_then_else (match_dup 1)
(label_ref (match_operand 0 "" ""))
(pc)))]
"TARGET_80387"
"ix86_expand_branch (UNGT, operands[0]); DONE;")
(define_expand "bunle"
[(set (pc)
(if_then_else (match_dup 1)
(label_ref (match_operand 0 "" ""))
(pc)))]
"TARGET_80387"
"ix86_expand_branch (UNLE, operands[0]); DONE;")
(define_expand "bunlt"
[(set (pc)
(if_then_else (match_dup 1)
(label_ref (match_operand 0 "" ""))
(pc)))]
"TARGET_80387"
"ix86_expand_branch (UNLT, operands[0]); DONE;")
(define_expand "bltgt"
[(set (pc)
(if_then_else (match_dup 1)
(label_ref (match_operand 0 "" ""))
(pc)))]
"TARGET_80387"
"ix86_expand_branch (LTGT, operands[0]); DONE;")
(define_insn "*jcc_1" (define_insn "*jcc_1"
[(set (pc) [(set (pc)
...@@ -6815,7 +6927,7 @@ ...@@ -6815,7 +6927,7 @@
(define_insn "*jcc_3" (define_insn "*jcc_3"
[(set (pc) [(set (pc)
(if_then_else (match_operator 0 "comparison_operator" (if_then_else (match_operator 0 "uno_comparison_operator"
[(reg:CC 17) (const_int 0)]) [(reg:CC 17) (const_int 0)])
(label_ref (match_operand 1 "" "")) (label_ref (match_operand 1 "" ""))
(pc)))] (pc)))]
...@@ -6832,7 +6944,7 @@ ...@@ -6832,7 +6944,7 @@
(define_insn "*jcc_4" (define_insn "*jcc_4"
[(set (pc) [(set (pc)
(if_then_else (match_operator 0 "comparison_operator" (if_then_else (match_operator 0 "uno_comparison_operator"
[(reg:CC 17) (const_int 0)]) [(reg:CC 17) (const_int 0)])
(pc) (pc)
(label_ref (match_operand 1 "" ""))))] (label_ref (match_operand 1 "" ""))))]
...@@ -6847,6 +6959,139 @@ ...@@ -6847,6 +6959,139 @@
(const_int 2) (const_int 2)
(const_int 6)))]) (const_int 6)))])
;; Define combination compare-and-branch fp compare instructions to use
;; during early optimization. Splitting the operation apart early makes
;; for bad code when we want to reverse the operation.
(define_insn "*fp_jcc_1"
[(set (pc)
(if_then_else (match_operator 0 "comparison_operator"
[(match_operand 1 "register_operand" "f")
(match_operand 2 "register_operand" "f")])
(label_ref (match_operand 3 "" ""))
(pc)))
(clobber (reg:CCFP 18))
(clobber (reg:CCFP 17))]
"TARGET_CMOVE && TARGET_80387
&& FLOAT_MODE_P (GET_MODE (operands[1]))
&& GET_MODE (operands[1]) == GET_MODE (operands[2])"
"#")
(define_insn "*fp_jcc_2"
[(set (pc)
(if_then_else (match_operator 0 "comparison_operator"
[(match_operand 1 "register_operand" "f")
(match_operand 2 "register_operand" "f")])
(pc)
(label_ref (match_operand 3 "" ""))))
(clobber (reg:CCFP 18))
(clobber (reg:CCFP 17))]
"TARGET_CMOVE && TARGET_80387
&& FLOAT_MODE_P (GET_MODE (operands[1]))
&& GET_MODE (operands[1]) == GET_MODE (operands[2])"
"#")
(define_insn "*fp_jcc_3"
[(set (pc)
(if_then_else (match_operator:CCFP 0 "comparison_operator"
[(match_operand 1 "register_operand" "f")
(match_operand 2 "nonimmediate_operand" "fm")])
(label_ref (match_operand 3 "" ""))
(pc)))
(clobber (reg:CCFP 18))
(clobber (reg:CCFP 17))
(clobber (match_scratch:HI 4 "=a"))]
"TARGET_80387
&& (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
&& GET_MODE (operands[1]) == GET_MODE (operands[2])"
"#")
(define_insn "*fp_jcc_4"
[(set (pc)
(if_then_else (match_operator:CCFP 0 "comparison_operator"
[(match_operand 1 "register_operand" "f")
(match_operand 2 "nonimmediate_operand" "fm")])
(pc)
(label_ref (match_operand 3 "" ""))))
(clobber (reg:CCFP 18))
(clobber (reg:CCFP 17))
(clobber (match_scratch:HI 4 "=a"))]
"TARGET_80387
&& (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
&& GET_MODE (operands[1]) == GET_MODE (operands[2])"
"#")
(define_insn "*fp_jcc_5"
[(set (pc)
(if_then_else (match_operator 0 "comparison_operator"
[(match_operand 1 "register_operand" "f")
(match_operand 2 "register_operand" "f")])
(label_ref (match_operand 3 "" ""))
(pc)))
(clobber (reg:CCFP 18))
(clobber (reg:CCFP 17))
(clobber (match_scratch:HI 4 "=a"))]
"TARGET_80387
&& FLOAT_MODE_P (GET_MODE (operands[1]))
&& GET_MODE (operands[1]) == GET_MODE (operands[2])"
"#")
(define_insn "*fp_jcc_6"
[(set (pc)
(if_then_else (match_operator 0 "comparison_operator"
[(match_operand 1 "register_operand" "f")
(match_operand 2 "register_operand" "f")])
(pc)
(label_ref (match_operand 3 "" ""))))
(clobber (reg:CCFP 18))
(clobber (reg:CCFP 17))
(clobber (match_scratch:HI 4 "=a"))]
"TARGET_80387
&& FLOAT_MODE_P (GET_MODE (operands[1]))
&& GET_MODE (operands[1]) == GET_MODE (operands[2])"
"#")
(define_split
[(set (pc)
(if_then_else (match_operator 0 "comparison_operator"
[(match_operand 1 "register_operand" "")
(match_operand 2 "nonimmediate_operand" "")])
(match_operand 3 "" "")
(match_operand 4 "" "")))
(clobber (reg:CCFP 18))
(clobber (reg:CCFP 17))]
"reload_completed"
[(set (pc)
(if_then_else (match_dup 5)
(match_dup 3)
(match_dup 4)))]
"
{
operands[5] = ix86_expand_fp_compare (GET_CODE (operands[0]), operands[1],
operands[2], NULL_RTX);
}")
(define_split
[(set (pc)
(if_then_else (match_operator 0 "comparison_operator"
[(match_operand 1 "register_operand" "")
(match_operand 2 "nonimmediate_operand" "")])
(match_operand 3 "" "")
(match_operand 4 "" "")))
(clobber (reg:CCFP 18))
(clobber (reg:CCFP 17))
(clobber (match_scratch:HI 5 "=a"))]
"reload_completed"
[(set (pc)
(if_then_else (match_dup 6)
(match_dup 3)
(match_dup 4)))]
"
{
operands[6] = ix86_expand_fp_compare (GET_CODE (operands[0]), operands[1],
operands[2], operands[5]);
}")
;; Unconditional and other jump instructions ;; Unconditional and other jump instructions
(define_insn "jump" (define_insn "jump"
...@@ -8824,7 +9069,7 @@ ...@@ -8824,7 +9069,7 @@
(define_insn "*movsicc_c" (define_insn "*movsicc_c"
[(set (match_operand:SI 0 "register_operand" "=r,r") [(set (match_operand:SI 0 "register_operand" "=r,r")
(if_then_else:SI (match_operator 1 "comparison_operator" (if_then_else:SI (match_operator 1 "uno_comparison_operator"
[(reg:CC 17) (const_int 0)]) [(reg:CC 17) (const_int 0)])
(match_operand:SI 2 "nonimmediate_operand" "rm,0") (match_operand:SI 2 "nonimmediate_operand" "rm,0")
(match_operand:SI 3 "nonimmediate_operand" "0,rm")))] (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
...@@ -8858,7 +9103,7 @@ ...@@ -8858,7 +9103,7 @@
(define_insn "*movhicc_c" (define_insn "*movhicc_c"
[(set (match_operand:HI 0 "register_operand" "=r,r") [(set (match_operand:HI 0 "register_operand" "=r,r")
(if_then_else:HI (match_operator 1 "comparison_operator" (if_then_else:HI (match_operator 1 "uno_comparison_operator"
[(reg:CC 17) (const_int 0)]) [(reg:CC 17) (const_int 0)])
(match_operand:HI 2 "nonimmediate_operand" "rm,0") (match_operand:HI 2 "nonimmediate_operand" "rm,0")
(match_operand:HI 3 "nonimmediate_operand" "0,rm")))] (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
......
...@@ -211,7 +211,9 @@ static struct pred_table ...@@ -211,7 +211,9 @@ static struct pred_table
{"pop_operand", {MEM}}, {"pop_operand", {MEM}},
{"memory_operand", {SUBREG, MEM}}, {"memory_operand", {SUBREG, MEM}},
{"indirect_operand", {SUBREG, MEM}}, {"indirect_operand", {SUBREG, MEM}},
{"comparison_operator", {EQ, NE, LE, LT, GE, GT, LEU, LTU, GEU, GTU}}, {"comparison_operator", {EQ, NE, LE, LT, GE, GT, LEU, LTU, GEU, GTU,
UNORDERED, ORDERED, UNEQ, UNGE, UNGT, UNLE,
UNLT, LTGT}},
{"mode_independent_operand", {CONST_INT, CONST_DOUBLE, CONST, SYMBOL_REF, {"mode_independent_operand", {CONST_INT, CONST_DOUBLE, CONST, SYMBOL_REF,
LABEL_REF, SUBREG, REG, MEM}} LABEL_REF, SUBREG, REG, MEM}}
}; };
......
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