aboutsummaryrefslogtreecommitdiff
path: root/gcc/expr.c
diff options
context:
space:
mode:
authorRichard Kenner <kenner@vlsi1.ultra.nyu.edu>2000-09-01 15:10:52 +0000
committerRichard Kenner <kenner@gcc.gnu.org>2000-09-01 11:10:52 -0400
commitfcf1b822b45416e106c5496c9f13506f543a6082 (patch)
treef870792eadf7ea7ef5ebb149b9f2b0048b2a407c /gcc/expr.c
parentad17a40dcec76fcb2746f6c6d9e3b5071e04e004 (diff)
downloadgcc-fcf1b822b45416e106c5496c9f13506f543a6082.zip
gcc-fcf1b822b45416e106c5496c9f13506f543a6082.tar.gz
gcc-fcf1b822b45416e106c5496c9f13506f543a6082.tar.bz2
expr.c (clear_storage): Don't use emit_move_insn unless either BLKmode or proper size.
* expr.c (clear_storage): Don't use emit_move_insn unless either BLKmode or proper size. (store_constructor): Don't call clear_storage if REG of wrong size. From-SVN: r36101
Diffstat (limited to 'gcc/expr.c')
-rw-r--r--gcc/expr.c18
1 files changed, 13 insertions, 5 deletions
diff --git a/gcc/expr.c b/gcc/expr.c
index 341586a..9c4237b 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -2392,7 +2392,13 @@ clear_storage (object, size, align)
#endif
rtx retval = 0;
- if (GET_MODE (object) == BLKmode)
+ /* If OBJECT is not BLKmode and SIZE is the same size as its mode,
+ just move a zero. Otherwise, do this a piece at a time. */
+ if (GET_MODE (object) != BLKmode
+ && GET_CODE (size) == CONST_INT
+ && GET_MODE_SIZE (GET_MODE (object)) == INTVAL (size))
+ emit_move_insn (object, CONST0_RTX (GET_MODE (object)));
+ else
{
object = protect_from_queue (object, 1);
size = protect_from_queue (size, 0);
@@ -2544,8 +2550,6 @@ clear_storage (object, size, align)
#endif
}
}
- else
- emit_move_insn (object, CONST0_RTX (GET_MODE (object)));
return retval;
}
@@ -4263,11 +4267,15 @@ store_constructor (exp, target, align, cleared, size)
/* If the constructor has fewer fields than the structure
or if we are initializing the structure to mostly zeros,
- clear the whole structure first. */
+ clear the whole structure first. Don't do this is TARGET is
+ register whose mode size isn't equal to SIZE since clear_storage
+ can't handle this case. */
else if (size > 0
&& ((list_length (CONSTRUCTOR_ELTS (exp))
!= fields_length (type))
- || mostly_zeros_p (exp)))
+ || mostly_zeros_p (exp))
+ && (GET_CODE (target) != REG
+ || GET_MODE_SIZE (GET_MODE (target)) == size))
{
if (! cleared)
clear_storage (target, GEN_INT (size), align);