This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Blackfin patch [1/2]: Parallel instructions


The Blackfin has the capability to execute up to three instructions in
parallel.  The assembler notation for this is
  A || B || C;
where A must be part of a class of instructions that assemble to a
32-bit instruction word, while B and C must be load or store operations
that assemble to a 16-bit instruction, for a 64-bit bundle in total.
There are a couple of additional restrictions on valid combinations.

This patch adds scheduling support for this; the compiler will now
generate instructions in the right order but emit them as
  A;
  B;
  C;
i.e., not as a parallel instruction bundle.  That will be fixed by the
next patch.

Committed as 119090.


Bernd
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 119088)
+++ ChangeLog	(working copy)
@@ -1,3 +1,19 @@
+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.
Index: config/bfin/bfin.md
===================================================================
--- config/bfin/bfin.md	(revision 119048)
+++ config/bfin/bfin.md	(working copy)
@@ -160,28 +160,94 @@ (define_attr "type"
   "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 @@ (define_attr "length" ""
 
 	(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 @@ (define_insn "*popsi_insn"
   ""
   "%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
Index: config/bfin/predicates.md
===================================================================
--- config/bfin/predicates.md	(revision 119048)
+++ config/bfin/predicates.md	(working copy)
@@ -76,6 +76,11 @@ (define_predicate "valid_reg_operand"
   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 @@ (define_predicate "register_no_elim_oper
 ;; 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);
+})
Index: config/bfin/bfin.c
===================================================================
--- config/bfin/bfin.c	(revision 119055)
+++ config/bfin/bfin.c	(working copy)
@@ -2816,8 +2816,15 @@ bfin_expand_movmem (rtx dst, rtx src, rt
     }
   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 targe
 #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

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]