Index: config/avr/avr.md =================================================================== --- config/avr/avr.md (revision 179181) +++ config/avr/avr.md (working copy) @@ -136,8 +136,12 @@ (define_attr "length" "" ;; Otherwise do special processing depending on the attribute. (define_attr "adjust_len" - "yes,no,reload_in16,reload_in32,out_bitop,out_plus,tsthi,tstsi,compare" - (const_string "yes")) + "no, out_bitop, out_plus, tsthi, tstsi, compare, + mov8, mov16, mov32, reload_in16, reload_in32, + ashlqi, ashrqi, lshrqi, + ashlhi, ashrhi, lshrhi, + ashlsi, ashrsi, lshrsi" + (const_string "no")) ;; Define mode iterators (define_mode_iterator QIHI [(QI "") (HI "")]) @@ -297,6 +301,7 @@ (define_insn "*movqi" || register_operand (operands[1], QImode) || const0_rtx == operands[1])" "* return output_movqi (insn, operands, NULL);" [(set_attr "length" "1,1,5,5,1,1,4") + (set_attr "adjust_len" "mov8") (set_attr "cc" "none,none,clobber,clobber,none,none,clobber")]) ;; This is used in peephole2 to optimize loading immediate constants @@ -401,6 +406,7 @@ (define_insn "*movhi" || register_operand (operands[1],HImode) || const0_rtx == operands[1])" "* return output_movhi (insn, operands, NULL);" [(set_attr "length" "2,2,6,7,2,6,5,2") + (set_attr "adjust_len" "mov16") (set_attr "cc" "none,clobber,clobber,clobber,none,clobber,none,none")]) (define_peephole2 ; movw @@ -468,7 +474,7 @@ (define_insn "*reload_insi" (clobber (match_operand:QI 2 "register_operand" "=&d"))] "reload_completed" { - return output_reload_insisf (insn, operands, operands[2], NULL); + return output_reload_insisf (operands, operands[2], NULL); } [(set_attr "length" "8") (set_attr "adjust_len" "reload_in32") @@ -484,6 +490,7 @@ (define_insn "*movsi" return output_movsisf (insn, operands, NULL); } [(set_attr "length" "4,4,8,9,4,10") + (set_attr "adjust_len" "mov32") (set_attr "cc" "none,set_zn,clobber,clobber,clobber,clobber")]) ;; fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff @@ -513,6 +520,7 @@ (define_insn "*movsf" return output_movsisf (insn, operands, NULL); } [(set_attr "length" "4,4,8,9,4,10") + (set_attr "adjust_len" "mov32") (set_attr "cc" "none,set_zn,clobber,clobber,clobber,clobber")]) (define_peephole2 ; *reload_insf @@ -533,7 +541,7 @@ (define_insn "*reload_insf" (clobber (match_operand:QI 2 "register_operand" "=&d"))] "reload_completed" { - return output_reload_insisf (insn, operands, operands[2], NULL); + return output_reload_insisf (operands, operands[2], NULL); } [(set_attr "length" "8") (set_attr "adjust_len" "reload_in32") @@ -934,7 +942,7 @@ (define_insn "addsi3" return asm_code [which_alternative]; } [(set_attr "length" "4,3,3,4,5,5,8,8") - (set_attr "adjust_len" "no,no,no,no,no,no,out_plus,out_plus") + (set_attr "adjust_len" "*,*,*,*,*,*,out_plus,out_plus") (set_attr "cc" "set_n,set_n,set_czn,set_czn,set_n,set_n,clobber,clobber")]) (define_insn "*addsi3_zero_extend" @@ -2271,7 +2279,7 @@ (define_insn "andhi3" return avr_out_bitop (insn, operands, NULL); } [(set_attr "length" "2,2,2,4,4") - (set_attr "adjust_len" "no,no,out_bitop,out_bitop,out_bitop") + (set_attr "adjust_len" "*,*,out_bitop,out_bitop,out_bitop") (set_attr "cc" "set_n,set_n,clobber,clobber,clobber")]) (define_insn "andsi3" @@ -2290,7 +2298,7 @@ (define_insn "andsi3" return avr_out_bitop (insn, operands, NULL); } [(set_attr "length" "4,4,8,8") - (set_attr "adjust_len" "no,out_bitop,out_bitop,out_bitop") + (set_attr "adjust_len" "*,out_bitop,out_bitop,out_bitop") (set_attr "cc" "set_n,clobber,clobber,clobber")]) (define_peephole2 ; andi @@ -2335,7 +2343,7 @@ (define_insn "iorhi3" return avr_out_bitop (insn, operands, NULL); } [(set_attr "length" "2,2,2,4,4") - (set_attr "adjust_len" "no,no,out_bitop,out_bitop,out_bitop") + (set_attr "adjust_len" "*,*,out_bitop,out_bitop,out_bitop") (set_attr "cc" "set_n,set_n,clobber,clobber,clobber")]) (define_insn "iorsi3" @@ -2354,7 +2362,7 @@ (define_insn "iorsi3" return avr_out_bitop (insn, operands, NULL); } [(set_attr "length" "4,4,8,8") - (set_attr "adjust_len" "no,out_bitop,out_bitop,out_bitop") + (set_attr "adjust_len" "*,out_bitop,out_bitop,out_bitop") (set_attr "cc" "set_n,clobber,clobber,clobber")]) ;;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -2382,7 +2390,7 @@ (define_insn "xorhi3" return avr_out_bitop (insn, operands, NULL); } [(set_attr "length" "2,2,4") - (set_attr "adjust_len" "no,out_bitop,out_bitop") + (set_attr "adjust_len" "*,out_bitop,out_bitop") (set_attr "cc" "set_n,clobber,clobber")]) (define_insn "xorsi3" @@ -2401,7 +2409,7 @@ (define_insn "xorsi3" return avr_out_bitop (insn, operands, NULL); } [(set_attr "length" "4,8,8") - (set_attr "adjust_len" "no,out_bitop,out_bitop") + (set_attr "adjust_len" "*,out_bitop,out_bitop") (set_attr "cc" "set_n,clobber,clobber")]) ;; swap swap swap swap swap swap swap swap swap swap swap swap swap swap swap @@ -2623,6 +2631,7 @@ (define_insn "*ashlqi3" "" "* return ashlqi3_out (insn, operands, NULL);" [(set_attr "length" "5,0,1,2,4,6,9") + (set_attr "adjust_len" "ashlqi") (set_attr "cc" "clobber,none,set_czn,set_czn,set_czn,set_czn,clobber")]) (define_insn "ashlhi3" @@ -2632,6 +2641,7 @@ (define_insn "ashlhi3" "" "* return ashlhi3_out (insn, operands, NULL);" [(set_attr "length" "6,0,2,2,4,10,10") + (set_attr "adjust_len" "ashlhi") (set_attr "cc" "clobber,none,set_n,clobber,set_n,clobber,clobber")]) @@ -2723,6 +2733,7 @@ (define_insn "ashlsi3" "" "* return ashlsi3_out (insn, operands, NULL);" [(set_attr "length" "8,0,4,4,8,10,12") + (set_attr "adjust_len" "ashlsi") (set_attr "cc" "clobber,none,set_n,clobber,set_n,clobber,clobber")]) ;; Optimize if a scratch register from LD_REGS happens to be available. @@ -2780,6 +2791,7 @@ (define_insn "*ashlhi3_const" "reload_completed" "* return ashlhi3_out (insn, operands, NULL);" [(set_attr "length" "0,2,2,4,10") + (set_attr "adjust_len" "ashlhi") (set_attr "cc" "none,set_n,clobber,set_n,clobber")]) (define_peephole2 @@ -2800,6 +2812,7 @@ (define_insn "*ashlsi3_const" "reload_completed" "* return ashlsi3_out (insn, operands, NULL);" [(set_attr "length" "0,4,4,10") + (set_attr "adjust_len" "ashlsi") (set_attr "cc" "none,set_n,clobber,clobber")]) ;; >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> @@ -2812,6 +2825,7 @@ (define_insn "ashrqi3" "" "* return ashrqi3_out (insn, operands, NULL);" [(set_attr "length" "5,0,1,2,5,9") + (set_attr "adjust_len" "ashrqi") (set_attr "cc" "clobber,none,clobber,clobber,clobber,clobber")]) (define_insn "ashrhi3" @@ -2821,6 +2835,7 @@ (define_insn "ashrhi3" "" "* return ashrhi3_out (insn, operands, NULL);" [(set_attr "length" "6,0,2,4,4,10,10") + (set_attr "adjust_len" "ashrhi") (set_attr "cc" "clobber,none,clobber,set_n,clobber,clobber,clobber")]) (define_insn "ashrsi3" @@ -2830,6 +2845,7 @@ (define_insn "ashrsi3" "" "* return ashrsi3_out (insn, operands, NULL);" [(set_attr "length" "8,0,4,6,8,10,12") + (set_attr "adjust_len" "ashrsi") (set_attr "cc" "clobber,none,clobber,set_n,clobber,clobber,clobber")]) ;; Optimize if a scratch register from LD_REGS happens to be available. @@ -2852,6 +2868,7 @@ (define_insn "*ashrhi3_const" "reload_completed" "* return ashrhi3_out (insn, operands, NULL);" [(set_attr "length" "0,2,4,4,10") + (set_attr "adjust_len" "ashrhi") (set_attr "cc" "none,clobber,set_n,clobber,clobber")]) (define_peephole2 @@ -2872,6 +2889,7 @@ (define_insn "*ashrsi3_const" "reload_completed" "* return ashrsi3_out (insn, operands, NULL);" [(set_attr "length" "0,4,4,10") + (set_attr "adjust_len" "ashrsi") (set_attr "cc" "none,clobber,set_n,clobber")]) ;; >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> @@ -2920,6 +2938,7 @@ (define_insn "*lshrqi3" "" "* return lshrqi3_out (insn, operands, NULL);" [(set_attr "length" "5,0,1,2,4,6,9") + (set_attr "adjust_len" "lshrqi") (set_attr "cc" "clobber,none,set_czn,set_czn,set_czn,set_czn,clobber")]) (define_insn "lshrhi3" @@ -2929,6 +2948,7 @@ (define_insn "lshrhi3" "" "* return lshrhi3_out (insn, operands, NULL);" [(set_attr "length" "6,0,2,2,4,10,10") + (set_attr "adjust_len" "lshrhi") (set_attr "cc" "clobber,none,clobber,clobber,clobber,clobber,clobber")]) (define_insn "lshrsi3" @@ -2938,6 +2958,7 @@ (define_insn "lshrsi3" "" "* return lshrsi3_out (insn, operands, NULL);" [(set_attr "length" "8,0,4,4,8,10,12") + (set_attr "adjust_len" "lshrsi") (set_attr "cc" "clobber,none,clobber,clobber,clobber,clobber,clobber")]) ;; Optimize if a scratch register from LD_REGS happens to be available. @@ -2995,6 +3016,7 @@ (define_insn "*lshrhi3_const" "reload_completed" "* return lshrhi3_out (insn, operands, NULL);" [(set_attr "length" "0,2,2,4,10") + (set_attr "adjust_len" "lshrhi") (set_attr "cc" "none,clobber,clobber,clobber,clobber")]) (define_peephole2 @@ -3015,6 +3037,7 @@ (define_insn "*lshrsi3_const" "reload_completed" "* return lshrsi3_out (insn, operands, NULL);" [(set_attr "length" "0,4,4,10") + (set_attr "adjust_len" "lshrsi") (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) @@ -3383,7 +3406,7 @@ (define_insn "*cmphi" } [(set_attr "cc" "compare") (set_attr "length" "1,2,2,3,4,2,4") - (set_attr "adjust_len" "tsthi,tsthi,no,no,no,compare,compare")]) + (set_attr "adjust_len" "tsthi,tsthi,*,*,*,compare,compare")]) (define_insn "*cmpsi" @@ -3402,7 +3425,7 @@ (define_insn "*cmpsi" } [(set_attr "cc" "compare") (set_attr "length" "4,4,4,5,8") - (set_attr "adjust_len" "tstsi,no,compare,compare,compare")]) + (set_attr "adjust_len" "tstsi,*,compare,compare,compare")]) ;; ---------------------------------------------------------------------- Index: config/avr/avr-protos.h =================================================================== --- config/avr/avr-protos.h (revision 179181) +++ config/avr/avr-protos.h (working copy) @@ -88,7 +88,7 @@ extern bool avr_popcount_each_byte (rtx, extern int extra_constraint_Q (rtx x); extern int adjust_insn_length (rtx insn, int len); extern const char* output_reload_inhi (rtx*, rtx, int*); -extern const char *output_reload_insisf (rtx insn, rtx *operands, rtx clobber, int *len); +extern const char* output_reload_insisf (rtx*, rtx, int*); extern void notice_update_cc (rtx body, rtx insn); extern void print_operand (FILE *file, rtx x, int code); extern void print_operand_address (FILE *file, rtx addr); Index: config/avr/avr.c =================================================================== --- config/avr/avr.c (revision 179181) +++ config/avr/avr.c (working copy) @@ -2691,7 +2691,7 @@ output_movsisf (rtx insn, rtx operands[] else if (CONST_INT_P (src) || CONST_DOUBLE_P (src)) { - return output_reload_insisf (insn, operands, NULL_RTX, real_l); + return output_reload_insisf (operands, NULL_RTX, real_l); } else if (CONSTANT_P (src)) { @@ -5019,7 +5019,7 @@ avr_rotate_bytes (rtx operands[]) int adjust_insn_length (rtx insn, int len) { - rtx patt, set; + rtx *op = recog_data.operand; enum attr_adjust_len adjust_len; /* Some complex insns don't need length adjustment and therefore @@ -5036,131 +5036,53 @@ adjust_insn_length (rtx insn, int len) adjust_len = get_attr_adjust_len (insn); - if (adjust_len != ADJUST_LEN_YES) + if (adjust_len == ADJUST_LEN_NO) { - rtx *op = recog_data.operand; - - if (adjust_len == ADJUST_LEN_NO) - { - /* Nothing to adjust: The length from attribute "length" is fine. */ - - return len; - } - - /* Extract insn's operands. */ - - extract_constrain_insn_cached (insn); - - /* Dispatch to right function. */ - - switch (adjust_len) - { - case ADJUST_LEN_RELOAD_IN16: - output_reload_inhi (op, op[2], &len); - break; - - case ADJUST_LEN_RELOAD_IN32: - output_reload_insisf (insn, op, op[2], &len); - break; - - case ADJUST_LEN_OUT_BITOP: - avr_out_bitop (insn, op, &len); - break; - - case ADJUST_LEN_OUT_PLUS: - avr_out_plus (op, &len); - break; - - case ADJUST_LEN_TSTHI: avr_out_tsthi (insn, op, &len); break; - case ADJUST_LEN_TSTSI: avr_out_tstsi (insn, op, &len); break; - case ADJUST_LEN_COMPARE: avr_out_compare (insn, op, &len); break; - - default: - gcc_unreachable(); - } + /* Nothing to adjust: The length from attribute "length" is fine. + This is the default. */ return len; - } /* adjust_length != ADJUST_LEN_YES */ - - /* adjust_len == "yes": Analyse insn by hand. */ - - patt = PATTERN (insn); - - if (GET_CODE (patt) == SET) - { - rtx op[10]; - op[1] = SET_SRC (patt); - op[0] = SET_DEST (patt); - if (general_operand (op[1], VOIDmode) - && general_operand (op[0], VOIDmode)) - { - switch (GET_MODE (op[0])) - { - case QImode: - output_movqi (insn, op, &len); - break; - case HImode: - output_movhi (insn, op, &len); - break; - case SImode: - case SFmode: - output_movsisf (insn, op, &len); - break; - default: - break; - } - } } - set = single_set (insn); - if (set) + + /* Extract insn's operands. */ + + extract_constrain_insn_cached (insn); + + /* Dispatch to right function. */ + + switch (adjust_len) { - rtx op[10]; - - op[1] = SET_SRC (set); - op[0] = SET_DEST (set); - - if (GET_CODE (op[1]) == ASHIFT - || GET_CODE (op[1]) == ASHIFTRT - || GET_CODE (op[1]) == LSHIFTRT) - { - rtx ops[10]; - ops[0] = op[0]; - ops[1] = XEXP (op[1],0); - ops[2] = XEXP (op[1],1); - switch (GET_CODE (op[1])) - { - case ASHIFT: - switch (GET_MODE (op[0])) - { - case QImode: ashlqi3_out (insn,ops,&len); break; - case HImode: ashlhi3_out (insn,ops,&len); break; - case SImode: ashlsi3_out (insn,ops,&len); break; - default: break; - } - break; - case ASHIFTRT: - switch (GET_MODE (op[0])) - { - case QImode: ashrqi3_out (insn,ops,&len); break; - case HImode: ashrhi3_out (insn,ops,&len); break; - case SImode: ashrsi3_out (insn,ops,&len); break; - default: break; - } - break; - case LSHIFTRT: - switch (GET_MODE (op[0])) - { - case QImode: lshrqi3_out (insn,ops,&len); break; - case HImode: lshrhi3_out (insn,ops,&len); break; - case SImode: lshrsi3_out (insn,ops,&len); break; - default: break; - } - break; - default: - break; - } - } + case ADJUST_LEN_RELOAD_IN16: output_reload_inhi (op, op[2], &len); break; + case ADJUST_LEN_RELOAD_IN32: output_reload_insisf (op, op[2], &len); break; + + case ADJUST_LEN_OUT_BITOP: avr_out_bitop (insn, op, &len); break; + + case ADJUST_LEN_OUT_PLUS: avr_out_plus (op, &len); break; + + case ADJUST_LEN_MOV8: output_movqi (insn, op, &len); break; + case ADJUST_LEN_MOV16: output_movhi (insn, op, &len); break; + case ADJUST_LEN_MOV32: output_movsisf (insn, op, &len); break; + + case ADJUST_LEN_TSTHI: avr_out_tsthi (insn, op, &len); break; + case ADJUST_LEN_TSTSI: avr_out_tstsi (insn, op, &len); break; + case ADJUST_LEN_COMPARE: avr_out_compare (insn, op, &len); break; + + case ADJUST_LEN_LSHRQI: lshrqi3_out (insn, op, &len); break; + case ADJUST_LEN_LSHRHI: lshrhi3_out (insn, op, &len); break; + case ADJUST_LEN_LSHRSI: lshrsi3_out (insn, op, &len); break; + + case ADJUST_LEN_ASHRQI: ashrqi3_out (insn, op, &len); break; + case ADJUST_LEN_ASHRHI: ashrhi3_out (insn, op, &len); break; + case ADJUST_LEN_ASHRSI: ashrsi3_out (insn, op, &len); break; + + case ADJUST_LEN_ASHLQI: ashlqi3_out (insn, op, &len); break; + case ADJUST_LEN_ASHLHI: ashlhi3_out (insn, op, &len); break; + case ADJUST_LEN_ASHLSI: ashlsi3_out (insn, op, &len); break; + + default: + gcc_unreachable(); } + return len; } @@ -7064,7 +6986,7 @@ avr_hard_regno_mode_ok (int regno, enum } -/* A helper for `output_reload_insisf'. */ +/* A helper for `output_reload_insisf' and `output_reload_inhi'. */ /* Set 32-bit register OP[0] to compile-time constant OP[1]. CLOBBER_REG is a QI clobber register or NULL_RTX. LEN == NULL: output instructions. @@ -7329,8 +7251,7 @@ output_reload_inhi (rtx *op, rtx clobber Return "". */ const char * -output_reload_insisf (rtx insn ATTRIBUTE_UNUSED, - rtx *op, rtx clobber_reg, int *len) +output_reload_insisf (rtx *op, rtx clobber_reg, int *len) { gcc_assert (REG_P (op[0]) && CONSTANT_P (op[1]));