You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
324 lines
11 KiB
Diff
324 lines
11 KiB
Diff
15 years ago
|
Index: gcc/config/avr/avr.md
|
||
|
===================================================================
|
||
|
--- gcc/config/avr/avr.md (revision 129892)
|
||
|
+++ gcc/config/avr/avr.md (working copy)
|
||
|
@@ -45,21 +45,22 @@
|
||
|
(REG_SP 32)
|
||
|
(TMP_REGNO 0) ; temporary register r0
|
||
|
(ZERO_REGNO 1) ; zero register r1
|
||
|
|
||
|
(SREG_ADDR 0x5F)
|
||
|
(RAMPZ_ADDR 0x5B)
|
||
|
|
||
|
(UNSPEC_STRLEN 0)
|
||
|
(UNSPEC_INDEX_JMP 1)
|
||
|
(UNSPEC_SEI 2)
|
||
|
(UNSPEC_CLI 3)
|
||
|
+ (UNSPEC_SWAP 4)
|
||
|
|
||
|
(UNSPECV_PROLOGUE_SAVES 0)
|
||
|
(UNSPECV_EPILOGUE_RESTORES 1)])
|
||
|
|
||
|
(include "predicates.md")
|
||
|
(include "constraints.md")
|
||
|
|
||
|
;; Condition code settings.
|
||
|
(define_attr "cc" "none,set_czn,set_zn,set_n,compare,clobber"
|
||
|
(const_string "none"))
|
||
|
@@ -1185,20 +1186,33 @@
|
||
|
return (AS2 (andi, %A0,lo8(%2)) CR_TAB
|
||
|
AS2 (andi, %B0,hi8(%2)) CR_TAB
|
||
|
AS2 (andi, %C0,hlo8(%2)) CR_TAB
|
||
|
AS2 (andi, %D0,hhi8(%2)));
|
||
|
}
|
||
|
return \"bug\";
|
||
|
}"
|
||
|
[(set_attr "length" "4,4")
|
||
|
(set_attr "cc" "set_n,set_n")])
|
||
|
|
||
|
+(define_peephole2 ; andi
|
||
|
+ [(set (match_operand:QI 0 "d_register_operand" "")
|
||
|
+ (and:QI (match_dup 0)
|
||
|
+ (match_operand:QI 1 "const_int_operand" "")))
|
||
|
+ (set (match_dup 0)
|
||
|
+ (and:QI (match_dup 0)
|
||
|
+ (match_operand:QI 2 "const_int_operand" "")))]
|
||
|
+ ""
|
||
|
+ [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))]
|
||
|
+ {
|
||
|
+ operands[1] = GEN_INT (INTVAL (operands[1]) & INTVAL (operands[2]));
|
||
|
+ })
|
||
|
+
|
||
|
;;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||
|
;; ior
|
||
|
|
||
|
(define_insn "iorqi3"
|
||
|
[(set (match_operand:QI 0 "register_operand" "=r,d")
|
||
|
(ior:QI (match_operand:QI 1 "register_operand" "%0,0")
|
||
|
(match_operand:QI 2 "nonmemory_operand" "r,i")))]
|
||
|
""
|
||
|
"@
|
||
|
or %0,%2
|
||
|
@@ -1313,24 +1327,71 @@
|
||
|
(xor:SI (match_operand:SI 1 "register_operand" "%0")
|
||
|
(match_operand:SI 2 "register_operand" "r")))]
|
||
|
""
|
||
|
"eor %0,%2
|
||
|
eor %B0,%B2
|
||
|
eor %C0,%C2
|
||
|
eor %D0,%D2"
|
||
|
[(set_attr "length" "4")
|
||
|
(set_attr "cc" "set_n")])
|
||
|
|
||
|
+;; swap
|
||
|
+
|
||
|
+(define_insn "*swap"
|
||
|
+ [(set (match_operand:QI 0 "register_operand" "=r")
|
||
|
+ (unspec:QI [(match_operand:QI 1 "register_operand" "0")]
|
||
|
+ UNSPEC_SWAP))]
|
||
|
+ ""
|
||
|
+ "swap %0"
|
||
|
+ [(set_attr "length" "1")
|
||
|
+ (set_attr "cc" "none")])
|
||
|
+
|
||
|
;;<< << << << << << << << << << << << << << << << << << << << << << << << << <<
|
||
|
;; arithmetic shift left
|
||
|
|
||
|
-(define_insn "ashlqi3"
|
||
|
+(define_expand "ashlqi3"
|
||
|
+ [(set (match_operand:QI 0 "register_operand" "")
|
||
|
+ (ashift:QI (match_operand:QI 1 "register_operand" "")
|
||
|
+ (match_operand:QI 2 "general_operand" "")))]
|
||
|
+ ""
|
||
|
+ "")
|
||
|
+
|
||
|
+(define_split ; ashlqi3_const4
|
||
|
+ [(set (match_operand:QI 0 "d_register_operand" "")
|
||
|
+ (ashift:QI (match_operand:QI 1 "d_register_operand" "")
|
||
|
+ (const_int 4)))]
|
||
|
+ ""
|
||
|
+ [(set (match_dup 0) (unspec:QI [(match_dup 0)] UNSPEC_SWAP))
|
||
|
+ (set (match_dup 0) (and:QI (match_dup 0) (const_int -16)))]
|
||
|
+ "")
|
||
|
+
|
||
|
+(define_split ; ashlqi3_const5
|
||
|
+ [(set (match_operand:QI 0 "d_register_operand" "")
|
||
|
+ (ashift:QI (match_operand:QI 1 "d_register_operand" "")
|
||
|
+ (const_int 5)))]
|
||
|
+ ""
|
||
|
+ [(set (match_dup 0) (unspec:QI [(match_dup 0)] UNSPEC_SWAP))
|
||
|
+ (set (match_dup 0) (ashift:QI (match_dup 0) (const_int 1)))
|
||
|
+ (set (match_dup 0) (and:QI (match_dup 0) (const_int -32)))]
|
||
|
+ "")
|
||
|
+
|
||
|
+(define_split ; ashlqi3_const6
|
||
|
+ [(set (match_operand:QI 0 "d_register_operand" "")
|
||
|
+ (ashift:QI (match_operand:QI 1 "d_register_operand" "")
|
||
|
+ (const_int 6)))]
|
||
|
+ ""
|
||
|
+ [(set (match_dup 0) (unspec:QI [(match_dup 0)] UNSPEC_SWAP))
|
||
|
+ (set (match_dup 0) (ashift:QI (match_dup 0) (const_int 2)))
|
||
|
+ (set (match_dup 0) (and:QI (match_dup 0) (const_int -64)))]
|
||
|
+ "")
|
||
|
+
|
||
|
+(define_insn "*ashlqi3"
|
||
|
[(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,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,r")
|
||
|
@@ -1346,20 +1407,61 @@
|
||
|
(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,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.
|
||
|
|
||
|
(define_peephole2
|
||
|
+ [(match_scratch:QI 2 "d")
|
||
|
+ (set (match_operand:QI 0 "l_register_operand" "")
|
||
|
+ (ashift:QI (match_operand:QI 1 "l_register_operand" "")
|
||
|
+ (const_int 4)))]
|
||
|
+ ""
|
||
|
+ [(set (match_dup 0) (unspec:QI [(match_dup 0)] UNSPEC_SWAP))
|
||
|
+ (set (match_dup 2) (const_int -16))
|
||
|
+ (set (match_dup 0) (and:QI (match_dup 0) (match_dup 2)))
|
||
|
+ (clobber (match_dup 2))]
|
||
|
+ "if (!avr_peep2_scratch_safe (operands[2]))
|
||
|
+ FAIL;")
|
||
|
+
|
||
|
+(define_peephole2
|
||
|
+ [(match_scratch:QI 2 "d")
|
||
|
+ (set (match_operand:QI 0 "l_register_operand" "")
|
||
|
+ (ashift:QI (match_operand:QI 1 "l_register_operand" "")
|
||
|
+ (const_int 5)))]
|
||
|
+ ""
|
||
|
+ [(set (match_dup 0) (unspec:QI [(match_dup 0)] UNSPEC_SWAP))
|
||
|
+ (set (match_dup 0) (ashift:QI (match_dup 0) (const_int 1)))
|
||
|
+ (set (match_dup 2) (const_int -32))
|
||
|
+ (set (match_dup 0) (and:QI (match_dup 0) (match_dup 2)))
|
||
|
+ (clobber (match_dup 2))]
|
||
|
+ "if (!avr_peep2_scratch_safe (operands[2]))
|
||
|
+ FAIL;")
|
||
|
+
|
||
|
+(define_peephole2
|
||
|
+ [(match_scratch:QI 2 "d")
|
||
|
+ (set (match_operand:QI 0 "l_register_operand" "")
|
||
|
+ (ashift:QI (match_operand:QI 1 "l_register_operand" "")
|
||
|
+ (const_int 6)))]
|
||
|
+ ""
|
||
|
+ [(set (match_dup 0) (unspec:QI [(match_dup 0)] UNSPEC_SWAP))
|
||
|
+ (set (match_dup 0) (ashift:QI (match_dup 0) (const_int 2)))
|
||
|
+ (set (match_dup 2) (const_int -64))
|
||
|
+ (set (match_dup 0) (and:QI (match_dup 0) (match_dup 2)))
|
||
|
+ (clobber (match_dup 2))]
|
||
|
+ "if (!avr_peep2_scratch_safe (operands[2]))
|
||
|
+ FAIL;")
|
||
|
+
|
||
|
+(define_peephole2
|
||
|
[(match_scratch:QI 3 "d")
|
||
|
(set (match_operand:HI 0 "register_operand" "")
|
||
|
(ashift:HI (match_operand:HI 1 "register_operand" "")
|
||
|
(match_operand:QI 2 "const_int_operand" "")))]
|
||
|
""
|
||
|
[(parallel [(set (match_dup 0) (ashift:HI (match_dup 1) (match_dup 2)))
|
||
|
(clobber (match_dup 3))])]
|
||
|
"if (!avr_peep2_scratch_safe (operands[3]))
|
||
|
FAIL;")
|
||
|
|
||
|
@@ -1464,21 +1566,63 @@
|
||
|
(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" "0,4,4,10")
|
||
|
(set_attr "cc" "none,clobber,set_n,clobber")])
|
||
|
|
||
|
;; >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >>
|
||
|
;; logical shift right
|
||
|
|
||
|
-(define_insn "lshrqi3"
|
||
|
+(define_expand "lshrqi3"
|
||
|
+ [(set (match_operand:QI 0 "register_operand" "")
|
||
|
+ (lshiftrt:QI (match_operand:QI 1 "register_operand" "")
|
||
|
+ (match_operand:QI 2 "general_operand" "")))]
|
||
|
+ ""
|
||
|
+ "")
|
||
|
+
|
||
|
+(define_insn_and_split "*lshrqi3_const4"
|
||
|
+ [(set (match_operand:QI 0 "d_register_operand" "=d")
|
||
|
+ (lshiftrt:QI (match_operand:QI 1 "d_register_operand" "0")
|
||
|
+ (const_int 4)))]
|
||
|
+ ""
|
||
|
+ "#"
|
||
|
+ ""
|
||
|
+ [(set (match_dup 0) (unspec:QI [(match_dup 0)] UNSPEC_SWAP))
|
||
|
+ (set (match_dup 0) (and:QI (match_dup 0) (const_int 15)))]
|
||
|
+ "")
|
||
|
+
|
||
|
+(define_insn_and_split "*lshrqi3_const5"
|
||
|
+ [(set (match_operand:QI 0 "d_register_operand" "=d")
|
||
|
+ (lshiftrt:QI (match_operand:QI 1 "d_register_operand" "0")
|
||
|
+ (const_int 5)))]
|
||
|
+ ""
|
||
|
+ "#"
|
||
|
+ ""
|
||
|
+ [(set (match_dup 0) (unspec:QI [(match_dup 0)] UNSPEC_SWAP))
|
||
|
+ (set (match_dup 0) (lshiftrt:QI (match_dup 0) (const_int 1)))
|
||
|
+ (set (match_dup 0) (and:QI (match_dup 0) (const_int 7)))]
|
||
|
+ "")
|
||
|
+
|
||
|
+(define_insn_and_split "*lshrqi3_const6"
|
||
|
+ [(set (match_operand:QI 0 "d_register_operand" "=d")
|
||
|
+ (lshiftrt:QI (match_operand:QI 1 "d_register_operand" "0")
|
||
|
+ (const_int 6)))]
|
||
|
+ ""
|
||
|
+ "#"
|
||
|
+ ""
|
||
|
+ [(set (match_dup 0) (unspec:QI [(match_dup 0)] UNSPEC_SWAP))
|
||
|
+ (set (match_dup 0) (lshiftrt:QI (match_dup 0) (const_int 2)))
|
||
|
+ (set (match_dup 0) (and:QI (match_dup 0) (const_int 3)))]
|
||
|
+ "")
|
||
|
+
|
||
|
+(define_insn "*lshrqi3"
|
||
|
[(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,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,r")
|
||
|
@@ -1494,20 +1638,61 @@
|
||
|
(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,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.
|
||
|
|
||
|
(define_peephole2
|
||
|
+ [(match_scratch:QI 2 "d")
|
||
|
+ (set (match_operand:QI 0 "l_register_operand" "")
|
||
|
+ (lshiftrt:QI (match_operand:QI 1 "l_register_operand" "")
|
||
|
+ (const_int 4)))]
|
||
|
+ ""
|
||
|
+ [(set (match_dup 0) (unspec:QI [(match_dup 0)] UNSPEC_SWAP))
|
||
|
+ (set (match_dup 2) (const_int 15))
|
||
|
+ (set (match_dup 0) (and:QI (match_dup 0) (match_dup 2)))
|
||
|
+ (clobber (match_dup 2))]
|
||
|
+ "if (!avr_peep2_scratch_safe (operands[2]))
|
||
|
+ FAIL;")
|
||
|
+
|
||
|
+(define_peephole2
|
||
|
+ [(match_scratch:QI 2 "d")
|
||
|
+ (set (match_operand:QI 0 "l_register_operand" "")
|
||
|
+ (lshiftrt:QI (match_operand:QI 1 "l_register_operand" "")
|
||
|
+ (const_int 5)))]
|
||
|
+ ""
|
||
|
+ [(set (match_dup 0) (unspec:QI [(match_dup 0)] UNSPEC_SWAP))
|
||
|
+ (set (match_dup 0) (lshiftrt:QI (match_dup 0) (const_int 1)))
|
||
|
+ (set (match_dup 2) (const_int 7))
|
||
|
+ (set (match_dup 0) (and:QI (match_dup 0) (match_dup 2)))
|
||
|
+ (clobber (match_dup 2))]
|
||
|
+ "if (!avr_peep2_scratch_safe (operands[2]))
|
||
|
+ FAIL;")
|
||
|
+
|
||
|
+(define_peephole2
|
||
|
+ [(match_scratch:QI 2 "d")
|
||
|
+ (set (match_operand:QI 0 "l_register_operand" "")
|
||
|
+ (lshiftrt:QI (match_operand:QI 1 "l_register_operand" "")
|
||
|
+ (const_int 6)))]
|
||
|
+ ""
|
||
|
+ [(set (match_dup 0) (unspec:QI [(match_dup 0)] UNSPEC_SWAP))
|
||
|
+ (set (match_dup 0) (lshiftrt:QI (match_dup 0) (const_int 2)))
|
||
|
+ (set (match_dup 2) (const_int 3))
|
||
|
+ (set (match_dup 0) (and:QI (match_dup 0) (match_dup 2)))
|
||
|
+ (clobber (match_dup 2))]
|
||
|
+ "if (!avr_peep2_scratch_safe (operands[2]))
|
||
|
+ FAIL;")
|
||
|
+
|
||
|
+(define_peephole2
|
||
|
[(match_scratch:QI 3 "d")
|
||
|
(set (match_operand:HI 0 "register_operand" "")
|
||
|
(lshiftrt:HI (match_operand:HI 1 "register_operand" "")
|
||
|
(match_operand:QI 2 "const_int_operand" "")))]
|
||
|
""
|
||
|
[(parallel [(set (match_dup 0) (lshiftrt:HI (match_dup 1) (match_dup 2)))
|
||
|
(clobber (match_dup 3))])]
|
||
|
"if (!avr_peep2_scratch_safe (operands[3]))
|
||
|
FAIL;")
|
||
|
|