aboutsummaryrefslogtreecommitdiff
path: root/gcc/expr.c
diff options
context:
space:
mode:
authorRichard Kenner <kenner@vlsi1.ultra.nyu.edu>2001-11-21 23:32:03 +0000
committerRichard Kenner <kenner@gcc.gnu.org>2001-11-21 18:32:03 -0500
commitc11c10d87b229fc9bfa4a1e0a5a342e3344f737d (patch)
treec9328a6f72e26ab58f5c08b5f144508cc16878e1 /gcc/expr.c
parent2e7d5318fc0902a682ef1a2b1e43df40f7f3de29 (diff)
downloadgcc-c11c10d87b229fc9bfa4a1e0a5a342e3344f737d.zip
gcc-c11c10d87b229fc9bfa4a1e0a5a342e3344f737d.tar.gz
gcc-c11c10d87b229fc9bfa4a1e0a5a342e3344f737d.tar.bz2
expr.c (expand_expr, [...]): Refine slightly and also support TREE_ADDRESSABLE.
* expr.c (expand_expr, case VIEW_CONVERT_EXPR): Refine slightly and also support TREE_ADDRESSABLE. * tree.def (VIEW_CONVERT_EXPR): Document TREE_ADDRESSABLE. From-SVN: r47249
Diffstat (limited to 'gcc/expr.c')
-rw-r--r--gcc/expr.c47
1 files changed, 23 insertions, 24 deletions
diff --git a/gcc/expr.c b/gcc/expr.c
index 0c5429e..9ea2345 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -7542,47 +7542,43 @@ expand_expr (exp, target, tmode, modifier)
/* If the input and output modes are both the same, we are done.
Otherwise, if neither mode is BLKmode and both are within a word, we
- can use gen_lowpart. If neither is true, store the operand into
- memory and convert the MEM to the new mode. */
+ can use gen_lowpart. If neither is true, make sure the operand is
+ in memory and convert the MEM to the new mode. */
if (TYPE_MODE (type) == GET_MODE (op0))
;
else if (TYPE_MODE (type) != BLKmode && GET_MODE (op0) != BLKmode
&& GET_MODE_SIZE (TYPE_MODE (type)) <= UNITS_PER_WORD
&& GET_MODE_SIZE (GET_MODE (op0)) <= UNITS_PER_WORD)
op0 = gen_lowpart (TYPE_MODE (type), op0);
- else
+ else if (GET_CODE (op0) != MEM)
{
+ /* If the operand is not a MEM, force it into memory. Since we
+ are going to be be changing the mode of the MEM, don't call
+ force_const_mem for constants because we don't allow pool
+ constants to change mode. */
tree inner_type = TREE_TYPE (TREE_OPERAND (exp, 0));
- enum machine_mode non_blkmode
- = GET_MODE (op0) == BLKmode ? TYPE_MODE (type) : GET_MODE (op0);
- if (CONSTANT_P (op0))
- op0 = validize_mem (force_const_mem (TYPE_MODE (inner_type), op0));
- else
- {
- if (target == 0 || GET_MODE (target) != TYPE_MODE (inner_type))
- target
- = assign_stack_temp_for_type (TYPE_MODE (inner_type),
- GET_MODE_SIZE (non_blkmode),
- 0, inner_type);
+ if (TREE_ADDRESSABLE (exp))
+ abort ();
- if (GET_MODE (target) == BLKmode)
- emit_block_move (target, op0,
- expr_size (TREE_OPERAND (exp, 0)));
- else
- emit_move_insn (target, op0);
+ if (target == 0 || GET_MODE (target) != TYPE_MODE (inner_type))
+ target
+ = assign_stack_temp_for_type
+ (TYPE_MODE (inner_type),
+ GET_MODE_SIZE (TYPE_MODE (inner_type)), 0, inner_type);
- op0 = target;
- }
+ emit_move_insn (target, op0);
+ op0 = target;
}
+ /* At this point, OP0 is in the correct mode. If the output type is such
+ that the operand is known to be aligned, indicate that it is.
+ Otherwise, we need only be concerned about alignment for non-BLKmode
+ results. */
if (GET_CODE (op0) == MEM)
{
op0 = copy_rtx (op0);
- /* If the output type is such that the operand is known to be
- aligned, indicate that it is. Otherwise, we need only be
- concerned about alignment for non-BLKmode results. */
if (TYPE_ALIGN_OK (type))
set_mem_align (op0, MAX (MEM_ALIGN (op0), TYPE_ALIGN (type)));
else if (TYPE_MODE (type) != BLKmode && STRICT_ALIGNMENT
@@ -7595,6 +7591,9 @@ expand_expr (exp, target, tmode, modifier)
temp_size, 0, type);
rtx new_with_op0_mode = copy_rtx (new);
+ if (TREE_ADDRESSABLE (exp))
+ abort ();
+
PUT_MODE (new_with_op0_mode, GET_MODE (op0));
if (GET_MODE (op0) == BLKmode)
emit_block_move (new_with_op0_mode, op0,