]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR target/50358 (AVR: Implement [u]maddqihi4 [u]msubqihi4 patterns on the enhanced...
authorGeorg-Johann Lay <avr@gjlay.de>
Fri, 16 Sep 2011 18:27:10 +0000 (18:27 +0000)
committerGeorg-Johann Lay <gjl@gcc.gnu.org>
Fri, 16 Sep 2011 18:27:10 +0000 (18:27 +0000)
PR target/50358
* config/avr/avr.md (*ashiftqihi2.signx.1): New insn.
(*maddqi4, *maddqi4.const): New insns.
(*msubqi4, *msubqi4.const): New insns.
* config/avr/avr.c (avr_rtx_costs): Record costs of above in cases
PLUS:QI and MINUS:QI.  Increase costs of multiply-add/-sub for
HImode by 1 in the case of multiplying with a CONST_INT.
Record cost of *ashiftqihi2.signx.1 in case ASHIFT:QI.

From-SVN: r178912

gcc/ChangeLog
gcc/config/avr/avr.c
gcc/config/avr/avr.md

index 469aeb3a188fcf29b7a72134a934195e3ed55a16..25cd753744951088137518b0afb2d7045459ae6a 100644 (file)
@@ -1,3 +1,14 @@
+2011-09-16  Georg-Johann Lay  <avr@gjlay.de>
+
+       PR target/50358
+       * config/avr/avr.md (*ashiftqihi2.signx.1): New insn.
+       (*maddqi4, *maddqi4.const): New insns.
+       (*msubqi4, *msubqi4.const): New insns.
+       * config/avr/avr.c (avr_rtx_costs): Record costs of above in cases
+       PLUS:QI and MINUS:QI.  Increase costs of multiply-add/-sub for
+       HImode by 1 in the case of multiplying with a CONST_INT.
+       Record cost of *ashiftqihi2.signx.1 in case ASHIFT:QI.
+
 2011-09-15   Jan Hubicka  <jh@suse.cz>
 
        PR lto/50430
index 773aec2442dde67b8d45db50246aea7109634d71..b69efa9507585dfe68d04f081a3419a6a0dca05f 100644 (file)
@@ -1528,7 +1528,7 @@ notice_update_cc (rtx body ATTRIBUTE_UNUSED, rtx insn)
       /* Insn doesn't leave CC in a usable state.  */
       CC_STATUS_INIT;
 
-      /* Correct CC for the ashrqi3 with the shift count as CONST_INT != 6 */
+      /* Correct CC for the ashrqi3 with the shift count as CONST_INT < 6 */
       set = single_set (insn);
       if (set)
        {
@@ -5570,6 +5570,17 @@ avr_rtx_costs (rtx x, int codearg, int outer_code ATTRIBUTE_UNUSED,
       switch (mode)
        {
        case QImode:
+          if (AVR_HAVE_MUL
+              && MULT == GET_CODE (XEXP (x, 0))
+              && register_operand (XEXP (x, 1), QImode))
+            {
+              /* multiply-add */
+              *total = COSTS_N_INSNS (speed ? 4 : 3);
+              /* multiply-add with constant: will be split and load constant. */
+              if (CONST_INT_P (XEXP (XEXP (x, 0), 1)))
+                *total = COSTS_N_INSNS (1) + *total;
+              return true;
+            }
          *total = COSTS_N_INSNS (1);
          if (GET_CODE (XEXP (x, 1)) != CONST_INT)
            *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1, speed);
@@ -5583,7 +5594,11 @@ avr_rtx_costs (rtx x, int codearg, int outer_code ATTRIBUTE_UNUSED,
               && (ZERO_EXTEND == GET_CODE (XEXP (XEXP (x, 0), 0))
                   || SIGN_EXTEND == GET_CODE (XEXP (XEXP (x, 0), 0))))
             {
+              /* multiply-add */
               *total = COSTS_N_INSNS (speed ? 5 : 4);
+              /* multiply-add with constant: will be split and load constant. */
+              if (CONST_INT_P (XEXP (XEXP (x, 0), 1)))
+                *total = COSTS_N_INSNS (1) + *total;
               return true;
             }
          if (GET_CODE (XEXP (x, 1)) != CONST_INT)
@@ -5618,6 +5633,18 @@ avr_rtx_costs (rtx x, int codearg, int outer_code ATTRIBUTE_UNUSED,
       return true;
 
     case MINUS:
+      if (AVR_HAVE_MUL
+          && QImode == mode
+          && register_operand (XEXP (x, 0), QImode)
+          && MULT == GET_CODE (XEXP (x, 1)))
+        {
+          /* multiply-sub */
+          *total = COSTS_N_INSNS (speed ? 4 : 3);
+          /* multiply-sub with constant: will be split and load constant. */
+          if (CONST_INT_P (XEXP (XEXP (x, 1), 1)))
+            *total = COSTS_N_INSNS (1) + *total;
+          return true;
+        }
       if (AVR_HAVE_MUL
           && HImode == mode
           && register_operand (XEXP (x, 0), HImode)
@@ -5626,7 +5653,11 @@ avr_rtx_costs (rtx x, int codearg, int outer_code ATTRIBUTE_UNUSED,
           && (ZERO_EXTEND == GET_CODE (XEXP (XEXP (x, 1), 0))
               || SIGN_EXTEND == GET_CODE (XEXP (XEXP (x, 1), 0))))
         {
+          /* multiply-sub */
           *total = COSTS_N_INSNS (speed ? 5 : 4);
+          /* multiply-sub with constant: will be split and load constant. */
+          if (CONST_INT_P (XEXP (XEXP (x, 1), 1)))
+            *total = COSTS_N_INSNS (1) + *total;
           return true;
         }
     case AND:
@@ -5815,6 +5846,13 @@ avr_rtx_costs (rtx x, int codearg, int outer_code ATTRIBUTE_UNUSED,
                 }
             }
           
+          if (const1_rtx == (XEXP (x, 1))
+              && SIGN_EXTEND == GET_CODE (XEXP (x, 0)))
+            {
+              *total = COSTS_N_INSNS (2);
+              return true;
+            }
+          
          if (GET_CODE (XEXP (x, 1)) != CONST_INT)
            {
              *total = COSTS_N_INSNS (!speed ? 5 : 41);
index 8721314e73b3a4d7bad230a18c60732498983719..c16150497eb320c1ba0e16a25147b8f855f2b586 100644 (file)
   [(set_attr "length" "4")
    (set_attr "cc" "clobber")])
 
+;******************************************************************************
+; multiply-add/sub QI: $0 = $3 +/- $1*$2
+;******************************************************************************
+
+(define_insn "*maddqi4"
+  [(set (match_operand:QI 0 "register_operand"                  "=r")
+        (plus:QI (mult:QI (match_operand:QI 1 "register_operand" "r")
+                          (match_operand:QI 2 "register_operand" "r"))
+                 (match_operand:QI 3 "register_operand"          "0")))]
+  
+  "AVR_HAVE_MUL"
+  "mul %1,%2
+       add %A0,r0
+       clr __zero_reg__"
+  [(set_attr "length" "4")
+   (set_attr "cc" "clobber")])
+
+(define_insn "*msubqi4"
+  [(set (match_operand:QI 0 "register_operand"                   "=r")
+        (minus:QI (match_operand:QI 3 "register_operand"          "0")
+                  (mult:QI (match_operand:QI 1 "register_operand" "r")
+                           (match_operand:QI 2 "register_operand" "r"))))]
+  "AVR_HAVE_MUL"
+  "mul %1,%2
+       sub %A0,r0
+       clr __zero_reg__"
+  [(set_attr "length" "4")
+   (set_attr "cc" "clobber")])
+
+(define_insn_and_split "*maddqi4.const"
+  [(set (match_operand:QI 0 "register_operand"                   "=r")
+        (plus:QI (mult:QI (match_operand:QI 1 "register_operand"  "r")
+                          (match_operand:QI 2 "const_int_operand" "n"))
+                 (match_operand:QI 3 "register_operand"           "0")))
+   (clobber (match_scratch:QI 4                                 "=&d"))]
+  "AVR_HAVE_MUL"
+  "#"
+  "&& reload_completed"
+  [(set (match_dup 4)
+        (match_dup 2))
+   ; *maddqi4
+   (set (match_dup 0)
+        (plus:QI (mult:QI (match_dup 1)
+                          (match_dup 4))
+                 (match_dup 3)))]
+  "")
+
+(define_insn_and_split "*msubqi4.const"
+  [(set (match_operand:QI 0 "register_operand"                    "=r")
+        (minus:QI (match_operand:QI 3 "register_operand"           "0")
+                  (mult:QI (match_operand:QI 1 "register_operand"  "r")
+                           (match_operand:QI 2 "const_int_operand" "n"))))
+   (clobber (match_scratch:QI 4                                  "=&d"))]
+  "AVR_HAVE_MUL"
+  "#"
+  "&& reload_completed"
+  [(set (match_dup 4)
+        (match_dup 2))
+   ; *msubqi4
+   (set (match_dup 0)
+        (minus:QI (match_dup 3)
+                  (mult:QI (match_dup 1)
+                           (match_dup 4))))]
+  "")
+
+
 ;******************************************************************************
 ; multiply-add/sub HI: $0 = $3 +/- $1*$2  with 8-bit values $1, $2
 ;******************************************************************************
 ;; expand decides to use ASHIFT instead of MUL because ASHIFT costs are cheaper
 ;; at that time.  Fix that.
 
+(define_insn "*ashiftqihi2.signx.1"
+  [(set (match_operand:HI 0 "register_operand"                           "=r,*r")
+        (ashift:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "0,r"))
+                   (const_int 1)))]
+  ""
+  "@
+       lsl %A0\;sbc %B0,%B0
+       mov %A0,%1\;lsl %A0\;sbc %B0,%B0"
+  [(set_attr "length" "2,3")
+   (set_attr "cc" "clobber")])
+
 (define_insn_and_split "*ashifthi3.signx.const"
   [(set (match_operand:HI 0 "register_operand"                           "=r")
         (ashift:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "d"))