Commit c980ac49 by Richard Stallman

(expand_expr...

(expand_expr, case PLUS_EXPR): In the special case
to return sym+integer as an expression, limit it to when
the non-CONST_INT arg is at least a constant.

(expand_increment): Do preinc with single insn if there's such an insn.

(store_field): Store unaligned field with bit field methods.

From-SVN: r4810
parent c62d2a9c
...@@ -2701,7 +2701,14 @@ store_field (target, bitsize, bitpos, mode, exp, value_mode, ...@@ -2701,7 +2701,14 @@ store_field (target, bitsize, bitpos, mode, exp, value_mode,
if (mode == VOIDmode if (mode == VOIDmode
|| (mode != BLKmode && ! direct_store[(int) mode]) || (mode != BLKmode && ! direct_store[(int) mode])
|| GET_CODE (target) == REG || GET_CODE (target) == REG
|| GET_CODE (target) == SUBREG) || GET_CODE (target) == SUBREG
/* If the field isn't aligned enough to fetch as a unit,
fetch it as a bit field. */
#ifdef STRICT_ALIGNMENT
|| align * BITS_PER_UNIT < GET_MODE_ALIGNMENT (mode)
|| bitpos % GET_MODE_ALIGNMENT (mode) != 0
#endif
)
{ {
rtx temp = expand_expr (exp, NULL_RTX, VOIDmode, 0); rtx temp = expand_expr (exp, NULL_RTX, VOIDmode, 0);
/* Store the value in the bitfield. */ /* Store the value in the bitfield. */
...@@ -4306,30 +4313,38 @@ expand_expr (exp, target, tmode, modifier) ...@@ -4306,30 +4313,38 @@ expand_expr (exp, target, tmode, modifier)
address. address.
If this is an EXPAND_SUM call, always return the sum. */ If this is an EXPAND_SUM call, always return the sum. */
if (TREE_CODE (TREE_OPERAND (exp, 0)) == INTEGER_CST if (modifier == EXPAND_SUM || modifier == EXPAND_INITIALIZER
&& GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT || mode == Pmode)
&& (modifier == EXPAND_SUM || modifier == EXPAND_INITIALIZER
|| mode == Pmode))
{ {
op1 = expand_expr (TREE_OPERAND (exp, 1), subtarget, VOIDmode, if (TREE_CODE (TREE_OPERAND (exp, 0)) == INTEGER_CST
EXPAND_SUM); && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
op1 = plus_constant (op1, TREE_INT_CST_LOW (TREE_OPERAND (exp, 0))); && TREE_CONSTANT (TREE_OPERAND (exp, 1)))
if (modifier != EXPAND_SUM && modifier != EXPAND_INITIALIZER) {
op1 = force_operand (op1, target); op1 = expand_expr (TREE_OPERAND (exp, 1), subtarget, VOIDmode,
return op1; EXPAND_SUM);
} op1 = plus_constant (op1, TREE_INT_CST_LOW (TREE_OPERAND (exp, 0)));
if (modifier != EXPAND_SUM && modifier != EXPAND_INITIALIZER)
op1 = force_operand (op1, target);
return op1;
}
else if (TREE_CODE (TREE_OPERAND (exp, 1)) == INTEGER_CST else if (TREE_CODE (TREE_OPERAND (exp, 1)) == INTEGER_CST
&& GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_INT && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_INT
&& (modifier == EXPAND_SUM || modifier == EXPAND_INITIALIZER && TREE_CONSTANT (TREE_OPERAND (exp, 0)))
|| mode == Pmode)) {
{ op0 = expand_expr (TREE_OPERAND (exp, 0), subtarget, VOIDmode,
op0 = expand_expr (TREE_OPERAND (exp, 0), subtarget, VOIDmode, EXPAND_SUM);
EXPAND_SUM); if (! CONSTANT_P (op0))
op0 = plus_constant (op0, TREE_INT_CST_LOW (TREE_OPERAND (exp, 1))); {
if (modifier != EXPAND_SUM && modifier != EXPAND_INITIALIZER) op1 = expand_expr (TREE_OPERAND (exp, 1), NULL_RTX,
op0 = force_operand (op0, target); VOIDmode, modifier);
return op0; goto both_summands;
}
op0 = plus_constant (op0, TREE_INT_CST_LOW (TREE_OPERAND (exp, 1)));
if (modifier != EXPAND_SUM && modifier != EXPAND_INITIALIZER)
op0 = force_operand (op0, target);
return op0;
}
} }
/* No sense saving up arithmetic to be done /* No sense saving up arithmetic to be done
...@@ -4337,7 +4352,8 @@ expand_expr (exp, target, tmode, modifier) ...@@ -4337,7 +4352,8 @@ expand_expr (exp, target, tmode, modifier)
And force_operand won't know whether to sign-extend or And force_operand won't know whether to sign-extend or
zero-extend. */ zero-extend. */
if ((modifier != EXPAND_SUM && modifier != EXPAND_INITIALIZER) if ((modifier != EXPAND_SUM && modifier != EXPAND_INITIALIZER)
|| mode != Pmode) goto binop; || mode != Pmode)
goto binop;
preexpand_calls (exp); preexpand_calls (exp);
if (! safe_from_p (subtarget, TREE_OPERAND (exp, 1))) if (! safe_from_p (subtarget, TREE_OPERAND (exp, 1)))
...@@ -4346,6 +4362,7 @@ expand_expr (exp, target, tmode, modifier) ...@@ -4346,6 +4362,7 @@ expand_expr (exp, target, tmode, modifier)
op0 = expand_expr (TREE_OPERAND (exp, 0), subtarget, VOIDmode, modifier); op0 = expand_expr (TREE_OPERAND (exp, 0), subtarget, VOIDmode, modifier);
op1 = expand_expr (TREE_OPERAND (exp, 1), NULL_RTX, VOIDmode, modifier); op1 = expand_expr (TREE_OPERAND (exp, 1), NULL_RTX, VOIDmode, modifier);
both_summands:
/* Make sure any term that's a sum with a constant comes last. */ /* Make sure any term that's a sum with a constant comes last. */
if (GET_CODE (op0) == PLUS if (GET_CODE (op0) == PLUS
&& CONSTANT_P (XEXP (op0, 1))) && CONSTANT_P (XEXP (op0, 1)))
...@@ -6839,6 +6856,7 @@ expand_increment (exp, post) ...@@ -6839,6 +6856,7 @@ expand_increment (exp, post)
int icode; int icode;
enum machine_mode mode = TYPE_MODE (TREE_TYPE (exp)); enum machine_mode mode = TYPE_MODE (TREE_TYPE (exp));
int op0_is_copy = 0; int op0_is_copy = 0;
int single_insn = 0;
/* Stabilize any component ref that might need to be /* Stabilize any component ref that might need to be
evaluated more than once below. */ evaluated more than once below. */
...@@ -6877,12 +6895,25 @@ expand_increment (exp, post) ...@@ -6877,12 +6895,25 @@ expand_increment (exp, post)
|| TREE_CODE (exp) == PREDECREMENT_EXPR) || TREE_CODE (exp) == PREDECREMENT_EXPR)
this_optab = sub_optab; this_optab = sub_optab;
/* For a preincrement, see if we can do this with a single instruction. */
if (!post)
{
icode = (int) this_optab->handlers[(int) mode].insn_code;
if (icode != (int) CODE_FOR_nothing
/* Make sure that OP0 is valid for operands 0 and 1
of the insn we want to queue. */
&& (*insn_operand_predicate[icode][0]) (op0, mode)
&& (*insn_operand_predicate[icode][1]) (op0, mode)
&& (*insn_operand_predicate[icode][2]) (op1, mode))
single_insn = 1;
}
/* If OP0 is not the actual lvalue, but rather a copy in a register, /* If OP0 is not the actual lvalue, but rather a copy in a register,
then we cannot just increment OP0. We must therefore contrive to then we cannot just increment OP0. We must therefore contrive to
increment the original value. Then, for postincrement, we can return increment the original value. Then, for postincrement, we can return
OP0 since it is a copy of the old value. For preincrement, we want OP0 since it is a copy of the old value. For preincrement, expand here
to always expand here, since this generates better or equivalent code. */ unless we can do it with a single insn. */
if (!post || op0_is_copy) if (op0_is_copy || (!post && !single_insn))
{ {
/* This is the easiest way to increment the value wherever it is. /* This is the easiest way to increment the value wherever it is.
Problems with multiple evaluation of INCREMENTED are prevented Problems with multiple evaluation of INCREMENTED are prevented
......
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