summaryrefslogtreecommitdiff
path: root/gcc/expr.c
diff options
context:
space:
mode:
authorrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>2004-12-26 03:59:28 +0000
committerrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>2004-12-26 03:59:28 +0000
commit83016f380cedf2e96fd4c9c689b33360d8451e34 (patch)
tree4403a3fcc0caca4650a778eef642eaae7575c16d /gcc/expr.c
parent09afa07afac6512473988502c64ee22a3cf0fe91 (diff)
downloadgcc-83016f380cedf2e96fd4c9c689b33360d8451e34.tar.gz
* expr.c (clear_storage): Validate CONST0_RTX extant. Special case
complex modes. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@92615 138bc75d-0d04-0410-961f-82ee72b054a4
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 f602306d3e5..6782feb0bfc 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;