Commit 50ed9cea by Richard Henderson Committed by Richard Henderson

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
parent ec53454b
2004-08-19 Richard Henderson <rth@redhat.com>
* 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 <joern.rennecke@superh.com> 2004-08-19 J"orn Rennecke <joern.rennecke@superh.com>
* regclass.c (globalize_reg): Update call_really_used_regs. * regclass.c (globalize_reg): Update call_really_used_regs.
......
...@@ -116,8 +116,10 @@ extern int load_multiple_sequence (rtx *, int, int *, int *, HOST_WIDE_INT *); ...@@ -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 const char *emit_ldm_seq (rtx *, int);
extern int store_multiple_sequence (rtx *, int, int *, int *, HOST_WIDE_INT *); extern int store_multiple_sequence (rtx *, int, int *, int *, HOST_WIDE_INT *);
extern const char * emit_stm_seq (rtx *, 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_load_multiple (int, int, rtx, int, int,
extern rtx arm_gen_store_multiple (int, int, rtx, int, int, int, 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 int arm_gen_movmemqi (rtx *);
extern rtx arm_gen_rotated_half_load (rtx); extern rtx arm_gen_rotated_half_load (rtx);
extern enum machine_mode arm_select_cc_mode (RTX_CODE, rtx, rtx); extern enum machine_mode arm_select_cc_mode (RTX_CODE, rtx, rtx);
......
...@@ -6118,13 +6118,13 @@ multi_register_push (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED) ...@@ -6118,13 +6118,13 @@ multi_register_push (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
rtx rtx
arm_gen_load_multiple (int base_regno, int count, rtx from, int up, arm_gen_load_multiple (int base_regno, int count, rtx from, int up,
int write_back, int unchanging_p, int in_struct_p, int write_back, rtx basemem, HOST_WIDE_INT *offsetp)
int scalar_p)
{ {
HOST_WIDE_INT offset = *offsetp;
int i = 0, j; int i = 0, j;
rtx result; rtx result;
int sign = up ? 1 : -1; int sign = up ? 1 : -1;
rtx mem; rtx mem, addr;
/* XScale has load-store double instructions, but they have stricter /* XScale has load-store double instructions, but they have stricter
alignment requirements than load-store multiple, so we cannot 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, ...@@ -6162,15 +6162,17 @@ arm_gen_load_multiple (int base_regno, int count, rtx from, int up,
for (i = 0; i < count; i++) for (i = 0; i < count; i++)
{ {
mem = gen_rtx_MEM (SImode, plus_constant (from, i * 4 * sign)); addr = plus_constant (from, i * 4 * sign);
MEM_READONLY_P (mem) = unchanging_p; mem = adjust_automodify_address (basemem, SImode, addr, offset);
MEM_IN_STRUCT_P (mem) = in_struct_p;
MEM_SCALAR_P (mem) = scalar_p;
emit_move_insn (gen_rtx_REG (SImode, base_regno + i), mem); emit_move_insn (gen_rtx_REG (SImode, base_regno + i), mem);
offset += 4 * sign;
} }
if (write_back) 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 (); seq = get_insns ();
end_sequence (); end_sequence ();
...@@ -6191,26 +6193,28 @@ arm_gen_load_multiple (int base_regno, int count, rtx from, int up, ...@@ -6191,26 +6193,28 @@ arm_gen_load_multiple (int base_regno, int count, rtx from, int up,
for (j = 0; i < count; i++, j++) for (j = 0; i < count; i++, j++)
{ {
mem = gen_rtx_MEM (SImode, plus_constant (from, j * 4 * sign)); addr = plus_constant (from, j * 4 * sign);
MEM_READONLY_P (mem) = unchanging_p; mem = adjust_automodify_address_nv (basemem, SImode, addr, offset);
MEM_IN_STRUCT_P (mem) = in_struct_p;
MEM_SCALAR_P (mem) = scalar_p;
XVECEXP (result, 0, i) XVECEXP (result, 0, i)
= gen_rtx_SET (VOIDmode, gen_rtx_REG (SImode, base_regno + j), mem); = gen_rtx_SET (VOIDmode, gen_rtx_REG (SImode, base_regno + j), mem);
offset += 4 * sign;
} }
if (write_back)
*offsetp = offset;
return result; return result;
} }
rtx rtx
arm_gen_store_multiple (int base_regno, int count, rtx to, int up, arm_gen_store_multiple (int base_regno, int count, rtx to, int up,
int write_back, int unchanging_p, int in_struct_p, int write_back, rtx basemem, HOST_WIDE_INT *offsetp)
int scalar_p)
{ {
HOST_WIDE_INT offset = *offsetp;
int i = 0, j; int i = 0, j;
rtx result; rtx result;
int sign = up ? 1 : -1; int sign = up ? 1 : -1;
rtx mem; rtx mem, addr;
/* See arm_gen_load_multiple for discussion of /* See arm_gen_load_multiple for discussion of
the pros/cons of ldm/stm usage for XScale. */ 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, ...@@ -6222,15 +6226,17 @@ arm_gen_store_multiple (int base_regno, int count, rtx to, int up,
for (i = 0; i < count; i++) for (i = 0; i < count; i++)
{ {
mem = gen_rtx_MEM (SImode, plus_constant (to, i * 4 * sign)); addr = plus_constant (to, i * 4 * sign);
MEM_READONLY_P (mem) = unchanging_p; mem = adjust_automodify_address (basemem, SImode, addr, offset);
MEM_IN_STRUCT_P (mem) = in_struct_p;
MEM_SCALAR_P (mem) = scalar_p;
emit_move_insn (mem, gen_rtx_REG (SImode, base_regno + i)); emit_move_insn (mem, gen_rtx_REG (SImode, base_regno + i));
offset += 4 * sign;
} }
if (write_back) 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 (); seq = get_insns ();
end_sequence (); end_sequence ();
...@@ -6251,15 +6257,16 @@ arm_gen_store_multiple (int base_regno, int count, rtx to, int up, ...@@ -6251,15 +6257,16 @@ arm_gen_store_multiple (int base_regno, int count, rtx to, int up,
for (j = 0; i < count; i++, j++) for (j = 0; i < count; i++, j++)
{ {
mem = gen_rtx_MEM (SImode, plus_constant (to, j * 4 * sign)); addr = plus_constant (to, j * 4 * sign);
MEM_READONLY_P (mem) = unchanging_p; mem = adjust_automodify_address_nv (basemem, SImode, addr, offset);
MEM_IN_STRUCT_P (mem) = in_struct_p;
MEM_SCALAR_P (mem) = scalar_p;
XVECEXP (result, 0, i) XVECEXP (result, 0, i)
= gen_rtx_SET (VOIDmode, mem, gen_rtx_REG (SImode, base_regno + j)); = gen_rtx_SET (VOIDmode, mem, gen_rtx_REG (SImode, base_regno + j));
offset += 4 * sign;
} }
if (write_back)
*offsetp = offset;
return result; return result;
} }
...@@ -6267,13 +6274,11 @@ int ...@@ -6267,13 +6274,11 @@ int
arm_gen_movmemqi (rtx *operands) arm_gen_movmemqi (rtx *operands)
{ {
HOST_WIDE_INT in_words_to_go, out_words_to_go, last_bytes; HOST_WIDE_INT in_words_to_go, out_words_to_go, last_bytes;
HOST_WIDE_INT srcoffset, dstoffset;
int i; int i;
rtx src, dst; rtx src, dst, srcbase, dstbase;
rtx st_src, st_dst, fin_src, fin_dst;
rtx part_bytes_reg = NULL; rtx part_bytes_reg = NULL;
rtx mem; 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 if (GET_CODE (operands[2]) != CONST_INT
|| GET_CODE (operands[3]) != CONST_INT || GET_CODE (operands[3]) != CONST_INT
...@@ -6281,22 +6286,16 @@ arm_gen_movmemqi (rtx *operands) ...@@ -6281,22 +6286,16 @@ arm_gen_movmemqi (rtx *operands)
|| INTVAL (operands[3]) & 3) || INTVAL (operands[3]) & 3)
return 0; return 0;
st_dst = XEXP (operands[0], 0); dstbase = operands[0];
st_src = XEXP (operands[1], 0); srcbase = operands[1];
dst_unchanging_p = MEM_READONLY_P (operands[0]); dst = copy_to_mode_reg (SImode, XEXP (dstbase, 0));
dst_in_struct_p = MEM_IN_STRUCT_P (operands[0]); src = copy_to_mode_reg (SImode, XEXP (srcbase, 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);
in_words_to_go = ARM_NUM_INTS (INTVAL (operands[2])); in_words_to_go = ARM_NUM_INTS (INTVAL (operands[2]));
out_words_to_go = INTVAL (operands[2]) / 4; out_words_to_go = INTVAL (operands[2]) / 4;
last_bytes = INTVAL (operands[2]) & 3; 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) 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); part_bytes_reg = gen_rtx_REG (SImode, (in_words_to_go - 1) & 3);
...@@ -6305,38 +6304,31 @@ arm_gen_movmemqi (rtx *operands) ...@@ -6305,38 +6304,31 @@ arm_gen_movmemqi (rtx *operands)
{ {
if (in_words_to_go > 4) if (in_words_to_go > 4)
emit_insn (arm_gen_load_multiple (0, 4, src, TRUE, TRUE, emit_insn (arm_gen_load_multiple (0, 4, src, TRUE, TRUE,
src_unchanging_p, srcbase, &srcoffset));
src_in_struct_p,
src_scalar_p));
else else
emit_insn (arm_gen_load_multiple (0, in_words_to_go, src, TRUE, emit_insn (arm_gen_load_multiple (0, in_words_to_go, src, TRUE,
FALSE, src_unchanging_p, FALSE, srcbase, &srcoffset));
src_in_struct_p, src_scalar_p));
if (out_words_to_go) if (out_words_to_go)
{ {
if (out_words_to_go > 4) if (out_words_to_go > 4)
emit_insn (arm_gen_store_multiple (0, 4, dst, TRUE, TRUE, emit_insn (arm_gen_store_multiple (0, 4, dst, TRUE, TRUE,
dst_unchanging_p, dstbase, &dstoffset));
dst_in_struct_p,
dst_scalar_p));
else if (out_words_to_go != 1) else if (out_words_to_go != 1)
emit_insn (arm_gen_store_multiple (0, out_words_to_go, emit_insn (arm_gen_store_multiple (0, out_words_to_go,
dst, TRUE, dst, TRUE,
(last_bytes == 0 (last_bytes == 0
? FALSE : TRUE), ? FALSE : TRUE),
dst_unchanging_p, dstbase, &dstoffset));
dst_in_struct_p,
dst_scalar_p));
else else
{ {
mem = gen_rtx_MEM (SImode, dst); mem = adjust_automodify_address (dstbase, SImode, dst, dstoffset);
MEM_READONLY_P (mem) = dst_unchanging_p;
MEM_IN_STRUCT_P (mem) = dst_in_struct_p;
MEM_SCALAR_P (mem) = dst_scalar_p;
emit_move_insn (mem, gen_rtx_REG (SImode, 0)); emit_move_insn (mem, gen_rtx_REG (SImode, 0));
if (last_bytes != 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) ...@@ -6349,19 +6341,11 @@ arm_gen_movmemqi (rtx *operands)
{ {
rtx sreg; rtx sreg;
mem = gen_rtx_MEM (SImode, src); mem = adjust_automodify_address (srcbase, SImode, src, srcoffset);
MEM_READONLY_P (mem) = src_unchanging_p; sreg = copy_to_reg (mem);
MEM_IN_STRUCT_P (mem) = src_in_struct_p;
MEM_SCALAR_P (mem) = src_scalar_p; mem = adjust_automodify_address (dstbase, SImode, dst, dstoffset);
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;
emit_move_insn (mem, sreg); emit_move_insn (mem, sreg);
emit_move_insn (fin_dst = gen_reg_rtx (SImode), plus_constant (dst, 4));
in_words_to_go--; in_words_to_go--;
if (in_words_to_go) /* Sanity check */ if (in_words_to_go) /* Sanity check */
...@@ -6373,10 +6357,7 @@ arm_gen_movmemqi (rtx *operands) ...@@ -6373,10 +6357,7 @@ arm_gen_movmemqi (rtx *operands)
if (in_words_to_go < 0) if (in_words_to_go < 0)
abort (); abort ();
mem = gen_rtx_MEM (SImode, src); mem = adjust_automodify_address (srcbase, SImode, src, srcoffset);
MEM_READONLY_P (mem) = src_unchanging_p;
MEM_IN_STRUCT_P (mem) = src_in_struct_p;
MEM_SCALAR_P (mem) = src_scalar_p;
part_bytes_reg = copy_to_mode_reg (SImode, mem); part_bytes_reg = copy_to_mode_reg (SImode, mem);
} }
...@@ -6394,10 +6375,9 @@ arm_gen_movmemqi (rtx *operands) ...@@ -6394,10 +6375,9 @@ arm_gen_movmemqi (rtx *operands)
while (last_bytes) while (last_bytes)
{ {
mem = gen_rtx_MEM (QImode, plus_constant (dst, last_bytes - 1)); mem = adjust_automodify_address (dstbase, QImode,
MEM_READONLY_P (mem) = dst_unchanging_p; plus_constant (dst, last_bytes - 1),
MEM_IN_STRUCT_P (mem) = dst_in_struct_p; dstoffset + last_bytes - 1);
MEM_SCALAR_P (mem) = dst_scalar_p;
emit_move_insn (mem, gen_lowpart (QImode, part_bytes_reg)); emit_move_insn (mem, gen_lowpart (QImode, part_bytes_reg));
if (--last_bytes) if (--last_bytes)
...@@ -6413,28 +6393,22 @@ arm_gen_movmemqi (rtx *operands) ...@@ -6413,28 +6393,22 @@ arm_gen_movmemqi (rtx *operands)
{ {
if (last_bytes > 1) if (last_bytes > 1)
{ {
mem = gen_rtx_MEM (HImode, dst); mem = adjust_automodify_address (dstbase, HImode, dst, dstoffset);
MEM_READONLY_P (mem) = dst_unchanging_p;
MEM_IN_STRUCT_P (mem) = dst_in_struct_p;
MEM_SCALAR_P (mem) = dst_scalar_p;
emit_move_insn (mem, gen_lowpart (HImode, part_bytes_reg)); emit_move_insn (mem, gen_lowpart (HImode, part_bytes_reg));
last_bytes -= 2; last_bytes -= 2;
if (last_bytes) if (last_bytes)
{ {
rtx tmp = gen_reg_rtx (SImode); rtx tmp = gen_reg_rtx (SImode);
emit_insn (gen_addsi3 (dst, dst, const2_rtx)); emit_insn (gen_addsi3 (dst, dst, const2_rtx));
emit_insn (gen_lshrsi3 (tmp, part_bytes_reg, GEN_INT (16))); emit_insn (gen_lshrsi3 (tmp, part_bytes_reg, GEN_INT (16)));
part_bytes_reg = tmp; part_bytes_reg = tmp;
dstoffset += 2;
} }
} }
if (last_bytes) if (last_bytes)
{ {
mem = gen_rtx_MEM (QImode, dst); mem = adjust_automodify_address (dstbase, QImode, dst, dstoffset);
MEM_READONLY_P (mem) = dst_unchanging_p;
MEM_IN_STRUCT_P (mem) = dst_in_struct_p;
MEM_SCALAR_P (mem) = dst_scalar_p;
emit_move_insn (mem, gen_lowpart (QImode, part_bytes_reg)); emit_move_insn (mem, gen_lowpart (QImode, part_bytes_reg));
} }
} }
......
...@@ -5244,7 +5244,9 @@ ...@@ -5244,7 +5244,9 @@
(match_operand:SI 1 "" "")) (match_operand:SI 1 "" ""))
(use (match_operand:SI 2 "" ""))])] (use (match_operand:SI 2 "" ""))])]
"TARGET_ARM" "TARGET_ARM"
" {
HOST_WIDE_INT offset = 0;
/* Support only fixed point registers. */ /* Support only fixed point registers. */
if (GET_CODE (operands[2]) != CONST_INT if (GET_CODE (operands[2]) != CONST_INT
|| INTVAL (operands[2]) > 14 || INTVAL (operands[2]) > 14
...@@ -5258,11 +5260,8 @@ ...@@ -5258,11 +5260,8 @@
operands[3] operands[3]
= arm_gen_load_multiple (REGNO (operands[0]), INTVAL (operands[2]), = arm_gen_load_multiple (REGNO (operands[0]), INTVAL (operands[2]),
force_reg (SImode, XEXP (operands[1], 0)), force_reg (SImode, XEXP (operands[1], 0)),
TRUE, FALSE, MEM_READONLY_P (operands[1]), TRUE, FALSE, operands[1], &offset);
MEM_IN_STRUCT_P (operands[1]), })
MEM_SCALAR_P (operands[1]));
"
)
;; Load multiple with write-back ;; Load multiple with write-back
...@@ -5366,7 +5365,9 @@ ...@@ -5366,7 +5365,9 @@
(match_operand:SI 1 "" "")) (match_operand:SI 1 "" ""))
(use (match_operand:SI 2 "" ""))])] (use (match_operand:SI 2 "" ""))])]
"TARGET_ARM" "TARGET_ARM"
" {
HOST_WIDE_INT offset = 0;
/* Support only fixed point registers. */ /* Support only fixed point registers. */
if (GET_CODE (operands[2]) != CONST_INT if (GET_CODE (operands[2]) != CONST_INT
|| INTVAL (operands[2]) > 14 || INTVAL (operands[2]) > 14
...@@ -5380,11 +5381,8 @@ ...@@ -5380,11 +5381,8 @@
operands[3] operands[3]
= arm_gen_store_multiple (REGNO (operands[1]), INTVAL (operands[2]), = arm_gen_store_multiple (REGNO (operands[1]), INTVAL (operands[2]),
force_reg (SImode, XEXP (operands[0], 0)), force_reg (SImode, XEXP (operands[0], 0)),
TRUE, FALSE, MEM_READONLY_P (operands[0]), TRUE, FALSE, operands[0], &offset);
MEM_IN_STRUCT_P (operands[0]), })
MEM_SCALAR_P (operands[0]));
"
)
;; Store multiple with write-back ;; Store multiple with write-back
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment