From: Alan Modra Date: Thu, 12 Sep 2002 02:14:26 +0000 (+0000) Subject: emit-rtl.c (set_mem_size): New function. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=35aff10b0f617c6f4dab622ec0d1700e270f16a0;p=gcc.git 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 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 200f20f64fe..701bd4c7845 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2002-09-12 Alan Modra + + * 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. diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index 5974d3bce09..7195ce9c11b 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -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); } - diff --git a/gcc/emit-rtl.c b/gcc/emit-rtl.c index e94fc4ec843..b8297a8808c 100644 --- a/gcc/emit-rtl.c +++ b/gcc/emit-rtl.c @@ -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. diff --git a/gcc/expr.h b/gcc/expr.h index c3a1009a12a..470ebd49a17 100644 --- a/gcc/expr.h +++ b/gcc/expr.h @@ -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.