diff options
author | Georg-Johann Lay <avr@gjlay.de> | 2011-10-05 11:16:10 +0000 |
---|---|---|
committer | Georg-Johann Lay <gjl@gcc.gnu.org> | 2011-10-05 11:16:10 +0000 |
commit | 180ee6d101f95274336595fe66d9a2935f8e5c57 (patch) | |
tree | 328703969c841c2bbf25b1c9df7a051801ebcf82 /gcc | |
parent | d3878abfccb6f6b9235bdf084f28ebe6cc1cc490 (diff) | |
download | gcc-180ee6d101f95274336595fe66d9a2935f8e5c57.zip gcc-180ee6d101f95274336595fe66d9a2935f8e5c57.tar.gz gcc-180ee6d101f95274336595fe66d9a2935f8e5c57.tar.bz2 |
avr-protos.h (avr_out_addto_sp): New prototype.
* config/avr/avr-protos.h (avr_out_addto_sp): New prototype.
* config/avr/avr.c (avr_out_addto_sp): New function.
(adjust_insn_length): Handle ADJUST_LEN_ADDTO_SP.
* config/avr/avr.md (adjust_len): Add "addto_sp".
(*movhi_sp): Remove insn.
(*addhi3_sp_R_pc2, *addhi3_sp_R_pc3): Merge to *addhi3_sp_R.
From-SVN: r179544
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/config/avr/avr-protos.h | 1 | ||||
-rw-r--r-- | gcc/config/avr/avr.c | 43 | ||||
-rw-r--r-- | gcc/config/avr/avr.md | 151 |
4 files changed, 61 insertions, 143 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index da53b38..96cac67 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2011-10-05 Georg-Johann Lay <avr@gjlay.de> + + * config/avr/avr-protos.h (avr_out_addto_sp): New prototype. + * config/avr/avr.c (avr_out_addto_sp): New function. + (adjust_insn_length): Handle ADJUST_LEN_ADDTO_SP. + * config/avr/avr.md (adjust_len): Add "addto_sp". + (*movhi_sp): Remove insn. + (*addhi3_sp_R_pc2, *addhi3_sp_R_pc3): Merge to *addhi3_sp_R. + 2011-10-05 Richard Guenther <rguenther@suse.de> * gimple-fold.c (gimple_fold_stmt_to_constant_1): For diff --git a/gcc/config/avr/avr-protos.h b/gcc/config/avr/avr-protos.h index 7ad0f1c..a2a5dd0 100644 --- a/gcc/config/avr/avr-protos.h +++ b/gcc/config/avr/avr-protos.h @@ -83,6 +83,7 @@ extern void avr_output_addr_vec_elt (FILE *stream, int value); extern const char *avr_out_sbxx_branch (rtx insn, rtx operands[]); extern const char* avr_out_bitop (rtx, rtx*, int*); extern const char* avr_out_plus (rtx*, int*); +extern const char* avr_out_addto_sp (rtx*, int*); extern bool avr_popcount_each_byte (rtx, int, int); extern int extra_constraint_Q (rtx x); diff --git a/gcc/config/avr/avr.c b/gcc/config/avr/avr.c index e6cb214..c28b593a8 100644 --- a/gcc/config/avr/avr.c +++ b/gcc/config/avr/avr.c @@ -4961,6 +4961,47 @@ avr_out_bitop (rtx insn, rtx *xop, int *plen) return ""; } + +/* PLEN == NULL: Output code to add CONST_INT OP[0] to SP. + PLEN != NULL: Set *PLEN to the length of that sequence. + Return "". */ + +const char* +avr_out_addto_sp (rtx *op, int *plen) +{ + int pc_len = AVR_2_BYTE_PC ? 2 : 3; + int addend = INTVAL (op[0]); + + if (plen) + *plen = 0; + + if (addend < 0) + { + if (flag_verbose_asm || flag_print_asm_name) + avr_asm_len (ASM_COMMENT_START "SP -= %n0", op, plen, 0); + + while (addend <= -pc_len) + { + addend += pc_len; + avr_asm_len ("rcall .", op, plen, 1); + } + + while (addend++ < 0) + avr_asm_len ("push __zero_reg__", op, plen, 1); + } + else if (addend > 0) + { + if (flag_verbose_asm || flag_print_asm_name) + avr_asm_len (ASM_COMMENT_START "SP += %0", op, plen, 0); + + while (addend-- > 0) + avr_asm_len ("pop __tmp_reg__", op, plen, 1); + } + + return ""; +} + + /* Create RTL split patterns for byte sized rotate expressions. This produces a series of move instructions and considers overlap situations. Overlapping non-HImode operands need a scratch register. */ @@ -5154,6 +5195,8 @@ adjust_insn_length (rtx insn, int len) 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_ADDTO_SP: avr_out_addto_sp (op, &len); break; case ADJUST_LEN_MOV8: output_movqi (insn, op, &len); break; case ADJUST_LEN_MOV16: output_movhi (insn, op, &len); break; diff --git a/gcc/config/avr/avr.md b/gcc/config/avr/avr.md index 3b1800d..f1ac95d 100644 --- a/gcc/config/avr/avr.md +++ b/gcc/config/avr/avr.md @@ -136,7 +136,7 @@ ;; Otherwise do special processing depending on the attribute. (define_attr "adjust_len" - "out_bitop, out_plus, tsthi, tstsi, compare, + "out_bitop, out_plus, addto_sp, tsthi, tstsi, compare, mov8, mov16, mov32, reload_in16, reload_in32, ashlqi, ashrqi, lshrqi, ashlhi, ashrhi, lshrhi, @@ -346,15 +346,6 @@ } }") -(define_insn "*movhi_sp" - [(set (match_operand:HI 0 "register_operand" "=q,r") - (match_operand:HI 1 "register_operand" "r,q"))] - "((stack_register_operand(operands[0], HImode) && register_operand (operands[1], HImode)) - || (register_operand (operands[0], HImode) && stack_register_operand(operands[1], HImode)))" - "* return output_movhi (insn, operands, NULL);" - [(set_attr "length" "5,2") - (set_attr "cc" "none,none")]) - (define_insn "movhi_sp_r_irq_off" [(set (match_operand:HI 0 "stack_register_operand" "=q") (unspec_volatile:HI [(match_operand:HI 1 "register_operand" "r")] @@ -767,142 +758,16 @@ [(set_attr "length" "2") (set_attr "cc" "set_n")]) -(define_insn "*addhi3_sp_R_pc2" +(define_insn "*addhi3_sp_R" [(set (match_operand:HI 1 "stack_register_operand" "=q") (plus:HI (match_operand:HI 2 "stack_register_operand" "q") (match_operand:HI 0 "avr_sp_immediate_operand" "R")))] - "AVR_2_BYTE_PC" - "*{ - if (CONST_INT_P (operands[0])) - { - switch(INTVAL (operands[0])) - { - case -6: - return \"rcall .\" CR_TAB - \"rcall .\" CR_TAB - \"rcall .\"; - case -5: - return \"rcall .\" CR_TAB - \"rcall .\" CR_TAB - \"push __tmp_reg__\"; - case -4: - return \"rcall .\" CR_TAB - \"rcall .\"; - case -3: - return \"rcall .\" CR_TAB - \"push __tmp_reg__\"; - case -2: - return \"rcall .\"; - case -1: - return \"push __tmp_reg__\"; - case 0: - return \"\"; - case 1: - return \"pop __tmp_reg__\"; - case 2: - return \"pop __tmp_reg__\" CR_TAB - \"pop __tmp_reg__\"; - case 3: - return \"pop __tmp_reg__\" CR_TAB - \"pop __tmp_reg__\" CR_TAB - \"pop __tmp_reg__\"; - case 4: - return \"pop __tmp_reg__\" CR_TAB - \"pop __tmp_reg__\" CR_TAB - \"pop __tmp_reg__\" CR_TAB - \"pop __tmp_reg__\"; - case 5: - return \"pop __tmp_reg__\" CR_TAB - \"pop __tmp_reg__\" CR_TAB - \"pop __tmp_reg__\" CR_TAB - \"pop __tmp_reg__\" CR_TAB - \"pop __tmp_reg__\"; - } - } - return \"bug\"; - }" - [(set (attr "length") - (cond [(eq (const_int -6) (symbol_ref "INTVAL (operands[0])")) (const_int 3) - (eq (const_int -5) (symbol_ref "INTVAL (operands[0])")) (const_int 3) - (eq (const_int -4) (symbol_ref "INTVAL (operands[0])")) (const_int 2) - (eq (const_int -3) (symbol_ref "INTVAL (operands[0])")) (const_int 2) - (eq (const_int -2) (symbol_ref "INTVAL (operands[0])")) (const_int 1) - (eq (const_int -1) (symbol_ref "INTVAL (operands[0])")) (const_int 1) - (eq (const_int 0) (symbol_ref "INTVAL (operands[0])")) (const_int 0) - (eq (const_int 1) (symbol_ref "INTVAL (operands[0])")) (const_int 1) - (eq (const_int 2) (symbol_ref "INTVAL (operands[0])")) (const_int 2) - (eq (const_int 3) (symbol_ref "INTVAL (operands[0])")) (const_int 3) - (eq (const_int 4) (symbol_ref "INTVAL (operands[0])")) (const_int 4) - (eq (const_int 5) (symbol_ref "INTVAL (operands[0])")) (const_int 5)] - (const_int 0)))]) - -(define_insn "*addhi3_sp_R_pc3" - [(set (match_operand:HI 1 "stack_register_operand" "=q") - (plus:HI (match_operand:HI 2 "stack_register_operand" "q") - (match_operand:QI 0 "avr_sp_immediate_operand" "R")))] - "AVR_3_BYTE_PC" - "*{ - if (CONST_INT_P (operands[0])) - { - switch(INTVAL (operands[0])) - { - case -6: - return \"rcall .\" CR_TAB - \"rcall .\"; - case -5: - return \"rcall .\" CR_TAB - \"push __tmp_reg__\" CR_TAB - \"push __tmp_reg__\"; - case -4: - return \"rcall .\" CR_TAB - \"push __tmp_reg__\"; - case -3: - return \"rcall .\"; - case -2: - return \"push __tmp_reg__\" CR_TAB - \"push __tmp_reg__\"; - case -1: - return \"push __tmp_reg__\"; - case 0: - return \"\"; - case 1: - return \"pop __tmp_reg__\"; - case 2: - return \"pop __tmp_reg__\" CR_TAB - \"pop __tmp_reg__\"; - case 3: - return \"pop __tmp_reg__\" CR_TAB - \"pop __tmp_reg__\" CR_TAB - \"pop __tmp_reg__\"; - case 4: - return \"pop __tmp_reg__\" CR_TAB - \"pop __tmp_reg__\" CR_TAB - \"pop __tmp_reg__\" CR_TAB - \"pop __tmp_reg__\"; - case 5: - return \"pop __tmp_reg__\" CR_TAB - \"pop __tmp_reg__\" CR_TAB - \"pop __tmp_reg__\" CR_TAB - \"pop __tmp_reg__\" CR_TAB - \"pop __tmp_reg__\"; - } - } - return \"bug\"; - }" - [(set (attr "length") - (cond [(eq (const_int -6) (symbol_ref "INTVAL (operands[0])")) (const_int 2) - (eq (const_int -5) (symbol_ref "INTVAL (operands[0])")) (const_int 3) - (eq (const_int -4) (symbol_ref "INTVAL (operands[0])")) (const_int 2) - (eq (const_int -3) (symbol_ref "INTVAL (operands[0])")) (const_int 1) - (eq (const_int -2) (symbol_ref "INTVAL (operands[0])")) (const_int 2) - (eq (const_int -1) (symbol_ref "INTVAL (operands[0])")) (const_int 1) - (eq (const_int 0) (symbol_ref "INTVAL (operands[0])")) (const_int 0) - (eq (const_int 1) (symbol_ref "INTVAL (operands[0])")) (const_int 1) - (eq (const_int 2) (symbol_ref "INTVAL (operands[0])")) (const_int 2) - (eq (const_int 3) (symbol_ref "INTVAL (operands[0])")) (const_int 3) - (eq (const_int 4) (symbol_ref "INTVAL (operands[0])")) (const_int 4) - (eq (const_int 5) (symbol_ref "INTVAL (operands[0])")) (const_int 5)] - (const_int 0)))]) + "" + { + return avr_out_addto_sp (operands, NULL); + } + [(set_attr "length" "5") + (set_attr "adjust_len" "addto_sp")]) (define_insn "*addhi3" [(set (match_operand:HI 0 "register_operand" "=r,!w,!w,d,r,r") |