Commit 09fe1c49 by Richard Henderson Committed by Richard Henderson

alpha.c (alpha_emit_conditional_move): If TARGET_FIX, handle cmove with…

alpha.c (alpha_emit_conditional_move): If TARGET_FIX, handle cmove with mismatched test and data modes.

        * alpha.c (alpha_emit_conditional_move): If TARGET_FIX, handle
        cmove with mismatched test and data modes.

From-SVN: r31021
parent b00c3006
Sat Dec 18 20:34:00 1999 Richard Henderson <rth@cygnus.com>
* alpha.c (alpha_emit_conditional_move): If TARGET_FIX, handle
cmove with mismatched test and data modes.
Sat Dec 18 20:30:15 1999 Richard Henderson <rth@cygnus.com> Sat Dec 18 20:30:15 1999 Richard Henderson <rth@cygnus.com>
* c-typeck.c (c_expand_start_case): Don't warn for long switch * c-typeck.c (c_expand_start_case): Don't warn for long switch
......
...@@ -1580,18 +1580,63 @@ alpha_emit_conditional_move (cmp, mode) ...@@ -1580,18 +1580,63 @@ alpha_emit_conditional_move (cmp, mode)
= (GET_MODE (op0) == VOIDmode ? DImode : GET_MODE (op0)); = (GET_MODE (op0) == VOIDmode ? DImode : GET_MODE (op0));
enum machine_mode cmp_op_mode = fp_p ? DFmode : DImode; enum machine_mode cmp_op_mode = fp_p ? DFmode : DImode;
enum machine_mode cmov_mode = VOIDmode; enum machine_mode cmov_mode = VOIDmode;
int local_fast_math = flag_fast_math;
rtx tem; rtx tem;
/* Zero the operands. */ /* Zero the operands. */
memset (&alpha_compare, 0, sizeof (alpha_compare)); memset (&alpha_compare, 0, sizeof (alpha_compare));
if (fp_p != FLOAT_MODE_P (mode)) if (fp_p != FLOAT_MODE_P (mode))
return 0; {
enum rtx_code cmp_code;
if (! TARGET_FIX)
return 0;
/* If we have fp<->int register move instructions, do a cmov by
performing the comparison in fp registers, and move the
zero/non-zero value to integer registers, where we can then
use a normal cmov, or vice-versa. */
switch (code)
{
case EQ: case LE: case LT: case LEU: case LTU:
/* We have these compares. */
cmp_code = code, code = NE;
break;
case NE:
/* This must be reversed. */
cmp_code = EQ, code = EQ;
break;
case GE: case GT: case GEU: case GTU:
/* These must be swapped. */
cmp_code = swap_condition (code);
code = NE;
tem = op0, op0 = op1, op1 = tem;
break;
default:
abort ();
}
tem = gen_reg_rtx (cmp_op_mode);
emit_insn (gen_rtx_SET (VOIDmode, tem,
gen_rtx_fmt_ee (cmp_code, cmp_op_mode,
op0, op1)));
cmp_mode = cmp_op_mode = fp_p ? DImode : DFmode;
op0 = gen_lowpart (cmp_op_mode, tem);
op1 = CONST0_RTX (cmp_op_mode);
fp_p = !fp_p;
local_fast_math = 1;
}
/* We may be able to use a conditional move directly. /* We may be able to use a conditional move directly.
This avoids emitting spurious compares. */ This avoids emitting spurious compares. */
if (signed_comparison_operator (cmp, cmp_op_mode) if (signed_comparison_operator (cmp, cmp_op_mode)
&& (!fp_p || flag_fast_math) && (!fp_p || local_fast_math)
&& (op0 == CONST0_RTX (cmp_mode) || op1 == CONST0_RTX (cmp_mode))) && (op0 == CONST0_RTX (cmp_mode) || op1 == CONST0_RTX (cmp_mode)))
return gen_rtx_fmt_ee (code, VOIDmode, op0, op1); return gen_rtx_fmt_ee (code, VOIDmode, op0, op1);
...@@ -1627,7 +1672,7 @@ alpha_emit_conditional_move (cmp, mode) ...@@ -1627,7 +1672,7 @@ alpha_emit_conditional_move (cmp, mode)
/* ??? We mark the branch mode to be CCmode to prevent the compare /* ??? We mark the branch mode to be CCmode to prevent the compare
and cmov from being combined, since the compare insn follows IEEE and cmov from being combined, since the compare insn follows IEEE
rules that the cmov does not. */ rules that the cmov does not. */
if (fp_p && !flag_fast_math) if (fp_p && !local_fast_math)
cmov_mode = CCmode; cmov_mode = CCmode;
tem = gen_reg_rtx (cmp_op_mode); tem = gen_reg_rtx (cmp_op_mode);
......
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