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
This commit is contained in:
parent
5158e8d8c1
commit
fba73eb1cb
@ -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.
|
||||
|
@ -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[]);
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user