Index: avr.md =================================================================== --- avr.md (revision 143753) +++ avr.md (working copy) @@ -3262,3 +3262,61 @@ expand_epilogue (); DONE; }") + + + +;; Fix for #27663 +;; http://gcc.gnu.org/bugzilla/show_bug.cgi?id=27663 +(define_insn_and_split "*iorsi3_ashiftsi_zeroxqisi" + [(set (match_operand:SI 0 "register_operand" "=r") + (ior:SI (ashift:SI (zero_extend:SI (match_operand:QI 1 "register_operand" "r")) + (match_operand:QI 2 "const_int_operand" "O")) + (match_operand:SI 3 "register_operand" "0")))] + "satisfies_constraint_O(operands[2])" + "#" + "&& reload_completed" + [(set (match_dup 4) + (ior:QI (match_dup 5) + (match_dup 1)))] + { + operands[4] = simplify_gen_subreg (QImode, operands[0], SImode, INTVAL(operands[2]) >> 3); + operands[5] = simplify_gen_subreg (QImode, operands[3], SImode, INTVAL(operands[2]) >> 3); + }) + +;; #27663 +;; same as above for offset 0, i.e. no shift needed +(define_insn_and_split "*iorsi3_zeroxqisi" + [(set (match_operand:SI 0 "register_operand" "=r") + (ior:SI (zero_extend:SI (match_operand:QI 1 "register_operand" "r")) + (match_operand:SI 2 "register_operand" "0")))] + "1" + "#" + "&& reload_completed" + [(set (match_dup 3) + (ior:QI (match_dup 4) + (match_dup 1)))] + { + operands[3] = simplify_gen_subreg (QImode, operands[0], SImode, 0); + operands[4] = simplify_gen_subreg (QImode, operands[2], SImode, 0); + }) + +;; #27663 +;; same as "*iorsi3_ashiftsi_zeroxqisi" without IOR +(define_insn_and_split "*ashiftsi_zeroxqisi" + [(set (match_operand:SI 0 "register_operand" "=r") + (ashift:SI (zero_extend:SI (match_operand:QI 1 "register_operand" "r")) + (match_operand:QI 2 "const_int_operand" "O")))] + "satisfies_constraint_O(operands[2])" + "#" + "&& reload_completed" + [(set (match_dup 3) (match_dup 1)) + (set (match_dup 4) (const_int 0)) + (set (match_dup 5) (const_int 0)) + (set (match_dup 6) (const_int 0))] + { + int off = INTVAL (operands[2]) >> 3; + operands[3] = simplify_gen_subreg (QImode, operands[0], SImode, off); + operands[4] = simplify_gen_subreg (QImode, operands[0], SImode, (off+1) % 4); + operands[5] = simplify_gen_subreg (QImode, operands[0], SImode, (off+2) % 4); + operands[6] = simplify_gen_subreg (QImode, operands[0], SImode, (off+3) % 4); + })