diff -ur ../gcc-4.3.4.orig/gcc/config/avr/avr.md ./gcc/config/avr/avr.md --- ../gcc-4.3.4.orig/gcc/config/avr/avr.md 2009-10-02 15:08:58.000000000 +0200 +++ ./gcc/config/avr/avr.md 2009-10-02 15:09:26.000000000 +0200 @@ -54,6 +54,7 @@ (UNSPEC_INDEX_JMP 1) (UNSPEC_SEI 2) (UNSPEC_CLI 3) + (UNSPEC_SWAP 4) (UNSPECV_PROLOGUE_SAVES 0) (UNSPECV_EPILOGUE_RESTORES 1)]) @@ -1183,6 +1184,19 @@ [(set_attr "length" "4,4") (set_attr "cc" "set_n,clobber")]) +(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 @@ -1311,10 +1325,57 @@ [(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")))] @@ -1344,6 +1405,47 @@ ;; 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" "") @@ -1462,7 +1564,49 @@ ;; >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> ;; 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")))] @@ -1492,6 +1636,47 @@ ;; 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" "") Only in ./gcc/config/avr: avr.md.orig