From 36662eb11d2e4a91dfe6560ff15d916680ac5df0 Mon Sep 17 00:00:00 2001 From: Bernd Schmidt Date: Wed, 22 Nov 2006 14:12:46 +0000 Subject: [PATCH] predicates.md (d_register_operand, [...]): New predicates. * 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. From-SVN: r119090 --- gcc/ChangeLog | 16 +++++++ gcc/config/bfin/bfin.c | 12 +++++- gcc/config/bfin/bfin.md | 78 ++++++++++++++++++++++++++++++++--- gcc/config/bfin/predicates.md | 33 +++++++++++++++ 4 files changed, 132 insertions(+), 7 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 665fe81fe28..500152838dc 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,19 @@ +2006-11-22 Bernd Schmidt + + * 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 * doc/c-tree.texi: Document new tree codes. diff --git a/gcc/config/bfin/bfin.c b/gcc/config/bfin/bfin.c index 10ccda2d99b..8a002685717 100644 --- a/gcc/config/bfin/bfin.c +++ b/gcc/config/bfin/bfin.c @@ -2816,8 +2816,15 @@ bfin_expand_movmem (rtx dst, rtx src, rtx count_exp, rtx align_exp) } return false; } - +/* Implement TARGET_SCHED_ISSUE_RATE. */ + +static int +bfin_issue_rate (void) +{ + return 3; +} + static int bfin_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost) { @@ -4527,6 +4534,9 @@ bfin_expand_builtin (tree exp, rtx target ATTRIBUTE_UNUSED, #undef TARGET_SCHED_ADJUST_COST #define TARGET_SCHED_ADJUST_COST bfin_adjust_cost +#undef TARGET_SCHED_ISSUE_RATE +#define TARGET_SCHED_ISSUE_RATE bfin_issue_rate + #undef TARGET_PROMOTE_PROTOTYPES #define TARGET_PROMOTE_PROTOTYPES hook_bool_tree_true #undef TARGET_PROMOTE_FUNCTION_ARGS diff --git a/gcc/config/bfin/bfin.md b/gcc/config/bfin/bfin.md index e509d0353ad..de4b8b48bbd 100644 --- a/gcc/config/bfin/bfin.md +++ b/gcc/config/bfin/bfin.md @@ -160,28 +160,94 @@ "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") ;; Operand and operator predicates @@ -254,7 +320,6 @@ (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" @@ -445,6 +510,7 @@ "" "%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 diff --git a/gcc/config/bfin/predicates.md b/gcc/config/bfin/predicates.md index 933b7f8e1b6..a0a796009eb 100644 --- a/gcc/config/bfin/predicates.md +++ b/gcc/config/bfin/predicates.md @@ -76,6 +76,11 @@ 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") @@ -171,3 +176,31 @@ ;; 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); +})