diff options
author | Richard Henderson <rth@redhat.com> | 2004-08-18 22:25:53 -0700 |
---|---|---|
committer | Richard Henderson <rth@gcc.gnu.org> | 2004-08-18 22:25:53 -0700 |
commit | 8804266301bdace8640830a0d2481c10917440e3 (patch) | |
tree | 01216a0943b59c1d93a0635b12ccf67dcd3bd4bb /gcc/config/mcore | |
parent | 27ab0504a862cd9441a549c288d6b9716306de8f (diff) | |
download | gcc-8804266301bdace8640830a0d2481c10917440e3.zip gcc-8804266301bdace8640830a0d2481c10917440e3.tar.gz gcc-8804266301bdace8640830a0d2481c10917440e3.tar.bz2 |
mcore.c (mode_from_align): Remove DImode.
* config/mcore/mcore.c (mode_from_align): Remove DImode.
(block_move_sequence): Rewrite to use adjust_address.
(mcore_expand_block_move): Cleanup logic. Accept only operands.
Return boolean indicating success/failure.
* config/mcore/mcore-protos.h (mcore_expand_block_move): Update decl.
* config/mcore/mcore.md (movmemsi): Update to match.
From-SVN: r86234
Diffstat (limited to 'gcc/config/mcore')
-rw-r--r-- | gcc/config/mcore/mcore-protos.h | 2 | ||||
-rw-r--r-- | gcc/config/mcore/mcore.c | 163 | ||||
-rw-r--r-- | gcc/config/mcore/mcore.md | 10 |
3 files changed, 81 insertions, 94 deletions
diff --git a/gcc/config/mcore/mcore-protos.h b/gcc/config/mcore/mcore-protos.h index ede6f93..35cb69b 100644 --- a/gcc/config/mcore/mcore-protos.h +++ b/gcc/config/mcore/mcore-protos.h @@ -57,7 +57,7 @@ extern char * mcore_output_call (rtx *, int); extern int mcore_is_dead (rtx, rtx); extern int mcore_expand_insv (rtx *); extern int mcore_modify_comparison (RTX_CODE); -extern void mcore_expand_block_move (rtx, rtx, rtx *); +extern bool mcore_expand_block_move (rtx *); extern const char * mcore_output_andn (rtx, rtx *); extern void mcore_print_operand_address (FILE *, rtx); extern void mcore_print_operand (FILE *, rtx, int); diff --git a/gcc/config/mcore/mcore.c b/gcc/config/mcore/mcore.c index 3d9d6d8..d121848 100644 --- a/gcc/config/mcore/mcore.c +++ b/gcc/config/mcore/mcore.c @@ -122,7 +122,6 @@ static int calc_live_regs (int *); static int const_ok_for_mcore (int); static int try_constant_tricks (long, int *, int *); static const char * output_inline_const (enum machine_mode, rtx *); -static void block_move_sequence (rtx, rtx, rtx, rtx, int, int, int); static void layout_mcore_frame (struct mcore_frame *); static void mcore_setup_incoming_varargs (CUMULATIVE_ARGS *, enum machine_mode, tree, int *, int); static cond_type is_cond_candidate (rtx); @@ -1824,127 +1823,117 @@ mcore_store_multiple_operation (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED) static const enum machine_mode mode_from_align[] = { VOIDmode, QImode, HImode, VOIDmode, SImode, - VOIDmode, VOIDmode, VOIDmode, DImode }; static void -block_move_sequence (rtx dest, rtx dst_mem, rtx src, rtx src_mem, - int size, int align, int offset) +block_move_sequence (rtx dst_mem, rtx src_mem, int size, int align) { rtx temp[2]; enum machine_mode mode[2]; int amount[2]; - int active[2]; + bool active[2]; int phase = 0; int next; - int offset_ld = offset; - int offset_st = offset; + int offset_ld = 0; + int offset_st = 0; + rtx x; - active[0] = active[1] = FALSE; - - /* Establish parameters for the first load and for the second load if - it is known to be the same mode as the first. */ - amount[0] = amount[1] = align; - - mode[0] = mode_from_align[align]; + x = XEXP (dst_mem, 0); + if (!REG_P (x)) + { + x = force_reg (Pmode, x); + dst_mem = replace_equiv_address (dst_mem, x); + } - temp[0] = gen_reg_rtx (mode[0]); - - if (size >= 2 * align) + x = XEXP (src_mem, 0); + if (!REG_P (x)) { - mode[1] = mode[0]; - temp[1] = gen_reg_rtx (mode[1]); + x = force_reg (Pmode, x); + src_mem = replace_equiv_address (src_mem, x); } + active[0] = active[1] = false; + do { - rtx srcp, dstp; - next = phase; - phase = !phase; + phase ^= 1; if (size > 0) { - /* Change modes as the sequence tails off. */ - if (size < amount[next]) - { - amount[next] = (size >= 4 ? 4 : (size >= 2 ? 2 : 1)); - mode[next] = mode_from_align[amount[next]]; - temp[next] = gen_reg_rtx (mode[next]); - } - - size -= amount[next]; - srcp = gen_rtx_MEM ( -#if 0 - MEM_IN_STRUCT_P (src_mem) ? mode[next] : BLKmode, -#else - mode[next], -#endif - gen_rtx_PLUS (Pmode, src, GEN_INT (offset_ld))); - - MEM_READONLY_P (srcp) = MEM_READONLY_P (src_mem); - MEM_VOLATILE_P (srcp) = MEM_VOLATILE_P (src_mem); - MEM_IN_STRUCT_P (srcp) = 1; - emit_insn (gen_rtx_SET (VOIDmode, temp[next], srcp)); - offset_ld += amount[next]; - active[next] = TRUE; + int next_amount; + + next_amount = (size >= 4 ? 4 : (size >= 2 ? 2 : 1)); + next_amount = MIN (next_amount, align); + + amount[next] = next_amount; + mode[next] = mode_from_align[next_amount]; + temp[next] = gen_reg_rtx (mode[next]); + + x = adjust_address (src_mem, mode[next], offset_ld); + emit_insn (gen_rtx_SET (VOIDmode, temp[next], x)); + + offset_ld += next_amount; + size -= next_amount; + active[next] = true; } if (active[phase]) { - active[phase] = FALSE; - - dstp = gen_rtx_MEM ( -#if 0 - MEM_IN_STRUCT_P (dst_mem) ? mode[phase] : BLKmode, -#else - mode[phase], -#endif - gen_rtx_PLUS (Pmode, dest, GEN_INT (offset_st))); + active[phase] = false; - MEM_READONLY_P (dstp) = MEM_READONLY_P (dst_mem); - MEM_VOLATILE_P (dstp) = MEM_VOLATILE_P (dst_mem); - MEM_IN_STRUCT_P (dstp) = 1; - emit_insn (gen_rtx_SET (VOIDmode, dstp, temp[phase])); + x = adjust_address (dst_mem, mode[phase], offset_st); + emit_insn (gen_rtx_SET (VOIDmode, x, temp[phase])); + offset_st += amount[phase]; } } while (active[next]); } -void -mcore_expand_block_move (rtx dst_mem, rtx src_mem, rtx * operands) +bool +mcore_expand_block_move (rtx *operands) { - int align = INTVAL (operands[3]); - int bytes; + HOST_WIDE_INT align, bytes, max; + + if (GET_CODE (operands[2]) != CONST_INT) + return false; + + bytes = INTVAL (operands[2]); + align = INTVAL (operands[3]); - if (GET_CODE (operands[2]) == CONST_INT) + if (bytes <= 0) + return false; + if (align > 4) + align = 4; + + switch (align) { - bytes = INTVAL (operands[2]); - - if (bytes <= 0) - return; - if (align > 4) - align = 4; - - /* RBE: bumped 1 and 2 byte align from 1 and 2 to 4 and 8 bytes before - we give up and go to memcpy. */ - if ((align == 4 && (bytes <= 4*4 - || ((bytes & 01) == 0 && bytes <= 8*4) - || ((bytes & 03) == 0 && bytes <= 16*4))) - || (align == 2 && bytes <= 4*2) - || (align == 1 && bytes <= 4*1)) - { - block_move_sequence (operands[0], dst_mem, operands[1], src_mem, - bytes, align, 0); - return; - } + case 4: + if (bytes & 1) + max = 4*4; + else if (bytes & 3) + max = 8*4; + else + max = 16*4; + break; + case 2: + max = 4*2; + break; + case 1: + max = 4*1; + break; + default: + abort (); + } + + if (bytes <= max) + { + block_move_sequence (operands[0], operands[1], bytes, align); + return true; } - /* If we get here, just use the library routine. */ - emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "memcpy"), 0, VOIDmode, 3, - operands[0], Pmode, operands[1], Pmode, operands[2], - SImode); + return false; } @@ -3104,7 +3093,7 @@ mcore_function_arg (CUMULATIVE_ARGS cum, enum machine_mode mode, { int arg_reg; - if (! named) + if (! named || mode == VOIDmode) return 0; if (targetm.calls.must_pass_in_stack (mode, type)) diff --git a/gcc/config/mcore/mcore.md b/gcc/config/mcore/mcore.md index 066930b5..b45a3c6 100644 --- a/gcc/config/mcore/mcore.md +++ b/gcc/config/mcore/mcore.md @@ -2854,12 +2854,10 @@ "" " { - rtx dest_mem = operands[0]; - rtx src_mem = operands[1]; - operands[0] = copy_to_mode_reg (SImode, XEXP (operands[0], 0)); - operands[1] = copy_to_mode_reg (SImode, XEXP (operands[1], 0)); - mcore_expand_block_move (dest_mem, src_mem, operands); - DONE; + if (mcore_expand_block_move (operands)) + DONE; + else + FAIL; }") ;; ;;; ??? These patterns are meant to be generated from expand_block_move, |