aboutsummaryrefslogtreecommitdiff
path: root/gcc/expr.c
diff options
context:
space:
mode:
authorRichard Henderson <rth@redhat.com>2004-12-25 19:59:28 -0800
committerRichard Henderson <rth@gcc.gnu.org>2004-12-25 19:59:28 -0800
commit57aaef66e54574a9ae1740491516066e8eddc64b (patch)
tree4403a3fcc0caca4650a778eef642eaae7575c16d /gcc/expr.c
parent798e3fe5a033121d06c9e17f871aaabf3c35dfbd (diff)
downloadgcc-57aaef66e54574a9ae1740491516066e8eddc64b.zip
gcc-57aaef66e54574a9ae1740491516066e8eddc64b.tar.gz
gcc-57aaef66e54574a9ae1740491516066e8eddc64b.tar.bz2
expr.c (clear_storage): Validate CONST0_RTX extant.
* expr.c (clear_storage): Validate CONST0_RTX extant. Special case complex modes. From-SVN: r92615
Diffstat (limited to 'gcc/expr.c')
-rw-r--r--gcc/expr.c53
1 files changed, 36 insertions, 17 deletions
diff --git a/gcc/expr.c b/gcc/expr.c
index f602306..6782feb 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -159,6 +159,7 @@ static void emit_single_push_insn (enum machine_mode, rtx, tree);
#endif
static void do_tablejump (rtx, enum machine_mode, rtx, rtx, rtx);
static rtx const_vector_from_tree (tree);
+static void write_complex_part (rtx, rtx, bool);
/* Record for each mode whether we can move a register directly to or
from an object of that mode in memory. If we can't, we won't try
@@ -2405,30 +2406,48 @@ store_by_pieces_2 (rtx (*genfun) (rtx, ...), enum machine_mode mode,
rtx
clear_storage (rtx object, rtx size)
{
- rtx retval = 0;
- unsigned int align = (MEM_P (object) ? MEM_ALIGN (object)
- : GET_MODE_ALIGNMENT (GET_MODE (object)));
+ enum machine_mode mode = GET_MODE (object);
+ unsigned int align;
/* 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
+ if (mode != BLKmode
&& GET_CODE (size) == CONST_INT
- && INTVAL (size) == (HOST_WIDE_INT) GET_MODE_SIZE (GET_MODE (object)))
- emit_move_insn (object, CONST0_RTX (GET_MODE (object)));
- else
+ && INTVAL (size) == (HOST_WIDE_INT) GET_MODE_SIZE (mode))
{
- if (size == const0_rtx)
- ;
- else if (GET_CODE (size) == CONST_INT
- && CLEAR_BY_PIECES_P (INTVAL (size), align))
- clear_by_pieces (object, INTVAL (size), align);
- else if (clear_storage_via_clrmem (object, size, align))
- ;
- else
- retval = clear_storage_via_libcall (object, size);
+ rtx zero = CONST0_RTX (mode);
+ if (zero != NULL)
+ {
+ emit_move_insn (object, zero);
+ return NULL;
+ }
+
+ if (COMPLEX_MODE_P (mode))
+ {
+ zero = CONST0_RTX (GET_MODE_INNER (mode));
+ if (zero != NULL)
+ {
+ write_complex_part (object, zero, 0);
+ write_complex_part (object, zero, 1);
+ return NULL;
+ }
+ }
}
- return retval;
+ if (size == const0_rtx)
+ return NULL;
+
+ align = MEM_ALIGN (object);
+
+ if (GET_CODE (size) == CONST_INT
+ && CLEAR_BY_PIECES_P (INTVAL (size), align))
+ clear_by_pieces (object, INTVAL (size), align);
+ else if (clear_storage_via_clrmem (object, size, align))
+ ;
+ else
+ return clear_storage_via_libcall (object, size);
+
+ return NULL;
}
/* A subroutine of clear_storage. Expand a clrmem pattern;