Commit b258707c by Richard Stallman

(expand_expr): For TRUTH_AND_EXPR...

(expand_expr): For TRUTH_AND_EXPR, TRUTH_OR_EXPR
and TRUTH_XOR_EXPR, if result mode doesn't match operands,
don't use subtarget.

(store_expr): Convert constants to proper mode in two places.

From-SVN: r6096
parent 649f35f1
...@@ -2610,6 +2610,14 @@ store_expr (exp, target, want_value) ...@@ -2610,6 +2610,14 @@ store_expr (exp, target, want_value)
expression. */ expression. */
{ {
temp = expand_expr (exp, NULL_RTX, VOIDmode, 0); temp = expand_expr (exp, NULL_RTX, VOIDmode, 0);
/* If TEMP is a VOIDmode constant, use convert_modes to make
sure that we properly convert it. */
if (CONSTANT_P (temp) && GET_MODE (temp) == VOIDmode)
temp = convert_modes (GET_MODE (SUBREG_REG (target)),
TYPE_MODE (TREE_TYPE (exp)), temp,
SUBREG_PROMOTED_UNSIGNED_P (target));
convert_move (SUBREG_REG (target), temp, convert_move (SUBREG_REG (target), temp,
SUBREG_PROMOTED_UNSIGNED_P (target)); SUBREG_PROMOTED_UNSIGNED_P (target));
return want_value ? temp : NULL_RTX; return want_value ? temp : NULL_RTX;
...@@ -2633,6 +2641,15 @@ store_expr (exp, target, want_value) ...@@ -2633,6 +2641,15 @@ store_expr (exp, target, want_value)
dont_return_target = 1; dont_return_target = 1;
} }
/* If TEMP is a VOIDmode constant and the mode of the type of EXP is not
the same as that of TARGET, adjust the constant. This is needed, for
example, in case it is a CONST_DOUBLE and we want only a word-sized
value. */
if (CONSTANT_P (temp) && GET_MODE (temp) == VOIDmode
&& GET_MODE (target) != TYPE_MODE (TREE_TYPE (exp)))
temp = convert_modes (GET_MODE (target), TYPE_MODE (TREE_TYPE (exp)),
temp, TREE_UNSIGNED (TREE_TYPE (exp)));
/* If value was not generated in the target, store it there. /* If value was not generated in the target, store it there.
Convert the value to TARGET's type first if nec. */ Convert the value to TARGET's type first if nec. */
...@@ -5147,18 +5164,26 @@ expand_expr (exp, target, tmode, modifier) ...@@ -5147,18 +5164,26 @@ expand_expr (exp, target, tmode, modifier)
treating TRUTH_AND_EXPR like TRUTH_ANDIF_EXPR; treating TRUTH_AND_EXPR like TRUTH_ANDIF_EXPR;
but the question is how to recognize those cases. */ but the question is how to recognize those cases. */
/* TRUTH_AND_EXPR can have a result whose mode doesn't match
th operands. If so, don't use our target. */
case TRUTH_AND_EXPR: case TRUTH_AND_EXPR:
if (mode != TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp, 0))))
subtarget = 0;
case BIT_AND_EXPR: case BIT_AND_EXPR:
this_optab = and_optab; this_optab = and_optab;
goto binop; goto binop;
/* See comment above about TRUTH_AND_EXPR; it applies here too. */ /* See comment above about TRUTH_AND_EXPR; it applies here too. */
case TRUTH_OR_EXPR: case TRUTH_OR_EXPR:
if (mode != TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp, 0))))
subtarget = 0;
case BIT_IOR_EXPR: case BIT_IOR_EXPR:
this_optab = ior_optab; this_optab = ior_optab;
goto binop; goto binop;
case TRUTH_XOR_EXPR: case TRUTH_XOR_EXPR:
if (mode != TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp, 0))))
subtarget = 0;
case BIT_XOR_EXPR: case BIT_XOR_EXPR:
this_optab = xor_optab; this_optab = xor_optab;
goto binop; goto binop;
......
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