From 3efd5670ca52e1a2bce4d29b7e16669dd88bacdc Mon Sep 17 00:00:00 2001 From: Bernd Schmidt Date: Thu, 12 Apr 2007 13:03:17 +0000 Subject: [PATCH] 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 --- gcc/ChangeLog | 19 ++++++ gcc/config/bfin/bfin.c | 11 ++- gcc/config/bfin/bfin.h | 13 ++++ gcc/config/bfin/bfin.md | 174 ++++++++++++++++++++++++++++++++++++++++-------- gcc/doc/md.texi | 8 +++ 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 + + * 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 * 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. -- 2.7.4