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
This commit is contained in:
parent
f4de8ba686
commit
3efd5670ca
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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")])
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
|
Loading…
Reference in New Issue