aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoger Sayle <roger@eyesopen.com>2003-09-07 20:34:13 +0000
committerRoger Sayle <sayle@gcc.gnu.org>2003-09-07 20:34:13 +0000
commiteb698c5883ecbe510585bf6c37a9ae198577cea2 (patch)
tree9b2ed270edaa17237187e1b284596268edbe916e
parent4f61b3b722d34b8cd37376bc1e21879c01296c1b (diff)
downloadgcc-eb698c5883ecbe510585bf6c37a9ae198577cea2.zip
gcc-eb698c5883ecbe510585bf6c37a9ae198577cea2.tar.gz
gcc-eb698c5883ecbe510585bf6c37a9ae198577cea2.tar.bz2
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
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/expr.c104
2 files changed, 60 insertions, 51 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 5b10868..3308345 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,12 @@
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.
diff --git a/gcc/expr.c b/gcc/expr.c
index eb25fed..0538707 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -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);
@@ -6523,6 +6525,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.
@@ -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);