aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorBernd Schmidt <bernd.schmidt@analog.com>2007-04-12 13:03:17 +0000
committerBernd Schmidt <bernds@gcc.gnu.org>2007-04-12 13:03:17 +0000
commit3efd5670ca52e1a2bce4d29b7e16669dd88bacdc (patch)
tree4ed1b7b9f4de2f2a74e9b4b54b9045f209f12db6 /gcc
parentf4de8ba686f8a4c7cc2d7ff9fa53315e826560c4 (diff)
downloadgcc-3efd5670ca52e1a2bce4d29b7e16669dd88bacdc.zip
gcc-3efd5670ca52e1a2bce4d29b7e16669dd88bacdc.tar.gz
gcc-3efd5670ca52e1a2bce4d29b7e16669dd88bacdc.tar.bz2
md.texi (Blackfin family constraints): Document PA and PB.
* 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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog19
-rw-r--r--gcc/config/bfin/bfin.c11
-rw-r--r--gcc/config/bfin/bfin.h13
-rw-r--r--gcc/config/bfin/bfin.md174
-rw-r--r--gcc/doc/md.texi8
5 files changed, 194 insertions, 31 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 1a72898..7d19530 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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.
diff --git a/gcc/config/bfin/bfin.c b/gcc/config/bfin/bfin.c
index dbbeac0..ecadb57 100644
--- a/gcc/config/bfin/bfin.c
+++ b/gcc/config/bfin/bfin.c
@@ -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;
diff --git a/gcc/config/bfin/bfin.h b/gcc/config/bfin/bfin.h
index b2ee26e..2c67bef 100644
--- a/gcc/config/bfin/bfin.h
+++ b/gcc/config/bfin/bfin.h
@@ -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
diff --git a/gcc/config/bfin/bfin.md b/gcc/config/bfin/bfin.md
index fd55f4f..e1eeaa6 100644
--- a/gcc/config/bfin/bfin.md
+++ b/gcc/config/bfin/bfin.md
@@ -154,9 +154,10 @@
(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"
@@ -1226,6 +1227,19 @@
"%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"
@@ -1643,6 +1657,22 @@
%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
@@ -3031,52 +3061,83 @@
}
[(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%!"
@@ -3338,6 +3399,63 @@
}
[(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")])
diff --git a/gcc/doc/md.texi b/gcc/doc/md.texi
index 2c60ace..4d485df 100644
--- a/gcc/doc/md.texi
+++ b/gcc/doc/md.texi
@@ -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.