aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/avr/avr.md
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/config/avr/avr.md')
-rw-r--r--gcc/config/avr/avr.md277
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