Commit eb698c58 by Roger Sayle Committed by Roger Sayle

expr.c (expand_operands): New function to expand an operand pair.


	* expr.c (expand_operands): New function to expand an operand pair.
	(expand_expr): Call expand_operands whenever we need to expand both
	operands of a binary operator.
	(do_store_flag): Likewise for operands of comparison operations.

From-SVN: r71179
parent 4f61b3b7
2003-09-07 Roger Sayle <roger@eyesopen.com>
* expr.c (expand_operands): New function to expand an operand pair.
(expand_expr): Call expand_operands whenever we need to expand both
operands of a binary operator.
(do_store_flag): Likewise for operands of comparison operations.
2003-09-07 Roger Sayle <roger@eyesopen.com>
* combine.c (combine_simplify_rtx): Don't convert -(A*B) into
(-A)*B if we care about sign-dependent rounding.
......
......@@ -164,6 +164,8 @@ static unsigned HOST_WIDE_INT highest_pow2_factor_for_type (tree, tree);
static int is_aligning_offset (tree, tree);
static rtx expand_increment (tree, int, int);
static void expand_operands (tree, tree, rtx, rtx*, rtx*,
enum expand_modifier);
static rtx do_store_flag (tree, rtx, enum machine_mode, int);
#ifdef PUSH_ROUNDING
static void emit_single_push_insn (enum machine_mode, rtx, tree);
......@@ -6524,6 +6526,30 @@ find_placeholder (tree exp, tree *plist)
return 0;
}
/* Subroutine of expand_expr. Expand the two operands of a binary
expression EXP0 and EXP1 placing the results in OP0 and OP1.
The value may be stored in TARGET if TARGET is nonzero. The
MODIFIER argument is as documented by expand_expr. */
static void
expand_operands (tree exp0, tree exp1, rtx target, rtx *op0, rtx *op1,
enum expand_modifier modifier)
{
if (! safe_from_p (target, exp1, 1))
target = 0;
if (operand_equal_p (exp0, exp1, 0))
{
*op0 = expand_expr (exp0, target, VOIDmode, modifier);
*op1 = copy_rtx (*op0);
}
else
{
*op0 = expand_expr (exp0, target, VOIDmode, modifier);
*op1 = expand_expr (exp1, NULL_RTX, VOIDmode, modifier);
}
}
/* expand_expr: generate code for computing expression EXP.
An rtx for the computed value is returned. The value is never null.
In the case of a void EXP, const0_rtx is returned.
......@@ -6567,7 +6593,8 @@ find_placeholder (tree exp, tree *plist)
emit_block_move will be flagged with BLOCK_OP_CALL_PARM. */
rtx
expand_expr (tree exp, rtx target, enum machine_mode tmode, enum expand_modifier modifier)
expand_expr (tree exp, rtx target, enum machine_mode tmode,
enum expand_modifier modifier)
{
rtx op0, op1, temp;
tree type = TREE_TYPE (exp);
......@@ -8141,12 +8168,8 @@ expand_expr (tree exp, rtx target, enum machine_mode tmode, enum expand_modifier
if ((modifier != EXPAND_SUM && modifier != EXPAND_INITIALIZER)
|| mode != ptr_mode)
{
op0 = expand_expr (TREE_OPERAND (exp, 0), subtarget, VOIDmode, 0);
if (! operand_equal_p (TREE_OPERAND (exp, 0),
TREE_OPERAND (exp, 1), 0))
op1 = expand_expr (TREE_OPERAND (exp, 1), NULL_RTX, VOIDmode, 0);
else
op1 = op0;
expand_operands (TREE_OPERAND (exp, 0), TREE_OPERAND (exp, 1),
subtarget, &op0, &op1, 0);
if (op0 == const0_rtx)
return op1;
if (op1 == const0_rtx)
......@@ -8154,13 +8177,8 @@ expand_expr (tree exp, rtx target, enum machine_mode tmode, enum expand_modifier
goto binop2;
}
op0 = expand_expr (TREE_OPERAND (exp, 0), subtarget, VOIDmode, modifier);
if (! operand_equal_p (TREE_OPERAND (exp, 0),
TREE_OPERAND (exp, 1), 0))
op1 = expand_expr (TREE_OPERAND (exp, 1), NULL_RTX,
VOIDmode, modifier);
else
op1 = op0;
expand_operands (TREE_OPERAND (exp, 0), TREE_OPERAND (exp, 1),
subtarget, &op0, &op1, modifier);
return simplify_gen_binary (PLUS, mode, op0, op1);
case MINUS_EXPR:
......@@ -8173,10 +8191,8 @@ expand_expr (tree exp, rtx target, enum machine_mode tmode, enum expand_modifier
&& really_constant_p (TREE_OPERAND (exp, 0))
&& really_constant_p (TREE_OPERAND (exp, 1)))
{
rtx op0 = expand_expr (TREE_OPERAND (exp, 0), NULL_RTX, VOIDmode,
modifier);
rtx op1 = expand_expr (TREE_OPERAND (exp, 1), NULL_RTX, VOIDmode,
modifier);
expand_operands (TREE_OPERAND (exp, 0), TREE_OPERAND (exp, 1),
NULL_RTX, &op0, &op1, modifier);
/* If the last operand is a CONST_INT, use plus_constant of
the negated constant. Else make the MINUS. */
......@@ -8198,11 +8214,8 @@ expand_expr (tree exp, rtx target, enum machine_mode tmode, enum expand_modifier
|| mode != ptr_mode)
goto binop;
if (! safe_from_p (subtarget, TREE_OPERAND (exp, 1), 1))
subtarget = 0;
op0 = expand_expr (TREE_OPERAND (exp, 0), subtarget, VOIDmode, modifier);
op1 = expand_expr (TREE_OPERAND (exp, 1), NULL_RTX, VOIDmode, modifier);
expand_operands (TREE_OPERAND (exp, 0), TREE_OPERAND (exp, 1),
subtarget, &op0, &op1, modifier);
/* Convert A - const to A + (-const). */
if (GET_CODE (op1) == CONST_INT)
......@@ -8297,14 +8310,14 @@ expand_expr (tree exp, rtx target, enum machine_mode tmode, enum expand_modifier
{
if (this_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
{
op0 = expand_expr (TREE_OPERAND (TREE_OPERAND (exp, 0), 0),
NULL_RTX, VOIDmode, 0);
if (TREE_CODE (TREE_OPERAND (exp, 1)) == INTEGER_CST)
op1 = expand_expr (TREE_OPERAND (exp, 1), NULL_RTX,
VOIDmode, 0);
expand_operands (TREE_OPERAND (TREE_OPERAND (exp, 0), 0),
TREE_OPERAND (exp, 1),
NULL_RTX, &op0, &op1, 0);
else
op1 = expand_expr (TREE_OPERAND (TREE_OPERAND (exp, 1), 0),
NULL_RTX, VOIDmode, 0);
expand_operands (TREE_OPERAND (TREE_OPERAND (exp, 0), 0),
TREE_OPERAND (TREE_OPERAND (exp, 1), 0),
NULL_RTX, &op0, &op1, 0);
goto binop2;
}
else if (other_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing
......@@ -8333,12 +8346,8 @@ expand_expr (tree exp, rtx target, enum machine_mode tmode, enum expand_modifier
}
}
}
op0 = expand_expr (TREE_OPERAND (exp, 0), subtarget, VOIDmode, 0);
if (! operand_equal_p (TREE_OPERAND (exp, 0),
TREE_OPERAND (exp, 1), 0))
op1 = expand_expr (TREE_OPERAND (exp, 1), NULL_RTX, VOIDmode, 0);
else
op1 = op0;
expand_operands (TREE_OPERAND (exp, 0), TREE_OPERAND (exp, 1),
subtarget, &op0, &op1, 0);
return expand_mult (mode, op0, op1, target, unsignedp);
case TRUNC_DIV_EXPR:
......@@ -8346,15 +8355,13 @@ expand_expr (tree exp, rtx target, enum machine_mode tmode, enum expand_modifier
case CEIL_DIV_EXPR:
case ROUND_DIV_EXPR:
case EXACT_DIV_EXPR:
if (! safe_from_p (subtarget, TREE_OPERAND (exp, 1), 1))
subtarget = 0;
if (modifier == EXPAND_STACK_PARM)
target = 0;
/* Possible optimization: compute the dividend with EXPAND_SUM
then if the divisor is constant can optimize the case
where some terms of the dividend have coeffs divisible by it. */
op0 = expand_expr (TREE_OPERAND (exp, 0), subtarget, VOIDmode, 0);
op1 = expand_expr (TREE_OPERAND (exp, 1), NULL_RTX, VOIDmode, 0);
expand_operands (TREE_OPERAND (exp, 0), TREE_OPERAND (exp, 1),
subtarget, &op0, &op1, 0);
return expand_divmod (0, code, mode, op0, op1, target, unsignedp);
case RDIV_EXPR:
......@@ -8376,12 +8383,10 @@ expand_expr (tree exp, rtx target, enum machine_mode tmode, enum expand_modifier
case FLOOR_MOD_EXPR:
case CEIL_MOD_EXPR:
case ROUND_MOD_EXPR:
if (! safe_from_p (subtarget, TREE_OPERAND (exp, 1), 1))
subtarget = 0;
if (modifier == EXPAND_STACK_PARM)
target = 0;
op0 = expand_expr (TREE_OPERAND (exp, 0), subtarget, VOIDmode, 0);
op1 = expand_expr (TREE_OPERAND (exp, 1), NULL_RTX, VOIDmode, 0);
expand_operands (TREE_OPERAND (exp, 0), TREE_OPERAND (exp, 1),
subtarget, &op0, &op1, 0);
return expand_divmod (1, code, mode, op0, op1, target, unsignedp);
case FIX_ROUND_EXPR:
......@@ -8450,8 +8455,8 @@ expand_expr (tree exp, rtx target, enum machine_mode tmode, enum expand_modifier
|| (GET_CODE (target) == REG
&& REGNO (target) < FIRST_PSEUDO_REGISTER))
target = gen_reg_rtx (mode);
op1 = expand_expr (TREE_OPERAND (exp, 1), NULL_RTX, VOIDmode, 0);
op0 = expand_expr (TREE_OPERAND (exp, 0), target, VOIDmode, 0);
expand_operands (TREE_OPERAND (exp, 0), TREE_OPERAND (exp, 1),
target, &op0, &op1, 0);
/* First try to do it with a special MIN or MAX instruction.
If that does not win, use a conditional jump to select the proper
......@@ -9506,10 +9511,8 @@ expand_expr (tree exp, rtx target, enum machine_mode tmode, enum expand_modifier
/* Here to do an ordinary binary operator, generating an instruction
from the optab already placed in `this_optab'. */
binop:
if (! safe_from_p (subtarget, TREE_OPERAND (exp, 1), 1))
subtarget = 0;
op0 = expand_expr (TREE_OPERAND (exp, 0), subtarget, VOIDmode, 0);
op1 = expand_expr (TREE_OPERAND (exp, 1), NULL_RTX, VOIDmode, 0);
expand_operands (TREE_OPERAND (exp, 0), TREE_OPERAND (exp, 1),
subtarget, &op0, &op1, 0);
binop2:
if (modifier == EXPAND_STACK_PARM)
target = 0;
......@@ -10008,8 +10011,7 @@ do_store_flag (tree exp, rtx target, enum machine_mode mode, int only_cheap)
|| ! safe_from_p (subtarget, arg1, 1))
subtarget = 0;
op0 = expand_expr (arg0, subtarget, VOIDmode, 0);
op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
expand_operands (arg0, arg1, subtarget, &op0, &op1, 0);
if (target == 0)
target = gen_reg_rtx (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