From: Richard Kenner Date: Wed, 17 Apr 1996 12:40:51 +0000 (-0400) Subject: (alpha_emit_conditional_move): Fix some bugs in previous change and do X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=1ad2a62d1c61d5ca4f6f2a836cc743a5fbb0f8ba;p=gcc.git (alpha_emit_conditional_move): Fix some bugs in previous change and do some cleanup. From-SVN: r11834 --- diff --git a/gcc/config/alpha/alpha.c b/gcc/config/alpha/alpha.c index e3edeca9470..aa1f1e3d06e 100644 --- a/gcc/config/alpha/alpha.c +++ b/gcc/config/alpha/alpha.c @@ -977,54 +977,54 @@ alpha_emit_conditional_move (cmp, mode) rtx cmp; enum machine_mode mode; { + enum rtx_code code = GET_CODE (cmp); rtx op0 = alpha_compare_op0; rtx op1 = alpha_compare_op1; - rtx zero = CONST0_RTX (mode); - rtx tmp; - enum rtx_code code = GET_CODE (cmp), code2; + 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; + rtx tem; - if (alpha_compare_fp_p != FLOAT_MODE_P(mode)) + if (alpha_compare_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, mode) && (op0 == zero || op1 == zero)) - return gen_rtx (code, mode, op0, op1); + if (signed_comparison_operator (cmp, cmp_op_mode) + && (op0 == CONST0_RTX (cmp_mode) || op1 == CONST0_RTX (cmp_mode))) + return gen_rtx (code, VOIDmode, op0, op1); /* We can't put the comparison insides a conditional move; emit a compare instruction and put that inside the - conditional move. */ + conditional move. Make sure we emit only comparisons we have; + swap or reverse as necessary. */ - /* The alpha does not have NE GE GT compares for any mode. Avoid them. */ - code2 = NE; switch (code) { - /* We have these compares: */ - case EQ: case LE: case LT: + case EQ: case LE: case LT: case LEU: case LTU: + /* We have these compares: */ break; - /* These must be inverted: */ + case NE: - code = code2 = EQ; - break; - case GE: - code = LE; - op0 = force_reg (mode, alpha_compare_op1); - op1 = alpha_compare_op0; + /* This must be reversed. */ + code = reverse_condition (code); break; - case GT: - code = LT; - op0 = force_reg (mode, alpha_compare_op1); - op1 = alpha_compare_op0; + + case GE: case GT: case GEU: case GTU: + /* These must be swapped. Make sure the new first operand is in + a register. */ + code = swap_condition (code); + tem = op0, op0 = op1, op1 = tem; + op0 = force_reg (cmp_mode, op0); break; + default: - return 0; + abort (); } - cmp = gen_rtx (code, mode, op0, op1); - tmp = gen_reg_rtx (mode); - emit_insn (gen_rtx (SET, VOIDmode, tmp, cmp)); - cmp = gen_rtx (code2, VOIDmode, tmp, zero); - return cmp; + tem = gen_reg_rtx (cmp_op_mode); + emit_move_insn (tem, gen_rtx (code, cmp_op_mode, op0, op1)); + return gen_rtx (code == NE ? EQ : NE, VOIDmode, tem, CONST0_RTX (mode)); } /* Adjust the cost of a scheduling dependency. Return the new cost of