summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkenner <kenner@138bc75d-0d04-0410-961f-82ee72b054a4>2000-03-26 17:05:34 +0000
committerkenner <kenner@138bc75d-0d04-0410-961f-82ee72b054a4>2000-03-26 17:05:34 +0000
commit2e91880441f9441fe451fb8abb019be73c0fc82e (patch)
treea4b08daab16d206b224e9368ad326ed434f256e5
parent0eacd41206a6d0c5f2ec96038263b4eb6a089b49 (diff)
downloadppe42-gcc-2e91880441f9441fe451fb8abb019be73c0fc82e.tar.gz
ppe42-gcc-2e91880441f9441fe451fb8abb019be73c0fc82e.zip
* expr.c (expand_assignment): Add code to handle variable-sized
BLKmode case. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@32749 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/expr.c64
1 files changed, 43 insertions, 21 deletions
diff --git a/gcc/expr.c b/gcc/expr.c
index 4d7007e4766..3e0085d0b46 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -3447,27 +3447,49 @@ expand_assignment (to, from, want_value, suggest_reg)
TYPE_MODE (integer_type_node));
}
- result = store_field (to_rtx, bitsize, bitpos, mode1, from,
- (want_value
- /* Spurious cast makes HPUX compiler happy. */
- ? (enum machine_mode) TYPE_MODE (TREE_TYPE (to))
- : VOIDmode),
- unsignedp,
- /* Required alignment of containing datum. */
- alignment,
- int_size_in_bytes (TREE_TYPE (tem)),
- get_alias_set (to));
- preserve_temp_slots (result);
- free_temp_slots ();
- pop_temp_slots ();
-
- /* If the value is meaningful, convert RESULT to the proper mode.
- Otherwise, return nothing. */
- return (want_value ? convert_modes (TYPE_MODE (TREE_TYPE (to)),
- TYPE_MODE (TREE_TYPE (from)),
- result,
- TREE_UNSIGNED (TREE_TYPE (to)))
- : NULL_RTX);
+ /* If this is a varying-length object, we must get the address of
+ the source and do an explicit block move. */
+ if (bitsize < 0)
+ {
+ unsigned int from_align;
+ rtx from_rtx = expand_expr_unaligned (from, &from_align);
+ rtx inner_to_rtx
+ = change_address (to_rtx, VOIDmode,
+ plus_constant (XEXP (to_rtx, 0),
+ bitpos / BITS_PER_UNIT));
+
+ emit_block_move (inner_to_rtx, from_rtx, expr_size (from),
+ MIN (alignment, from_align) / BITS_PER_UNIT);
+ free_temp_slots ();
+ pop_temp_slots ();
+ return to_rtx;
+ }
+ else
+ {
+ result = store_field (to_rtx, bitsize, bitpos, mode1, from,
+ (want_value
+ /* Spurious cast for HPUX compiler. */
+ ? ((enum machine_mode)
+ TYPE_MODE (TREE_TYPE (to)))
+ : VOIDmode),
+ unsignedp,
+ /* Required alignment of containing datum. */
+ alignment,
+ int_size_in_bytes (TREE_TYPE (tem)),
+ get_alias_set (to));
+
+ preserve_temp_slots (result);
+ free_temp_slots ();
+ pop_temp_slots ();
+
+ /* If the value is meaningful, convert RESULT to the proper mode.
+ Otherwise, return nothing. */
+ return (want_value ? convert_modes (TYPE_MODE (TREE_TYPE (to)),
+ TYPE_MODE (TREE_TYPE (from)),
+ result,
+ TREE_UNSIGNED (TREE_TYPE (to)))
+ : NULL_RTX);
+ }
}
/* If the rhs is a function call and its value is not an aggregate,
OpenPOWER on IntegriCloud