From a69beca121baeb70efa57d7f381cf7376778d21a Mon Sep 17 00:00:00 2001 From: Richard Kenner Date: Sun, 26 Mar 2000 12:05:34 -0500 Subject: expr.c (expand_assignment): Add code to handle variable-sized BLKmode case. * expr.c (expand_assignment): Add code to handle variable-sized BLKmode case. From-SVN: r32749 --- gcc/expr.c | 64 +++++++++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 43 insertions(+), 21 deletions(-) (limited to 'gcc') diff --git a/gcc/expr.c b/gcc/expr.c index 4d7007e..3e0085d 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, -- cgit v1.1