aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorDavid Edelsohn <dje@gcc.gnu.org>2004-08-10 22:40:45 -0400
committerDavid Edelsohn <dje@gcc.gnu.org>2004-08-10 22:40:45 -0400
commitfba73eb1cb3e624b60cb9974d53c004c2562486b (patch)
treebad682d36f8cd0b419bd01fae554222ddeef7d4b /gcc
parent5158e8d8c1a81c0506defd908022aba439f3edeb (diff)
downloadgcc-fba73eb1cb3e624b60cb9974d53c004c2562486b.zip
gcc-fba73eb1cb3e624b60cb9974d53c004c2562486b.tar.gz
gcc-fba73eb1cb3e624b60cb9974d53c004c2562486b.tar.bz2
rs6000-protos.h (expand_block_clear): Declare.
* config/rs6000/rs6000-protos.h (expand_block_clear): Declare. * config/rs6000/rs6000.md (clrmemsi): New pattern. * config/rs6000/rs6000.c (expand_block_clear): New function. (expand_block_move): Convert alignment to bits. Use SImode and HImode for unaligned addresses if not STRICT_ALIGNMENT. From-SVN: r85787
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog10
-rw-r--r--gcc/config/rs6000/rs6000-protos.h1
-rw-r--r--gcc/config/rs6000/rs6000.c91
-rw-r--r--gcc/config/rs6000/rs6000.md14
4 files changed, 111 insertions, 5 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 5ac385c..7a79351 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,4 +1,12 @@
-2004-08-10 Caroline Tice <ctice@apple.com
+2004-08-10 David Edelsohn <edelsohn@gnu.org>
+
+ * config/rs6000/rs6000-protos.h (expand_block_clear): Declare.
+ * config/rs6000/rs6000.md (clrmemsi): New pattern.
+ * config/rs6000/rs6000.c (expand_block_clear): New function.
+ (expand_block_move): Convert alignment to bits. Use SImode and
+ HImode for unaligned addresses if not STRICT_ALIGNMENT.
+
+2004-08-10 Caroline Tice <ctice@apple.com>
* varasm.c (unlikely_section_label): New global variable.
(unlikely_text_section_name): New global variable.
diff --git a/gcc/config/rs6000/rs6000-protos.h b/gcc/config/rs6000/rs6000-protos.h
index 5a85078..2e5afb6 100644
--- a/gcc/config/rs6000/rs6000-protos.h
+++ b/gcc/config/rs6000/rs6000-protos.h
@@ -86,6 +86,7 @@ extern int input_operand (rtx, enum machine_mode);
extern int small_data_operand (rtx, enum machine_mode);
extern int s8bit_cint_operand (rtx, enum machine_mode);
extern bool legitimate_constant_pool_address_p (rtx);
+extern int expand_block_clear (rtx[]);
extern int expand_block_move (rtx[]);
extern int load_multiple_operation (rtx, enum machine_mode);
extern const char * rs6000_output_load_multiple (rtx[]);
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index 338ed82..7381a46 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -8253,6 +8253,89 @@ rs6000_init_libfuncs (void)
set_conv_libfunc (sfloat_optab, TFmode, SImode, "_q_itoq");
}
}
+
+
+/* Expand a block clear operation, and return 1 if successful. Return 0
+ if we should let the compiler generate normal code.
+
+ operands[0] is the destination
+ operands[1] is the length
+ operands[2] is the alignment */
+
+int
+expand_block_clear (rtx operands[])
+{
+ rtx orig_dest = operands[0];
+ rtx bytes_rtx = operands[1];
+ rtx align_rtx = operands[2];
+ int constp = (GET_CODE (bytes_rtx) == CONST_INT);
+ int align;
+ int bytes;
+ int offset;
+ int clear_bytes;
+
+ /* If this is not a fixed size move, just call memcpy */
+ if (! constp)
+ return 0;
+
+ /* If this is not a fixed size alignment, abort */
+ if (GET_CODE (align_rtx) != CONST_INT)
+ abort ();
+ align = INTVAL (align_rtx) * BITS_PER_UNIT;
+
+ /* Anything to clear? */
+ bytes = INTVAL (bytes_rtx);
+ if (bytes <= 0)
+ return 1;
+
+ if (bytes > (TARGET_POWERPC64 && align >= 32 ? 64 : 32))
+ return 0;
+
+ if (optimize_size && bytes > 16)
+ return 0;
+
+ for (offset = 0; bytes > 0; offset += clear_bytes, bytes -= clear_bytes)
+ {
+ rtx (*mov) (rtx, rtx);
+ enum machine_mode mode = BLKmode;
+ rtx dest;
+
+ if (bytes >= 8 && TARGET_POWERPC64
+ /* 64-bit loads and stores require word-aligned
+ displacements. */
+ && (align >= 64 || (!STRICT_ALIGNMENT && align >= 32)))
+ {
+ clear_bytes = 8;
+ mode = DImode;
+ mov = gen_movdi;
+ }
+ else if (bytes >= 4 && !STRICT_ALIGNMENT)
+ { /* move 4 bytes */
+ clear_bytes = 4;
+ mode = SImode;
+ mov = gen_movsi;
+ }
+ else if (bytes == 2 && !STRICT_ALIGNMENT)
+ { /* move 2 bytes */
+ clear_bytes = 2;
+ mode = HImode;
+ mov = gen_movhi;
+ }
+ else /* move 1 byte at a time */
+ {
+ clear_bytes = 1;
+ mode = QImode;
+ mov = gen_movqi;
+ }
+
+ dest = adjust_address (orig_dest, mode, offset);
+
+ emit_insn ((*mov) (dest, const0_rtx));
+ }
+
+ return 1;
+}
+
/* Expand a block move operation, and return 1 if successful. Return 0
if we should let the compiler generate normal code.
@@ -8286,7 +8369,7 @@ expand_block_move (rtx operands[])
/* If this is not a fixed size alignment, abort */
if (GET_CODE (align_rtx) != CONST_INT)
abort ();
- align = INTVAL (align_rtx);
+ align = INTVAL (align_rtx) * BITS_PER_UNIT;
/* Anything to move? */
bytes = INTVAL (bytes_rtx);
@@ -8346,7 +8429,7 @@ expand_block_move (rtx operands[])
else if (bytes >= 8 && TARGET_POWERPC64
/* 64-bit loads and stores require word-aligned
displacements. */
- && (align >= 8 || (! STRICT_ALIGNMENT && align >= 4)))
+ && (align >= 64 || (!STRICT_ALIGNMENT && align >= 32)))
{
move_bytes = 8;
mode = DImode;
@@ -8357,13 +8440,13 @@ expand_block_move (rtx operands[])
move_bytes = (bytes > 8) ? 8 : bytes;
gen_func.movmemsi = gen_movmemsi_2reg;
}
- else if (bytes >= 4 && (align >= 4 || ! STRICT_ALIGNMENT))
+ else if (bytes >= 4 && !STRICT_ALIGNMENT)
{ /* move 4 bytes */
move_bytes = 4;
mode = SImode;
gen_func.mov = gen_movsi;
}
- else if (bytes == 2 && (align >= 2 || ! STRICT_ALIGNMENT))
+ else if (bytes == 2 && !STRICT_ALIGNMENT)
{ /* move 2 bytes */
move_bytes = 2;
mode = HImode;
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index dc8ce50..aef44d5 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -9093,6 +9093,20 @@
"{stsi|stswi} %2,%1,%O0"
[(set_attr "type" "store")])
+(define_expand "clrmemsi"
+ [(parallel [(set (match_operand:BLK 0 "" "")
+ (const_int 0))
+ (use (match_operand:SI 1 "" ""))
+ (use (match_operand:SI 2 "" ""))])]
+ ""
+ "
+{
+ if (expand_block_clear (operands))
+ DONE;
+ else
+ FAIL;
+}")
+
;; String/block move insn.
;; Argument 0 is the destination
;; Argument 1 is the source