md.texi (Blackfin family constraints): Document PA and PB.
authorBernd Schmidt <bernd.schmidt@analog.com>
Thu, 12 Apr 2007 13:03:17 +0000 (13:03 +0000)
committerBernd Schmidt <bernds@gcc.gnu.org>
Thu, 12 Apr 2007 13:03:17 +0000 (13:03 +0000)
* doc/md.texi (Blackfin family constraints): Document PA and PB.
* config/bfin/bfin.h (CONST_OK_FOR_P): Handle PA and PB.
(MACFLAGS_MATCH_P): New macro.
* config/bfin/bfin.c (print_operand): Handle MACFLAG_IS_M.
(bfin_secondary_reload): Treat EVEN_AREGS and ODD_AREGS like AREGS.
* config/bfin/bfin.md (MACFLAG_IS_M): New constant.  Renumber some of
the other MACFLAG constants.
(sum_of_accumulators, lshrpdi3, ashrpdi3): New patterns.
(flag_machi): Tighten constraints.  Renumber some of the operands.
(flag_machi_acconly): Tighten constraints.  Correct operand numbers in
output template.
(flag_machi_parts_acconly): New pattern.
(flag_macinithi): Tighten constraints.  Allow any accumulator to be
used.
(flag_macinit1hi): Tighten constraints.
(flag_mul_macv2hi_parts_acconly): New pattern.

From-SVN: r123745

gcc/ChangeLog
gcc/config/bfin/bfin.c
gcc/config/bfin/bfin.h
gcc/config/bfin/bfin.md
gcc/doc/md.texi

index 1a72898..7d19530 100644 (file)
@@ -1,3 +1,22 @@
+2007-04-12  Bernd Schmidt  <bernd.schmidt@analog.com>
+
+       * doc/md.texi (Blackfin family constraints): Document PA and PB.
+       * config/bfin/bfin.h (CONST_OK_FOR_P): Handle PA and PB.
+       (MACFLAGS_MATCH_P): New macro.
+       * config/bfin/bfin.c (print_operand): Handle MACFLAG_IS_M.
+       (bfin_secondary_reload): Treat EVEN_AREGS and ODD_AREGS like AREGS.
+       * config/bfin/bfin.md (MACFLAG_IS_M): New constant.  Renumber some of
+       the other MACFLAG constants.
+       (sum_of_accumulators, lshrpdi3, ashrpdi3): New patterns.
+       (flag_machi): Tighten constraints.  Renumber some of the operands.
+       (flag_machi_acconly): Tighten constraints.  Correct operand numbers in
+       output template.
+       (flag_machi_parts_acconly): New pattern.
+       (flag_macinithi): Tighten constraints.  Allow any accumulator to be
+       used.
+       (flag_macinit1hi): Tighten constraints.
+       (flag_mul_macv2hi_parts_acconly): New pattern.
+
 2007-04-12  Richard Sandiford  <richard@codesourcery.com>
 
        * config.gcc (*-*-vxworks*): Don't add to tm_files in this stanza.
index dbbeac0..ecadb57 100644 (file)
@@ -1356,6 +1356,9 @@ print_operand (FILE *file, rtx x, char code)
                case MACFLAG_M:
                  fputs ("(M)", file);
                  break;
+               case MACFLAG_IS_M:
+                 fputs ("(IS,M)", file);
+                 break;
                case MACFLAG_ISS2:
                  fputs ("(ISS2)", file);
                  break;
@@ -2014,10 +2017,12 @@ bfin_secondary_reload (bool in_p ATTRIBUTE_UNUSED, rtx x, enum reg_class class,
   /* Data can usually be moved freely between registers of most classes.
      AREGS are an exception; they can only move to or from another register
      in AREGS or one in DREGS.  They can also be assigned the constant 0.  */
-  if (x_class == AREGS)
-    return class == DREGS || class == AREGS ? NO_REGS : DREGS;
+  if (x_class == AREGS || x_class == EVEN_AREGS || x_class == ODD_AREGS)
+    return (class == DREGS || class == AREGS || class == EVEN_AREGS
+           || class == ODD_AREGS
+           ? NO_REGS : DREGS);
 
-  if (class == AREGS)
+  if (class == AREGS || class == EVEN_AREGS || class == ODD_AREGS)
     {
       if (x != const0_rtx && x_class != DREGS)
        return DREGS;
index b2ee26e..2c67bef 100644 (file)
@@ -1084,6 +1084,8 @@ do {                                             \
      : (STR)[1] == '2' ? (VALUE) == 2 \
      : (STR)[1] == '3' ? (VALUE) == 3 \
      : (STR)[1] == '4' ? (VALUE) == 4 \
+     : (STR)[1] == 'A' ? (VALUE) != MACFLAG_M && (VALUE) != MACFLAG_IS_M \
+     : (STR)[1] == 'B' ? (VALUE) == MACFLAG_M || (VALUE) == MACFLAG_IS_M \
      : 0)
 
 #define CONST_OK_FOR_K(VALUE, STR)                     \
@@ -1143,6 +1145,17 @@ do {                                            \
 #define EXTRA_CONSTRAINT(VALUE, D) \
     ((D) == 'Q' ? GET_CODE (VALUE) == SYMBOL_REF : 0)
 
+/* Evaluates to true if A and B are mac flags that can be used
+   together in a single multiply insn.  That is the case if they are
+   both the same flag not involving M, or if one is a combination of
+   the other with M.  */
+#define MACFLAGS_MATCH_P(A, B) \
+ ((A) == (B) \
+  || ((A) == MACFLAG_NONE && (B) == MACFLAG_M) \
+  || ((A) == MACFLAG_M && (B) == MACFLAG_NONE) \
+  || ((A) == MACFLAG_IS && (B) == MACFLAG_IS_M) \
+  || ((A) == MACFLAG_IS_M && (B) == MACFLAG_IS))
+
 /* Switch into a generic section.  */
 #define TARGET_ASM_NAMED_SECTION  default_elf_asm_named_section
 
index fd55f4f..e1eeaa6 100644 (file)
    (MACFLAG_IU 5)
    (MACFLAG_W32 6)
    (MACFLAG_M 7)
-   (MACFLAG_S2RND 8)
-   (MACFLAG_ISS2 9)
-   (MACFLAG_IH 10)])
+   (MACFLAG_IS_M 8)
+   (MACFLAG_S2RND 9)
+   (MACFLAG_ISS2 10)
+   (MACFLAG_IH 11)])
 
 (define_attr "type"
   "move,movcc,mvi,mcld,mcst,dsp32,mult,alu0,shft,brcc,br,call,misc,sync,compare,dummy"
   "%0 = %1 - %2 (S)%!"
   [(set_attr "type" "dsp32")])
 
+;; Accumulator addition
+
+(define_insn "sum_of_accumulators"
+  [(set (match_operand:SI 0 "register_operand" "=d")
+       (ss_truncate:SI
+        (ss_plus:PDI (match_operand:PDI 2 "register_operand" "1")
+                     (match_operand:PDI 3 "register_operand" "B"))))
+   (set (match_operand:PDI 1 "register_operand" "=A")
+        (ss_plus:PDI (match_dup 2) (match_dup 3)))]
+  ""
+  "%0 = (A0 += A1)%!"
+  [(set_attr "type" "dsp32")])
+
 ;; Bit test instructions
 
 (define_insn "*not_bittst"
    %0 = %1 >> %2;"
   [(set_attr "type" "shft,dsp32,shft")])
 
+(define_insn "lshrpdi3"
+  [(set (match_operand:PDI 0 "register_operand" "=e")
+       (lshiftrt:PDI (match_operand:PDI 1 "register_operand" "0")
+                     (match_operand:SI 2 "nonmemory_operand" "Ku5")))]
+  ""
+  "%0 = %1 >> %2%!"
+  [(set_attr "type" "dsp32")])
+
+(define_insn "ashrpdi3"
+  [(set (match_operand:PDI 0 "register_operand" "=e")
+       (ashiftrt:PDI (match_operand:PDI 1 "register_operand" "0")
+                     (match_operand:SI 2 "nonmemory_operand" "Ku5")))]
+  ""
+  "%0 = %1 >>> %2%!"
+  [(set_attr "type" "dsp32")])
+
 ;; A pattern to reload the equivalent of
 ;;   (set (Dreg) (plus (FP) (large_constant)))
 ;; or
 }
   [(set_attr "type" "dsp32")])
 
+;; Three alternatives here to cover all possible allocations:
+;; 0. mac flag is usable only for accumulator 1 - use A1 and odd DREG
+;; 1. mac flag is usable for accumulator 0 - use A0 and even DREG
+;; 2. mac flag is usable in any accumulator - use A1 and odd DREG
+;; Other patterns which don't have a DREG destination can collapse cases
+;; 1 and 2 into one.
 (define_insn "flag_machi"
-  [(set (match_operand:HI 0 "register_operand" "=d")
-       (unspec:HI [(match_operand:HI 1 "register_operand" "d")
-                   (match_operand:HI 2 "register_operand" "d")
-                   (match_operand 3 "register_operand" "A")
-                   (match_operand 4 "const01_operand" "P0P1")
-                   (match_operand 5 "const_int_operand" "n")]
+  [(set (match_operand:HI 0 "register_operand" "=W,D,W")
+       (unspec:HI [(match_operand:HI 2 "register_operand" "d,d,d")
+                   (match_operand:HI 3 "register_operand" "d,d,d")
+                   (match_operand 4 "register_operand" "1,1,1")
+                   (match_operand 5 "const01_operand" "P0P1,P0P1,P0P1")
+                   (match_operand 6 "const_int_operand" "PB,PA,PA")]
                   UNSPEC_MAC_WITH_FLAG))
-   (set (match_operand:PDI 6 "register_operand" "=A")
+   (set (match_operand:PDI 1 "register_operand" "=B,A,B")
        (unspec:PDI [(match_dup 1) (match_dup 2) (match_dup 3)
                     (match_dup 4) (match_dup 5)]
                    UNSPEC_MAC_WITH_FLAG))]
   ""
-  "%h0 = (A0 %b4 %h1 * %h2) %M6%!"
+  "%h0 = (%1 %b5 %h2 * %h3) %M6%!"
   [(set_attr "type" "dsp32")])
 
 (define_insn "flag_machi_acconly"
-  [(set (match_operand:PDI 0 "register_operand" "=e")
-       (unspec:PDI [(match_operand:HI 1 "register_operand" "d")
-                    (match_operand:HI 2 "register_operand" "d")
-                    (match_operand 3 "register_operand" "A")
-                    (match_operand 4 "const01_operand" "P0P1")
-                    (match_operand 5 "const_int_operand" "n")]
+  [(set (match_operand:PDI 0 "register_operand" "=B,e")
+       (unspec:PDI [(match_operand:HI 1 "register_operand" "d,d")
+                    (match_operand:HI 2 "register_operand" "d,d")
+                    (match_operand 3 "register_operand" "0,0")
+                    (match_operand 4 "const01_operand" "P0P1,P0P1")
+                    (match_operand 5 "const_int_operand" "PB,PA")]
                    UNSPEC_MAC_WITH_FLAG))]
   ""
-  "%0 %b4 %h1 * %h2 %M6%!"
+  "%0 %b4 %h1 * %h2 %M5%!"
+  [(set_attr "type" "dsp32")])
+
+(define_insn "flag_machi_parts_acconly"
+  [(set (match_operand:PDI 0 "register_operand" "=B,e")
+       (unspec:PDI [(vec_select:HI
+                     (match_operand:V2HI 1 "register_operand" "d,d")
+                     (parallel [(match_operand 3 "const01_operand" "P0P1,P0P1")]))
+                    (vec_select:HI
+                     (match_operand:V2HI 2 "register_operand" "d,d")
+                     (parallel [(match_operand 4 "const01_operand" "P0P1,P0P1")]))
+                    (match_operand:PDI 5 "register_operand" "0,0")
+                    (match_operand 6 "const01_operand" "P0P1,P0P1")
+                    (match_operand 7 "const_int_operand" "PB,PA")]
+                   UNSPEC_MAC_WITH_FLAG))]
+  ""
+{
+  const char *templates[] = {
+    "%0 %b6 %h1 * %h2 %M7%!",
+    "%0 %b6 %d1 * %h2 %M7%!",
+    "%0 %b6 %h1 * %d2 %M7%!",
+    "%0 %b6 %d1 * %d2 %M7%!"
+  };
+  int alt = INTVAL (operands[3]) + (INTVAL (operands[4]) << 1);
+  return templates[alt];
+}
   [(set_attr "type" "dsp32")])
 
 (define_insn "flag_macinithi"
-  [(set (match_operand:HI 0 "register_operand" "=d")
-       (unspec:HI [(match_operand:HI 1 "register_operand" "d")
-                   (match_operand:HI 2 "register_operand" "d")
-                   (match_operand 3 "const_int_operand" "n")]
+  [(set (match_operand:HI 0 "register_operand" "=W,D,W")
+       (unspec:HI [(match_operand:HI 1 "register_operand" "d,d,d")
+                   (match_operand:HI 2 "register_operand" "d,d,d")
+                   (match_operand 3 "const_int_operand" "PB,PA,PA")]
                   UNSPEC_MAC_WITH_FLAG))
-   (set (match_operand:PDI 4 "register_operand" "=A")
+   (set (match_operand:PDI 4 "register_operand" "=B,A,B")
        (unspec:PDI [(match_dup 1) (match_dup 2) (match_dup 3)]
                    UNSPEC_MAC_WITH_FLAG))]
   ""
-  "%h0 = (A0 = %h1 * %h2) %M3%!"
+  "%h0 = (%4 = %h1 * %h2) %M3%!"
   [(set_attr "type" "dsp32")])
 
 (define_insn "flag_macinit1hi"
-  [(set (match_operand:PDI 0 "register_operand" "=e")
-       (unspec:PDI [(match_operand:HI 1 "register_operand" "d")
-                    (match_operand:HI 2 "register_operand" "d")
-                    (match_operand 3 "const_int_operand" "n")]
+  [(set (match_operand:PDI 0 "register_operand" "=B,e")
+       (unspec:PDI [(match_operand:HI 1 "register_operand" "d,d")
+                    (match_operand:HI 2 "register_operand" "d,d")
+                    (match_operand 3 "const_int_operand" "PB,PA")]
                    UNSPEC_MAC_WITH_FLAG))]
   ""
   "%0 = %h1 * %h2 %M3%!"
 }
   [(set_attr "type" "dsp32")])
 
+;; A mixture of multiply and multiply-accumulate for when we only want to
+;; initialize one part.
+(define_insn "flag_mul_macv2hi_parts_acconly"
+  [(set (match_operand:PDI 0 "register_operand" "=B,e,e")
+       (unspec:PDI [(vec_select:HI
+                     (match_operand:V2HI 2 "register_operand" "d,d,d")
+                     (parallel [(match_operand 4 "const01_operand" "P0P1,P0P1,P0P1")]))
+                    (vec_select:HI
+                     (match_operand:V2HI 3 "register_operand" "d,d,d")
+                     (parallel [(match_operand 6 "const01_operand" "P0P1,P0P1,P0P1")]))
+                    (match_operand 10 "const_int_operand" "PB,PA,PA")]
+                   UNSPEC_MUL_WITH_FLAG))
+   (set (match_operand:PDI 1 "register_operand" "=B,e,e")
+       (unspec:PDI [(vec_select:HI
+                     (match_dup 2)
+                     (parallel [(match_operand 5 "const01_operand" "P0P1,P0P1,P0P1")]))
+                    (vec_select:HI
+                     (match_dup 3)
+                     (parallel [(match_operand 7 "const01_operand" "P0P1,P0P1,P0P1")]))
+                    (match_operand:PDI 8 "register_operand" "1,1,1")
+                    (match_operand 9 "const01_operand" "P0P1,P0P1,P0P1")
+                    (match_operand 11 "const_int_operand" "PA,PB,PA")]
+                   UNSPEC_MAC_WITH_FLAG))]
+  "MACFLAGS_MATCH_P (INTVAL (operands[10]), INTVAL (operands[11]))"
+{
+  rtx xops[6];
+  const char *templates[] = {
+    "%0 = %h2 * %h3, %1 %b4 %h2 * %h3 %M5%!",
+    "%0 = %d2 * %h3, %1 %b4 %h2 * %h3 %M5%!",
+    "%0 = %h2 * %h3, %1 %b4 %d2 * %h3 %M5%!",
+    "%0 = %d2 * %h3, %1 %b4 %d2 * %h3 %M5%!",
+    "%0 = %h2 * %d3, %1 %b4 %h2 * %h3 %M5%!",
+    "%0 = %d2 * %d3, %1 %b4 %h2 * %h3 %M5%!",
+    "%0 = %h2 * %d3, %1 %b4 %d2 * %h3 %M5%!",
+    "%0 = %d2 * %d3, %1 %b4 %d2 * %h3 %M5%!",
+    "%0 = %h2 * %h3, %1 %b4 %h2 * %d3 %M5%!",
+    "%0 = %d2 * %h3, %1 %b4 %h2 * %d3 %M5%!",
+    "%0 = %h2 * %h3, %1 %b4 %d2 * %d3 %M5%!",
+    "%0 = %d2 * %h3, %1 %b4 %d2 * %d3 %M5%!",
+    "%0 = %h2 * %d3, %1 %b4 %h2 * %d3 %M5%!",
+    "%0 = %d2 * %d3, %1 %b4 %h2 * %d3 %M5%!",
+    "%0 = %h2 * %d3, %1 %b4 %d2 * %d3 %M5%!",
+    "%0 = %d2 * %d3, %1 %b4 %d2 * %d3 %M5%!" };
+  int alt = (INTVAL (operands[4]) + (INTVAL (operands[5]) << 1)
+            + (INTVAL (operands[6]) << 2)  + (INTVAL (operands[7]) << 3));
+  xops[0] = operands[0];
+  xops[1] = operands[1];
+  xops[2] = operands[2];
+  xops[3] = operands[3];
+  xops[4] = operands[9];
+  xops[5] = which_alternative == 0 ? operands[10] : operands[11];
+  output_asm_insn (templates[alt], xops);
+  return "";
+}
+  [(set_attr "type" "dsp32")])
+
+
 (define_code_macro s_or_u [sign_extend zero_extend])
 (define_code_attr su_optab [(sign_extend "mul")
                            (zero_extend "umul")])
index 2c60ace..4d485df 100644 (file)
@@ -2249,6 +2249,14 @@ Unsigned 3 bit integer (in the range 0 to 7)
 @item P@var{n}
 Constant @var{n}, where @var{n} is a single-digit constant in the range 0 to 4.
 
+@item PA
+An integer equal to one of the MACFLAG_XXX constants that is suitable for
+use with either accumulator.
+
+@item PB
+An integer equal to one of the MACFLAG_XXX constants that is suitable for
+use only with accumulator A1.
+
 @item M1
 Constant 255.