avr-protos.h (avr_out_addto_sp): New prototype.
authorGeorg-Johann Lay <avr@gjlay.de>
Wed, 5 Oct 2011 11:16:10 +0000 (11:16 +0000)
committerGeorg-Johann Lay <gjl@gcc.gnu.org>
Wed, 5 Oct 2011 11:16:10 +0000 (11:16 +0000)
* 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

gcc/ChangeLog
gcc/config/avr/avr-protos.h
gcc/config/avr/avr.c
gcc/config/avr/avr.md

index da53b3869759fdfc16a4a0198719be559fa162f2..96cac6765d482c4fee620e8c396f2ae29e6ca9c6 100644 (file)
@@ -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
index 7ad0f1c04a3b01ee55b017f2724271ba6ab6f487..a2a5dd0c04e9f0abc0122667785ff58384f1d8db 100644 (file)
@@ -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);
index e6cb2140924bde912270432876ed61709453f56b..c28b593a8b8cc162c8a7efd764554ed5f8850fc0 100644 (file)
@@ -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;
index 3b1800d3fb07eb4999ff27c27f3b35281f512ab5..f1ac95d7f00480d5754cc76ab66650b2d73e0fc8 100644 (file)
 ;; 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,
     }
 }")
 
-(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")] 
   [(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")