/* Save information from a "cmpxx" operation until the branch or scc is
emitted. */
-rtx alpha_compare_op0, alpha_compare_op1;
-int alpha_compare_fp_p;
+struct alpha_compare alpha_compare;
/* Non-zero if inside of a function, because the Alpha asm can't
handle .files inside of functions. */
{
enum rtx_code cmp_code, branch_code;
enum machine_mode cmp_mode, branch_mode = VOIDmode;
- rtx op0 = alpha_compare_op0, op1 = alpha_compare_op1;
+ rtx op0 = alpha_compare.op0, op1 = alpha_compare.op1;
rtx tem;
/* The general case: fold the comparison code to the types of compares
case GE: case GT: case GEU: case GTU:
/* For FP, we swap them, for INT, we reverse them. */
- if (alpha_compare_fp_p)
+ if (alpha_compare.fp_p)
{
cmp_code = swap_condition (code);
branch_code = NE;
abort ();
}
- if (alpha_compare_fp_p)
+ if (alpha_compare.fp_p)
{
cmp_mode = DFmode;
if (flag_fast_math)
emit_move_insn (tem, gen_rtx_fmt_ee (cmp_code, cmp_mode, op0, op1));
}
+ /* Zero the operands. */
+ memset (&alpha_compare, 0, sizeof (alpha_compare));
+
/* Return the branch comparison. */
return gen_rtx_fmt_ee (branch_code, branch_mode, tem, CONST0_RTX (cmp_mode));
}
{
enum rtx_code code = GET_CODE (cmp);
enum rtx_code cmov_code = NE;
- rtx op0 = alpha_compare_op0;
- rtx op1 = alpha_compare_op1;
+ rtx op0 = alpha_compare.op0;
+ rtx op1 = alpha_compare.op1;
+ int fp_p = alpha_compare.fp_p;
enum machine_mode cmp_mode
= (GET_MODE (op0) == VOIDmode ? DImode : GET_MODE (op0));
- enum machine_mode cmp_op_mode = alpha_compare_fp_p ? DFmode : DImode;
+ enum machine_mode cmp_op_mode = fp_p ? DFmode : DImode;
enum machine_mode cmov_mode = VOIDmode;
rtx tem;
- if (alpha_compare_fp_p != FLOAT_MODE_P (mode))
+ /* Zero the operands. */
+ memset (&alpha_compare, 0, sizeof (alpha_compare));
+
+ if (fp_p != FLOAT_MODE_P (mode))
return 0;
/* We may be able to use a conditional move directly.
This avoids emitting spurious compares. */
if (signed_comparison_operator (cmp, cmp_op_mode)
- && (!alpha_compare_fp_p || flag_fast_math)
+ && (!fp_p || flag_fast_math)
&& (op0 == CONST0_RTX (cmp_mode) || op1 == CONST0_RTX (cmp_mode)))
return gen_rtx_fmt_ee (code, VOIDmode, op0, op1);
/* ??? We mark the branch mode to be CCmode to prevent the compare
and cmov from being combined, since the compare insn follows IEEE
rules that the cmov does not. */
- if (alpha_compare_fp_p && !flag_fast_math)
+ if (fp_p && !flag_fast_math)
cmov_mode = CCmode;
tem = gen_reg_rtx (cmp_op_mode);
"TARGET_FP"
"
{
- alpha_compare_op0 = operands[0];
- alpha_compare_op1 = operands[1];
- alpha_compare_fp_p = 1;
+ alpha_compare.op0 = operands[0];
+ alpha_compare.op1 = operands[1];
+ alpha_compare.fp_p = 1;
DONE;
}")
""
"
{
- alpha_compare_op0 = operands[0];
- alpha_compare_op1 = operands[1];
- alpha_compare_fp_p = 0;
+ alpha_compare.op0 = operands[0];
+ alpha_compare.op1 = operands[1];
+ alpha_compare.fp_p = 0;
DONE;
}")
""
"
{
- if (alpha_compare_fp_p)
+ if (alpha_compare.fp_p)
FAIL;
- operands[1] = gen_rtx_EQ (DImode, alpha_compare_op0, alpha_compare_op1);
+ operands[1] = gen_rtx_EQ (DImode, alpha_compare.op0, alpha_compare.op1);
+ alpha_compare.op0 = alpha_compare.op1 = NULL_RTX;
}")
(define_expand "sne"
""
"
{
- if (alpha_compare_fp_p)
+ if (alpha_compare.fp_p)
FAIL;
- operands[1] = gen_rtx_EQ (DImode, alpha_compare_op0, alpha_compare_op1);
+ if (alpha_compare.op1 == const0_rtx)
+ {
+ emit_insn (gen_sgtu (operands[0]));
+ DONE;
+ }
+
+ operands[1] = gen_rtx_EQ (DImode, alpha_compare.op0, alpha_compare.op1);
+ alpha_compare.op0 = alpha_compare.op1 = NULL_RTX;
}")
(define_expand "slt"
""
"
{
- if (alpha_compare_fp_p)
+ if (alpha_compare.fp_p)
FAIL;
- operands[1] = gen_rtx_LT (DImode, alpha_compare_op0, alpha_compare_op1);
+ operands[1] = gen_rtx_LT (DImode, alpha_compare.op0, alpha_compare.op1);
+ alpha_compare.op0 = alpha_compare.op1 = NULL_RTX;
}")
(define_expand "sle"
""
"
{
- if (alpha_compare_fp_p)
+ if (alpha_compare.fp_p)
FAIL;
- operands[1] = gen_rtx_LE (DImode, alpha_compare_op0, alpha_compare_op1);
+ operands[1] = gen_rtx_LE (DImode, alpha_compare.op0, alpha_compare.op1);
+ alpha_compare.op0 = alpha_compare.op1 = NULL_RTX;
}")
(define_expand "sgt"
""
"
{
- if (alpha_compare_fp_p)
+ if (alpha_compare.fp_p)
FAIL;
- operands[1] = gen_rtx_LT (DImode, force_reg (DImode, alpha_compare_op1),
- alpha_compare_op0);
+ operands[1] = gen_rtx_LT (DImode, force_reg (DImode, alpha_compare.op1),
+ alpha_compare.op0);
+ alpha_compare.op0 = alpha_compare.op1 = NULL_RTX;
}")
(define_expand "sge"
""
"
{
- if (alpha_compare_fp_p)
+ if (alpha_compare.fp_p)
FAIL;
- operands[1] = gen_rtx_LE (DImode, force_reg (DImode, alpha_compare_op1),
- alpha_compare_op0);
+ operands[1] = gen_rtx_LE (DImode, force_reg (DImode, alpha_compare.op1),
+ alpha_compare.op0);
+ alpha_compare.op0 = alpha_compare.op1 = NULL_RTX;
}")
(define_expand "sltu"
""
"
{
- if (alpha_compare_fp_p)
+ if (alpha_compare.fp_p)
FAIL;
- operands[1] = gen_rtx_LTU (DImode, alpha_compare_op0, alpha_compare_op1);
+ operands[1] = gen_rtx_LTU (DImode, alpha_compare.op0, alpha_compare.op1);
+ alpha_compare.op0 = alpha_compare.op1 = NULL_RTX;
}")
(define_expand "sleu"
""
"
{
- if (alpha_compare_fp_p)
+ if (alpha_compare.fp_p)
FAIL;
- operands[1] = gen_rtx_LEU (DImode, alpha_compare_op0, alpha_compare_op1);
+ operands[1] = gen_rtx_LEU (DImode, alpha_compare.op0, alpha_compare.op1);
+ alpha_compare.op0 = alpha_compare.op1 = NULL_RTX;
}")
(define_expand "sgtu"
""
"
{
- if (alpha_compare_fp_p)
+ if (alpha_compare.fp_p)
FAIL;
- operands[1] = gen_rtx_LTU (DImode, force_reg (DImode, alpha_compare_op1),
- alpha_compare_op0);
+ operands[1] = gen_rtx_LTU (DImode, force_reg (DImode, alpha_compare.op1),
+ alpha_compare.op0);
+ alpha_compare.op0 = alpha_compare.op1 = NULL_RTX;
}")
(define_expand "sgeu"
""
"
{
- if (alpha_compare_fp_p)
+ if (alpha_compare.fp_p)
FAIL;
- operands[1] = gen_rtx_LEU (DImode, force_reg (DImode, alpha_compare_op1),
- alpha_compare_op0);
+ operands[1] = gen_rtx_LEU (DImode, force_reg (DImode, alpha_compare.op1),
+ alpha_compare.op0);
+ alpha_compare.op0 = alpha_compare.op1 = NULL_RTX;
}")
\f
;; These are the main define_expand's used to make conditional moves.