aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Stallman <rms@gnu.org>1993-11-15 02:42:39 +0000
committerRichard Stallman <rms@gnu.org>1993-11-15 02:42:39 +0000
commitb258707c7efd72e380f3b95d70208a9d2975a095 (patch)
tree528432373685c8610dc03d613eebab6d4087a506
parent649f35f1673b77fb7143ef4f37c9add9b00f0630 (diff)
downloadgcc-b258707c7efd72e380f3b95d70208a9d2975a095.zip
gcc-b258707c7efd72e380f3b95d70208a9d2975a095.tar.gz
gcc-b258707c7efd72e380f3b95d70208a9d2975a095.tar.bz2
(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
-rw-r--r--gcc/expr.c25
1 files changed, 25 insertions, 0 deletions
diff --git a/gcc/expr.c b/gcc/expr.c
index 70636b6..f82c2ab 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -2610,6 +2610,14 @@ store_expr (exp, target, want_value)
expression. */
{
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,
SUBREG_PROMOTED_UNSIGNED_P (target));
return want_value ? temp : NULL_RTX;
@@ -2633,6 +2641,15 @@ store_expr (exp, target, want_value)
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.
Convert the value to TARGET's type first if nec. */
@@ -5147,18 +5164,26 @@ expand_expr (exp, target, tmode, modifier)
treating TRUTH_AND_EXPR like TRUTH_ANDIF_EXPR;
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:
+ if (mode != TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp, 0))))
+ subtarget = 0;
case BIT_AND_EXPR:
this_optab = and_optab;
goto binop;
/* See comment above about TRUTH_AND_EXPR; it applies here too. */
case TRUTH_OR_EXPR:
+ if (mode != TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp, 0))))
+ subtarget = 0;
case BIT_IOR_EXPR:
this_optab = ior_optab;
goto binop;
case TRUTH_XOR_EXPR:
+ if (mode != TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp, 0))))
+ subtarget = 0;
case BIT_XOR_EXPR:
this_optab = xor_optab;
goto binop;