From e042bf99fa1f08ea70f276bd0b65ebade5c10aba Mon Sep 17 00:00:00 2001 From: dje Date: Wed, 11 Aug 2004 02:40:45 +0000 Subject: [PATCH] * 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@85787 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 10 ++++- gcc/config/rs6000/rs6000-protos.h | 1 + gcc/config/rs6000/rs6000.c | 91 +++++++++++++++++++++++++++++++++++++-- gcc/config/rs6000/rs6000.md | 14 ++++++ 4 files changed, 111 insertions(+), 5 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 5ac385c421e..7a793511fd1 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,4 +1,12 @@ -2004-08-10 Caroline Tice + + * 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 * 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 5a85078e158..2e5afb6cb44 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 338ed825031..7381a464a12 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 dc8ce50b137..aef44d53e4a 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 -- 2.11.4.GIT