From 50ed9cea9d0b76c02e87d9c9c2643f43f25eed10 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Thu, 19 Aug 2004 10:02:03 -0700 Subject: [PATCH] arm.c (arm_gen_load_multiple): Use adjust_automodify_address. * config/arm/arm.c (arm_gen_load_multiple): Use adjust_automodify_address. Take base memory and offset instead of unchanging/struct/scalar bits. (arm_gen_store_multiple): Likewise. (arm_gen_movmemqi): Use adjust_automodify_address. * config/arm/arm-protos.h: Update decls. * config/arm/arm.md (load_multiple): Update arm_gen_load_multiple call. (store_multiple): Similarly. From-SVN: r86257 --- gcc/ChangeLog | 11 +++ gcc/config/arm/arm-protos.h | 6 +- gcc/config/arm/arm.c | 144 +++++++++++++++--------------------- gcc/config/arm/arm.md | 22 +++--- 4 files changed, 84 insertions(+), 99 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 6092b04d06f..bca0f90125c 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,14 @@ +2004-08-19 Richard Henderson + + * config/arm/arm.c (arm_gen_load_multiple): Use + adjust_automodify_address. Take base memory and offset instead + of unchanging/struct/scalar bits. + (arm_gen_store_multiple): Likewise. + (arm_gen_movmemqi): Use adjust_automodify_address. + * config/arm/arm-protos.h: Update decls. + * config/arm/arm.md (load_multiple): Update arm_gen_load_multiple call. + (store_multiple): Similarly. + 2004-08-19 J"orn Rennecke * regclass.c (globalize_reg): Update call_really_used_regs. diff --git a/gcc/config/arm/arm-protos.h b/gcc/config/arm/arm-protos.h index b6b2fc4d816..b2a29a506a4 100644 --- a/gcc/config/arm/arm-protos.h +++ b/gcc/config/arm/arm-protos.h @@ -116,8 +116,10 @@ extern int load_multiple_sequence (rtx *, int, int *, int *, HOST_WIDE_INT *); extern const char *emit_ldm_seq (rtx *, int); extern int store_multiple_sequence (rtx *, int, int *, int *, HOST_WIDE_INT *); extern const char * emit_stm_seq (rtx *, int); -extern rtx arm_gen_load_multiple (int, int, rtx, int, int, int, int, int); -extern rtx arm_gen_store_multiple (int, int, rtx, int, int, int, int, int); +extern rtx arm_gen_load_multiple (int, int, rtx, int, int, + rtx, HOST_WIDE_INT *); +extern rtx arm_gen_store_multiple (int, int, rtx, int, int, + rtx, HOST_WIDE_INT *); extern int arm_gen_movmemqi (rtx *); extern rtx arm_gen_rotated_half_load (rtx); extern enum machine_mode arm_select_cc_mode (RTX_CODE, rtx, rtx); diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index bcb3c533f72..19a63bfcfc3 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -6118,13 +6118,13 @@ multi_register_push (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED) rtx arm_gen_load_multiple (int base_regno, int count, rtx from, int up, - int write_back, int unchanging_p, int in_struct_p, - int scalar_p) + int write_back, rtx basemem, HOST_WIDE_INT *offsetp) { + HOST_WIDE_INT offset = *offsetp; int i = 0, j; rtx result; int sign = up ? 1 : -1; - rtx mem; + rtx mem, addr; /* XScale has load-store double instructions, but they have stricter alignment requirements than load-store multiple, so we cannot @@ -6162,15 +6162,17 @@ arm_gen_load_multiple (int base_regno, int count, rtx from, int up, for (i = 0; i < count; i++) { - mem = gen_rtx_MEM (SImode, plus_constant (from, i * 4 * sign)); - MEM_READONLY_P (mem) = unchanging_p; - MEM_IN_STRUCT_P (mem) = in_struct_p; - MEM_SCALAR_P (mem) = scalar_p; + addr = plus_constant (from, i * 4 * sign); + mem = adjust_automodify_address (basemem, SImode, addr, offset); emit_move_insn (gen_rtx_REG (SImode, base_regno + i), mem); + offset += 4 * sign; } if (write_back) - emit_move_insn (from, plus_constant (from, count * 4 * sign)); + { + emit_move_insn (from, plus_constant (from, count * 4 * sign)); + *offsetp = offset; + } seq = get_insns (); end_sequence (); @@ -6191,26 +6193,28 @@ arm_gen_load_multiple (int base_regno, int count, rtx from, int up, for (j = 0; i < count; i++, j++) { - mem = gen_rtx_MEM (SImode, plus_constant (from, j * 4 * sign)); - MEM_READONLY_P (mem) = unchanging_p; - MEM_IN_STRUCT_P (mem) = in_struct_p; - MEM_SCALAR_P (mem) = scalar_p; + addr = plus_constant (from, j * 4 * sign); + mem = adjust_automodify_address_nv (basemem, SImode, addr, offset); XVECEXP (result, 0, i) = gen_rtx_SET (VOIDmode, gen_rtx_REG (SImode, base_regno + j), mem); + offset += 4 * sign; } + if (write_back) + *offsetp = offset; + return result; } rtx arm_gen_store_multiple (int base_regno, int count, rtx to, int up, - int write_back, int unchanging_p, int in_struct_p, - int scalar_p) + int write_back, rtx basemem, HOST_WIDE_INT *offsetp) { + HOST_WIDE_INT offset = *offsetp; int i = 0, j; rtx result; int sign = up ? 1 : -1; - rtx mem; + rtx mem, addr; /* See arm_gen_load_multiple for discussion of the pros/cons of ldm/stm usage for XScale. */ @@ -6222,15 +6226,17 @@ arm_gen_store_multiple (int base_regno, int count, rtx to, int up, for (i = 0; i < count; i++) { - mem = gen_rtx_MEM (SImode, plus_constant (to, i * 4 * sign)); - MEM_READONLY_P (mem) = unchanging_p; - MEM_IN_STRUCT_P (mem) = in_struct_p; - MEM_SCALAR_P (mem) = scalar_p; + addr = plus_constant (to, i * 4 * sign); + mem = adjust_automodify_address (basemem, SImode, addr, offset); emit_move_insn (mem, gen_rtx_REG (SImode, base_regno + i)); + offset += 4 * sign; } if (write_back) - emit_move_insn (to, plus_constant (to, count * 4 * sign)); + { + emit_move_insn (to, plus_constant (to, count * 4 * sign)); + *offsetp = offset; + } seq = get_insns (); end_sequence (); @@ -6251,15 +6257,16 @@ arm_gen_store_multiple (int base_regno, int count, rtx to, int up, for (j = 0; i < count; i++, j++) { - mem = gen_rtx_MEM (SImode, plus_constant (to, j * 4 * sign)); - MEM_READONLY_P (mem) = unchanging_p; - MEM_IN_STRUCT_P (mem) = in_struct_p; - MEM_SCALAR_P (mem) = scalar_p; - + addr = plus_constant (to, j * 4 * sign); + mem = adjust_automodify_address_nv (basemem, SImode, addr, offset); XVECEXP (result, 0, i) = gen_rtx_SET (VOIDmode, mem, gen_rtx_REG (SImode, base_regno + j)); + offset += 4 * sign; } + if (write_back) + *offsetp = offset; + return result; } @@ -6267,13 +6274,11 @@ int arm_gen_movmemqi (rtx *operands) { HOST_WIDE_INT in_words_to_go, out_words_to_go, last_bytes; + HOST_WIDE_INT srcoffset, dstoffset; int i; - rtx src, dst; - rtx st_src, st_dst, fin_src, fin_dst; + rtx src, dst, srcbase, dstbase; rtx part_bytes_reg = NULL; rtx mem; - int dst_unchanging_p, dst_in_struct_p, src_unchanging_p, src_in_struct_p; - int dst_scalar_p, src_scalar_p; if (GET_CODE (operands[2]) != CONST_INT || GET_CODE (operands[3]) != CONST_INT @@ -6281,22 +6286,16 @@ arm_gen_movmemqi (rtx *operands) || INTVAL (operands[3]) & 3) return 0; - st_dst = XEXP (operands[0], 0); - st_src = XEXP (operands[1], 0); + dstbase = operands[0]; + srcbase = operands[1]; - dst_unchanging_p = MEM_READONLY_P (operands[0]); - dst_in_struct_p = MEM_IN_STRUCT_P (operands[0]); - dst_scalar_p = MEM_SCALAR_P (operands[0]); - src_unchanging_p = MEM_READONLY_P (operands[1]); - src_in_struct_p = MEM_IN_STRUCT_P (operands[1]); - src_scalar_p = MEM_SCALAR_P (operands[1]); - - fin_dst = dst = copy_to_mode_reg (SImode, st_dst); - fin_src = src = copy_to_mode_reg (SImode, st_src); + dst = copy_to_mode_reg (SImode, XEXP (dstbase, 0)); + src = copy_to_mode_reg (SImode, XEXP (srcbase, 0)); in_words_to_go = ARM_NUM_INTS (INTVAL (operands[2])); out_words_to_go = INTVAL (operands[2]) / 4; last_bytes = INTVAL (operands[2]) & 3; + dstoffset = srcoffset = 0; if (out_words_to_go != in_words_to_go && ((in_words_to_go - 1) & 3) != 0) part_bytes_reg = gen_rtx_REG (SImode, (in_words_to_go - 1) & 3); @@ -6305,38 +6304,31 @@ arm_gen_movmemqi (rtx *operands) { if (in_words_to_go > 4) emit_insn (arm_gen_load_multiple (0, 4, src, TRUE, TRUE, - src_unchanging_p, - src_in_struct_p, - src_scalar_p)); + srcbase, &srcoffset)); else emit_insn (arm_gen_load_multiple (0, in_words_to_go, src, TRUE, - FALSE, src_unchanging_p, - src_in_struct_p, src_scalar_p)); + FALSE, srcbase, &srcoffset)); if (out_words_to_go) { if (out_words_to_go > 4) emit_insn (arm_gen_store_multiple (0, 4, dst, TRUE, TRUE, - dst_unchanging_p, - dst_in_struct_p, - dst_scalar_p)); + dstbase, &dstoffset)); else if (out_words_to_go != 1) emit_insn (arm_gen_store_multiple (0, out_words_to_go, dst, TRUE, (last_bytes == 0 ? FALSE : TRUE), - dst_unchanging_p, - dst_in_struct_p, - dst_scalar_p)); + dstbase, &dstoffset)); else { - mem = gen_rtx_MEM (SImode, dst); - MEM_READONLY_P (mem) = dst_unchanging_p; - MEM_IN_STRUCT_P (mem) = dst_in_struct_p; - MEM_SCALAR_P (mem) = dst_scalar_p; + mem = adjust_automodify_address (dstbase, SImode, dst, dstoffset); emit_move_insn (mem, gen_rtx_REG (SImode, 0)); if (last_bytes != 0) - emit_insn (gen_addsi3 (dst, dst, GEN_INT (4))); + { + emit_insn (gen_addsi3 (dst, dst, GEN_INT (4))); + dstoffset += 4; + } } } @@ -6349,19 +6341,11 @@ arm_gen_movmemqi (rtx *operands) { rtx sreg; - mem = gen_rtx_MEM (SImode, src); - MEM_READONLY_P (mem) = src_unchanging_p; - MEM_IN_STRUCT_P (mem) = src_in_struct_p; - MEM_SCALAR_P (mem) = src_scalar_p; - emit_move_insn (sreg = gen_reg_rtx (SImode), mem); - emit_move_insn (fin_src = gen_reg_rtx (SImode), plus_constant (src, 4)); - - mem = gen_rtx_MEM (SImode, dst); - MEM_READONLY_P (mem) = dst_unchanging_p; - MEM_IN_STRUCT_P (mem) = dst_in_struct_p; - MEM_SCALAR_P (mem) = dst_scalar_p; + mem = adjust_automodify_address (srcbase, SImode, src, srcoffset); + sreg = copy_to_reg (mem); + + mem = adjust_automodify_address (dstbase, SImode, dst, dstoffset); emit_move_insn (mem, sreg); - emit_move_insn (fin_dst = gen_reg_rtx (SImode), plus_constant (dst, 4)); in_words_to_go--; if (in_words_to_go) /* Sanity check */ @@ -6373,10 +6357,7 @@ arm_gen_movmemqi (rtx *operands) if (in_words_to_go < 0) abort (); - mem = gen_rtx_MEM (SImode, src); - MEM_READONLY_P (mem) = src_unchanging_p; - MEM_IN_STRUCT_P (mem) = src_in_struct_p; - MEM_SCALAR_P (mem) = src_scalar_p; + mem = adjust_automodify_address (srcbase, SImode, src, srcoffset); part_bytes_reg = copy_to_mode_reg (SImode, mem); } @@ -6394,10 +6375,9 @@ arm_gen_movmemqi (rtx *operands) while (last_bytes) { - mem = gen_rtx_MEM (QImode, plus_constant (dst, last_bytes - 1)); - MEM_READONLY_P (mem) = dst_unchanging_p; - MEM_IN_STRUCT_P (mem) = dst_in_struct_p; - MEM_SCALAR_P (mem) = dst_scalar_p; + mem = adjust_automodify_address (dstbase, QImode, + plus_constant (dst, last_bytes - 1), + dstoffset + last_bytes - 1); emit_move_insn (mem, gen_lowpart (QImode, part_bytes_reg)); if (--last_bytes) @@ -6413,28 +6393,22 @@ arm_gen_movmemqi (rtx *operands) { if (last_bytes > 1) { - mem = gen_rtx_MEM (HImode, dst); - MEM_READONLY_P (mem) = dst_unchanging_p; - MEM_IN_STRUCT_P (mem) = dst_in_struct_p; - MEM_SCALAR_P (mem) = dst_scalar_p; + mem = adjust_automodify_address (dstbase, HImode, dst, dstoffset); emit_move_insn (mem, gen_lowpart (HImode, part_bytes_reg)); last_bytes -= 2; if (last_bytes) { rtx tmp = gen_reg_rtx (SImode); - emit_insn (gen_addsi3 (dst, dst, const2_rtx)); emit_insn (gen_lshrsi3 (tmp, part_bytes_reg, GEN_INT (16))); part_bytes_reg = tmp; + dstoffset += 2; } } if (last_bytes) { - mem = gen_rtx_MEM (QImode, dst); - MEM_READONLY_P (mem) = dst_unchanging_p; - MEM_IN_STRUCT_P (mem) = dst_in_struct_p; - MEM_SCALAR_P (mem) = dst_scalar_p; + mem = adjust_automodify_address (dstbase, QImode, dst, dstoffset); emit_move_insn (mem, gen_lowpart (QImode, part_bytes_reg)); } } diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md index 6346960330d..e6e72db9525 100644 --- a/gcc/config/arm/arm.md +++ b/gcc/config/arm/arm.md @@ -5244,7 +5244,9 @@ (match_operand:SI 1 "" "")) (use (match_operand:SI 2 "" ""))])] "TARGET_ARM" - " +{ + HOST_WIDE_INT offset = 0; + /* Support only fixed point registers. */ if (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) > 14 @@ -5258,11 +5260,8 @@ operands[3] = arm_gen_load_multiple (REGNO (operands[0]), INTVAL (operands[2]), force_reg (SImode, XEXP (operands[1], 0)), - TRUE, FALSE, MEM_READONLY_P (operands[1]), - MEM_IN_STRUCT_P (operands[1]), - MEM_SCALAR_P (operands[1])); - " -) + TRUE, FALSE, operands[1], &offset); +}) ;; Load multiple with write-back @@ -5366,7 +5365,9 @@ (match_operand:SI 1 "" "")) (use (match_operand:SI 2 "" ""))])] "TARGET_ARM" - " +{ + HOST_WIDE_INT offset = 0; + /* Support only fixed point registers. */ if (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) > 14 @@ -5380,11 +5381,8 @@ operands[3] = arm_gen_store_multiple (REGNO (operands[1]), INTVAL (operands[2]), force_reg (SImode, XEXP (operands[0], 0)), - TRUE, FALSE, MEM_READONLY_P (operands[0]), - MEM_IN_STRUCT_P (operands[0]), - MEM_SCALAR_P (operands[0])); - " -) + TRUE, FALSE, operands[0], &offset); +}) ;; Store multiple with write-back -- 2.30.2