summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog9
-rw-r--r--gcc/config/m32r/m32r.c72
-rw-r--r--gcc/config/m32r/m32r.md16
3 files changed, 72 insertions, 25 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 9460fe1d273..55f1f8a8c61 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,14 @@
2004-01-09 Kazu Hirata <kazu@cs.umass.edu>
+ * config/m32r/m32r.c (m32r_expand_block_move): Call
+ gen_movestrsi_internal with two more arguments.
+ (m32r_output_block_move): Adjust operand numbers.
+ Properly update the source and destination pointers.
+ * config/m32r/m32r.md (movstrsi_internal): Use 'r' instead of
+ 'r+'. Change the set detinations to match_operand.
+
+2004-01-09 Kazu Hirata <kazu@cs.umass.edu>
+
* final.c (FIRST_INSN_ADDRESS): Remove.
(shorten_branches): Don't use FIRST_INSN_ADDRESS.
* system.h (FIRST_INSN_ADDRESS): Poison.
diff --git a/gcc/config/m32r/m32r.c b/gcc/config/m32r/m32r.c
index 6bc4b9475c3..f1c5c35383d 100644
--- a/gcc/config/m32r/m32r.c
+++ b/gcc/config/m32r/m32r.c
@@ -2809,6 +2809,8 @@ m32r_expand_block_move (rtx operands[])
rtx final_src = NULL_RTX;
rtx at_a_time = GEN_INT (MAX_MOVE_BYTES);
rtx rounded_total = GEN_INT (bytes);
+ rtx new_dst_reg = gen_reg_rtx (SImode);
+ rtx new_src_reg = gen_reg_rtx (SImode);
/* If we are going to have to perform this loop more than
once, then generate a label and compute the address the
@@ -2834,7 +2836,10 @@ m32r_expand_block_move (rtx operands[])
to the word after the end of the source block, and dst_reg to point
to the last word of the destination block, provided that the block
is MAX_MOVE_BYTES long. */
- emit_insn (gen_movstrsi_internal (dst_reg, src_reg, at_a_time));
+ emit_insn (gen_movstrsi_internal (dst_reg, src_reg, at_a_time,
+ new_dst_reg, new_src_reg));
+ emit_move_insn (dst_reg, new_dst_reg);
+ emit_move_insn (src_reg, new_src_reg);
emit_insn (gen_addsi3 (dst_reg, dst_reg, GEN_INT (4)));
if (bytes > MAX_MOVE_BYTES)
@@ -2845,7 +2850,9 @@ m32r_expand_block_move (rtx operands[])
}
if (leftover)
- emit_insn (gen_movstrsi_internal (dst_reg, src_reg, GEN_INT (leftover)));
+ emit_insn (gen_movstrsi_internal (dst_reg, src_reg, GEN_INT (leftover),
+ gen_reg_rtx (SImode),
+ gen_reg_rtx (SImode)));
}
@@ -2881,17 +2888,17 @@ m32r_output_block_move (rtx insn ATTRIBUTE_UNUSED, rtx operands[])
{
if (first_time)
{
- output_asm_insn ("ld\t%3, %p1", operands);
- output_asm_insn ("ld\t%4, %p1", operands);
- output_asm_insn ("st\t%3, @%0", operands);
- output_asm_insn ("st\t%4, %s0", operands);
+ output_asm_insn ("ld\t%5, %p1", operands);
+ output_asm_insn ("ld\t%6, %p1", operands);
+ output_asm_insn ("st\t%5, @%0", operands);
+ output_asm_insn ("st\t%6, %s0", operands);
}
else
{
- output_asm_insn ("ld\t%3, %p1", operands);
- output_asm_insn ("ld\t%4, %p1", operands);
- output_asm_insn ("st\t%3, %s0", operands);
- output_asm_insn ("st\t%4, %s0", operands);
+ output_asm_insn ("ld\t%5, %p1", operands);
+ output_asm_insn ("ld\t%6, %p1", operands);
+ output_asm_insn ("st\t%5, %s0", operands);
+ output_asm_insn ("st\t%6, %s0", operands);
}
bytes -= 8;
@@ -2901,15 +2908,15 @@ m32r_output_block_move (rtx insn ATTRIBUTE_UNUSED, rtx operands[])
if (bytes > 4)
got_extra = 1;
- output_asm_insn ("ld\t%3, %p1", operands);
+ output_asm_insn ("ld\t%5, %p1", operands);
if (got_extra)
- output_asm_insn ("ld\t%4, %p1", operands);
+ output_asm_insn ("ld\t%6, %p1", operands);
if (first_time)
- output_asm_insn ("st\t%3, @%0", operands);
+ output_asm_insn ("st\t%5, @%0", operands);
else
- output_asm_insn ("st\t%3, %s0", operands);
+ output_asm_insn ("st\t%5, %s0", operands);
bytes -= 4;
}
@@ -2921,20 +2928,25 @@ m32r_output_block_move (rtx insn ATTRIBUTE_UNUSED, rtx operands[])
valid memory [since we don't get called if things aren't properly
aligned]. */
int dst_offset = first_time ? 0 : 4;
+ /* The amount of increment we have to make to the
+ destination pointer. */
+ int dst_inc_amount = dst_offset + bytes - 4;
+ /* The same for the source pointer. */
+ int src_inc_amount = bytes;
int last_shift;
rtx my_operands[3];
/* If got_extra is true then we have already loaded
the next word as part of loading and storing the previous word. */
if (! got_extra)
- output_asm_insn ("ld\t%4, @%1", operands);
+ output_asm_insn ("ld\t%6, @%1", operands);
if (bytes >= 2)
{
bytes -= 2;
- output_asm_insn ("sra3\t%3, %4, #16", operands);
- my_operands[0] = operands[3];
+ output_asm_insn ("sra3\t%5, %6, #16", operands);
+ my_operands[0] = operands[5];
my_operands[1] = GEN_INT (dst_offset);
my_operands[2] = operands[0];
output_asm_insn ("sth\t%0, @(%1,%2)", my_operands);
@@ -2955,14 +2967,36 @@ m32r_output_block_move (rtx insn ATTRIBUTE_UNUSED, rtx operands[])
if (bytes > 0)
{
- my_operands[0] = operands[4];
+ my_operands[0] = operands[6];
my_operands[1] = GEN_INT (last_shift);
output_asm_insn ("srai\t%0, #%1", my_operands);
- my_operands[0] = operands[4];
+ my_operands[0] = operands[6];
my_operands[1] = GEN_INT (dst_offset);
my_operands[2] = operands[0];
output_asm_insn ("stb\t%0, @(%1,%2)", my_operands);
}
+
+ /* Update the destination pointer if needed. We have to do
+ this so that the patterns matches what we output in this
+ function. */
+ if (dst_inc_amount
+ && !find_reg_note (insn, REG_UNUSED, operands[0]))
+ {
+ my_operands[0] = operands[0];
+ my_operands[1] = GEN_INT (dst_inc_amount);
+ output_asm_insn ("addi\t%0, #%1", my_operands);
+ }
+
+ /* Update the source pointer if needed. We have to do this
+ so that the patterns matches what we output in this
+ function. */
+ if (src_inc_amount
+ && !find_reg_note (insn, REG_UNUSED, operands[1]))
+ {
+ my_operands[0] = operands[1];
+ my_operands[1] = GEN_INT (src_inc_amount);
+ output_asm_insn ("addi\t%0, #%1", my_operands);
+ }
bytes = 0;
}
diff --git a/gcc/config/m32r/m32r.md b/gcc/config/m32r/m32r.md
index 5e562a7f5c0..5a43ff74995 100644
--- a/gcc/config/m32r/m32r.md
+++ b/gcc/config/m32r/m32r.md
@@ -2675,13 +2675,17 @@
;; Insn generated by block moves
(define_insn "movstrsi_internal"
- [(set (mem:BLK (match_operand:SI 0 "register_operand" "+r")) ;; destination
- (mem:BLK (match_operand:SI 1 "register_operand" "+r"))) ;; source
+ [(set (mem:BLK (match_operand:SI 0 "register_operand" "r")) ;; destination
+ (mem:BLK (match_operand:SI 1 "register_operand" "r"))) ;; source
(use (match_operand:SI 2 "m32r_block_immediate_operand" "J"));; # bytes to move
- (set (match_dup 0) (plus:SI (match_dup 0) (minus:SI (match_dup 2) (const_int 4))))
- (set (match_dup 1) (plus:SI (match_dup 1) (match_dup 2)))
- (clobber (match_scratch:SI 3 "=&r")) ;; temp 1
- (clobber (match_scratch:SI 4 "=&r"))] ;; temp 2
+ (set (match_operand:SI 3 "register_operand" "=0")
+ (plus:SI (match_dup 0)
+ (minus (match_dup 2) (const_int 4))))
+ (set (match_operand:SI 4 "register_operand" "=1")
+ (plus:SI (match_dup 1)
+ (match_dup 2)))
+ (clobber (match_scratch:SI 5 "=&r")) ;; temp1
+ (clobber (match_scratch:SI 6 "=&r"))] ;; temp2
""
"* m32r_output_block_move (insn, operands); return \"\"; "
[(set_attr "type" "store8")