re PR target/50465 ([avr] Use insn attribute to depict if and how instruction lengths...
authorGeorg-Johann Lay <avr@gjlay.de>
Mon, 26 Sep 2011 11:53:40 +0000 (11:53 +0000)
committerGeorg-Johann Lay <gjl@gcc.gnu.org>
Mon, 26 Sep 2011 11:53:40 +0000 (11:53 +0000)
PR target/50465
* config/avr/avr-protos.h (output_reload_insisf): Don't pass insn.
* config/avr/avr.md (*reload_insi, *reload_insf): Change call to
output_reload_insisf.
(adjust_len): Set default to "no".
Remove alternative "yes".  Add alternatives: "mov8", "mov16",
"mov32", "ashlqi", "ashrqi", "lshrqi", "ashlhi", "ashrhi",
"lshrhi", "ashlsi, "ashrsi", "lshrsi".
(*movqi, *movhi, *movsi, *ashlqi3, ashlhi3, ashlsi3,
*ashlhi3_const, *ashlsi3_const, ashrqi3, ashrhi3, ashrsi3,
*ashrhi3_const, *ashrsi3_const, *lshrqi3, lshrhi3, *lshrhi3_const,
*lshrsi3_const): Set attribute "adjust_len".
* config/avr/avr.c (output_reload_insisf): Remove parameter "insn".
(output_movsisf): Don't pass insn to output_reload_insisf.
(adjust_insn_length): Handle new alternatives to adjust_len.
Remove handling of ADJUST_LEN_YES.  Clean-up code.

From-SVN: r179191

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

index 1e68d98..2d7def0 100644 (file)
@@ -1,3 +1,22 @@
+2011-09-26  Georg-Johann Lay  <avr@gjlay.de>
+
+       PR target/50465
+       * config/avr/avr-protos.h (output_reload_insisf): Don't pass insn.
+       * config/avr/avr.md (*reload_insi, *reload_insf): Change call to
+       output_reload_insisf.
+       (adjust_len): Set default to "no".
+       Remove alternative "yes".  Add alternatives: "mov8", "mov16",
+       "mov32", "ashlqi", "ashrqi", "lshrqi", "ashlhi", "ashrhi",
+       "lshrhi", "ashlsi, "ashrsi", "lshrsi".
+       (*movqi, *movhi, *movsi, *ashlqi3, ashlhi3, ashlsi3,
+       *ashlhi3_const, *ashlsi3_const, ashrqi3, ashrhi3, ashrsi3,
+       *ashrhi3_const, *ashrsi3_const, *lshrqi3, lshrhi3, *lshrhi3_const,
+       *lshrsi3_const): Set attribute "adjust_len".
+       * config/avr/avr.c (output_reload_insisf): Remove parameter "insn".
+       (output_movsisf): Don't pass insn to output_reload_insisf.
+       (adjust_insn_length): Handle new alternatives to adjust_len.
+       Remove handling of ADJUST_LEN_YES.  Clean-up code.
+
 2011-09-26  Eric Botcazou  <ebotcazou@adacore.com>
 
        * ifcvt.c (noce_try_cmove_arith): Use may_trap_or_fault_p in lieu of
index fe02dc9..ed88ef7 100644 (file)
@@ -88,7 +88,7 @@ extern bool avr_popcount_each_byte (rtx, int, int);
 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 8f4ae97..da53041 100644 (file)
@@ -2691,7 +2691,7 @@ output_movsisf (rtx insn, rtx operands[], int *l)
       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;
+      /* Nothing to adjust: The length from attribute "length" is fine.
+         This is the default.  */
       
-      if (adjust_len == ADJUST_LEN_NO)
-        {
-          /* Nothing to adjust: The length from attribute "length" is fine.  */
-          
-          return len;
-        }
-
-      /* Extract insn's operands.  */
+      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 (op, op[2], &len); break;
       
-      extract_constrain_insn_cached (insn);
-
-      /* Dispatch to right function.  */
+    case ADJUST_LEN_OUT_BITOP: avr_out_bitop (insn, op, &len); break;
       
-      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();
-        }
+    case ADJUST_LEN_OUT_PLUS: avr_out_plus (op, &len); break;
       
-      return len;
-    } /* adjust_length != ADJUST_LEN_YES */
-
-  /* adjust_len == "yes": Analyse insn by hand.  */
-  
-  patt = PATTERN (insn);
+    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;
 
-  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)
-    {
-      rtx op[10];
+    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;
 
-      op[1] = SET_SRC (set);
-      op[0] = SET_DEST (set);
+    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;
 
-      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_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 machine_mode mode)
 }
 
 
-/* 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_reg, int *plen)
    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]));
index 2940230..2efb0c4 100644 (file)
 ;; 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"))
+  "out_bitop, out_plus, tsthi, tstsi, compare,
+   mov8, mov16, mov32, reload_in16, reload_in32,
+   ashlqi, ashrqi, lshrqi,
+   ashlhi, ashrhi, lshrhi,
+   ashlsi, ashrsi, lshrsi,
+   no"
+  (const_string "no"))
 
 ;; Define mode iterators
 (define_mode_iterator QIHI  [(QI "") (HI "")])
     || 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
     || 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
    (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")
     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
     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
    (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")
     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"
     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"
     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
     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"
     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")])
 
 ;;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
     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"
     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
   ""
   "* 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"
   ""
   "* 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")])
 
 
   ""
   "* 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.
   "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
   "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")])
 
 ;; >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >>
   ""
   "* 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"
   ""
   "* 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"
   ""
   "* 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.
   "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
   "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")])
 
 ;; >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >>
   ""
   "* 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"
   ""
   "* 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"
   ""
   "* 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.
   "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
   "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)
   } 
   [(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"
   }
   [(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")])
 
 
 ;; ----------------------------------------------------------------------