From 6bbaec0912db7f78d62640f99ba1782c109b19de Mon Sep 17 00:00:00 2001 From: Andy Hutchinson Date: Sun, 13 Mar 2005 10:09:53 +0000 Subject: [PATCH] re PR target/18251 (unable to find a register to spill in class `POINTER_REGS') PR target/18251 * config/avr/avr.md (movmemhi): Rewrite as RTL loop. (*movmemqi_insn): Delete. (*movmemhi): Delete. From-SVN: r96365 --- gcc/ChangeLog | 7 ++++ gcc/config/avr/avr.md | 110 ++++++++++++++++++++++++-------------------------- 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 + + PR target/18251 + * config/avr/avr.md (movmemhi): Rewrite as RTL loop. + (*movmemqi_insn): Delete. + (*movmemhi): Delete. + 2005-03-13 Kazu Hirata * 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) -- 2.7.4