Commit eaa49b49 by Richard Henderson Committed by Richard Henderson

re PR target/19009 (Loading of FP constants into FP reg via SSE reg)

        PR target/19099
        PR target/19250
        PR target/19252
        * config/i386/i386.md (cmpdf, cmpsf, bunordered, bordered, buneq,
        bunge, bungt, bunle, bunlt, bltgt): Enable for TARGET_SSE_MATH,
        not just TARGET_SSE.
        (cmpfp_i_387): Rename from cmpfp_i.  Move after sse patterns.
        (cmpfp_i_mixed): Rename from cmpfp_i_sse; use for TARGET_MIX_SSE_I387.
        (cmpfp_i_sse): Rename from cmpfp_i_sse_only; use for TARGET_SSE_MATH.
        (cmpfp_iu_mixed, cmpfp_iu_sse, cmpfp_iu_387): Similarly.
        (fp_jcc_1_mixed, fp_jcc_1_sse, fp_jcc_1_387): Similarly.
        (fp_jcc_2_mixed, fp_jcc_2_sse, fp_jcc_2_387): Similarly.
        (fp_jcc_3_387, fp_jcc_4_387, fp_jcc_5_387, fp_jcc_6_387,
        fp_jcc_7_387, fp_jcc_8_387): Rename from fp_jcc_N.
        (movdicc_c_rex64): Rename with '*'.
        (movsfcc, movdfcc): Add checks for 387 and sse math to condition.
        (movsfcc_1_sse_min, movsfcc_1_sse_max, movsfcc_1_sse): New.
        (movsfcc_1_387): Rename from movsfcc_1.
        (movdfcc_1_sse_min, movdfcc_1_sse_max, movdfcc_1_sse): New.
        (movdfcc_1, movdfcc_1_rex64): Add check for 387.
        (sminsf3, smaxsf3, smindf3, smaxdf3): New.
        (minsf3, minsf, minsf_nonieee, minsf_sse, mindf3, mindf,
        mindf_nonieee, mindf_sse, maxsf3, maxsf, maxsf_nonieee, maxsf_sse,
        maxdf3, maxdf, maxdf_nonieee, maxdf_sse, sse_movsfcc, sse_movsfcc_eq,
        sse_movdfcc, sse_movdfcc_eq, sse_movsfcc_const0_1,
        sse_movsfcc_const0_2, sse_movsfcc_const0_3, sse_movsfcc_const0_4,
        sse_movdfcc_const0_1, sse_movdfcc_const0_2, sse_movdfcc_const0_3,
        sse_movdfcc_const0_4): Remove.
        * config/i386/i386.c (ix86_expand_fp_movcc): For TARGET_SSE_MATH,
        recognize min/max early.  Update for changed sse cmove patterns.
        (ix86_split_sse_movcc): New.
        * config/i386/i386-protos.h: Update.

From-SVN: r93620
parent 997e120f
2005-01-13 Richard Henderson <rth@redhat.com>
PR target/19099
PR target/19250
PR target/19252
* config/i386/i386.md (cmpdf, cmpsf, bunordered, bordered, buneq,
bunge, bungt, bunle, bunlt, bltgt): Enable for TARGET_SSE_MATH,
not just TARGET_SSE.
(cmpfp_i_387): Rename from cmpfp_i. Move after sse patterns.
(cmpfp_i_mixed): Rename from cmpfp_i_sse; use for TARGET_MIX_SSE_I387.
(cmpfp_i_sse): Rename from cmpfp_i_sse_only; use for TARGET_SSE_MATH.
(cmpfp_iu_mixed, cmpfp_iu_sse, cmpfp_iu_387): Similarly.
(fp_jcc_1_mixed, fp_jcc_1_sse, fp_jcc_1_387): Similarly.
(fp_jcc_2_mixed, fp_jcc_2_sse, fp_jcc_2_387): Similarly.
(fp_jcc_3_387, fp_jcc_4_387, fp_jcc_5_387, fp_jcc_6_387,
fp_jcc_7_387, fp_jcc_8_387): Rename from fp_jcc_N.
(movdicc_c_rex64): Rename with '*'.
(movsfcc, movdfcc): Add checks for 387 and sse math to condition.
(movsfcc_1_sse_min, movsfcc_1_sse_max, movsfcc_1_sse): New.
(movsfcc_1_387): Rename from movsfcc_1.
(movdfcc_1_sse_min, movdfcc_1_sse_max, movdfcc_1_sse): New.
(movdfcc_1, movdfcc_1_rex64): Add check for 387.
(sminsf3, smaxsf3, smindf3, smaxdf3): New.
(minsf3, minsf, minsf_nonieee, minsf_sse, mindf3, mindf,
mindf_nonieee, mindf_sse, maxsf3, maxsf, maxsf_nonieee, maxsf_sse,
maxdf3, maxdf, maxdf_nonieee, maxdf_sse, sse_movsfcc, sse_movsfcc_eq,
sse_movdfcc, sse_movdfcc_eq, sse_movsfcc_const0_1,
sse_movsfcc_const0_2, sse_movsfcc_const0_3, sse_movsfcc_const0_4,
sse_movdfcc_const0_1, sse_movdfcc_const0_2, sse_movdfcc_const0_3,
sse_movdfcc_const0_4): Remove.
* config/i386/i386.c (ix86_expand_fp_movcc): For TARGET_SSE_MATH,
recognize min/max early. Update for changed sse cmove patterns.
(ix86_split_sse_movcc): New.
* config/i386/i386-protos.h: Update.
2005-01-13 Steven Bosscher <stevenb@suse.de>
* tree-ssa-dse.c (fix_phi_uses): Use SSA operand iterators.
......
......@@ -145,6 +145,7 @@ extern void ix86_expand_branch (enum rtx_code, rtx);
extern int ix86_expand_setcc (enum rtx_code, rtx);
extern int ix86_expand_int_movcc (rtx[]);
extern int ix86_expand_fp_movcc (rtx[]);
extern void ix86_split_sse_movcc (rtx[]);
extern int ix86_expand_int_addcc (rtx[]);
extern void ix86_expand_call (rtx, rtx, rtx, rtx, rtx, int);
extern void x86_initialize_trampoline (rtx, rtx, rtx);
......
......@@ -9743,118 +9743,95 @@ ix86_expand_int_movcc (rtx operands[])
int
ix86_expand_fp_movcc (rtx operands[])
{
enum rtx_code code;
rtx tmp;
rtx compare_op, second_test, bypass_test;
/* For SF/DFmode conditional moves based on comparisons
in same mode, we may want to use SSE min/max instructions. */
if (((TARGET_SSE_MATH && GET_MODE (operands[0]) == SFmode)
|| (TARGET_SSE2 && TARGET_SSE_MATH && GET_MODE (operands[0]) == DFmode))
&& GET_MODE (ix86_compare_op0) == GET_MODE (operands[0])
/* The SSE comparisons does not support the LTGT/UNEQ pair. */
&& (!TARGET_IEEE_FP
|| (GET_CODE (operands[1]) != LTGT && GET_CODE (operands[1]) != UNEQ))
/* We may be called from the post-reload splitter. */
&& (!REG_P (operands[0])
|| SSE_REG_P (operands[0])
|| REGNO (operands[0]) >= FIRST_PSEUDO_REGISTER))
{
rtx op0 = ix86_compare_op0, op1 = ix86_compare_op1;
code = GET_CODE (operands[1]);
/* See if we have (cross) match between comparison operands and
conditional move operands. */
if (rtx_equal_p (operands[2], op1))
enum machine_mode mode = GET_MODE (operands[0]);
enum rtx_code code = GET_CODE (operands[1]);
rtx tmp, compare_op, second_test, bypass_test;
if (TARGET_SSE_MATH && SSE_FLOAT_MODE_P (mode))
{
rtx cmp_op0, cmp_op1, if_true, if_false;
rtx clob;
enum machine_mode vmode, cmode;
bool is_minmax = false;
cmp_op0 = ix86_compare_op0;
cmp_op1 = ix86_compare_op1;
if_true = operands[2];
if_false = operands[3];
/* Since we've no cmove for sse registers, don't force bad register
allocation just to gain access to it. Deny movcc when the
comparison mode doesn't match the move mode. */
cmode = GET_MODE (cmp_op0);
if (cmode == VOIDmode)
cmode = GET_MODE (cmp_op1);
if (cmode != mode)
return 0;
/* Massage condition to satisfy sse_comparison_operator. In case we
are in non-ieee mode, try to canonicalize the destination operand
to be first in the comparison - this helps reload to avoid extra
moves. */
if (!sse_comparison_operator (operands[1], VOIDmode)
|| ((COMMUTATIVE_P (operands[1]) || !TARGET_IEEE_FP)
&& rtx_equal_p (operands[0], cmp_op1)))
{
rtx tmp = op0;
op0 = op1;
op1 = tmp;
code = reverse_condition_maybe_unordered (code);
tmp = cmp_op0;
cmp_op0 = cmp_op1;
cmp_op1 = tmp;
code = swap_condition (code);
}
if (rtx_equal_p (operands[2], op0) && rtx_equal_p (operands[3], op1))
{
/* Check for min operation. */
if (code == LT || code == UNLE)
{
if (code == UNLE)
/* Detect conditional moves that exactly match min/max operational
semantics. Note that this is IEEE safe, as long as we don't
interchange the operands. Which is why we keep this in the form
if an IF_THEN_ELSE instead of reducing to SMIN/SMAX. */
if ((code == LT || code == UNGE) && REG_P (cmp_op0) && REG_P (cmp_op1))
{
rtx tmp = op0;
op0 = op1;
op1 = tmp;
}
operands[0] = force_reg (GET_MODE (operands[0]), operands[0]);
if (memory_operand (op0, VOIDmode))
op0 = force_reg (GET_MODE (operands[0]), op0);
if (GET_MODE (operands[0]) == SFmode)
emit_insn (gen_minsf3 (operands[0], op0, op1));
else
emit_insn (gen_mindf3 (operands[0], op0, op1));
return 1;
}
/* Check for max operation. */
if (code == GT || code == UNGE)
if (((cmp_op0 == if_true && cmp_op1 == if_false)
|| (cmp_op0 == if_false && cmp_op1 == if_true)))
{
is_minmax = true;
if (code == UNGE)
{
rtx tmp = op0;
op0 = op1;
op1 = tmp;
code = LT;
tmp = if_true;
if_true = if_false;
if_false = tmp;
}
operands[0] = force_reg (GET_MODE (operands[0]), operands[0]);
if (memory_operand (op0, VOIDmode))
op0 = force_reg (GET_MODE (operands[0]), op0);
if (GET_MODE (operands[0]) == SFmode)
emit_insn (gen_maxsf3 (operands[0], op0, op1));
else
emit_insn (gen_maxdf3 (operands[0], op0, op1));
return 1;
}
}
/* Manage condition to be sse_comparison_operator. In case we are
in non-ieee mode, try to canonicalize the destination operand
to be first in the comparison - this helps reload to avoid extra
moves. */
if (!sse_comparison_operator (operands[1], VOIDmode)
|| (rtx_equal_p (operands[0], ix86_compare_op1) && !TARGET_IEEE_FP))
if (mode == SFmode)
vmode = V4SFmode;
else if (mode == DFmode)
vmode = V2DFmode;
else
gcc_unreachable ();
cmp_op0 = force_reg (mode, cmp_op0);
if (!nonimmediate_operand (cmp_op1, mode))
cmp_op1 = force_reg (mode, cmp_op1);
tmp = gen_rtx_fmt_ee (code, mode, cmp_op0, cmp_op1);
gcc_assert (sse_comparison_operator (tmp, VOIDmode));
tmp = gen_rtx_IF_THEN_ELSE (mode, tmp, if_true, if_false);
tmp = gen_rtx_SET (VOIDmode, operands[0], tmp);
if (!is_minmax)
{
rtx tmp = ix86_compare_op0;
ix86_compare_op0 = ix86_compare_op1;
ix86_compare_op1 = tmp;
operands[1] = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[1])),
VOIDmode, ix86_compare_op0,
ix86_compare_op1);
}
/* Similarly try to manage result to be first operand of conditional
move. We also don't support the NE comparison on SSE, so try to
avoid it. */
if ((rtx_equal_p (operands[0], operands[3])
&& (!TARGET_IEEE_FP || GET_CODE (operands[1]) != EQ))
|| (GET_CODE (operands[1]) == NE && TARGET_IEEE_FP))
{
rtx tmp = operands[2];
operands[2] = operands[3];
operands[3] = tmp;
operands[1] = gen_rtx_fmt_ee (reverse_condition_maybe_unordered
(GET_CODE (operands[1])),
VOIDmode, ix86_compare_op0,
ix86_compare_op1);
clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (vmode));
tmp = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, tmp, clob));
}
if (GET_MODE (operands[0]) == SFmode)
emit_insn (gen_sse_movsfcc (operands[0], operands[1],
operands[2], operands[3],
ix86_compare_op0, ix86_compare_op1));
else
emit_insn (gen_sse_movdfcc (operands[0], operands[1],
operands[2], operands[3],
ix86_compare_op0, ix86_compare_op1));
emit_insn (tmp);
return 1;
}
/* The floating point conditional move instructions don't directly
support conditions resulting from a signed integer comparison. */
code = GET_CODE (operands[1]);
compare_op = ix86_expand_compare (code, &second_test, &bypass_test);
/* The floating point conditional move instructions don't directly
......@@ -9873,38 +9850,86 @@ ix86_expand_fp_movcc (rtx operands[])
}
if (bypass_test && reg_overlap_mentioned_p (operands[0], operands[3]))
{
tmp = gen_reg_rtx (GET_MODE (operands[0]));
tmp = gen_reg_rtx (mode);
emit_move_insn (tmp, operands[3]);
operands[3] = tmp;
}
if (second_test && reg_overlap_mentioned_p (operands[0], operands[2]))
{
tmp = gen_reg_rtx (GET_MODE (operands[0]));
tmp = gen_reg_rtx (mode);
emit_move_insn (tmp, operands[2]);
operands[2] = tmp;
}
emit_insn (gen_rtx_SET (VOIDmode, operands[0],
gen_rtx_IF_THEN_ELSE (GET_MODE (operands[0]),
compare_op,
operands[2],
operands[3])));
gen_rtx_IF_THEN_ELSE (mode, compare_op,
operands[2], operands[3])));
if (bypass_test)
emit_insn (gen_rtx_SET (VOIDmode, operands[0],
gen_rtx_IF_THEN_ELSE (GET_MODE (operands[0]),
bypass_test,
operands[3],
operands[0])));
gen_rtx_IF_THEN_ELSE (mode, bypass_test,
operands[3], operands[0])));
if (second_test)
emit_insn (gen_rtx_SET (VOIDmode, operands[0],
gen_rtx_IF_THEN_ELSE (GET_MODE (operands[0]),
second_test,
operands[2],
operands[0])));
gen_rtx_IF_THEN_ELSE (mode, second_test,
operands[2], operands[0])));
return 1;
}
void
ix86_split_sse_movcc (rtx operands[])
{
rtx dest, scratch, cmp, op_true, op_false, x;
enum machine_mode mode, vmode;
/* Note that the operator CMP has been set up with matching constraints
such that dest is valid for the comparison. Unless one of the true
or false operands are zero, the true operand has already been placed
in SCRATCH. */
dest = operands[0];
scratch = operands[1];
op_true = operands[2];
op_false = operands[3];
cmp = operands[4];
mode = GET_MODE (dest);
vmode = GET_MODE (scratch);
emit_insn (gen_rtx_SET (VOIDmode, dest, cmp));
dest = simplify_gen_subreg (vmode, dest, mode, 0);
if (op_false == CONST0_RTX (mode))
{
op_true = simplify_gen_subreg (vmode, op_true, mode, 0);
x = gen_rtx_AND (vmode, dest, op_true);
emit_insn (gen_rtx_SET (VOIDmode, dest, x));
}
else
{
op_false = simplify_gen_subreg (vmode, op_false, mode, 0);
if (op_true == CONST0_RTX (mode))
{
x = gen_rtx_NOT (vmode, dest);
x = gen_rtx_AND (vmode, x, op_false);
emit_insn (gen_rtx_SET (VOIDmode, dest, x));
}
else
{
x = gen_rtx_AND (vmode, scratch, dest);
emit_insn (gen_rtx_SET (VOIDmode, scratch, x));
x = gen_rtx_NOT (vmode, dest);
x = gen_rtx_AND (vmode, x, op_false);
emit_insn (gen_rtx_SET (VOIDmode, dest, x));
x = gen_rtx_IOR (vmode, dest, scratch);
emit_insn (gen_rtx_SET (VOIDmode, dest, x));
}
}
}
/* Expand conditional increment or decrement using adb/sbb instructions.
The default case using setcc followed by the conditional move can be
done by generic code. */
......
......@@ -774,7 +774,7 @@
[(set (reg:CC FLAGS_REG)
(compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
(match_operand:DF 1 "cmp_fp_expander_operand" "")))]
"TARGET_80387 || TARGET_SSE2"
"TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
{
ix86_compare_op0 = operands[0];
ix86_compare_op1 = operands[1];
......@@ -785,7 +785,7 @@
[(set (reg:CC FLAGS_REG)
(compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
(match_operand:SF 1 "cmp_fp_expander_operand" "")))]
"TARGET_80387 || TARGET_SSE"
"TARGET_80387 || TARGET_SSE_MATH"
{
ix86_compare_op0 = operands[0];
ix86_compare_op1 = operands[1];
......@@ -935,30 +935,11 @@
;; Pentium Pro can do steps 1 through 3 in one go.
(define_insn "*cmpfp_i"
[(set (reg:CCFP FLAGS_REG)
(compare:CCFP (match_operand 0 "register_operand" "f")
(match_operand 1 "register_operand" "f")))]
"TARGET_80387 && TARGET_CMOVE
&& !SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
&& FLOAT_MODE_P (GET_MODE (operands[0]))
&& GET_MODE (operands[0]) == GET_MODE (operands[1])"
"* return output_fp_compare (insn, operands, 1, 0);"
[(set_attr "type" "fcmp")
(set (attr "mode")
(cond [(match_operand:SF 1 "" "")
(const_string "SF")
(match_operand:DF 1 "" "")
(const_string "DF")
]
(const_string "XF")))
(set_attr "athlon_decode" "vector")])
(define_insn "*cmpfp_i_sse"
(define_insn "*cmpfp_i_mixed"
[(set (reg:CCFP FLAGS_REG)
(compare:CCFP (match_operand 0 "register_operand" "f#x,x#f")
(match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
"TARGET_80387
"TARGET_MIX_SSE_I387
&& SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
&& GET_MODE (operands[0]) == GET_MODE (operands[1])"
"* return output_fp_compare (insn, operands, 1, 0);"
......@@ -969,11 +950,12 @@
(const_string "DF")))
(set_attr "athlon_decode" "vector")])
(define_insn "*cmpfp_i_sse_only"
(define_insn "*cmpfp_i_sse"
[(set (reg:CCFP FLAGS_REG)
(compare:CCFP (match_operand 0 "register_operand" "x")
(match_operand 1 "nonimmediate_operand" "xm")))]
"SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
"TARGET_SSE_MATH
&& SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
&& GET_MODE (operands[0]) == GET_MODE (operands[1])"
"* return output_fp_compare (insn, operands, 1, 0);"
[(set_attr "type" "ssecomi")
......@@ -983,15 +965,15 @@
(const_string "DF")))
(set_attr "athlon_decode" "vector")])
(define_insn "*cmpfp_iu"
[(set (reg:CCFPU FLAGS_REG)
(compare:CCFPU (match_operand 0 "register_operand" "f")
(define_insn "*cmpfp_i_i387"
[(set (reg:CCFP FLAGS_REG)
(compare:CCFP (match_operand 0 "register_operand" "f")
(match_operand 1 "register_operand" "f")))]
"TARGET_80387 && TARGET_CMOVE
&& !SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
&& (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
&& FLOAT_MODE_P (GET_MODE (operands[0]))
&& GET_MODE (operands[0]) == GET_MODE (operands[1])"
"* return output_fp_compare (insn, operands, 1, 1);"
"* return output_fp_compare (insn, operands, 1, 0);"
[(set_attr "type" "fcmp")
(set (attr "mode")
(cond [(match_operand:SF 1 "" "")
......@@ -1002,11 +984,11 @@
(const_string "XF")))
(set_attr "athlon_decode" "vector")])
(define_insn "*cmpfp_iu_sse"
(define_insn "*cmpfp_iu_mixed"
[(set (reg:CCFPU FLAGS_REG)
(compare:CCFPU (match_operand 0 "register_operand" "f#x,x#f")
(match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
"TARGET_80387
"TARGET_MIX_SSE_I387
&& SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
&& GET_MODE (operands[0]) == GET_MODE (operands[1])"
"* return output_fp_compare (insn, operands, 1, 1);"
......@@ -1017,11 +999,12 @@
(const_string "DF")))
(set_attr "athlon_decode" "vector")])
(define_insn "*cmpfp_iu_sse_only"
(define_insn "*cmpfp_iu_sse"
[(set (reg:CCFPU FLAGS_REG)
(compare:CCFPU (match_operand 0 "register_operand" "x")
(match_operand 1 "nonimmediate_operand" "xm")))]
"SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
"TARGET_SSE_MATH
&& SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
&& GET_MODE (operands[0]) == GET_MODE (operands[1])"
"* return output_fp_compare (insn, operands, 1, 1);"
[(set_attr "type" "ssecomi")
......@@ -1031,6 +1014,25 @@
(const_string "DF")))
(set_attr "athlon_decode" "vector")])
(define_insn "*cmpfp_iu_387"
[(set (reg:CCFPU FLAGS_REG)
(compare:CCFPU (match_operand 0 "register_operand" "f")
(match_operand 1 "register_operand" "f")))]
"TARGET_80387 && TARGET_CMOVE
&& (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
&& FLOAT_MODE_P (GET_MODE (operands[0]))
&& GET_MODE (operands[0]) == GET_MODE (operands[1])"
"* return output_fp_compare (insn, operands, 1, 1);"
[(set_attr "type" "fcmp")
(set (attr "mode")
(cond [(match_operand:SF 1 "" "")
(const_string "SF")
(match_operand:DF 1 "" "")
(const_string "DF")
]
(const_string "XF")))
(set_attr "athlon_decode" "vector")])
;; Move instructions.
;; General case of fullword move.
......@@ -12683,7 +12685,7 @@
(if_then_else (match_dup 1)
(label_ref (match_operand 0 "" ""))
(pc)))]
"TARGET_80387 || TARGET_SSE"
"TARGET_80387 || TARGET_SSE_MATH"
"ix86_expand_branch (UNORDERED, operands[0]); DONE;")
(define_expand "bordered"
......@@ -12691,7 +12693,7 @@
(if_then_else (match_dup 1)
(label_ref (match_operand 0 "" ""))
(pc)))]
"TARGET_80387 || TARGET_SSE"
"TARGET_80387 || TARGET_SSE_MATH"
"ix86_expand_branch (ORDERED, operands[0]); DONE;")
(define_expand "buneq"
......@@ -12699,7 +12701,7 @@
(if_then_else (match_dup 1)
(label_ref (match_operand 0 "" ""))
(pc)))]
"TARGET_80387 || TARGET_SSE"
"TARGET_80387 || TARGET_SSE_MATH"
"ix86_expand_branch (UNEQ, operands[0]); DONE;")
(define_expand "bunge"
......@@ -12707,7 +12709,7 @@
(if_then_else (match_dup 1)
(label_ref (match_operand 0 "" ""))
(pc)))]
"TARGET_80387 || TARGET_SSE"
"TARGET_80387 || TARGET_SSE_MATH"
"ix86_expand_branch (UNGE, operands[0]); DONE;")
(define_expand "bungt"
......@@ -12715,7 +12717,7 @@
(if_then_else (match_dup 1)
(label_ref (match_operand 0 "" ""))
(pc)))]
"TARGET_80387 || TARGET_SSE"
"TARGET_80387 || TARGET_SSE_MATH"
"ix86_expand_branch (UNGT, operands[0]); DONE;")
(define_expand "bunle"
......@@ -12723,7 +12725,7 @@
(if_then_else (match_dup 1)
(label_ref (match_operand 0 "" ""))
(pc)))]
"TARGET_80387 || TARGET_SSE"
"TARGET_80387 || TARGET_SSE_MATH"
"ix86_expand_branch (UNLE, operands[0]); DONE;")
(define_expand "bunlt"
......@@ -12731,7 +12733,7 @@
(if_then_else (match_dup 1)
(label_ref (match_operand 0 "" ""))
(pc)))]
"TARGET_80387 || TARGET_SSE"
"TARGET_80387 || TARGET_SSE_MATH"
"ix86_expand_branch (UNLT, operands[0]); DONE;")
(define_expand "bltgt"
......@@ -12739,7 +12741,7 @@
(if_then_else (match_dup 1)
(label_ref (match_operand 0 "" ""))
(pc)))]
"TARGET_80387 || TARGET_SSE"
"TARGET_80387 || TARGET_SSE_MATH"
"ix86_expand_branch (LTGT, operands[0]); DONE;")
(define_insn "*jcc_1"
......@@ -12831,18 +12833,17 @@
;; during early optimization. Splitting the operation apart early makes
;; for bad code when we want to reverse the operation.
(define_insn "*fp_jcc_1"
(define_insn "*fp_jcc_1_mixed"
[(set (pc)
(if_then_else (match_operator 0 "comparison_operator"
[(match_operand 1 "register_operand" "f")
(match_operand 2 "register_operand" "f")])
[(match_operand 1 "register_operand" "f#x,x#f")
(match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
(label_ref (match_operand 3 "" ""))
(pc)))
(clobber (reg:CCFP FPSR_REG))
(clobber (reg:CCFP FLAGS_REG))]
"TARGET_CMOVE && TARGET_80387
&& !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
&& FLOAT_MODE_P (GET_MODE (operands[1]))
"TARGET_MIX_SSE_I387
&& SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
&& GET_MODE (operands[1]) == GET_MODE (operands[2])
&& ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
"#")
......@@ -12850,44 +12851,44 @@
(define_insn "*fp_jcc_1_sse"
[(set (pc)
(if_then_else (match_operator 0 "comparison_operator"
[(match_operand 1 "register_operand" "f#x,x#f")
(match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
[(match_operand 1 "register_operand" "x")
(match_operand 2 "nonimmediate_operand" "xm")])
(label_ref (match_operand 3 "" ""))
(pc)))
(clobber (reg:CCFP FPSR_REG))
(clobber (reg:CCFP FLAGS_REG))]
"TARGET_80387
"TARGET_SSE_MATH
&& SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
&& GET_MODE (operands[1]) == GET_MODE (operands[2])
&& ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
"#")
(define_insn "*fp_jcc_1_sse_only"
(define_insn "*fp_jcc_1_387"
[(set (pc)
(if_then_else (match_operator 0 "comparison_operator"
[(match_operand 1 "register_operand" "x")
(match_operand 2 "nonimmediate_operand" "xm")])
[(match_operand 1 "register_operand" "f")
(match_operand 2 "register_operand" "f")])
(label_ref (match_operand 3 "" ""))
(pc)))
(clobber (reg:CCFP FPSR_REG))
(clobber (reg:CCFP FLAGS_REG))]
"SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
"TARGET_CMOVE && TARGET_80387
&& FLOAT_MODE_P (GET_MODE (operands[1]))
&& GET_MODE (operands[1]) == GET_MODE (operands[2])
&& ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
"#")
(define_insn "*fp_jcc_2"
(define_insn "*fp_jcc_2_mixed"
[(set (pc)
(if_then_else (match_operator 0 "comparison_operator"
[(match_operand 1 "register_operand" "f")
(match_operand 2 "register_operand" "f")])
[(match_operand 1 "register_operand" "f#x,x#f")
(match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
(pc)
(label_ref (match_operand 3 "" ""))))
(clobber (reg:CCFP FPSR_REG))
(clobber (reg:CCFP FLAGS_REG))]
"TARGET_CMOVE && TARGET_80387
&& !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
&& FLOAT_MODE_P (GET_MODE (operands[1]))
"TARGET_MIX_SSE_I387
&& SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
&& GET_MODE (operands[1]) == GET_MODE (operands[2])
&& ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
"#")
......@@ -12895,33 +12896,34 @@
(define_insn "*fp_jcc_2_sse"
[(set (pc)
(if_then_else (match_operator 0 "comparison_operator"
[(match_operand 1 "register_operand" "f#x,x#f")
(match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
[(match_operand 1 "register_operand" "x")
(match_operand 2 "nonimmediate_operand" "xm")])
(pc)
(label_ref (match_operand 3 "" ""))))
(clobber (reg:CCFP FPSR_REG))
(clobber (reg:CCFP FLAGS_REG))]
"TARGET_80387
"TARGET_SSE_MATH
&& SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
&& GET_MODE (operands[1]) == GET_MODE (operands[2])
&& ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
"#")
(define_insn "*fp_jcc_2_sse_only"
(define_insn "*fp_jcc_2_387"
[(set (pc)
(if_then_else (match_operator 0 "comparison_operator"
[(match_operand 1 "register_operand" "x")
(match_operand 2 "nonimmediate_operand" "xm")])
[(match_operand 1 "register_operand" "f")
(match_operand 2 "register_operand" "f")])
(pc)
(label_ref (match_operand 3 "" ""))))
(clobber (reg:CCFP FPSR_REG))
(clobber (reg:CCFP FLAGS_REG))]
"SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
"TARGET_CMOVE && TARGET_80387
&& FLOAT_MODE_P (GET_MODE (operands[1]))
&& GET_MODE (operands[1]) == GET_MODE (operands[2])
&& ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
"#")
(define_insn "*fp_jcc_3"
(define_insn "*fp_jcc_3_387"
[(set (pc)
(if_then_else (match_operator 0 "comparison_operator"
[(match_operand 1 "register_operand" "f")
......@@ -12940,7 +12942,7 @@
&& ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
"#")
(define_insn "*fp_jcc_4"
(define_insn "*fp_jcc_4_387"
[(set (pc)
(if_then_else (match_operator 0 "comparison_operator"
[(match_operand 1 "register_operand" "f")
......@@ -12959,7 +12961,7 @@
&& ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
"#")
(define_insn "*fp_jcc_5"
(define_insn "*fp_jcc_5_387"
[(set (pc)
(if_then_else (match_operator 0 "comparison_operator"
[(match_operand 1 "register_operand" "f")
......@@ -12975,7 +12977,7 @@
&& ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
"#")
(define_insn "*fp_jcc_6"
(define_insn "*fp_jcc_6_387"
[(set (pc)
(if_then_else (match_operator 0 "comparison_operator"
[(match_operand 1 "register_operand" "f")
......@@ -12991,7 +12993,7 @@
&& ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
"#")
(define_insn "*fp_jcc_7"
(define_insn "*fp_jcc_7_387"
[(set (pc)
(if_then_else (match_operator 0 "comparison_operator"
[(match_operand 1 "register_operand" "f")
......@@ -13015,7 +13017,7 @@
;; with a precedence over other operators and is always put in the first
;; place. Swap condition and operands to match ficom instruction.
(define_insn "*fp_jcc_8"
(define_insn "*fp_jcc_8_387"
[(set (pc)
(if_then_else (match_operator 0 "comparison_operator"
[(match_operator 1 "float_operator"
......@@ -17417,7 +17419,7 @@
(set_attr "mode" "DI")
(set_attr "length_immediate" "0")])
(define_insn "movdicc_c_rex64"
(define_insn "*movdicc_c_rex64"
[(set (match_operand:DI 0 "register_operand" "=r,r")
(if_then_else:DI (match_operator 1 "ix86_comparison_operator"
[(reg FLAGS_REG) (const_int 0)])
......@@ -17507,7 +17509,8 @@
(define_insn_and_split "*movqicc_noc"
[(set (match_operand:QI 0 "register_operand" "=r,r")
(if_then_else:QI (match_operator 1 "ix86_comparison_operator"
[(match_operand 4 "flags_reg_operand" "") (const_int 0)])
[(match_operand 4 "flags_reg_operand" "")
(const_int 0)])
(match_operand:QI 2 "register_operand" "r,0")
(match_operand:QI 3 "register_operand" "0,r")))]
"TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
......@@ -17528,16 +17531,61 @@
(if_then_else:SF (match_operand 1 "comparison_operator" "")
(match_operand:SF 2 "register_operand" "")
(match_operand:SF 3 "register_operand" "")))]
"TARGET_CMOVE"
"(TARGET_80387 && TARGET_CMOVE) || TARGET_SSE_MATH"
"if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
(define_insn "*movsfcc_1"
;; These versions of min/max are aware of the instruction's behaviour
;; wrt -0.0 and NaN inputs. If we don't care about either, then we
;; should have used the smin/smax expanders in the first place.
(define_insn "*movsfcc_1_sse_min"
[(set (match_operand:SF 0 "register_operand" "=x")
(if_then_else:SF
(lt:SF (match_operand:SF 1 "register_operand" "0")
(match_operand:SF 2 "nonimmediate_operand" "xm"))
(match_dup 1)
(match_dup 2)))]
"TARGET_SSE_MATH"
"minss\t{%2, %0|%0, %2}"
[(set_attr "type" "sseadd")
(set_attr "mode" "SF")])
(define_insn "*movsfcc_1_sse_max"
[(set (match_operand:SF 0 "register_operand" "=x")
(if_then_else:SF
(lt:SF (match_operand:SF 2 "nonimmediate_operand" "xm")
(match_operand:SF 1 "register_operand" "0"))
(match_dup 1)
(match_dup 2)))]
"TARGET_SSE_MATH"
"maxss\t{%2, %0|%0, %2}"
[(set_attr "type" "sseadd")
(set_attr "mode" "SF")])
(define_insn_and_split "*movsfcc_1_sse"
[(set (match_operand:SF 0 "register_operand" "=x,x,x")
(if_then_else:SF
(match_operator:SF 4 "sse_comparison_operator"
[(match_operand:SF 5 "register_operand" "0,0,0")
(match_operand:SF 6 "nonimmediate_operand" "xm,xm,xm")])
(match_operand:SF 2 "reg_or_0_operand" "C,x,1")
(match_operand:SF 3 "reg_or_0_operand" "x,C,x")))
(clobber (match_scratch:V4SF 1 "=X,X,x"))]
"TARGET_SSE_MATH"
"#"
"&& reload_completed"
[(const_int 0)]
{
ix86_split_sse_movcc (operands);
DONE;
})
(define_insn "*movsfcc_1_387"
[(set (match_operand:SF 0 "register_operand" "=f#r,f#r,r#f,r#f")
(if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
[(reg FLAGS_REG) (const_int 0)])
(match_operand:SF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
(match_operand:SF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
"TARGET_CMOVE
"TARGET_80387 && TARGET_CMOVE
&& (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
"@
fcmov%F1\t{%2, %0|%0, %2}
......@@ -17552,16 +17600,61 @@
(if_then_else:DF (match_operand 1 "comparison_operator" "")
(match_operand:DF 2 "register_operand" "")
(match_operand:DF 3 "register_operand" "")))]
"TARGET_CMOVE"
"(TARGET_80387 && TARGET_CMOVE) || (TARGET_SSE2 && TARGET_SSE_MATH)"
"if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
;; These versions of min/max are aware of the instruction's behaviour
;; wrt -0.0 and NaN inputs. If we don't care about either, then we
;; should have used the smin/smax expanders in the first place.
(define_insn "*movdfcc_1_sse_min"
[(set (match_operand:DF 0 "register_operand" "=x")
(if_then_else:DF
(lt:DF (match_operand:DF 1 "register_operand" "0")
(match_operand:DF 2 "nonimmediate_operand" "xm"))
(match_dup 1)
(match_dup 2)))]
"TARGET_SSE2 && TARGET_SSE_MATH"
"minsd\t{%2, %0|%0, %2}"
[(set_attr "type" "sseadd")
(set_attr "mode" "DF")])
(define_insn "*movdfcc_1_sse_max"
[(set (match_operand:DF 0 "register_operand" "=x")
(if_then_else:DF
(lt:DF (match_operand:DF 2 "nonimmediate_operand" "xm")
(match_operand:DF 1 "register_operand" "0"))
(match_dup 1)
(match_dup 2)))]
"TARGET_SSE2 && TARGET_SSE_MATH"
"maxsd\t{%2, %0|%0, %2}"
[(set_attr "type" "sseadd")
(set_attr "mode" "DF")])
(define_insn_and_split "*movdfcc_1_sse"
[(set (match_operand:DF 0 "register_operand" "=x,x,x")
(if_then_else:DF
(match_operator:DF 4 "sse_comparison_operator"
[(match_operand:DF 5 "register_operand" "0,0,0")
(match_operand:DF 6 "nonimmediate_operand" "xm,xm,xm")])
(match_operand:DF 2 "reg_or_0_operand" "C,x,1")
(match_operand:DF 3 "reg_or_0_operand" "x,C,x")))
(clobber (match_scratch:V2DF 1 "=X,X,x"))]
"TARGET_SSE2 && TARGET_SSE_MATH"
"#"
"&& reload_completed"
[(const_int 0)]
{
ix86_split_sse_movcc (operands);
DONE;
})
(define_insn "*movdfcc_1"
[(set (match_operand:DF 0 "register_operand" "=f#r,f#r,&r#f,&r#f")
(if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
[(reg FLAGS_REG) (const_int 0)])
(match_operand:DF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
(match_operand:DF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
"!TARGET_64BIT && TARGET_CMOVE
"!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
&& (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
"@
fcmov%F1\t{%2, %0|%0, %2}
......@@ -17577,7 +17670,7 @@
[(reg FLAGS_REG) (const_int 0)])
(match_operand:DF 2 "nonimmediate_operand" "f#r,0#r,rm#f,0#f")
(match_operand:DF 3 "nonimmediate_operand" "0#r,f#r,0#f,rm#f")))]
"TARGET_64BIT && TARGET_CMOVE
"TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
&& (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
"@
fcmov%F1\t{%2, %0|%0, %2}
......@@ -17590,7 +17683,8 @@
(define_split
[(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
(if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
[(match_operand 4 "flags_reg_operand" "") (const_int 0)])
[(match_operand 4 "flags_reg_operand" "")
(const_int 0)])
(match_operand:DF 2 "nonimmediate_operand" "")
(match_operand:DF 3 "nonimmediate_operand" "")))]
"!TARGET_64BIT && reload_completed"
......@@ -17611,7 +17705,7 @@
(if_then_else:XF (match_operand 1 "comparison_operator" "")
(match_operand:XF 2 "register_operand" "")
(match_operand:XF 3 "register_operand" "")))]
"TARGET_CMOVE"
"TARGET_80387 && TARGET_CMOVE"
"if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
(define_insn "*movxfcc_1"
......@@ -17620,62 +17714,53 @@
[(reg FLAGS_REG) (const_int 0)])
(match_operand:XF 2 "register_operand" "f,0")
(match_operand:XF 3 "register_operand" "0,f")))]
"TARGET_CMOVE"
"TARGET_80387 && TARGET_CMOVE"
"@
fcmov%F1\t{%2, %0|%0, %2}
fcmov%f1\t{%3, %0|%0, %3}"
[(set_attr "type" "fcmov")
(set_attr "mode" "XF")])
(define_expand "minsf3"
[(parallel [
(set (match_operand:SF 0 "register_operand" "")
(if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
(match_operand:SF 2 "nonimmediate_operand" ""))
(match_dup 1)
(match_dup 2)))
(clobber (reg:CC FLAGS_REG))])]
"TARGET_SSE"
"")
;; These versions of the min/max patterns are intentionally ignorant of
;; their behaviour wrt -0.0 and NaN (via the commutative operand mark).
;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
;; are undefined in this condition, we're certain this is correct.
(define_insn "*minsf"
[(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
(if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0,0,f#x")
(match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x,0"))
(match_dup 1)
(match_dup 2)))
(clobber (reg:CC FLAGS_REG))]
"TARGET_SSE && TARGET_IEEE_FP"
"#")
(define_insn "sminsf3"
[(set (match_operand:SF 0 "register_operand" "=x")
(smin:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
(match_operand:SF 2 "nonimmediate_operand" "xm")))]
"TARGET_SSE_MATH"
"minss\t{%2, %0|%0, %2}"
[(set_attr "type" "sseadd")
(set_attr "mode" "SF")])
(define_insn "*minsf_nonieee"
[(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
(if_then_else:SF (lt (match_operand:SF 1 "nonimmediate_operand" "%0,0")
(match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x"))
(match_dup 1)
(match_dup 2)))
(clobber (reg:CC FLAGS_REG))]
"TARGET_SSE && !TARGET_IEEE_FP
&& (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
"#")
(define_insn "smaxsf3"
[(set (match_operand:SF 0 "register_operand" "=x")
(smax:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
(match_operand:SF 2 "nonimmediate_operand" "xm")))]
"TARGET_SSE_MATH"
"minss\t{%2, %0|%0, %2}"
[(set_attr "type" "sseadd")
(set_attr "mode" "SF")])
(define_split
[(set (match_operand:SF 0 "register_operand" "")
(if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
(match_operand:SF 2 "nonimmediate_operand" ""))
(match_operand:SF 3 "register_operand" "")
(match_operand:SF 4 "nonimmediate_operand" "")))
(clobber (reg:CC FLAGS_REG))]
"SSE_REG_P (operands[0]) && reload_completed
&& ((operands_match_p (operands[1], operands[3])
&& operands_match_p (operands[2], operands[4]))
|| (operands_match_p (operands[1], operands[4])
&& operands_match_p (operands[2], operands[3])))"
[(set (match_dup 0)
(if_then_else:SF (lt (match_dup 1)
(match_dup 2))
(match_dup 1)
(match_dup 2)))])
(define_insn "smindf3"
[(set (match_operand:DF 0 "register_operand" "=x")
(smin:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
(match_operand:DF 2 "nonimmediate_operand" "xm")))]
"TARGET_SSE2 && TARGET_SSE_MATH"
"minsd\t{%2, %0|%0, %2}"
[(set_attr "type" "sseadd")
(set_attr "mode" "DF")])
(define_insn "smaxdf3"
[(set (match_operand:DF 0 "register_operand" "=x")
(smax:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
(match_operand:DF 2 "nonimmediate_operand" "xm")))]
"TARGET_SSE2 && TARGET_SSE_MATH"
"maxsd\t{%2, %0|%0, %2}"
[(set_attr "type" "sseadd")
(set_attr "mode" "DF")])
;; Conditional addition patterns
(define_expand "addqicc"
......@@ -17710,282 +17795,6 @@
"TARGET_64BIT"
"if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
;; We can't represent the LT test directly. Do this by swapping the operands.
(define_split
[(set (match_operand:SF 0 "fp_register_operand" "")
(if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
(match_operand:SF 2 "register_operand" ""))
(match_operand:SF 3 "register_operand" "")
(match_operand:SF 4 "register_operand" "")))
(clobber (reg:CC FLAGS_REG))]
"reload_completed
&& ((operands_match_p (operands[1], operands[3])
&& operands_match_p (operands[2], operands[4]))
|| (operands_match_p (operands[1], operands[4])
&& operands_match_p (operands[2], operands[3])))"
[(set (reg:CCFP FLAGS_REG)
(compare:CCFP (match_dup 2)
(match_dup 1)))
(set (match_dup 0)
(if_then_else:SF (ge (reg:CCFP FLAGS_REG) (const_int 0))
(match_dup 1)
(match_dup 2)))])
(define_insn "*minsf_sse"
[(set (match_operand:SF 0 "register_operand" "=x")
(if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0")
(match_operand:SF 2 "nonimmediate_operand" "xm"))
(match_dup 1)
(match_dup 2)))]
"TARGET_SSE && reload_completed"
"minss\t{%2, %0|%0, %2}"
[(set_attr "type" "sse")
(set_attr "mode" "SF")])
(define_expand "mindf3"
[(parallel [
(set (match_operand:DF 0 "register_operand" "")
(if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
(match_operand:DF 2 "nonimmediate_operand" ""))
(match_dup 1)
(match_dup 2)))
(clobber (reg:CC FLAGS_REG))])]
"TARGET_SSE2 && TARGET_SSE_MATH"
"#")
(define_insn "*mindf"
[(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
(if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0,0,f#Y")
(match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y,0"))
(match_dup 1)
(match_dup 2)))
(clobber (reg:CC FLAGS_REG))]
"TARGET_SSE2 && TARGET_IEEE_FP && TARGET_SSE_MATH"
"#")
(define_insn "*mindf_nonieee"
[(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
(if_then_else:DF (lt (match_operand:DF 1 "nonimmediate_operand" "%0,0")
(match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y"))
(match_dup 1)
(match_dup 2)))
(clobber (reg:CC FLAGS_REG))]
"TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_IEEE_FP
&& (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
"#")
(define_split
[(set (match_operand:DF 0 "register_operand" "")
(if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
(match_operand:DF 2 "nonimmediate_operand" ""))
(match_operand:DF 3 "register_operand" "")
(match_operand:DF 4 "nonimmediate_operand" "")))
(clobber (reg:CC FLAGS_REG))]
"SSE_REG_P (operands[0]) && reload_completed
&& ((operands_match_p (operands[1], operands[3])
&& operands_match_p (operands[2], operands[4]))
|| (operands_match_p (operands[1], operands[4])
&& operands_match_p (operands[2], operands[3])))"
[(set (match_dup 0)
(if_then_else:DF (lt (match_dup 1)
(match_dup 2))
(match_dup 1)
(match_dup 2)))])
;; We can't represent the LT test directly. Do this by swapping the operands.
(define_split
[(set (match_operand:DF 0 "fp_register_operand" "")
(if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
(match_operand:DF 2 "register_operand" ""))
(match_operand:DF 3 "register_operand" "")
(match_operand:DF 4 "register_operand" "")))
(clobber (reg:CC FLAGS_REG))]
"reload_completed
&& ((operands_match_p (operands[1], operands[3])
&& operands_match_p (operands[2], operands[4]))
|| (operands_match_p (operands[1], operands[4])
&& operands_match_p (operands[2], operands[3])))"
[(set (reg:CCFP FLAGS_REG)
(compare:CCFP (match_dup 2)
(match_dup 1)))
(set (match_dup 0)
(if_then_else:DF (ge (reg:CCFP FLAGS_REG) (const_int 0))
(match_dup 1)
(match_dup 2)))])
(define_insn "*mindf_sse"
[(set (match_operand:DF 0 "register_operand" "=Y")
(if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0")
(match_operand:DF 2 "nonimmediate_operand" "Ym"))
(match_dup 1)
(match_dup 2)))]
"TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
"minsd\t{%2, %0|%0, %2}"
[(set_attr "type" "sse")
(set_attr "mode" "DF")])
(define_expand "maxsf3"
[(parallel [
(set (match_operand:SF 0 "register_operand" "")
(if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
(match_operand:SF 2 "nonimmediate_operand" ""))
(match_dup 1)
(match_dup 2)))
(clobber (reg:CC FLAGS_REG))])]
"TARGET_SSE"
"#")
(define_insn "*maxsf"
[(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
(if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0,0,f#x")
(match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x,0"))
(match_dup 1)
(match_dup 2)))
(clobber (reg:CC FLAGS_REG))]
"TARGET_SSE && TARGET_IEEE_FP"
"#")
(define_insn "*maxsf_nonieee"
[(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
(if_then_else:SF (gt (match_operand:SF 1 "nonimmediate_operand" "%0,0")
(match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x"))
(match_dup 1)
(match_dup 2)))
(clobber (reg:CC FLAGS_REG))]
"TARGET_SSE && !TARGET_IEEE_FP
&& (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
"#")
(define_split
[(set (match_operand:SF 0 "register_operand" "")
(if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
(match_operand:SF 2 "nonimmediate_operand" ""))
(match_operand:SF 3 "register_operand" "")
(match_operand:SF 4 "nonimmediate_operand" "")))
(clobber (reg:CC FLAGS_REG))]
"SSE_REG_P (operands[0]) && reload_completed
&& ((operands_match_p (operands[1], operands[3])
&& operands_match_p (operands[2], operands[4]))
|| (operands_match_p (operands[1], operands[4])
&& operands_match_p (operands[2], operands[3])))"
[(set (match_dup 0)
(if_then_else:SF (gt (match_dup 1)
(match_dup 2))
(match_dup 1)
(match_dup 2)))])
(define_split
[(set (match_operand:SF 0 "fp_register_operand" "")
(if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
(match_operand:SF 2 "register_operand" ""))
(match_operand:SF 3 "register_operand" "")
(match_operand:SF 4 "register_operand" "")))
(clobber (reg:CC FLAGS_REG))]
"reload_completed
&& ((operands_match_p (operands[1], operands[3])
&& operands_match_p (operands[2], operands[4]))
|| (operands_match_p (operands[1], operands[4])
&& operands_match_p (operands[2], operands[3])))"
[(set (reg:CCFP FLAGS_REG)
(compare:CCFP (match_dup 1)
(match_dup 2)))
(set (match_dup 0)
(if_then_else:SF (gt (reg:CCFP FLAGS_REG) (const_int 0))
(match_dup 1)
(match_dup 2)))])
(define_insn "*maxsf_sse"
[(set (match_operand:SF 0 "register_operand" "=x")
(if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0")
(match_operand:SF 2 "nonimmediate_operand" "xm"))
(match_dup 1)
(match_dup 2)))]
"TARGET_SSE && reload_completed"
"maxss\t{%2, %0|%0, %2}"
[(set_attr "type" "sse")
(set_attr "mode" "SF")])
(define_expand "maxdf3"
[(parallel [
(set (match_operand:DF 0 "register_operand" "")
(if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
(match_operand:DF 2 "nonimmediate_operand" ""))
(match_dup 1)
(match_dup 2)))
(clobber (reg:CC FLAGS_REG))])]
"TARGET_SSE2 && TARGET_SSE_MATH"
"#")
(define_insn "*maxdf"
[(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
(if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0,0,f#Y")
(match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y,0"))
(match_dup 1)
(match_dup 2)))
(clobber (reg:CC FLAGS_REG))]
"TARGET_SSE2 && TARGET_SSE_MATH && TARGET_IEEE_FP"
"#")
(define_insn "*maxdf_nonieee"
[(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
(if_then_else:DF (gt (match_operand:DF 1 "nonimmediate_operand" "%0,0")
(match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y"))
(match_dup 1)
(match_dup 2)))
(clobber (reg:CC FLAGS_REG))]
"TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_IEEE_FP
&& (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
"#")
(define_split
[(set (match_operand:DF 0 "register_operand" "")
(if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
(match_operand:DF 2 "nonimmediate_operand" ""))
(match_operand:DF 3 "register_operand" "")
(match_operand:DF 4 "nonimmediate_operand" "")))
(clobber (reg:CC FLAGS_REG))]
"SSE_REG_P (operands[0]) && reload_completed
&& ((operands_match_p (operands[1], operands[3])
&& operands_match_p (operands[2], operands[4]))
|| (operands_match_p (operands[1], operands[4])
&& operands_match_p (operands[2], operands[3])))"
[(set (match_dup 0)
(if_then_else:DF (gt (match_dup 1)
(match_dup 2))
(match_dup 1)
(match_dup 2)))])
(define_split
[(set (match_operand:DF 0 "fp_register_operand" "")
(if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
(match_operand:DF 2 "register_operand" ""))
(match_operand:DF 3 "register_operand" "")
(match_operand:DF 4 "register_operand" "")))
(clobber (reg:CC FLAGS_REG))]
"reload_completed
&& ((operands_match_p (operands[1], operands[3])
&& operands_match_p (operands[2], operands[4]))
|| (operands_match_p (operands[1], operands[4])
&& operands_match_p (operands[2], operands[3])))"
[(set (reg:CCFP FLAGS_REG)
(compare:CCFP (match_dup 1)
(match_dup 2)))
(set (match_dup 0)
(if_then_else:DF (gt (reg:CCFP FLAGS_REG) (const_int 0))
(match_dup 1)
(match_dup 2)))])
(define_insn "*maxdf_sse"
[(set (match_operand:DF 0 "register_operand" "=Y")
(if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0")
(match_operand:DF 2 "nonimmediate_operand" "Ym"))
(match_dup 1)
(match_dup 2)))]
"TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
"maxsd\t{%2, %0|%0, %2}"
[(set_attr "type" "sse")
(set_attr "mode" "DF")])
;; Misc patterns (?)
......@@ -18107,364 +17916,6 @@
[(set_attr "type" "alu,lea")
(set_attr "mode" "DI")])
;; Placeholder for the conditional moves. This one is split either to SSE
;; based moves emulation or to usual cmove sequence. Little bit unfortunate
;; fact is that compares supported by the cmp??ss instructions are exactly
;; swapped of those supported by cmove sequence.
;; The EQ/NE comparisons also needs bit care, since they are not directly
;; supported by i387 comparisons and we do need to emit two conditional moves
;; in tandem.
(define_insn "sse_movsfcc"
[(set (match_operand:SF 0 "register_operand" "=&x#rf,x#rf,?f#xr,?f#xr,?f#xr,?f#xr,?r#xf,?r#xf,?r#xf,?r#xf")
(if_then_else:SF (match_operator 1 "sse_comparison_operator"
[(match_operand:SF 4 "nonimmediate_operand" "0#fx,x#fx,f#x,f#x,xm#f,xm#f,f#x,f#x,xm#f,xm#f")
(match_operand:SF 5 "nonimmediate_operand" "xm#f,xm#f,f#x,f#x,x#f,x#f,f#x,f#x,x#f,x#f")])
(match_operand:SF 2 "nonimmediate_operand" "x#fr,0#fr,f#fx,0#fx,f#fx,0#fx,rm#rx,0#rx,rm#rx,0#rx")
(match_operand:SF 3 "nonimmediate_operand" "x#fr,x#fr,0#fx,f#fx,0#fx,f#fx,0#fx,rm#rx,0#rx,rm#rx")))
(clobber (match_scratch:SF 6 "=2,&4,X,X,X,X,X,X,X,X"))
(clobber (reg:CC FLAGS_REG))]
"TARGET_SSE
&& (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
/* Avoid combine from being smart and converting min/max
instruction patterns into conditional moves. */
&& ((GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != GT
&& GET_CODE (operands[1]) != UNLE && GET_CODE (operands[1]) != UNGE)
|| !rtx_equal_p (operands[4], operands[2])
|| !rtx_equal_p (operands[5], operands[3]))
&& (!TARGET_IEEE_FP
|| (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
"#")
(define_insn "sse_movsfcc_eq"
[(set (match_operand:SF 0 "register_operand" "=&x#rf,x#rf,?f#xr,?f#xr,?r#xf,?r#xf")
(if_then_else:SF (eq (match_operand:SF 3 "nonimmediate_operand" "%0#fx,x#fx,f#x,xm#f,f#x,xm#f")
(match_operand:SF 4 "nonimmediate_operand" "xm#f,xm#f,f#x,x#f,f#x,x#f"))
(match_operand:SF 1 "nonimmediate_operand" "x#fr,0#fr,0#fx,0#fx,0#rx,0#rx")
(match_operand:SF 2 "nonimmediate_operand" "x#fr,x#fr,f#fx,f#fx,rm#rx,rm#rx")))
(clobber (match_scratch:SF 5 "=1,&3,X,X,X,X"))
(clobber (reg:CC FLAGS_REG))]
"TARGET_SSE
&& (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
"#")
(define_insn "sse_movdfcc"
[(set (match_operand:DF 0 "register_operand" "=&Y#rf,Y#rf,?f#Yr,?f#Yr,?f#Yr,?f#Yr,?r#Yf,?r#Yf,?r#Yf,?r#Yf")
(if_then_else:DF (match_operator 1 "sse_comparison_operator"
[(match_operand:DF 4 "nonimmediate_operand" "0#fY,Y#fY,f#Y,f#Y,Ym#f,Ym#f,f#Y,f#Y,Ym#f,Ym#f")
(match_operand:DF 5 "nonimmediate_operand" "Ym#f,Ym#f,f#Y,f#Y,Y#f,Y#f,f#Y,f#Y,Y#f,Y#f")])
(match_operand:DF 2 "nonimmediate_operand" "Y#fr,0#fr,f#fY,0#fY,f#fY,0#fY,rm#rY,0#rY,rm#rY,0#rY")
(match_operand:DF 3 "nonimmediate_operand" "Y#fr,Y#fr,0#fY,f#fY,0#fY,f#fY,0#fY,rm#rY,0#rY,rm#rY")))
(clobber (match_scratch:DF 6 "=2,&4,X,X,X,X,X,X,X,X"))
(clobber (reg:CC FLAGS_REG))]
"TARGET_SSE2
&& (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
/* Avoid combine from being smart and converting min/max
instruction patterns into conditional moves. */
&& ((GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != GT
&& GET_CODE (operands[1]) != UNLE && GET_CODE (operands[1]) != UNGE)
|| !rtx_equal_p (operands[4], operands[2])
|| !rtx_equal_p (operands[5], operands[3]))
&& (!TARGET_IEEE_FP
|| (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
"#")
(define_insn "sse_movdfcc_eq"
[(set (match_operand:DF 0 "register_operand" "=&Y#rf,Y#rf,?f#Yr,?f#Yr,?r#Yf,?r#Yf")
(if_then_else:DF (eq (match_operand:DF 3 "nonimmediate_operand" "%0#fY,Y#fY,f#Y,Ym#f,f#Y,Ym#f")
(match_operand:DF 4 "nonimmediate_operand" "Ym#f,Ym#f,f#Y,Y#f,f#Y,Y#f"))
(match_operand:DF 1 "nonimmediate_operand" "Y#fr,0#fr,0#fY,0#fY,0#rY,0#rY")
(match_operand:DF 2 "nonimmediate_operand" "Y#fr,Y#fr,f#fY,f#fY,rm#rY,rm#rY")))
(clobber (match_scratch:DF 5 "=1,&3,X,X,X,X"))
(clobber (reg:CC FLAGS_REG))]
"TARGET_SSE
&& (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
"#")
;; For non-sse moves just expand the usual cmove sequence.
(define_split
[(set (match_operand 0 "register_operand" "")
(if_then_else (match_operator 1 "comparison_operator"
[(match_operand 4 "nonimmediate_operand" "")
(match_operand 5 "register_operand" "")])
(match_operand 2 "nonimmediate_operand" "")
(match_operand 3 "nonimmediate_operand" "")))
(clobber (match_operand 6 "" ""))
(clobber (reg:CC FLAGS_REG))]
"!SSE_REG_P (operands[0]) && reload_completed
&& (GET_MODE (operands[0]) == SFmode
|| (TARGET_SSE2 && GET_MODE (operands[0]) == DFmode))"
[(const_int 0)]
{
ix86_compare_op0 = operands[5];
ix86_compare_op1 = operands[4];
operands[1] = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[1])),
VOIDmode, operands[5], operands[4]);
ix86_expand_fp_movcc (operands);
DONE;
})
;; Split SSE based conditional move into sequence:
;; cmpCC op0, op4 - set op0 to 0 or ffffffff depending on the comparison
;; and op2, op0 - zero op2 if comparison was false
;; nand op0, op3 - load op3 to op0 if comparison was false
;; or op2, op0 - get the nonzero one into the result.
(define_split
[(set (match_operand:SF 0 "register_operand" "")
(if_then_else:SF (match_operator:SF 1 "sse_comparison_operator"
[(match_operand:SF 4 "register_operand" "")
(match_operand:SF 5 "nonimmediate_operand" "")])
(match_operand:SF 2 "register_operand" "")
(match_operand:SF 3 "register_operand" "")))
(clobber (match_operand 6 "" ""))
(clobber (reg:CC FLAGS_REG))]
"SSE_REG_P (operands[0]) && reload_completed"
[(set (match_dup 4) (match_op_dup 1 [(match_dup 4) (match_dup 5)]))
(set (match_dup 2) (and:V4SF (match_dup 2)
(match_dup 8)))
(set (match_dup 8) (and:V4SF (not:V4SF (match_dup 8))
(match_dup 3)))
(set (match_dup 0) (ior:V4SF (match_dup 6)
(match_dup 7)))]
{
/* If op2 == op3, op3 would be clobbered before it is used. */
if (operands_match_p (operands[2], operands[3]))
{
emit_move_insn (operands[0], operands[2]);
DONE;
}
PUT_MODE (operands[1], GET_MODE (operands[0]));
if (operands_match_p (operands[0], operands[4]))
operands[6] = operands[4], operands[7] = operands[2];
else
operands[6] = operands[2], operands[7] = operands[4];
operands[0] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
operands[2] = simplify_gen_subreg (V4SFmode, operands[2], SFmode, 0);
operands[3] = simplify_gen_subreg (V4SFmode, operands[3], SFmode, 0);
operands[8] = simplify_gen_subreg (V4SFmode, operands[4], SFmode, 0);
operands[6] = simplify_gen_subreg (V4SFmode, operands[6], SFmode, 0);
operands[7] = simplify_gen_subreg (V4SFmode, operands[7], SFmode, 0);
})
(define_split
[(set (match_operand:DF 0 "register_operand" "")
(if_then_else:DF (match_operator:DF 1 "sse_comparison_operator"
[(match_operand:DF 4 "register_operand" "")
(match_operand:DF 5 "nonimmediate_operand" "")])
(match_operand:DF 2 "register_operand" "")
(match_operand:DF 3 "register_operand" "")))
(clobber (match_operand 6 "" ""))
(clobber (reg:CC FLAGS_REG))]
"SSE_REG_P (operands[0]) && reload_completed"
[(set (match_dup 4) (match_op_dup 1 [(match_dup 4) (match_dup 5)]))
(set (match_dup 2) (and:V2DF (match_dup 2)
(match_dup 8)))
(set (match_dup 8) (and:V2DF (not:V2DF (match_dup 8))
(match_dup 3)))
(set (match_dup 0) (ior:V2DF (match_dup 6)
(match_dup 7)))]
{
if (TARGET_SSE_SPLIT_REGS && !optimize_size)
{
rtx op = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
emit_insn (gen_sse2_unpcklpd (op, op, op));
op = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
emit_insn (gen_sse2_unpcklpd (op, op, op));
}
/* If op2 == op3, op3 would be clobbered before it is used. */
if (operands_match_p (operands[2], operands[3]))
{
emit_move_insn (operands[0], operands[2]);
DONE;
}
PUT_MODE (operands[1], GET_MODE (operands[0]));
if (operands_match_p (operands[0], operands[4]))
operands[6] = operands[4], operands[7] = operands[2];
else
operands[6] = operands[2], operands[7] = operands[4];
operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
operands[2] = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
operands[3] = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
operands[8] = simplify_gen_subreg (V2DFmode, operands[4], DFmode, 0);
operands[6] = simplify_gen_subreg (V2DFmode, operands[6], DFmode, 0);
operands[7] = simplify_gen_subreg (V2DFmode, operands[7], DFmode, 0);
})
;; Special case of conditional move we can handle effectively.
;; Do not brother with the integer/floating point case, since these are
;; bot considerably slower, unlike in the generic case.
(define_insn "*sse_movsfcc_const0_1"
[(set (match_operand:SF 0 "register_operand" "=&x")
(if_then_else:SF (match_operator 1 "sse_comparison_operator"
[(match_operand:SF 4 "register_operand" "0")
(match_operand:SF 5 "nonimmediate_operand" "xm")])
(match_operand:SF 2 "register_operand" "x")
(match_operand:SF 3 "const0_operand" "X")))]
"TARGET_SSE"
"#")
(define_insn "*sse_movsfcc_const0_2"
[(set (match_operand:SF 0 "register_operand" "=&x")
(if_then_else:SF (match_operator 1 "sse_comparison_operator"
[(match_operand:SF 4 "register_operand" "0")
(match_operand:SF 5 "nonimmediate_operand" "xm")])
(match_operand:SF 2 "const0_operand" "X")
(match_operand:SF 3 "register_operand" "x")))]
"TARGET_SSE"
"#")
(define_insn "*sse_movsfcc_const0_3"
[(set (match_operand:SF 0 "register_operand" "=&x")
(if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
[(match_operand:SF 4 "nonimmediate_operand" "xm")
(match_operand:SF 5 "register_operand" "0")])
(match_operand:SF 2 "register_operand" "x")
(match_operand:SF 3 "const0_operand" "X")))]
"TARGET_SSE"
"#")
(define_insn "*sse_movsfcc_const0_4"
[(set (match_operand:SF 0 "register_operand" "=&x")
(if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
[(match_operand:SF 4 "nonimmediate_operand" "xm")
(match_operand:SF 5 "register_operand" "0")])
(match_operand:SF 2 "const0_operand" "X")
(match_operand:SF 3 "register_operand" "x")))]
"TARGET_SSE"
"#")
(define_insn "*sse_movdfcc_const0_1"
[(set (match_operand:DF 0 "register_operand" "=&Y")
(if_then_else:DF (match_operator 1 "sse_comparison_operator"
[(match_operand:DF 4 "register_operand" "0")
(match_operand:DF 5 "nonimmediate_operand" "Ym")])
(match_operand:DF 2 "register_operand" "Y")
(match_operand:DF 3 "const0_operand" "X")))]
"TARGET_SSE2"
"#")
(define_insn "*sse_movdfcc_const0_2"
[(set (match_operand:DF 0 "register_operand" "=&Y")
(if_then_else:DF (match_operator 1 "sse_comparison_operator"
[(match_operand:DF 4 "register_operand" "0")
(match_operand:DF 5 "nonimmediate_operand" "Ym")])
(match_operand:DF 2 "const0_operand" "X")
(match_operand:DF 3 "register_operand" "Y")))]
"TARGET_SSE2"
"#")
(define_insn "*sse_movdfcc_const0_3"
[(set (match_operand:DF 0 "register_operand" "=&Y")
(if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
[(match_operand:DF 4 "nonimmediate_operand" "Ym")
(match_operand:DF 5 "register_operand" "0")])
(match_operand:DF 2 "register_operand" "Y")
(match_operand:DF 3 "const0_operand" "X")))]
"TARGET_SSE2"
"#")
(define_insn "*sse_movdfcc_const0_4"
[(set (match_operand:DF 0 "register_operand" "=&Y")
(if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
[(match_operand:DF 4 "nonimmediate_operand" "Ym")
(match_operand:DF 5 "register_operand" "0")])
(match_operand:DF 2 "const0_operand" "X")
(match_operand:DF 3 "register_operand" "Y")))]
"TARGET_SSE2"
"#")
(define_split
[(set (match_operand:SF 0 "register_operand" "")
(if_then_else:SF (match_operator 1 "comparison_operator"
[(match_operand:SF 4 "nonimmediate_operand" "")
(match_operand:SF 5 "nonimmediate_operand" "")])
(match_operand:SF 2 "nonmemory_operand" "")
(match_operand:SF 3 "nonmemory_operand" "")))]
"SSE_REG_P (operands[0]) && reload_completed
&& (const0_operand (operands[2], GET_MODE (operands[0]))
|| const0_operand (operands[3], GET_MODE (operands[0])))"
[(set (match_dup 0) (match_op_dup 1 [(match_dup 0) (match_dup 5)]))
(set (match_dup 8) (and:V4SF (match_dup 6) (match_dup 7)))]
{
PUT_MODE (operands[1], GET_MODE (operands[0]));
if (!sse_comparison_operator (operands[1], VOIDmode)
|| !rtx_equal_p (operands[0], operands[4]))
{
rtx tmp = operands[5];
operands[5] = operands[4];
operands[4] = tmp;
PUT_CODE (operands[1], swap_condition (GET_CODE (operands[1])));
}
if (!rtx_equal_p (operands[0], operands[4]))
abort ();
operands[8] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
if (const0_operand (operands[2], GET_MODE (operands[2])))
{
operands[7] = operands[3];
operands[6] = gen_rtx_NOT (V4SFmode, operands[8]);
}
else
{
operands[7] = operands[2];
operands[6] = operands[8];
}
operands[7] = simplify_gen_subreg (V4SFmode, operands[7], SFmode, 0);
})
(define_split
[(set (match_operand:DF 0 "register_operand" "")
(if_then_else:DF (match_operator 1 "comparison_operator"
[(match_operand:DF 4 "nonimmediate_operand" "")
(match_operand:DF 5 "nonimmediate_operand" "")])
(match_operand:DF 2 "nonmemory_operand" "")
(match_operand:DF 3 "nonmemory_operand" "")))]
"SSE_REG_P (operands[0]) && reload_completed
&& (const0_operand (operands[2], GET_MODE (operands[0]))
|| const0_operand (operands[3], GET_MODE (operands[0])))"
[(set (match_dup 0) (match_op_dup 1 [(match_dup 0) (match_dup 5)]))
(set (match_dup 8) (and:V2DF (match_dup 6) (match_dup 7)))]
{
if (TARGET_SSE_SPLIT_REGS && !optimize_size)
{
if (REG_P (operands[2]))
{
rtx op = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
emit_insn (gen_sse2_unpcklpd (op, op, op));
}
if (REG_P (operands[3]))
{
rtx op = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
emit_insn (gen_sse2_unpcklpd (op, op, op));
}
}
PUT_MODE (operands[1], GET_MODE (operands[0]));
if (!sse_comparison_operator (operands[1], VOIDmode)
|| !rtx_equal_p (operands[0], operands[4]))
{
rtx tmp = operands[5];
operands[5] = operands[4];
operands[4] = tmp;
PUT_CODE (operands[1], swap_condition (GET_CODE (operands[1])));
}
if (!rtx_equal_p (operands[0], operands[4]))
abort ();
operands[8] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
if (const0_operand (operands[2], GET_MODE (operands[2])))
{
operands[7] = operands[3];
operands[6] = gen_rtx_NOT (V2DFmode, operands[8]);
}
else
{
operands[7] = operands[2];
operands[6] = operands[8];
}
operands[7] = simplify_gen_subreg (V2DFmode, operands[7], DFmode, 0);
})
(define_expand "allocate_stack_worker"
[(match_operand:SI 0 "register_operand" "")]
"TARGET_STACK_PROBE"
......
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