aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/config/avr/avr.md110
2 files changed, 59 insertions, 58 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 0ea234e..6c0d36c 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@
+2005-03-13 Andy Hutchinson <HutchinsonAndy@netscape.net>
+
+ PR target/18251
+ * config/avr/avr.md (movmemhi): Rewrite as RTL loop.
+ (*movmemqi_insn): Delete.
+ (*movmemhi): Delete.
+
2005-03-13 Kazu Hirata <kazu@cs.umass.edu>
* builtins.c (fold_builtin_classify): Take decomposed
diff --git a/gcc/config/avr/avr.md b/gcc/config/avr/avr.md
index 458b1db..b6fb179 100644
--- a/gcc/config/avr/avr.md
+++ b/gcc/config/avr/avr.md
@@ -346,75 +346,69 @@
;;=========================================================================
;; move string (like memcpy)
+;; implement as RTL loop
(define_expand "movmemhi"
[(parallel [(set (match_operand:BLK 0 "memory_operand" "")
- (match_operand:BLK 1 "memory_operand" ""))
- (use (match_operand:HI 2 "const_int_operand" ""))
- (use (match_operand:HI 3 "const_int_operand" ""))
- (clobber (match_scratch:HI 4 ""))
- (clobber (match_scratch:HI 5 ""))
- (clobber (match_dup 6))])]
+ (match_operand:BLK 1 "memory_operand" ""))
+ (use (match_operand:HI 2 "const_int_operand" ""))
+ (use (match_operand:HI 3 "const_int_operand" ""))])]
""
"{
- rtx addr0, addr1;
- int cnt8;
+ int prob;
+ HOST_WIDE_INT count;
enum machine_mode mode;
+ rtx label = gen_label_rtx ();
+ rtx loop_reg;
+ rtx jump;
+
+ /* Copy pointers into new psuedos - they will be changed. */
+ rtx addr0 = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
+ rtx addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
+
+ /* Create rtx for tmp register - we use this as scratch. */
+ rtx tmp_reg_rtx = gen_rtx_REG (QImode, TMP_REGNO);
if (GET_CODE (operands[2]) != CONST_INT)
FAIL;
- cnt8 = byte_immediate_operand (operands[2], GET_MODE (operands[2]));
- mode = cnt8 ? QImode : HImode;
- operands[6] = gen_rtx_SCRATCH (mode);
- operands[2] = copy_to_mode_reg (mode,
- gen_int_mode (INTVAL (operands[2]), mode));
- addr0 = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
- addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
- operands[0] = gen_rtx_MEM (BLKmode, addr0);
- operands[1] = gen_rtx_MEM (BLKmode, addr1);
-}")
-
-(define_insn "*movmemqi_insn"
- [(set (mem:BLK (match_operand:HI 0 "register_operand" "e"))
- (mem:BLK (match_operand:HI 1 "register_operand" "e")))
- (use (match_operand:QI 2 "register_operand" "r"))
- (use (match_operand:QI 3 "const_int_operand" "i"))
- (clobber (match_scratch:HI 4 "=0"))
- (clobber (match_scratch:HI 5 "=1"))
- (clobber (match_scratch:QI 6 "=2"))]
- ""
- "ld __tmp_reg__,%a1+
- st %a0+,__tmp_reg__
- dec %2
- brne .-8"
- [(set_attr "length" "4")
- (set_attr "cc" "clobber")])
+ count = INTVAL (operands[2]);
+ if (count <= 0)
+ FAIL;
-(define_insn "*movmemhi"
- [(set (mem:BLK (match_operand:HI 0 "register_operand" "e,e"))
- (mem:BLK (match_operand:HI 1 "register_operand" "e,e")))
- (use (match_operand:HI 2 "register_operand" "!w,d"))
- (use (match_operand:HI 3 "const_int_operand" ""))
- (clobber (match_scratch:HI 4 "=0,0"))
- (clobber (match_scratch:HI 5 "=1,1"))
- (clobber (match_scratch:HI 6 "=2,2"))]
- ""
- "*{
- if (which_alternative==0)
- return (AS2 (ld,__tmp_reg__,%a1+) CR_TAB
- AS2 (st,%a0+,__tmp_reg__) CR_TAB
- AS2 (sbiw,%A2,1) CR_TAB
- AS1 (brne,.-8));
- else
- return (AS2 (ld,__tmp_reg__,%a1+) CR_TAB
- AS2 (st,%a0+,__tmp_reg__) CR_TAB
- AS2 (subi,%A2,1) CR_TAB
- AS2 (sbci,%B2,0) CR_TAB
- AS1 (brne,.-10));
-}"
- [(set_attr "length" "4,5")
- (set_attr "cc" "clobber,clobber")])
+ /* Work out branch probability for latter use. */
+ prob = REG_BR_PROB_BASE - REG_BR_PROB_BASE / count;
+
+ /* See if constant fit 8 bits. */
+ mode = (count < 0x100) ? QImode : HImode;
+ /* Create loop counter register. */
+ loop_reg = copy_to_mode_reg (mode, gen_int_mode (count, mode));
+
+ /* Now create RTL code for move loop. */
+ /* Label at top of loop. */
+ emit_label (label);
+
+ /* Move one byte into scratch and inc pointer. */
+ emit_move_insn (tmp_reg_rtx, gen_rtx_MEM (QImode, addr1));
+ emit_move_insn (addr1, gen_rtx_PLUS (Pmode, addr1, const1_rtx));
+
+ /* Move to mem and inc pointer. */
+ emit_move_insn (gen_rtx_MEM (QImode, addr0), tmp_reg_rtx);
+ emit_move_insn (addr0, gen_rtx_PLUS (Pmode, addr0, const1_rtx));
+
+ /* Decrement count. */
+ emit_move_insn (loop_reg, gen_rtx_PLUS (mode, loop_reg, constm1_rtx));
+
+ /* Compare with zero and jump if not equal. */
+ emit_cmp_and_jump_insns (loop_reg, const0_rtx, NE, NULL_RTX, mode, 1,
+ label);
+ /* Set jump probability based on loop count. */
+ jump = get_last_insn ();
+ REG_NOTES (jump) = gen_rtx_EXPR_LIST (REG_BR_PROB,
+ GEN_INT (prob),
+ REG_NOTES (jump));
+ DONE;
+}")
;; =0 =0 =0 =0 =0 =0 =0 =0 =0 =0 =0 =0 =0 =0 =0 =0 =0 =0 =0 =0 =0 =0 =0 =0
;; memset (%0, 0, %1)