+;; "umulqi3_highpart"
+;; "smulqi3_highpart"
+(define_insn "<extend_su>mulqi3_highpart"
+ [(set (match_operand:QI 0 "register_operand" "=r")
+ (truncate:QI
+ (lshiftrt:HI (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
+ (any_extend:HI (match_operand:QI 2 "register_operand" "<mul_r_d>")))
+ (const_int 8))))]
+ "AVR_HAVE_MUL"
+ "mul<extend_s> %1,%2
+ mov %0,r1
+ clr __zero_reg__"
+ [(set_attr "length" "3")
+ (set_attr "cc" "clobber")])
+
+
+;; Used when expanding div or mod inline for some special values
+(define_insn "*subqi3.ashiftrt7"
+ [(set (match_operand:QI 0 "register_operand" "=r")
+ (minus:QI (match_operand:QI 1 "register_operand" "0")
+ (ashiftrt:QI (match_operand:QI 2 "register_operand" "r")
+ (const_int 7))))]
+ ""
+ "sbrc %2,7\;inc %0"
+ [(set_attr "length" "2")
+ (set_attr "cc" "clobber")])
+
+(define_insn "*addqi3.lt0"
+ [(set (match_operand:QI 0 "register_operand" "=r")
+ (plus:QI (lt:QI (match_operand:QI 1 "register_operand" "r")
+ (const_int 0))
+ (match_operand:QI 2 "register_operand" "0")))]
+ ""
+ "sbrc %1,7\;inc %0"
+ [(set_attr "length" "2")
+ (set_attr "cc" "clobber")])
+
+(define_insn "*addhi3.lt0"
+ [(set (match_operand:HI 0 "register_operand" "=w,r")
+ (plus:HI (lt:HI (match_operand:QI 1 "register_operand" "r,r")
+ (const_int 0))
+ (match_operand:HI 2 "register_operand" "0,0")))
+ (clobber (match_scratch:QI 3 "=X,&1"))]
+ ""
+ "@
+ sbrc %1,7\;adiw %0,1
+ lsl %1\;adc %A0,__zero_reg__\;adc %B0,__zero_reg__"
+ [(set_attr "length" "2,3")
+ (set_attr "cc" "clobber")])
+
+(define_insn "*addpsi3.lt0"
+ [(set (match_operand:PSI 0 "register_operand" "=r")
+ (plus:PSI (lshiftrt:PSI (match_operand:PSI 1 "register_operand" "r")
+ (const_int 23))
+ (match_operand:PSI 2 "register_operand" "0")))]
+ ""
+ "mov __tmp_reg__,%C1\;lsl __tmp_reg__
+ adc %A0,__zero_reg__\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__"
+ [(set_attr "length" "5")
+ (set_attr "cc" "clobber")])
+
+(define_insn "*addsi3.lt0"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (plus:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
+ (const_int 31))
+ (match_operand:SI 2 "register_operand" "0")))]
+ ""
+ "mov __tmp_reg__,%D1\;lsl __tmp_reg__
+ adc %A0,__zero_reg__\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__"
+ [(set_attr "length" "6")
+ (set_attr "cc" "clobber")])
+
+
+;; "umulqihi3"
+;; "mulqihi3"
+(define_insn "<extend_u>mulqihi3"
+ [(set (match_operand:HI 0 "register_operand" "=r")
+ (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
+ (any_extend:HI (match_operand:QI 2 "register_operand" "<mul_r_d>"))))]
+ "AVR_HAVE_MUL"
+ "mul<extend_s> %1,%2
+ movw %0,r0
+ clr __zero_reg__"
+ [(set_attr "length" "3")
+ (set_attr "cc" "clobber")])
+
+(define_insn "usmulqihi3"
+ [(set (match_operand:HI 0 "register_operand" "=r")
+ (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "a"))
+ (sign_extend:HI (match_operand:QI 2 "register_operand" "a"))))]
+ "AVR_HAVE_MUL"
+ "mulsu %2,%1
+ movw %0,r0
+ clr __zero_reg__"
+ [(set_attr "length" "3")
+ (set_attr "cc" "clobber")])
+
+;; Above insn is not canonicalized by insn combine, so here is a version with
+;; operands swapped.
+
+(define_insn "*sumulqihi3"
+ [(set (match_operand:HI 0 "register_operand" "=r")
+ (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
+ (zero_extend:HI (match_operand:QI 2 "register_operand" "a"))))]
+ "AVR_HAVE_MUL"
+ "mulsu %1,%2
+ movw %0,r0
+ clr __zero_reg__"
+ [(set_attr "length" "3")
+ (set_attr "cc" "clobber")])
+
+;; One-extend operand 1
+
+(define_insn "*osmulqihi3"
+ [(set (match_operand:HI 0 "register_operand" "=&r")
+ (mult:HI (not:HI (zero_extend:HI (not:QI (match_operand:QI 1 "register_operand" "a"))))
+ (sign_extend:HI (match_operand:QI 2 "register_operand" "a"))))]
+ "AVR_HAVE_MUL"
+ "mulsu %2,%1
+ movw %0,r0
+ sub %B0,%2
+ clr __zero_reg__"
+ [(set_attr "length" "4")
+ (set_attr "cc" "clobber")])
+
+(define_insn "*oumulqihi3"
+ [(set (match_operand:HI 0 "register_operand" "=&r")
+ (mult:HI (not:HI (zero_extend:HI (not:QI (match_operand:QI 1 "register_operand" "r"))))
+ (zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
+ "AVR_HAVE_MUL"
+ "mul %2,%1
+ movw %0,r0
+ sub %B0,%2
+ clr __zero_reg__"
+ [(set_attr "length" "4")
+ (set_attr "cc" "clobber")])
+
+;******************************************************************************
+; multiply-add/sub QI: $0 = $3 +/- $1*$2
+;******************************************************************************
+
+(define_insn "*maddqi4"
+ [(set (match_operand:QI 0 "register_operand" "=r")
+ (plus:QI (mult:QI (match_operand:QI 1 "register_operand" "r")
+ (match_operand:QI 2 "register_operand" "r"))
+ (match_operand:QI 3 "register_operand" "0")))]
+
+ "AVR_HAVE_MUL"
+ "mul %1,%2
+ add %A0,r0
+ clr __zero_reg__"
+ [(set_attr "length" "4")
+ (set_attr "cc" "clobber")])
+
+(define_insn "*msubqi4"
+ [(set (match_operand:QI 0 "register_operand" "=r")
+ (minus:QI (match_operand:QI 3 "register_operand" "0")
+ (mult:QI (match_operand:QI 1 "register_operand" "r")
+ (match_operand:QI 2 "register_operand" "r"))))]
+ "AVR_HAVE_MUL"
+ "mul %1,%2
+ sub %A0,r0
+ clr __zero_reg__"
+ [(set_attr "length" "4")
+ (set_attr "cc" "clobber")])
+
+(define_insn_and_split "*maddqi4.const"
+ [(set (match_operand:QI 0 "register_operand" "=r")
+ (plus:QI (mult:QI (match_operand:QI 1 "register_operand" "r")
+ (match_operand:QI 2 "const_int_operand" "n"))
+ (match_operand:QI 3 "register_operand" "0")))
+ (clobber (match_scratch:QI 4 "=&d"))]
+ "AVR_HAVE_MUL"
+ "#"
+ "&& reload_completed"
+ [(set (match_dup 4)
+ (match_dup 2))
+ ; *maddqi4
+ (set (match_dup 0)
+ (plus:QI (mult:QI (match_dup 1)
+ (match_dup 4))
+ (match_dup 3)))]
+ "")
+
+(define_insn_and_split "*msubqi4.const"
+ [(set (match_operand:QI 0 "register_operand" "=r")
+ (minus:QI (match_operand:QI 3 "register_operand" "0")
+ (mult:QI (match_operand:QI 1 "register_operand" "r")
+ (match_operand:QI 2 "const_int_operand" "n"))))
+ (clobber (match_scratch:QI 4 "=&d"))]
+ "AVR_HAVE_MUL"
+ "#"
+ "&& reload_completed"
+ [(set (match_dup 4)
+ (match_dup 2))
+ ; *msubqi4
+ (set (match_dup 0)
+ (minus:QI (match_dup 3)
+ (mult:QI (match_dup 1)
+ (match_dup 4))))]
+ "")
+
+
+;******************************************************************************
+; multiply-add/sub HI: $0 = $3 +/- $1*$2 with 8-bit values $1, $2
+;******************************************************************************
+
+;; We don't use standard insns/expanders as they lead to cumbersome code for,
+;; e.g,
+;;
+;; int foo (unsigned char z)
+;; {
+;; extern int aInt[];
+;; return aInt[3*z+2];
+;; }
+;;
+;; because the constant +4 then is added explicitely instead of consuming it
+;; with the aInt symbol. Therefore, we rely on insn combine which takes costs
+;; into account more accurately and doesn't do burte-force multiply-add/sub.
+;; The implementational effort is the same so we are fine with that approach.
+
+
+;; "*maddqihi4"
+;; "*umaddqihi4"
+(define_insn "*<extend_u>maddqihi4"
+ [(set (match_operand:HI 0 "register_operand" "=r")
+ (plus:HI (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
+ (any_extend:HI (match_operand:QI 2 "register_operand" "<mul_r_d>")))
+ (match_operand:HI 3 "register_operand" "0")))]
+
+ "AVR_HAVE_MUL"
+ "mul<extend_s> %1,%2
+ add %A0,r0
+ adc %B0,r1
+ clr __zero_reg__"
+ [(set_attr "length" "4")
+ (set_attr "cc" "clobber")])
+
+;; "*msubqihi4"
+;; "*umsubqihi4"
+(define_insn "*<extend_u>msubqihi4"
+ [(set (match_operand:HI 0 "register_operand" "=r")
+ (minus:HI (match_operand:HI 3 "register_operand" "0")
+ (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
+ (any_extend:HI (match_operand:QI 2 "register_operand" "<mul_r_d>")))))]
+ "AVR_HAVE_MUL"
+ "mul<extend_s> %1,%2
+ sub %A0,r0
+ sbc %B0,r1
+ clr __zero_reg__"
+ [(set_attr "length" "4")
+ (set_attr "cc" "clobber")])
+
+;; "*usmaddqihi4"
+;; "*sumaddqihi4"
+(define_insn "*<any_extend:extend_su><any_extend2:extend_su>msubqihi4"
+ [(set (match_operand:HI 0 "register_operand" "=r")
+ (plus:HI (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "a"))
+ (any_extend2:HI (match_operand:QI 2 "register_operand" "a")))
+ (match_operand:HI 3 "register_operand" "0")))]
+ "AVR_HAVE_MUL
+ && reload_completed
+ && <any_extend:CODE> != <any_extend2:CODE>"
+ {
+ output_asm_insn (<any_extend:CODE> == SIGN_EXTEND
+ ? "mulsu %1,%2" : "mulsu %2,%1", operands);
+
+ return "add %A0,r0\;adc %B0,r1\;clr __zero_reg__";
+ }
+ [(set_attr "length" "4")
+ (set_attr "cc" "clobber")])
+
+;; "*usmsubqihi4"
+;; "*sumsubqihi4"
+(define_insn "*<any_extend:extend_su><any_extend2:extend_su>msubqihi4"
+ [(set (match_operand:HI 0 "register_operand" "=r")
+ (minus:HI (match_operand:HI 3 "register_operand" "0")
+ (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "a"))
+ (any_extend2:HI (match_operand:QI 2 "register_operand" "a")))))]
+ "AVR_HAVE_MUL
+ && reload_completed
+ && <any_extend:CODE> != <any_extend2:CODE>"
+ {
+ output_asm_insn (<any_extend:CODE> == SIGN_EXTEND
+ ? "mulsu %1,%2" : "mulsu %2,%1", operands);
+
+ return "sub %A0,r0\;sbc %B0,r1\;clr __zero_reg__";
+ }
+ [(set_attr "length" "4")
+ (set_attr "cc" "clobber")])
+
+;; Handle small constants
+
+;; "umaddqihi4.uconst"
+;; "maddqihi4.sconst"
+(define_insn_and_split "*<extend_u>maddqihi4.<extend_su>const"
+ [(set (match_operand:HI 0 "register_operand" "=r")
+ (plus:HI (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
+ (match_operand:HI 2 "<extend_su>8_operand" "n"))
+ (match_operand:HI 3 "register_operand" "0")))
+ (clobber (match_scratch:QI 4 "=&d"))]
+ "AVR_HAVE_MUL"
+ "#"
+ "&& reload_completed"
+ [(set (match_dup 4)
+ (match_dup 2))
+ ; *umaddqihi4 resp. *maddqihi4
+ (set (match_dup 0)
+ (plus:HI (mult:HI (any_extend:HI (match_dup 1))
+ (any_extend:HI (match_dup 4)))
+ (match_dup 3)))]
+ {
+ operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
+ })
+
+;; "*umsubqihi4.uconst"
+;; "*msubqihi4.sconst"
+(define_insn_and_split "*<extend_u>msubqihi4.<extend_su>const"
+ [(set (match_operand:HI 0 "register_operand" "=r")
+ (minus:HI (match_operand:HI 3 "register_operand" "0")
+ (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
+ (match_operand:HI 2 "<extend_su>8_operand" "n"))))
+ (clobber (match_scratch:QI 4 "=&d"))]
+ "AVR_HAVE_MUL"
+ "#"
+ "&& reload_completed"
+ [(set (match_dup 4)
+ (match_dup 2))
+ ; *umsubqihi4 resp. *msubqihi4
+ (set (match_dup 0)
+ (minus:HI (match_dup 3)
+ (mult:HI (any_extend:HI (match_dup 1))
+ (any_extend:HI (match_dup 4)))))]
+ {
+ operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
+ })
+
+;; Same as the insn above, but combiner tries versions canonicalized to ASHIFT
+;; for MULT with power of 2 and skips trying MULT insn above.
+
+(define_insn_and_split "*umsubqihi4.uconst.ashift"
+ [(set (match_operand:HI 0 "register_operand" "=r")
+ (minus:HI (match_operand:HI 3 "register_operand" "0")
+ (ashift:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))
+ (match_operand:HI 2 "const_2_to_7_operand" "n"))))
+ (clobber (match_scratch:QI 4 "=&d"))]
+ "AVR_HAVE_MUL"
+ "#"
+ "&& reload_completed"
+ [(set (match_dup 4)
+ (match_dup 2))
+ ; *umsubqihi4
+ (set (match_dup 0)
+ (minus:HI (match_dup 3)
+ (mult:HI (zero_extend:HI (match_dup 1))
+ (zero_extend:HI (match_dup 4)))))]
+ {
+ operands[2] = gen_int_mode (1 << INTVAL (operands[2]), QImode);
+ })
+
+;; Same as the insn above, but combiner tries versions canonicalized to ASHIFT
+;; for MULT with power of 2 and skips trying MULT insn above. We omit 128
+;; because this would require an extra pattern for just one value.
+
+(define_insn_and_split "*msubqihi4.sconst.ashift"
+ [(set (match_operand:HI 0 "register_operand" "=r")
+ (minus:HI (match_operand:HI 3 "register_operand" "0")
+ (ashift:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "d"))
+ (match_operand:HI 2 "const_1_to_6_operand" "M"))))
+ (clobber (match_scratch:QI 4 "=&d"))]
+ "AVR_HAVE_MUL"
+ "#"
+ "&& reload_completed"
+ [(set (match_dup 4)
+ (match_dup 2))
+ ; *smsubqihi4
+ (set (match_dup 0)
+ (minus:HI (match_dup 3)
+ (mult:HI (sign_extend:HI (match_dup 1))
+ (sign_extend:HI (match_dup 4)))))]
+ {
+ operands[2] = gen_int_mode (1 << INTVAL (operands[2]), QImode);
+ })
+
+;; For signed/unsigned combinations that require narrow constraint "a"
+;; just provide a pattern if signed/unsigned combination is actually needed.
+
+(define_insn_and_split "*sumaddqihi4.uconst"
+ [(set (match_operand:HI 0 "register_operand" "=r")
+ (plus:HI (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
+ (match_operand:HI 2 "u8_operand" "M"))
+ (match_operand:HI 3 "register_operand" "0")))
+ (clobber (match_scratch:QI 4 "=&a"))]
+ "AVR_HAVE_MUL
+ && !s8_operand (operands[2], VOIDmode)"
+ "#"
+ "&& reload_completed"
+ [(set (match_dup 4)
+ (match_dup 2))
+ ; *sumaddqihi4
+ (set (match_dup 0)
+ (plus:HI (mult:HI (sign_extend:HI (match_dup 1))
+ (zero_extend:HI (match_dup 4)))
+ (match_dup 3)))]
+ {
+ operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
+ })
+
+(define_insn_and_split "*sumsubqihi4.uconst"
+ [(set (match_operand:HI 0 "register_operand" "=r")
+ (minus:HI (match_operand:HI 3 "register_operand" "0")
+ (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
+ (match_operand:HI 2 "u8_operand" "M"))))
+ (clobber (match_scratch:QI 4 "=&a"))]
+ "AVR_HAVE_MUL
+ && !s8_operand (operands[2], VOIDmode)"
+ "#"
+ "&& reload_completed"
+ [(set (match_dup 4)
+ (match_dup 2))
+ ; *sumsubqihi4
+ (set (match_dup 0)
+ (minus:HI (match_dup 3)
+ (mult:HI (sign_extend:HI (match_dup 1))
+ (zero_extend:HI (match_dup 4)))))]
+ {
+ operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
+ })
+
+;******************************************************************************
+; mul HI: $1 = sign/zero-extend, $2 = small constant
+;******************************************************************************
+
+;; "*muluqihi3.uconst"
+;; "*mulsqihi3.sconst"
+(define_insn_and_split "*mul<extend_su>qihi3.<extend_su>const"
+ [(set (match_operand:HI 0 "register_operand" "=r")
+ (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
+ (match_operand:HI 2 "<extend_su>8_operand" "n")))
+ (clobber (match_scratch:QI 3 "=&d"))]
+ "AVR_HAVE_MUL"
+ "#"
+ "&& reload_completed"
+ [(set (match_dup 3)
+ (match_dup 2))
+ ; umulqihi3 resp. mulqihi3
+ (set (match_dup 0)
+ (mult:HI (any_extend:HI (match_dup 1))
+ (any_extend:HI (match_dup 3))))]
+ {
+ operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
+ })
+
+(define_insn_and_split "*muluqihi3.sconst"
+ [(set (match_operand:HI 0 "register_operand" "=r")
+ (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "a"))
+ (match_operand:HI 2 "s8_operand" "n")))
+ (clobber (match_scratch:QI 3 "=&a"))]
+ "AVR_HAVE_MUL"
+ "#"
+ "&& reload_completed"
+ [(set (match_dup 3)
+ (match_dup 2))
+ ; usmulqihi3
+ (set (match_dup 0)
+ (mult:HI (zero_extend:HI (match_dup 1))
+ (sign_extend:HI (match_dup 3))))]
+ {
+ operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
+ })
+
+(define_insn_and_split "*mulsqihi3.uconst"
+ [(set (match_operand:HI 0 "register_operand" "=r")
+ (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
+ (match_operand:HI 2 "u8_operand" "M")))
+ (clobber (match_scratch:QI 3 "=&a"))]
+ "AVR_HAVE_MUL"
+ "#"
+ "&& reload_completed"
+ [(set (match_dup 3)
+ (match_dup 2))
+ ; usmulqihi3
+ (set (match_dup 0)
+ (mult:HI (zero_extend:HI (match_dup 3))
+ (sign_extend:HI (match_dup 1))))]
+ {
+ operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
+ })
+
+(define_insn_and_split "*mulsqihi3.oconst"
+ [(set (match_operand:HI 0 "register_operand" "=&r")
+ (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
+ (match_operand:HI 2 "o8_operand" "n")))
+ (clobber (match_scratch:QI 3 "=&a"))]
+ "AVR_HAVE_MUL"
+ "#"
+ "&& reload_completed"
+ [(set (match_dup 3)
+ (match_dup 2))
+ ; *osmulqihi3
+ (set (match_dup 0)
+ (mult:HI (not:HI (zero_extend:HI (not:QI (match_dup 3))))
+ (sign_extend:HI (match_dup 1))))]
+ {
+ operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
+ })
+
+;; The EXTEND of $1 only appears in combine, we don't see it in expand so that
+;; expand decides to use ASHIFT instead of MUL because ASHIFT costs are cheaper
+;; at that time. Fix that.
+
+(define_insn "*ashiftqihi2.signx.1"
+ [(set (match_operand:HI 0 "register_operand" "=r,*r")
+ (ashift:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "0,r"))
+ (const_int 1)))]
+ ""
+ "@
+ lsl %A0\;sbc %B0,%B0
+ mov %A0,%1\;lsl %A0\;sbc %B0,%B0"
+ [(set_attr "length" "2,3")
+ (set_attr "cc" "clobber")])
+
+(define_insn_and_split "*ashifthi3.signx.const"
+ [(set (match_operand:HI 0 "register_operand" "=r")
+ (ashift:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "d"))
+ (match_operand:HI 2 "const_2_to_6_operand" "I")))
+ (clobber (match_scratch:QI 3 "=&d"))]
+ "AVR_HAVE_MUL"
+ "#"
+ "&& reload_completed"
+ [(set (match_dup 3)
+ (match_dup 2))
+ ; mulqihi3
+ (set (match_dup 0)
+ (mult:HI (sign_extend:HI (match_dup 1))
+ (sign_extend:HI (match_dup 3))))]
+ {
+ operands[2] = GEN_INT (1 << INTVAL (operands[2]));
+ })
+
+(define_insn_and_split "*ashifthi3.signx.const7"
+ [(set (match_operand:HI 0 "register_operand" "=r")
+ (ashift:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
+ (const_int 7)))
+ (clobber (match_scratch:QI 2 "=&a"))]
+ "AVR_HAVE_MUL"
+ "#"
+ "&& reload_completed"
+ [(set (match_dup 2)
+ (match_dup 3))
+ ; usmulqihi3
+ (set (match_dup 0)
+ (mult:HI (zero_extend:HI (match_dup 2))
+ (sign_extend:HI (match_dup 1))))]
+ {
+ operands[3] = gen_int_mode (1 << 7, QImode);
+ })
+
+(define_insn_and_split "*ashifthi3.zerox.const"
+ [(set (match_operand:HI 0 "register_operand" "=r")
+ (ashift:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))
+ (match_operand:HI 2 "const_2_to_7_operand" "I")))
+ (clobber (match_scratch:QI 3 "=&d"))]
+ "AVR_HAVE_MUL"
+ "#"
+ "&& reload_completed"
+ [(set (match_dup 3)
+ (match_dup 2))
+ ; umulqihi3
+ (set (match_dup 0)
+ (mult:HI (zero_extend:HI (match_dup 1))
+ (zero_extend:HI (match_dup 3))))]
+ {
+ operands[2] = gen_int_mode (1 << INTVAL (operands[2]), QImode);
+ })
+
+;******************************************************************************
+; mul HI: $1 = sign-/zero-/one-extend, $2 = reg
+;******************************************************************************
+
+(define_insn "mulsqihi3"
+ [(set (match_operand:HI 0 "register_operand" "=&r")
+ (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
+ (match_operand:HI 2 "register_operand" "a")))]
+ "AVR_HAVE_MUL"
+ "mulsu %1,%A2
+ movw %0,r0
+ mul %1,%B2
+ add %B0,r0
+ clr __zero_reg__"
+ [(set_attr "length" "5")
+ (set_attr "cc" "clobber")])
+
+(define_insn "muluqihi3"
+ [(set (match_operand:HI 0 "register_operand" "=&r")
+ (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))
+ (match_operand:HI 2 "register_operand" "r")))]