aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/bfin/bfin.md
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/config/bfin/bfin.md')
-rw-r--r--gcc/config/bfin/bfin.md199
1 files changed, 150 insertions, 49 deletions
diff --git a/gcc/config/bfin/bfin.md b/gcc/config/bfin/bfin.md
index a3638700a53..74c7a0a6f60 100644
--- a/gcc/config/bfin/bfin.md
+++ b/gcc/config/bfin/bfin.md
@@ -138,14 +138,16 @@
;; Distinguish a 32-bit version of an insn from a 16-bit version.
(UNSPEC_32BIT 11)
(UNSPEC_NOP 12)
- (UNSPEC_ONES 12)])
+ (UNSPEC_ONES 13)
+ (UNSPEC_ATOMIC 14)])
(define_constants
[(UNSPEC_VOLATILE_CSYNC 1)
(UNSPEC_VOLATILE_SSYNC 2)
(UNSPEC_VOLATILE_LOAD_FUNCDESC 3)
(UNSPEC_VOLATILE_STORE_EH_HANDLER 4)
- (UNSPEC_VOLATILE_DUMMY 5)])
+ (UNSPEC_VOLATILE_DUMMY 5)
+ (UNSPEC_VOLATILE_STALL 6)])
(define_constants
[(MACFLAG_NONE 0)
@@ -162,28 +164,42 @@
(MACFLAG_IH 11)])
(define_attr "type"
- "move,movcc,mvi,mcld,mcst,dsp32,mult,alu0,shft,brcc,br,call,misc,sync,compare,dummy"
+ "move,movcc,mvi,mcld,mcst,dsp32,dsp32shiftimm,mult,alu0,shft,brcc,br,call,misc,sync,compare,dummy,stall"
(const_string "misc"))
-(define_attr "addrtype" "32bit,preg,ireg"
+(define_attr "addrtype" "32bit,preg,spreg,ireg"
(cond [(and (eq_attr "type" "mcld")
- (and (match_operand 0 "d_register_operand" "")
+ (and (match_operand 0 "dp_register_operand" "")
(match_operand 1 "mem_p_address_operand" "")))
(const_string "preg")
(and (eq_attr "type" "mcld")
- (and (match_operand 0 "d_register_operand" "")
+ (and (match_operand 0 "dp_register_operand" "")
+ (match_operand 1 "mem_spfp_address_operand" "")))
+ (const_string "spreg")
+ (and (eq_attr "type" "mcld")
+ (and (match_operand 0 "dp_register_operand" "")
(match_operand 1 "mem_i_address_operand" "")))
(const_string "ireg")
(and (eq_attr "type" "mcst")
- (and (match_operand 1 "d_register_operand" "")
+ (and (match_operand 1 "dp_register_operand" "")
(match_operand 0 "mem_p_address_operand" "")))
(const_string "preg")
(and (eq_attr "type" "mcst")
- (and (match_operand 1 "d_register_operand" "")
+ (and (match_operand 1 "dp_register_operand" "")
+ (match_operand 0 "mem_spfp_address_operand" "")))
+ (const_string "spreg")
+ (and (eq_attr "type" "mcst")
+ (and (match_operand 1 "dp_register_operand" "")
(match_operand 0 "mem_i_address_operand" "")))
(const_string "ireg")]
(const_string "32bit")))
+(define_attr "storereg" "preg,other"
+ (cond [(and (eq_attr "type" "mcst")
+ (match_operand 1 "p_register_operand" ""))
+ (const_string "preg")]
+ (const_string "other")))
+
;; Scheduling definitions
(define_automaton "bfin")
@@ -198,6 +214,13 @@
(define_cpu_unit "store" "bfin")
(define_cpu_unit "pregs" "bfin")
+;; A dummy unit used to delay scheduling of loads after a conditional
+;; branch.
+(define_cpu_unit "load" "bfin")
+
+;; A logical unit used to work around anomaly 05000074.
+(define_cpu_unit "anomaly_05000074" "bfin")
+
(define_reservation "core" "slot0+slot1+slot2")
(define_insn_reservation "alu" 1
@@ -212,20 +235,37 @@
(eq_attr "type" "dsp32")
"slot0")
+(define_insn_reservation "dsp32shiftimm" 1
+ (and (eq_attr "type" "dsp32shiftimm")
+ (eq (symbol_ref "ENABLE_WA_05000074")
+ (const_int 0)))
+ "slot0")
+
+(define_insn_reservation "dsp32shiftimm_anomaly_05000074" 1
+ (and (eq_attr "type" "dsp32shiftimm")
+ (ne (symbol_ref "ENABLE_WA_05000074")
+ (const_int 0)))
+ "slot0+anomaly_05000074")
+
(define_insn_reservation "load32" 1
(and (not (eq_attr "seq_insns" "multi"))
(and (eq_attr "type" "mcld") (eq_attr "addrtype" "32bit")))
- "core")
+ "core+load")
(define_insn_reservation "loadp" 1
(and (not (eq_attr "seq_insns" "multi"))
(and (eq_attr "type" "mcld") (eq_attr "addrtype" "preg")))
- "(slot1|slot2)+pregs")
+ "slot1+pregs+load")
+
+(define_insn_reservation "loadsp" 1
+ (and (not (eq_attr "seq_insns" "multi"))
+ (and (eq_attr "type" "mcld") (eq_attr "addrtype" "spreg")))
+ "slot1+pregs")
(define_insn_reservation "loadi" 1
(and (not (eq_attr "seq_insns" "multi"))
(and (eq_attr "type" "mcld") (eq_attr "addrtype" "ireg")))
- "(slot1|slot2)")
+ "(slot1|slot2)+load")
(define_insn_reservation "store32" 1
(and (not (eq_attr "seq_insns" "multi"))
@@ -233,19 +273,55 @@
"core")
(define_insn_reservation "storep" 1
- (and (not (eq_attr "seq_insns" "multi"))
- (and (eq_attr "type" "mcst") (eq_attr "addrtype" "preg")))
- "(slot1|slot2)+pregs+store")
+ (and (and (not (eq_attr "seq_insns" "multi"))
+ (and (eq_attr "type" "mcst")
+ (ior (eq_attr "addrtype" "preg")
+ (eq_attr "addrtype" "spreg"))))
+ (ior (eq (symbol_ref "ENABLE_WA_05000074")
+ (const_int 0))
+ (eq_attr "storereg" "other")))
+ "slot1+pregs+store")
+
+(define_insn_reservation "storep_anomaly_05000074" 1
+ (and (and (not (eq_attr "seq_insns" "multi"))
+ (and (eq_attr "type" "mcst")
+ (ior (eq_attr "addrtype" "preg")
+ (eq_attr "addrtype" "spreg"))))
+ (and (ne (symbol_ref "ENABLE_WA_05000074")
+ (const_int 0))
+ (eq_attr "storereg" "preg")))
+ "slot1+anomaly_05000074+pregs+store")
(define_insn_reservation "storei" 1
- (and (not (eq_attr "seq_insns" "multi"))
- (and (eq_attr "type" "mcst") (eq_attr "addrtype" "ireg")))
+ (and (and (not (eq_attr "seq_insns" "multi"))
+ (and (eq_attr "type" "mcst") (eq_attr "addrtype" "ireg")))
+ (ior (eq (symbol_ref "ENABLE_WA_05000074")
+ (const_int 0))
+ (eq_attr "storereg" "other")))
"(slot1|slot2)+store")
+(define_insn_reservation "storei_anomaly_05000074" 1
+ (and (and (not (eq_attr "seq_insns" "multi"))
+ (and (eq_attr "type" "mcst") (eq_attr "addrtype" "ireg")))
+ (and (ne (symbol_ref "ENABLE_WA_05000074")
+ (const_int 0))
+ (eq_attr "storereg" "preg")))
+ "((slot1+anomaly_05000074)|slot2)+store")
+
(define_insn_reservation "multi" 2
(eq_attr "seq_insns" "multi")
"core")
+(define_insn_reservation "load_stall1" 1
+ (and (eq_attr "type" "stall")
+ (match_operand 0 "const1_operand" ""))
+ "core+load*2")
+
+(define_insn_reservation "load_stall3" 1
+ (and (eq_attr "type" "stall")
+ (match_operand 0 "const3_operand" ""))
+ "core+load*4")
+
(absence_set "slot0" "slot1,slot2")
(absence_set "slot1" "slot2")
@@ -302,6 +378,7 @@
(eq_attr "type" "move") (const_int 2)
(eq_attr "type" "dsp32") (const_int 4)
+ (eq_attr "type" "dsp32shiftimm") (const_int 4)
(eq_attr "type" "call") (const_int 4)
(eq_attr "type" "br")
@@ -555,7 +632,7 @@
"@
%0 = ROT %1 BY 0%!
%0 = %0 -|- %0%!"
- [(set_attr "type" "dsp32")])
+ [(set_attr "type" "dsp32shiftimm,dsp32")])
(define_split
[(set (match_operand:SI 0 "d_register_operand" "")
@@ -678,7 +755,7 @@
"@
%d0 = %h1 << 0%!
%d0 = %1;"
- [(set_attr "type" "dsp32,mvi")])
+ [(set_attr "type" "dsp32shiftimm,mvi")])
(define_expand "insv"
[(set (zero_extract:SI (match_operand:SI 0 "register_operand" "")
@@ -1588,7 +1665,7 @@
[(set (match_dup 0) (ashift:SI (match_dup 1) (const_int 2)))
(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 3)))]
"operands[3] = GEN_INT (INTVAL (operands[2]) - 2);"
- [(set_attr "type" "shft,dsp32,shft,shft,*")])
+ [(set_attr "type" "shft,dsp32shiftimm,shft,shft,*")])
(define_insn "ashrsi3"
[(set (match_operand:SI 0 "register_operand" "=d,d")
@@ -1598,7 +1675,7 @@
"@
%0 >>>= %2;
%0 = %1 >>> %2%!"
- [(set_attr "type" "shft,dsp32")])
+ [(set_attr "type" "shft,dsp32shiftimm")])
(define_insn "rotl16"
[(set (match_operand:SI 0 "register_operand" "=d")
@@ -1639,7 +1716,7 @@
(zero_extract:BI (match_dup 1) (const_int 1) (const_int 0)))]
""
"%0 = ROT %1 BY -1%!"
- [(set_attr "type" "dsp32")])
+ [(set_attr "type" "dsp32shiftimm")])
(define_insn "rol_one"
[(set (match_operand:SI 0 "register_operand" "+d")
@@ -1649,7 +1726,7 @@
(zero_extract:BI (match_dup 1) (const_int 31) (const_int 0)))]
""
"%0 = ROT %1 BY 1%!"
- [(set_attr "type" "dsp32")])
+ [(set_attr "type" "dsp32shiftimm")])
(define_expand "lshrdi3"
[(set (match_operand:DI 0 "register_operand" "")
@@ -1724,7 +1801,7 @@
%0 >>= %2;
%0 = %1 >> %2%!
%0 = %1 >> %2;"
- [(set_attr "type" "shft,dsp32,shft")])
+ [(set_attr "type" "shft,dsp32shiftimm,shft")])
(define_insn "lshrpdi3"
[(set (match_operand:PDI 0 "register_operand" "=e")
@@ -1732,7 +1809,7 @@
(match_operand:SI 2 "nonmemory_operand" "Ku5")))]
""
"%0 = %1 >> %2%!"
- [(set_attr "type" "dsp32")])
+ [(set_attr "type" "dsp32shiftimm")])
(define_insn "ashrpdi3"
[(set (match_operand:PDI 0 "register_operand" "=e")
@@ -1740,7 +1817,7 @@
(match_operand:SI 2 "nonmemory_operand" "Ku5")))]
""
"%0 = %1 >>> %2%!"
- [(set_attr "type" "dsp32")])
+ [(set_attr "type" "dsp32shiftimm")])
;; A pattern to reload the equivalent of
;; (set (Dreg) (plus (FP) (large_constant)))
@@ -2005,7 +2082,8 @@
[(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" "Q"))
(match_operand 1 "general_operand" "g"))
(use (match_operand:SI 2 "register_operand" "Z"))
- (use (match_operand 3 "" ""))]
+ (use (match_operand 3 "" ""))
+ (clobber (reg:SI REG_RETS))]
"! SIBLING_CALL_P (insn)
&& GET_CODE (operands[0]) == SYMBOL_REF
&& !bfin_longcall_p (operands[0], INTVAL (operands[3]))"
@@ -2031,7 +2109,8 @@
(call (mem:SI (match_operand:SI 1 "symbol_ref_operand" "Q"))
(match_operand 2 "general_operand" "g")))
(use (match_operand:SI 3 "register_operand" "Z"))
- (use (match_operand 4 "" ""))]
+ (use (match_operand 4 "" ""))
+ (clobber (reg:SI REG_RETS))]
"! SIBLING_CALL_P (insn)
&& GET_CODE (operands[1]) == SYMBOL_REF
&& !bfin_longcall_p (operands[1], INTVAL (operands[4]))"
@@ -2057,7 +2136,8 @@
[(call (mem:SI (match_operand:SI 0 "register_no_elim_operand" "Y"))
(match_operand 1 "general_operand" "g"))
(use (match_operand:SI 2 "register_operand" "Z"))
- (use (match_operand 3 "" ""))]
+ (use (match_operand 3 "" ""))
+ (clobber (reg:SI REG_RETS))]
"! SIBLING_CALL_P (insn)"
"call (%0);"
[(set_attr "type" "call")
@@ -2079,7 +2159,8 @@
(call (mem:SI (match_operand:SI 1 "register_no_elim_operand" "Y"))
(match_operand 2 "general_operand" "g")))
(use (match_operand:SI 3 "register_operand" "Z"))
- (use (match_operand 4 "" ""))]
+ (use (match_operand 4 "" ""))
+ (clobber (reg:SI REG_RETS))]
"! SIBLING_CALL_P (insn)"
"call (%1);"
[(set_attr "type" "call")
@@ -2100,7 +2181,8 @@
(define_insn "*call_symbol"
[(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" "Q"))
(match_operand 1 "general_operand" "g"))
- (use (match_operand 2 "" ""))]
+ (use (match_operand 2 "" ""))
+ (clobber (reg:SI REG_RETS))]
"! SIBLING_CALL_P (insn)
&& (!TARGET_ID_SHARED_LIBRARY || TARGET_LEAF_ID_SHARED_LIBRARY)
&& GET_CODE (operands[0]) == SYMBOL_REF
@@ -2126,7 +2208,8 @@
[(set (match_operand 0 "register_operand" "=d")
(call (mem:SI (match_operand:SI 1 "symbol_ref_operand" "Q"))
(match_operand 2 "general_operand" "g")))
- (use (match_operand 3 "" ""))]
+ (use (match_operand 3 "" ""))
+ (clobber (reg:SI REG_RETS))]
"! SIBLING_CALL_P (insn)
&& (!TARGET_ID_SHARED_LIBRARY || TARGET_LEAF_ID_SHARED_LIBRARY)
&& GET_CODE (operands[1]) == SYMBOL_REF
@@ -2152,7 +2235,8 @@
(define_insn "*call_insn"
[(call (mem:SI (match_operand:SI 0 "register_no_elim_operand" "a"))
(match_operand 1 "general_operand" "g"))
- (use (match_operand 2 "" ""))]
+ (use (match_operand 2 "" ""))
+ (clobber (reg:SI REG_RETS))]
"! SIBLING_CALL_P (insn)"
"call (%0);"
[(set_attr "type" "call")
@@ -2172,7 +2256,8 @@
[(set (match_operand 0 "register_operand" "=d")
(call (mem:SI (match_operand:SI 1 "register_no_elim_operand" "a"))
(match_operand 2 "general_operand" "g")))
- (use (match_operand 3 "" ""))]
+ (use (match_operand 3 "" ""))
+ (clobber (reg:SI REG_RETS))]
"! SIBLING_CALL_P (insn)"
"call (%1);"
[(set_attr "type" "call")
@@ -2641,23 +2726,26 @@
(define_insn "return_internal"
[(return)
- (unspec [(match_operand 0 "immediate_operand" "i")] UNSPEC_RETURN)]
+ (use (match_operand 0 "register_operand" ""))]
"reload_completed"
{
- switch (INTVAL (operands[0]))
+ switch (REGNO (operands[0]))
{
- case EXCPT_HANDLER:
+ case REG_RETX:
return "rtx;";
- case NMI_HANDLER:
+ case REG_RETN:
return "rtn;";
- case INTERRUPT_HANDLER:
+ case REG_RETI:
return "rti;";
- case SUBROUTINE:
+ case REG_RETS:
return "rts;";
}
gcc_unreachable ();
})
+;; When used at a location where CC contains 1, causes a speculative load
+;; that is later cancelled. This is used for certain workarounds in
+;; interrupt handler prologues.
(define_insn "dummy_load"
[(unspec_volatile [(match_operand 0 "register_operand" "a")
(match_operand 1 "register_operand" "C")]
@@ -2668,6 +2756,17 @@
(set_attr "length" "4")
(set_attr "seq_insns" "multi")])
+;; A placeholder insn inserted before the final scheduling pass. It is used
+;; to improve scheduling of loads when workarounds for speculative loads are
+;; needed, by not placing them in the first few cycles after a conditional
+;; branch.
+(define_insn "stall"
+ [(unspec_volatile [(match_operand 0 "const_int_operand" "P1P3")]
+ UNSPEC_VOLATILE_STALL)]
+ ""
+ ""
+ [(set_attr "type" "stall")])
+
(define_insn "csync"
[(unspec_volatile [(const_int 0)] UNSPEC_VOLATILE_CSYNC)]
""
@@ -2707,7 +2806,7 @@
(parallel [(const_int 1)]))))]
""
"%h0 = %h2 << 0%!"
- [(set_attr "type" "dsp32")])
+ [(set_attr "type" "dsp32shiftimm")])
(define_insn "movhiv2hi_high"
[(set (match_operand:V2HI 0 "register_operand" "=d")
@@ -2717,7 +2816,7 @@
(match_operand:HI 2 "register_operand" "d")))]
""
"%d0 = %h2 << 0%!"
- [(set_attr "type" "dsp32")])
+ [(set_attr "type" "dsp32shiftimm")])
;; No earlyclobber on alternative two since our sequence ought to be safe.
;; The order of operands is intentional to match the VDSP builtin (high word
@@ -2740,7 +2839,7 @@
(match_dup 2)
(vec_select:HI (match_dup 0) (parallel [(const_int 1)]))))]
""
- [(set_attr "type" "dsp32")])
+ [(set_attr "type" "dsp32shiftimm")])
; Like composev2hi, but operating on elements of V2HI vectors.
; Useful on its own, and as a combiner bridge for the multiply and
@@ -2763,7 +2862,7 @@
%0 = PACK (%h2,%d1)%!
%0 = PACK (%d2,%h1)%!
%0 = PACK (%d2,%d1)%!"
- [(set_attr "type" "dsp32")])
+ [(set_attr "type" "dsp32shiftimm,dsp32shiftimm,dsp32shiftimm,dsp32shiftimm,dsp32,dsp32,dsp32,dsp32")])
(define_insn "movv2hi_hi"
[(set (match_operand:HI 0 "register_operand" "=d,d,d")
@@ -2774,7 +2873,7 @@
/* optimized out */
%h0 = %h1 << 0%!
%h0 = %d1 << 0%!"
- [(set_attr "type" "dsp32")])
+ [(set_attr "type" "dsp32shiftimm")])
(define_expand "movv2hi_hi_low"
[(set (match_operand:HI 0 "register_operand" "")
@@ -4038,7 +4137,7 @@
%0 = ASHIFT %1 BY %h2 (V, S)%!
%0 = %1 << %2 (V,S)%!
%0 = %1 >>> %N2 (V,S)%!"
- [(set_attr "type" "dsp32")])
+ [(set_attr "type" "dsp32,dsp32shiftimm,dsp32shiftimm")])
(define_insn "ssashifthi3"
[(set (match_operand:HI 0 "register_operand" "=d,d,d")
@@ -4052,7 +4151,7 @@
%0 = ASHIFT %1 BY %h2 (V, S)%!
%0 = %1 << %2 (V,S)%!
%0 = %1 >>> %N2 (V,S)%!"
- [(set_attr "type" "dsp32")])
+ [(set_attr "type" "dsp32,dsp32shiftimm,dsp32shiftimm")])
(define_insn "ssashiftsi3"
[(set (match_operand:SI 0 "register_operand" "=d,d,d")
@@ -4066,7 +4165,7 @@
%0 = ASHIFT %1 BY %h2 (S)%!
%0 = %1 << %2 (S)%!
%0 = %1 >>> %N2 (S)%!"
- [(set_attr "type" "dsp32")])
+ [(set_attr "type" "dsp32,dsp32shiftimm,dsp32shiftimm")])
(define_insn "lshiftv2hi3"
[(set (match_operand:V2HI 0 "register_operand" "=d,d,d")
@@ -4080,7 +4179,7 @@
%0 = LSHIFT %1 BY %h2 (V)%!
%0 = %1 << %2 (V)%!
%0 = %1 >> %N2 (V)%!"
- [(set_attr "type" "dsp32")])
+ [(set_attr "type" "dsp32,dsp32shiftimm,dsp32shiftimm")])
(define_insn "lshifthi3"
[(set (match_operand:HI 0 "register_operand" "=d,d,d")
@@ -4094,7 +4193,7 @@
%0 = LSHIFT %1 BY %h2 (V)%!
%0 = %1 << %2 (V)%!
%0 = %1 >> %N2 (V)%!"
- [(set_attr "type" "dsp32")])
+ [(set_attr "type" "dsp32,dsp32shiftimm,dsp32shiftimm")])
;; Load without alignment exception (masking off low bits)
@@ -4106,3 +4205,5 @@
"DISALGNEXCPT || %0 = [%1];"
[(set_attr "type" "mcld")
(set_attr "length" "8")])
+
+(include "sync.md")