+2006-11-22 Bernd Schmidt <bernd.schmidt@analog.com>
+
+ * config/bfin/predicates.md (d_register_operand, mem_p_address_operand,
+ mem_i_address_operand): New predicates.
+ * config/bfin/bfin.c (bfin_issue_rate): New function.
+ (TARGET_SCHED_ISSUE_RATE): New macro.
+ * config/bfin/bfin.md (addrtype): New attribute.
+ (slot0, slot1, slot2, store, pregs): New cpu_units.
+ (core): Now a define_reservation.
+ (alu): Remove some insn types from this reservation.
+ (dsp32, load32, loadp, loadi, store32, storep, storei, multi): New
+ insn reservations.
+ (dummy reservation): Don't trigger for mcld insns.
+ (absence_sets): Two new absence sets to enforce slot ordering.
+ (popsi_insn): Set addrtype.
+
2006-11-22 Ira Rosen <irar@il.ibm.com>
* doc/c-tree.texi: Document new tree codes.
"move,mvi,mcld,mcst,dsp32,mult,alu0,shft,brcc,br,call,misc,sync,compare,dummy"
(const_string "misc"))
+(define_attr "addrtype" "32bit,preg,ireg"
+ (cond [(and (eq_attr "type" "mcld")
+ (and (match_operand 0 "d_register_operand" "")
+ (match_operand 1 "mem_p_address_operand" "")))
+ (const_string "preg")
+ (and (eq_attr "type" "mcld")
+ (and (match_operand 0 "d_register_operand" "")
+ (match_operand 1 "mem_i_address_operand" "")))
+ (const_string "ireg")
+ (and (eq_attr "type" "mcst")
+ (and (match_operand 1 "d_register_operand" "")
+ (match_operand 0 "mem_p_address_operand" "")))
+ (const_string "preg")
+ (and (eq_attr "type" "mcst")
+ (and (match_operand 1 "d_register_operand" "")
+ (match_operand 0 "mem_i_address_operand" "")))
+ (const_string "ireg")]
+ (const_string "32bit")))
+
;; Scheduling definitions
(define_automaton "bfin")
-(define_cpu_unit "core" "bfin")
+(define_cpu_unit "slot0" "bfin")
+(define_cpu_unit "slot1" "bfin")
+(define_cpu_unit "slot2" "bfin")
+
+;; Three units used to enforce parallel issue restrictions:
+;; only one of the 16 bit slots can use a P register in an address,
+;; and only one them can be a store.
+(define_cpu_unit "store" "bfin")
+(define_cpu_unit "pregs" "bfin")
+
+(define_reservation "core" "slot0+slot1+slot2")
(define_insn_reservation "alu" 1
- (eq_attr "type" "move,mvi,mcst,dsp32,alu0,shft,brcc,br,call,misc,sync,compare")
+ (eq_attr "type" "move,mvi,alu0,shft,brcc,br,call,misc,sync,compare")
"core")
(define_insn_reservation "imul" 3
(eq_attr "type" "mult")
"core*3")
-(define_insn_reservation "load" 1
- (eq_attr "type" "mcld")
+(define_insn_reservation "dsp32" 1
+ (eq_attr "type" "dsp32")
+ "slot0")
+
+(define_insn_reservation "load32" 1
+ (and (not (eq_attr "seq_insns" "multi"))
+ (and (eq_attr "type" "mcld") (eq_attr "addrtype" "32bit")))
+ "core")
+
+(define_insn_reservation "loadp" 1
+ (and (not (eq_attr "seq_insns" "multi"))
+ (and (eq_attr "type" "mcld") (eq_attr "addrtype" "preg")))
+ "(slot1|slot2)+pregs")
+
+(define_insn_reservation "loadi" 1
+ (and (not (eq_attr "seq_insns" "multi"))
+ (and (eq_attr "type" "mcld") (eq_attr "addrtype" "ireg")))
+ "(slot1|slot2)")
+
+(define_insn_reservation "store32" 1
+ (and (not (eq_attr "seq_insns" "multi"))
+ (and (eq_attr "type" "mcst") (eq_attr "addrtype" "32bit")))
"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")
+
+(define_insn_reservation "storei" 1
+ (and (not (eq_attr "seq_insns" "multi"))
+ (and (eq_attr "type" "mcst") (eq_attr "addrtype" "ireg")))
+ "(slot1|slot2)+store")
+
+(define_insn_reservation "multi" 2
+ (eq_attr "seq_insns" "multi")
+ "core")
+
+(absence_set "slot0" "slot1,slot2")
+(absence_set "slot1" "slot2")
+
;; Make sure genautomata knows about the maximum latency that can be produced
;; by the adjust_cost function.
(define_insn_reservation "dummy" 5
- (eq_attr "type" "mcld")
+ (eq_attr "type" "dummy")
"core")
\f
;; Operand and operator predicates
(const_int 2)))
-
;; Classify the insns into those that are one instruction and those that
;; are more than one in sequence.
(define_attr "seq_insns" "single,multi"
""
"%0 = [SP++];"
[(set_attr "type" "mcld")
+ (set_attr "addrtype" "preg")
(set_attr "length" "2")])
;; The first alternative is used to make reload choose a limited register
return 1;
})
+;; Return nonzero if OP is a D register.
+(define_predicate "d_register_operand"
+ (and (match_code "reg")
+ (match_test "D_REGNO_P (REGNO (op))")))
+
;; Return nonzero if OP is a LC register.
(define_predicate "lc_register_operand"
(and (match_code "reg")
;; Test for an operator valid in a conditional branch
(define_predicate "bfin_cbranch_operator"
(match_code "eq,ne"))
+
+;; The following two are used to compute the addrtype attribute. They return
+;; true if passed a memory address usable for a 16-bit load or store using a
+;; P or I register, respectively. If neither matches, we know we have a
+;; 32 bit instruction.
+(define_predicate "mem_p_address_operand"
+ (match_code "mem")
+{
+ if (effective_address_32bit_p (op, mode))
+ return 0;
+ op = XEXP (op, 0);
+ if (GET_CODE (op) == PLUS || GET_RTX_CLASS (GET_CODE (op)) == RTX_AUTOINC)
+ op = XEXP (op, 0);
+ gcc_assert (REG_P (op));
+ return PREG_P (op);
+})
+
+(define_predicate "mem_i_address_operand"
+ (match_code "mem")
+{
+ if (effective_address_32bit_p (op, mode))
+ return 0;
+ op = XEXP (op, 0);
+ if (GET_CODE (op) == PLUS || GET_RTX_CLASS (GET_CODE (op)) == RTX_AUTOINC)
+ op = XEXP (op, 0);
+ gcc_assert (REG_P (op));
+ return IREG_P (op);
+})