diff options
Diffstat (limited to 'gcc/config/avr/avr.md')
-rw-r--r-- | gcc/config/avr/avr.md | 277 |
1 files changed, 137 insertions, 140 deletions
diff --git a/gcc/config/avr/avr.md b/gcc/config/avr/avr.md index c545840fb14..53c2f7b857d 100644 --- a/gcc/config/avr/avr.md +++ b/gcc/config/avr/avr.md @@ -1,7 +1,8 @@ ;; -*- Mode: Scheme -*- ;; Machine description for GNU compiler, ;; for ATMEL AVR micro controllers. -;; Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004 Free Software Foundation, Inc. +;; Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004, 2005 +;; Free Software Foundation, Inc. ;; Contributed by Denis Chertykov (denisc@overta.ru) ;; This file is part of GCC. @@ -29,6 +30,8 @@ ;; j Branch condition. ;; k Reverse branch condition. ;; o Displacement for (mem (plus (reg) (const_int))) operands. +;; p POST_INC or PRE_DEC address as a pointer (X, Y, Z) +;; r POST_INC or PRE_DEC address as a register (r26, r28, r30) ;; ~ Output 'r' if not AVR_MEGA. ;; UNSPEC usage: @@ -343,75 +346,69 @@ ;;========================================================================= ;; move string (like memcpy) +;; implement as RTL loop (define_expand "movstrhi" [(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[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[6] = gen_rtx_SCRATCH (mode); - operands[0] = gen_rtx (MEM, BLKmode, addr0); - operands[1] = gen_rtx (MEM, BLKmode, addr1); -}") -(define_insn "*movstrqi_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 "*movstrhi" - [(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) @@ -1166,31 +1163,31 @@ ;; arithmetic shift left (define_insn "ashlqi3" - [(set (match_operand:QI 0 "register_operand" "=r,r,r,!d,r,r") - (ashift:QI (match_operand:QI 1 "register_operand" "0,0,0,0,0,0") - (match_operand:QI 2 "general_operand" "r,P,K,n,n,Qm")))] + [(set (match_operand:QI 0 "register_operand" "=r,r,r,r,!d,r,r") + (ashift:QI (match_operand:QI 1 "register_operand" "0,0,0,0,0,0,0") + (match_operand:QI 2 "general_operand" "r,L,P,K,n,n,Qm")))] "" "* return ashlqi3_out (insn, operands, NULL);" - [(set_attr "length" "5,1,2,4,6,9") - (set_attr "cc" "clobber,set_czn,set_czn,set_czn,set_czn,clobber")]) + [(set_attr "length" "5,0,1,2,4,6,9") + (set_attr "cc" "clobber,none,set_czn,set_czn,set_czn,set_czn,clobber")]) (define_insn "ashlhi3" - [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r,r") - (ashift:HI (match_operand:HI 1 "register_operand" "0,0,r,0,0,0") - (match_operand:QI 2 "general_operand" "r,P,O,K,n,Qm")))] + [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r,r,r") + (ashift:HI (match_operand:HI 1 "register_operand" "0,0,0,r,0,0,0") + (match_operand:QI 2 "general_operand" "r,L,P,O,K,n,Qm")))] "" "* return ashlhi3_out (insn, operands, NULL);" - [(set_attr "length" "6,2,2,4,10,10") - (set_attr "cc" "clobber,set_n,clobber,set_n,clobber,clobber")]) + [(set_attr "length" "6,0,2,2,4,10,10") + (set_attr "cc" "clobber,none,set_n,clobber,set_n,clobber,clobber")]) (define_insn "ashlsi3" - [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r") - (ashift:SI (match_operand:SI 1 "register_operand" "0,0,r,0,0,0") - (match_operand:QI 2 "general_operand" "r,P,O,K,n,Qm")))] + [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r") + (ashift:SI (match_operand:SI 1 "register_operand" "0,0,0,r,0,0,0") + (match_operand:QI 2 "general_operand" "r,L,P,O,K,n,Qm")))] "" "* return ashlsi3_out (insn, operands, NULL);" - [(set_attr "length" "8,4,4,8,10,12") - (set_attr "cc" "clobber,set_n,clobber,set_n,clobber,clobber")]) + [(set_attr "length" "8,0,4,4,8,10,12") + (set_attr "cc" "clobber,none,set_n,clobber,set_n,clobber,clobber")]) ;; Optimize if a scratch register from LD_REGS happens to be available. @@ -1206,14 +1203,14 @@ FAIL;") (define_insn "*ashlhi3_const" - [(set (match_operand:HI 0 "register_operand" "=r,r,r,r") - (ashift:HI (match_operand:HI 1 "register_operand" "0,r,0,0") - (match_operand:QI 2 "const_int_operand" "P,O,K,n"))) - (clobber (match_scratch:QI 3 "=X,X,X,&d"))] + [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r") + (ashift:HI (match_operand:HI 1 "register_operand" "0,0,r,0,0") + (match_operand:QI 2 "const_int_operand" "L,P,O,K,n"))) + (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))] "reload_completed" "* return ashlhi3_out (insn, operands, NULL);" - [(set_attr "length" "2,2,4,10") - (set_attr "cc" "set_n,clobber,set_n,clobber")]) + [(set_attr "length" "0,2,2,4,10") + (set_attr "cc" "none,set_n,clobber,set_n,clobber")]) (define_peephole2 [(match_scratch:QI 3 "d") @@ -1227,44 +1224,44 @@ FAIL;") (define_insn "*ashlsi3_const" - [(set (match_operand:SI 0 "register_operand" "=r,r,r") - (ashift:SI (match_operand:SI 1 "register_operand" "0,r,0") - (match_operand:QI 2 "const_int_operand" "P,O,n"))) - (clobber (match_scratch:QI 3 "=X,X,&d"))] + [(set (match_operand:SI 0 "register_operand" "=r,r,r,r") + (ashift:SI (match_operand:SI 1 "register_operand" "0,0,r,0") + (match_operand:QI 2 "const_int_operand" "L,P,O,n"))) + (clobber (match_scratch:QI 3 "=X,X,X,&d"))] "reload_completed" "* return ashlsi3_out (insn, operands, NULL);" - [(set_attr "length" "4,4,10") - (set_attr "cc" "set_n,clobber,clobber")]) + [(set_attr "length" "0,4,4,10") + (set_attr "cc" "none,set_n,clobber,clobber")]) ;; >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> ;; arithmetic shift right (define_insn "ashrqi3" - [(set (match_operand:QI 0 "register_operand" "=r,r,r,r,r") - (ashiftrt:QI (match_operand:QI 1 "register_operand" "0,0,0,0,0") - (match_operand:QI 2 "general_operand" "r,P,K,n,Qm")))] + [(set (match_operand:QI 0 "register_operand" "=r,r,r,r,r,r") + (ashiftrt:QI (match_operand:QI 1 "register_operand" "0,0,0,0,0,0") + (match_operand:QI 2 "general_operand" "r,L,P,K,n,Qm")))] "" "* return ashrqi3_out (insn, operands, NULL);" - [(set_attr "length" "5,1,2,5,9") - (set_attr "cc" "clobber,clobber,clobber,clobber,clobber")]) + [(set_attr "length" "5,0,1,2,5,9") + (set_attr "cc" "clobber,none,clobber,clobber,clobber,clobber")]) (define_insn "ashrhi3" - [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r,r") - (ashiftrt:HI (match_operand:HI 1 "register_operand" "0,0,r,0,0,0") - (match_operand:QI 2 "general_operand" "r,P,O,K,n,Qm")))] + [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r,r,r") + (ashiftrt:HI (match_operand:HI 1 "register_operand" "0,0,0,r,0,0,0") + (match_operand:QI 2 "general_operand" "r,L,P,O,K,n,Qm")))] "" "* return ashrhi3_out (insn, operands, NULL);" - [(set_attr "length" "6,2,4,4,10,10") - (set_attr "cc" "clobber,clobber,set_n,clobber,clobber,clobber")]) + [(set_attr "length" "6,0,2,4,4,10,10") + (set_attr "cc" "clobber,none,clobber,set_n,clobber,clobber,clobber")]) (define_insn "ashrsi3" - [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r") - (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0,r,0,0,0") - (match_operand:QI 2 "general_operand" "r,P,O,K,n,Qm")))] + [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r") + (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0,0,r,0,0,0") + (match_operand:QI 2 "general_operand" "r,L,P,O,K,n,Qm")))] "" "* return ashrsi3_out (insn, operands, NULL);" - [(set_attr "length" "8,4,6,8,10,12") - (set_attr "cc" "clobber,clobber,set_n,clobber,clobber,clobber")]) + [(set_attr "length" "8,0,4,6,8,10,12") + (set_attr "cc" "clobber,none,clobber,set_n,clobber,clobber,clobber")]) ;; Optimize if a scratch register from LD_REGS happens to be available. @@ -1280,14 +1277,14 @@ FAIL;") (define_insn "*ashrhi3_const" - [(set (match_operand:HI 0 "register_operand" "=r,r,r,r") - (ashiftrt:HI (match_operand:HI 1 "register_operand" "0,r,0,0") - (match_operand:QI 2 "const_int_operand" "P,O,K,n"))) - (clobber (match_scratch:QI 3 "=X,X,X,&d"))] + [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r") + (ashiftrt:HI (match_operand:HI 1 "register_operand" "0,0,r,0,0") + (match_operand:QI 2 "const_int_operand" "L,P,O,K,n"))) + (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))] "reload_completed" "* return ashrhi3_out (insn, operands, NULL);" - [(set_attr "length" "2,4,4,10") - (set_attr "cc" "clobber,set_n,clobber,clobber")]) + [(set_attr "length" "0,2,4,4,10") + (set_attr "cc" "none,clobber,set_n,clobber,clobber")]) (define_peephole2 [(match_scratch:QI 3 "d") @@ -1301,44 +1298,44 @@ FAIL;") (define_insn "*ashrsi3_const" - [(set (match_operand:SI 0 "register_operand" "=r,r,r") - (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,r,0") - (match_operand:QI 2 "const_int_operand" "P,O,n"))) - (clobber (match_scratch:QI 3 "=X,X,&d"))] + [(set (match_operand:SI 0 "register_operand" "=r,r,r,r") + (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0,r,0") + (match_operand:QI 2 "const_int_operand" "L,P,O,n"))) + (clobber (match_scratch:QI 3 "=X,X,X,&d"))] "reload_completed" "* return ashrsi3_out (insn, operands, NULL);" - [(set_attr "length" "4,4,10") - (set_attr "cc" "clobber,set_n,clobber")]) + [(set_attr "length" "0,4,4,10") + (set_attr "cc" "none,clobber,set_n,clobber")]) ;; >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> ;; logical shift right (define_insn "lshrqi3" - [(set (match_operand:QI 0 "register_operand" "=r,r,r,!d,r,r") - (lshiftrt:QI (match_operand:QI 1 "register_operand" "0,0,0,0,0,0") - (match_operand:QI 2 "general_operand" "r,P,K,n,n,Qm")))] + [(set (match_operand:QI 0 "register_operand" "=r,r,r,r,!d,r,r") + (lshiftrt:QI (match_operand:QI 1 "register_operand" "0,0,0,0,0,0,0") + (match_operand:QI 2 "general_operand" "r,L,P,K,n,n,Qm")))] "" "* return lshrqi3_out (insn, operands, NULL);" - [(set_attr "length" "5,1,2,4,6,9") - (set_attr "cc" "clobber,set_czn,set_czn,set_czn,set_czn,clobber")]) + [(set_attr "length" "5,0,1,2,4,6,9") + (set_attr "cc" "clobber,none,set_czn,set_czn,set_czn,set_czn,clobber")]) (define_insn "lshrhi3" - [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r,r") - (lshiftrt:HI (match_operand:HI 1 "register_operand" "0,0,r,0,0,0") - (match_operand:QI 2 "general_operand" "r,P,O,K,n,Qm")))] + [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r,r,r") + (lshiftrt:HI (match_operand:HI 1 "register_operand" "0,0,0,r,0,0,0") + (match_operand:QI 2 "general_operand" "r,L,P,O,K,n,Qm")))] "" "* return lshrhi3_out (insn, operands, NULL);" - [(set_attr "length" "6,2,2,4,10,10") - (set_attr "cc" "clobber,clobber,clobber,clobber,clobber,clobber")]) + [(set_attr "length" "6,0,2,2,4,10,10") + (set_attr "cc" "clobber,none,clobber,clobber,clobber,clobber,clobber")]) (define_insn "lshrsi3" - [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r") - (lshiftrt:SI (match_operand:SI 1 "register_operand" "0,0,r,0,0,0") - (match_operand:QI 2 "general_operand" "r,P,O,K,n,Qm")))] + [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r") + (lshiftrt:SI (match_operand:SI 1 "register_operand" "0,0,0,r,0,0,0") + (match_operand:QI 2 "general_operand" "r,L,P,O,K,n,Qm")))] "" "* return lshrsi3_out (insn, operands, NULL);" - [(set_attr "length" "8,4,4,8,10,12") - (set_attr "cc" "clobber,clobber,clobber,clobber,clobber,clobber")]) + [(set_attr "length" "8,0,4,4,8,10,12") + (set_attr "cc" "clobber,none,clobber,clobber,clobber,clobber,clobber")]) ;; Optimize if a scratch register from LD_REGS happens to be available. @@ -1354,14 +1351,14 @@ FAIL;") (define_insn "*lshrhi3_const" - [(set (match_operand:HI 0 "register_operand" "=r,r,r,r") - (lshiftrt:HI (match_operand:HI 1 "register_operand" "0,r,0,0") - (match_operand:QI 2 "const_int_operand" "P,O,K,n"))) - (clobber (match_scratch:QI 3 "=X,X,X,&d"))] + [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r") + (lshiftrt:HI (match_operand:HI 1 "register_operand" "0,0,r,0,0") + (match_operand:QI 2 "const_int_operand" "L,P,O,K,n"))) + (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))] "reload_completed" "* return lshrhi3_out (insn, operands, NULL);" - [(set_attr "length" "2,2,4,10") - (set_attr "cc" "clobber,clobber,clobber,clobber")]) + [(set_attr "length" "0,2,2,4,10") + (set_attr "cc" "none,clobber,clobber,clobber,clobber")]) (define_peephole2 [(match_scratch:QI 3 "d") @@ -1375,14 +1372,14 @@ FAIL;") (define_insn "*lshrsi3_const" - [(set (match_operand:SI 0 "register_operand" "=r,r,r") - (lshiftrt:SI (match_operand:SI 1 "register_operand" "0,r,0") - (match_operand:QI 2 "const_int_operand" "P,O,n"))) - (clobber (match_scratch:QI 3 "=X,X,&d"))] + [(set (match_operand:SI 0 "register_operand" "=r,r,r,r") + (lshiftrt:SI (match_operand:SI 1 "register_operand" "0,0,r,0") + (match_operand:QI 2 "const_int_operand" "L,P,O,n"))) + (clobber (match_scratch:QI 3 "=X,X,X,&d"))] "reload_completed" "* return lshrsi3_out (insn, operands, NULL);" - [(set_attr "length" "4,4,10") - (set_attr "cc" "clobber,clobber,clobber")]) + [(set_attr "length" "0,4,4,10") + (set_attr "cc" "none,clobber,clobber,clobber")]) ;; abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) ;; abs |