diff options
author | Richard Kenner <kenner@vlsi1.ultra.nyu.edu> | 2001-11-21 23:32:03 +0000 |
---|---|---|
committer | Richard Kenner <kenner@gcc.gnu.org> | 2001-11-21 18:32:03 -0500 |
commit | c11c10d87b229fc9bfa4a1e0a5a342e3344f737d (patch) | |
tree | c9328a6f72e26ab58f5c08b5f144508cc16878e1 /gcc/expr.c | |
parent | 2e7d5318fc0902a682ef1a2b1e43df40f7f3de29 (diff) | |
download | gcc-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.c | 47 |
1 files changed, 23 insertions, 24 deletions
@@ -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, |