Commit 3d32ffd1 by Tom Wood

(expand_divmod): Eliminate the generation of branches

	when possible.

From-SVN: r1687
parent 3a6aca8e
...@@ -2156,6 +2156,12 @@ expand_divmod (rem_flag, code, mode, op0, op1, target, unsignedp) ...@@ -2156,6 +2156,12 @@ expand_divmod (rem_flag, code, mode, op0, op1, target, unsignedp)
rtx adjusted_op0 = op0; rtx adjusted_op0 = op0;
optab optab1, optab2; optab optab1, optab2;
/* We shouldn't be called with op1 == const1_rtx, but some of the
code below will malfunction if we are, so check here and handle
the special case if so. */
if (op1 == const1_rtx)
return rem_flag ? const0_rtx : op0;
/* Don't use the function value register as a target /* Don't use the function value register as a target
since we have to read it as well as write it, since we have to read it as well as write it,
and function-inlining gets confused by this. */ and function-inlining gets confused by this. */
...@@ -2273,7 +2279,6 @@ expand_divmod (rem_flag, code, mode, op0, op1, target, unsignedp) ...@@ -2273,7 +2279,6 @@ expand_divmod (rem_flag, code, mode, op0, op1, target, unsignedp)
case TRUNC_DIV_EXPR: case TRUNC_DIV_EXPR:
if (log >= 0 && ! unsignedp) if (log >= 0 && ! unsignedp)
{ {
rtx label = gen_label_rtx ();
if (! can_clobber_op0) if (! can_clobber_op0)
{ {
adjusted_op0 = copy_to_suggested_reg (adjusted_op0, target, adjusted_op0 = copy_to_suggested_reg (adjusted_op0, target,
...@@ -2282,11 +2287,32 @@ expand_divmod (rem_flag, code, mode, op0, op1, target, unsignedp) ...@@ -2282,11 +2287,32 @@ expand_divmod (rem_flag, code, mode, op0, op1, target, unsignedp)
which will screw up mem refs for autoincrements. */ which will screw up mem refs for autoincrements. */
op0 = force_reg (compute_mode, op0); op0 = force_reg (compute_mode, op0);
} }
emit_cmp_insn (adjusted_op0, const0_rtx, GE, /* Here we need to add OP1-1 if OP0 is negative, 0 otherwise.
NULL_RTX, compute_mode, 0, 0); This can be computed without jumps by arithmetically shifting
emit_jump_insn (gen_bge (label)); OP0 right LOG-1 places and then shifting right logically
expand_inc (adjusted_op0, plus_constant (op1, -1)); SIZE-LOG bits. The resulting value is unconditionally added
emit_label (label); to OP0. */
if (log == 1 || BRANCH_COST >= 3)
{
rtx temp = gen_reg_rtx (compute_mode);
temp = copy_to_suggested_reg (adjusted_op0, temp, compute_mode);
temp = expand_shift (RSHIFT_EXPR, compute_mode, temp,
build_int_2 (log - 1, 0), NULL_RTX, 0);
temp = expand_shift (RSHIFT_EXPR, compute_mode, temp,
build_int_2 (GET_MODE_BITSIZE (mode) - log,
0),
temp, 1);
expand_inc (adjusted_op0, temp);
}
else
{
rtx label = gen_label_rtx ();
emit_cmp_insn (adjusted_op0, const0_rtx, GE,
NULL_RTX, compute_mode, 0, 0);
emit_jump_insn (gen_bge (label));
expand_inc (adjusted_op0, plus_constant (op1, -1));
emit_label (label);
}
mod_insn_no_good = 1; mod_insn_no_good = 1;
} }
break; break;
...@@ -2364,12 +2390,28 @@ expand_divmod (rem_flag, code, mode, op0, op1, target, unsignedp) ...@@ -2364,12 +2390,28 @@ expand_divmod (rem_flag, code, mode, op0, op1, target, unsignedp)
integer_one_node, NULL_RTX, 0); integer_one_node, NULL_RTX, 0);
if (! unsignedp) if (! unsignedp)
{ {
rtx label = gen_label_rtx (); if (BRANCH_COST >= 2)
emit_cmp_insn (adjusted_op0, const0_rtx, GE, NULL_RTX, {
compute_mode, 0, 0); /* Negate OP1 if OP0 < 0. Do this by computing a temporary
emit_jump_insn (gen_bge (label)); that has all bits equal to the sign bit and exclusive
expand_unop (compute_mode, neg_optab, op1, op1, 0); or-ing it with OP1. */
emit_label (label); rtx temp = gen_reg_rtx (compute_mode);
temp = copy_to_suggested_reg (adjusted_op0, temp, compute_mode);
temp = expand_shift (RSHIFT_EXPR, compute_mode, temp,
build_int_2 (GET_MODE_BITSIZE (mode) - 1, 0),
NULL_RTX, 0);
op1 = expand_binop (compute_mode, xor_optab, op1, temp, op1,
unsignedp, OPTAB_LIB_WIDEN);
}
else
{
rtx label = gen_label_rtx ();
emit_cmp_insn (adjusted_op0, const0_rtx, GE, NULL_RTX,
compute_mode, 0, 0);
emit_jump_insn (gen_bge (label));
expand_unop (compute_mode, neg_optab, op1, op1, 0);
emit_label (label);
}
} }
expand_inc (adjusted_op0, op1); expand_inc (adjusted_op0, op1);
} }
......
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