emit-rtl.c (set_mem_size): New function.

* emit-rtl.c (set_mem_size): New function.
	* expr.h (set_mem_size): Declare.
	* config/rs6000/rs6000.c (expand_block_move_mem): Exterminate.
	(expand_block_move): Instead, use adjust_address and
	replace_equiv_address to generate proper aliasing info.
	Move common code out of conditionals.  Localize vars.

From-SVN: r57047
This commit is contained in:
Alan Modra 2002-09-12 02:14:26 +00:00 committed by Alan Modra
parent 874f6a6d1f
commit 35aff10b0f
4 changed files with 94 additions and 159 deletions

View File

@ -1,3 +1,12 @@
2002-09-12 Alan Modra <amodra@bigpond.net.au>
* emit-rtl.c (set_mem_size): New function.
* expr.h (set_mem_size): Declare.
* config/rs6000/rs6000.c (expand_block_move_mem): Exterminate.
(expand_block_move): Instead, use adjust_address and
replace_equiv_address to generate proper aliasing info.
Move common code out of conditionals. Localize vars.
2002-09-09 Eric Botcazou ebotcazou@libertysurf.fr
* optabs.c (expand_binop): Minor cleanup.

View File

@ -167,7 +167,6 @@ struct builtin_description
static void rs6000_add_gc_roots PARAMS ((void));
static int num_insns_constant_wide PARAMS ((HOST_WIDE_INT));
static rtx expand_block_move_mem PARAMS ((enum machine_mode, rtx, rtx));
static void validate_condition_mode
PARAMS ((enum rtx_code, enum machine_mode));
static rtx rs6000_generate_compare PARAMS ((enum rtx_code));
@ -6044,21 +6043,7 @@ rs6000_common_init_builtins ()
}
}
/* Generate a memory reference for expand_block_move, copying volatile,
and other bits from an original memory reference. */
static rtx
expand_block_move_mem (mode, addr, orig_mem)
enum machine_mode mode;
rtx addr;
rtx orig_mem;
{
rtx mem = gen_rtx_MEM (mode, addr);
MEM_COPY_ATTRIBUTES (mem, orig_mem);
return mem;
}
/* Expand a block move operation, and return 1 if successful. Return 0
if we should let the compiler generate normal code.
@ -6081,14 +6066,6 @@ expand_block_move (operands)
int align;
int bytes;
int offset;
int num_reg;
int i;
rtx src_reg;
rtx dest_reg;
rtx src_addr;
rtx dest_addr;
rtx tmp_reg;
rtx stores[MAX_MOVE_REG];
int move_bytes;
/* If this is not a fixed size move, just call memcpy */
@ -6110,14 +6087,17 @@ expand_block_move (operands)
if (bytes > (TARGET_POWERPC64 ? 64 : 32))
return 0;
/* Move the address into scratch registers. */
dest_reg = copy_addr_to_reg (XEXP (orig_dest, 0));
src_reg = copy_addr_to_reg (XEXP (orig_src, 0));
if (TARGET_STRING) /* string instructions are available */
{
for ( ; bytes > 0; bytes -= move_bytes)
for (offset = 0; bytes > 0; offset += move_bytes, bytes -= move_bytes)
{
union {
rtx (*movstrsi) PARAMS ((rtx, rtx, rtx, rtx));
rtx (*mov) PARAMS ((rtx, rtx));
} gen_func;
enum machine_mode mode = BLKmode;
rtx src, dest;
if (bytes > 24 /* move up to 32 bytes at a time */
&& ! fixed_regs[5]
&& ! fixed_regs[6]
@ -6129,15 +6109,7 @@ expand_block_move (operands)
&& ! fixed_regs[12])
{
move_bytes = (bytes > 32) ? 32 : bytes;
emit_insn (gen_movstrsi_8reg (expand_block_move_mem (BLKmode,
dest_reg,
orig_dest),
expand_block_move_mem (BLKmode,
src_reg,
orig_src),
GEN_INT ((move_bytes == 32)
? 0 : move_bytes),
align_rtx));
gen_func.movstrsi = gen_movstrsi_8reg;
}
else if (bytes > 16 /* move up to 24 bytes at a time */
&& ! fixed_regs[5]
@ -6148,14 +6120,7 @@ expand_block_move (operands)
&& ! fixed_regs[10])
{
move_bytes = (bytes > 24) ? 24 : bytes;
emit_insn (gen_movstrsi_6reg (expand_block_move_mem (BLKmode,
dest_reg,
orig_dest),
expand_block_move_mem (BLKmode,
src_reg,
orig_src),
GEN_INT (move_bytes),
align_rtx));
gen_func.movstrsi = gen_movstrsi_6reg;
}
else if (bytes > 8 /* move up to 16 bytes at a time */
&& ! fixed_regs[5]
@ -6164,14 +6129,7 @@ expand_block_move (operands)
&& ! fixed_regs[8])
{
move_bytes = (bytes > 16) ? 16 : bytes;
emit_insn (gen_movstrsi_4reg (expand_block_move_mem (BLKmode,
dest_reg,
orig_dest),
expand_block_move_mem (BLKmode,
src_reg,
orig_src),
GEN_INT (move_bytes),
align_rtx));
gen_func.movstrsi = gen_movstrsi_4reg;
}
else if (bytes >= 8 && TARGET_POWERPC64
/* 64-bit loads and stores require word-aligned
@ -6179,108 +6137,84 @@ expand_block_move (operands)
&& (align >= 8 || (! STRICT_ALIGNMENT && align >= 4)))
{
move_bytes = 8;
tmp_reg = gen_reg_rtx (DImode);
emit_move_insn (tmp_reg,
expand_block_move_mem (DImode,
src_reg, orig_src));
emit_move_insn (expand_block_move_mem (DImode,
dest_reg, orig_dest),
tmp_reg);
mode = DImode;
gen_func.mov = gen_movdi;
}
else if (bytes > 4 && !TARGET_POWERPC64)
{ /* move up to 8 bytes at a time */
move_bytes = (bytes > 8) ? 8 : bytes;
emit_insn (gen_movstrsi_2reg (expand_block_move_mem (BLKmode,
dest_reg,
orig_dest),
expand_block_move_mem (BLKmode,
src_reg,
orig_src),
GEN_INT (move_bytes),
align_rtx));
gen_func.movstrsi = gen_movstrsi_2reg;
}
else if (bytes >= 4 && (align >= 4 || ! STRICT_ALIGNMENT))
{ /* move 4 bytes */
move_bytes = 4;
tmp_reg = gen_reg_rtx (SImode);
emit_move_insn (tmp_reg,
expand_block_move_mem (SImode,
src_reg, orig_src));
emit_move_insn (expand_block_move_mem (SImode,
dest_reg, orig_dest),
tmp_reg);
mode = SImode;
gen_func.mov = gen_movsi;
}
else if (bytes == 2 && (align >= 2 || ! STRICT_ALIGNMENT))
{ /* move 2 bytes */
move_bytes = 2;
tmp_reg = gen_reg_rtx (HImode);
emit_move_insn (tmp_reg,
expand_block_move_mem (HImode,
src_reg, orig_src));
emit_move_insn (expand_block_move_mem (HImode,
dest_reg, orig_dest),
tmp_reg);
mode = HImode;
gen_func.mov = gen_movhi;
}
else if (bytes == 1) /* move 1 byte */
{
move_bytes = 1;
tmp_reg = gen_reg_rtx (QImode);
emit_move_insn (tmp_reg,
expand_block_move_mem (QImode,
src_reg, orig_src));
emit_move_insn (expand_block_move_mem (QImode,
dest_reg, orig_dest),
tmp_reg);
mode = QImode;
gen_func.mov = gen_movqi;
}
else
{ /* move up to 4 bytes at a time */
move_bytes = (bytes > 4) ? 4 : bytes;
emit_insn (gen_movstrsi_1reg (expand_block_move_mem (BLKmode,
dest_reg,
orig_dest),
expand_block_move_mem (BLKmode,
src_reg,
orig_src),
GEN_INT (move_bytes),
align_rtx));
gen_func.movstrsi = gen_movstrsi_1reg;
}
if (bytes > move_bytes)
src = adjust_address (orig_src, mode, offset);
dest = adjust_address (orig_dest, mode, offset);
if (mode == BLKmode)
{
if (! TARGET_POWERPC64)
/* Move the address into scratch registers. The movstrsi
patterns require zero offset. */
if (!REG_P (XEXP (src, 0)))
{
emit_insn (gen_addsi3 (src_reg, src_reg,
GEN_INT (move_bytes)));
emit_insn (gen_addsi3 (dest_reg, dest_reg,
GEN_INT (move_bytes)));
rtx src_reg = copy_addr_to_reg (XEXP (src, 0));
src = replace_equiv_address (src, src_reg);
}
else
set_mem_size (src, GEN_INT (move_bytes));
if (!REG_P (XEXP (dest, 0)))
{
emit_insn (gen_adddi3 (src_reg, src_reg,
GEN_INT (move_bytes)));
emit_insn (gen_adddi3 (dest_reg, dest_reg,
GEN_INT (move_bytes)));
rtx dest_reg = copy_addr_to_reg (XEXP (dest, 0));
dest = replace_equiv_address (dest, dest_reg);
}
set_mem_size (dest, GEN_INT (move_bytes));
emit_insn ((*gen_func.movstrsi) (dest, src,
GEN_INT (move_bytes & 31),
align_rtx));
}
else
{
rtx tmp_reg = gen_reg_rtx (mode);
emit_insn ((*gen_func.mov) (tmp_reg, src));
emit_insn ((*gen_func.mov) (dest, tmp_reg));
}
}
}
else /* string instructions not available */
{
num_reg = offset = 0;
for ( ; bytes > 0; (bytes -= move_bytes), (offset += move_bytes))
rtx stores[MAX_MOVE_REG];
int num_reg = 0;
int i;
for (offset = 0; bytes > 0; offset += move_bytes, bytes -= move_bytes)
{
/* Calculate the correct offset for src/dest */
if (offset == 0)
{
src_addr = src_reg;
dest_addr = dest_reg;
}
else
{
src_addr = plus_constant (src_reg, offset);
dest_addr = plus_constant (dest_reg, offset);
}
rtx (*gen_mov_func) PARAMS ((rtx, rtx));
enum machine_mode mode;
rtx src, dest, tmp_reg;
/* Generate the appropriate load and store, saving the stores
for later. */
@ -6290,56 +6224,35 @@ expand_block_move (operands)
&& (align >= 8 || (! STRICT_ALIGNMENT && align >= 4)))
{
move_bytes = 8;
tmp_reg = gen_reg_rtx (DImode);
emit_insn (gen_movdi (tmp_reg,
expand_block_move_mem (DImode,
src_addr,
orig_src)));
stores[num_reg++] = gen_movdi (expand_block_move_mem (DImode,
dest_addr,
orig_dest),
tmp_reg);
mode = DImode;
gen_mov_func = gen_movdi;
}
else if (bytes >= 4 && (align >= 4 || ! STRICT_ALIGNMENT))
{
move_bytes = 4;
tmp_reg = gen_reg_rtx (SImode);
emit_insn (gen_movsi (tmp_reg,
expand_block_move_mem (SImode,
src_addr,
orig_src)));
stores[num_reg++] = gen_movsi (expand_block_move_mem (SImode,
dest_addr,
orig_dest),
tmp_reg);
mode = SImode;
gen_mov_func = gen_movsi;
}
else if (bytes >= 2 && (align >= 2 || ! STRICT_ALIGNMENT))
{
move_bytes = 2;
tmp_reg = gen_reg_rtx (HImode);
emit_insn (gen_movhi (tmp_reg,
expand_block_move_mem (HImode,
src_addr,
orig_src)));
stores[num_reg++] = gen_movhi (expand_block_move_mem (HImode,
dest_addr,
orig_dest),
tmp_reg);
mode = HImode;
gen_mov_func = gen_movhi;
}
else
{
move_bytes = 1;
tmp_reg = gen_reg_rtx (QImode);
emit_insn (gen_movqi (tmp_reg,
expand_block_move_mem (QImode,
src_addr,
orig_src)));
stores[num_reg++] = gen_movqi (expand_block_move_mem (QImode,
dest_addr,
orig_dest),
tmp_reg);
mode = QImode;
gen_mov_func = gen_movqi;
}
src = adjust_address (orig_src, mode, offset);
dest = adjust_address (orig_dest, mode, offset);
tmp_reg = gen_reg_rtx (mode);
emit_insn ((*gen_mov_func) (tmp_reg, src));
stores[num_reg++] = (*gen_mov_func) (dest, tmp_reg);
if (num_reg >= MAX_MOVE_REG)
{
for (i = 0; i < num_reg; i++)
@ -13225,4 +13138,3 @@ rs6000_binds_local_p (decl)
{
return default_binds_local_p_1 (decl, flag_pic || rs6000_flag_pic);
}

View File

@ -1968,6 +1968,17 @@ set_mem_offset (mem, offset)
offset, MEM_SIZE (mem), MEM_ALIGN (mem),
GET_MODE (mem));
}
/* Set the size of MEM to SIZE. */
void
set_mem_size (mem, size)
rtx mem, size;
{
MEM_ATTRS (mem) = get_mem_attrs (MEM_ALIAS_SET (mem), MEM_EXPR (mem),
MEM_OFFSET (mem), size, MEM_ALIGN (mem),
GET_MODE (mem));
}
/* Return a memory reference like MEMREF, but with its mode changed to MODE
and its address changed to ADDR. (VOIDmode means don't change the mode.

View File

@ -616,6 +616,9 @@ extern void set_mem_expr PARAMS ((rtx, tree));
/* Set the offset for MEM to OFFSET. */
extern void set_mem_offset PARAMS ((rtx, rtx));
/* Set the size for MEM to SIZE. */
extern void set_mem_size PARAMS ((rtx, rtx));
/* Return a memory reference like MEMREF, but with its mode changed
to MODE and its address changed to ADDR.
(VOIDmode means don't change the mode.