[itanium-sched-branch] Itanium1 DFA description [patch]

Vladimir Makarov vmakarov@redhat.com
Mon Sep 23 13:11:00 GMT 2002


  The following patch contains DFA description of Itanium1 process.
This is the first patch switching on usage of the DFA insn scheduler
but only before reload.

  The DFA description describes Itanium1 by (nondeterministic) DFA.
Nondeterminism is to try insert 0-2 nops before a real insn.  This is
important to guarantee issuing insn if it can be issued on a given
processor cycle.

  The following is compilation time (processor time) of Specint2000
tests (except for C++ test eon).

  gcc (--disable-checking) from itanium-sched-branchpoint  -- 28m29.871s
  gcc (--disable-checking) from itanium-sched-branch       -- 23m47.643s

The tests have been compiled on 733Mhz Itanium 1.

Vlad


2002-09-23  Vladimir Makarov  <vmakarov@redhat.com>

        * config/ia64/ia64.md: Add Itanium1 DFA description.
        (itanium_class): Add `nop' and `pre_cycle'.  Add
        define_function_unit for `nop'.
        (nop): Change attribute `itanium_class'.
        (pre_cycle): New define_insn.

        * config/ia64/ia64-protos.h (bundling_p): New external variable.
        (ia64_st_address_bypass_p, ia64_ld_address_bypass_p,
        ia64_produce_address_p): New function prototypes.

        * config/ia64/ia64.c (bundling_p): New global variable.
        (ia64_use_dfa_pipeline_interface,
        ia64_first_cycle_multipass_dfa_lookahead,
        ia64_init_dfa_pre_cycle_insn, ia64_dfa_pre_cycle_insn): New
        functions.
        (TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE,
        TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD,
        TARGET_SCHED_INIT_DFA_PRE_CYCLE_INSN,
        TARGET_SCHED_DFA_PRE_CYCLE_INSN): New macros.
        (ia64_sched_init, ia64_sched_reorder, ia64_sched_reorder2,
        ia64_variable_issue, ia64_sched_finish): Do nothing before
reload.
        (dfa_pre_cycle_insn): New variable.
        
Index: config/ia64/ia64-protos.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/ia64/ia64-protos.h,v
retrieving revision 1.46
diff -c -p -r1.46 ia64-protos.h
*** config/ia64/ia64-protos.h   9 Sep 2002 22:03:31 -0000       1.46
--- config/ia64/ia64-protos.h   23 Sep 2002 18:27:53 -0000
*************** extern GTY(()) rtx ia64_compare_op1;
*** 27,33 ****
--- 27,37 ----
  
  /* Functions defined in ia64.c */
  
+ extern int bundling_p;
  #ifdef RTX_CODE
+ extern int ia64_st_address_bypass_p PARAMS((rtx, rtx));
+ extern int ia64_ld_address_bypass_p PARAMS((rtx, rtx));
+ extern int ia64_produce_address_p PARAMS((rtx));
  extern int call_operand PARAMS((rtx, enum machine_mode));
  extern int sdata_symbolic_operand PARAMS((rtx, enum machine_mode));
  extern int got_symbolic_operand PARAMS((rtx, enum machine_mode));
Index: config/ia64/ia64.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/ia64/ia64.c,v
retrieving revision 1.184
diff -c -p -r1.184 ia64.c
*** config/ia64/ia64.c  9 Sep 2002 22:03:31 -0000       1.184
--- config/ia64/ia64.c  23 Sep 2002 18:27:54 -0000
*************** static int ia64_flag_schedule_insns2;
*** 109,115 ****
--- 109,124 ----
     sections.  */
  
  unsigned int ia64_section_threshold;
+ 
+ /* The following variable is used by the DFA insn scheduler.  The
value is
+    TRUE if we do insn bundling instead of insn scheduling.  */
+ int bundling_p = 0;
+ 
  
+ static int ia64_use_dfa_pipeline_interface PARAMS ((void));
+ static int ia64_first_cycle_multipass_dfa_lookahead PARAMS ((void));
+ static void ia64_init_dfa_pre_cycle_insn PARAMS ((void));
+ static rtx ia64_dfa_pre_cycle_insn PARAMS ((void));
  static rtx gen_tls_get_addr PARAMS ((void));
  static rtx gen_thread_pointer PARAMS ((void));
  static int find_gr_spill PARAMS ((int));
*************** static const struct attribute_spec ia64_
*** 239,244 ****
--- 248,264 ----
  #undef TARGET_SCHED_REORDER2
  #define TARGET_SCHED_REORDER2 ia64_sched_reorder2
  
+ #undef TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE
+ #define TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE
ia64_use_dfa_pipeline_interface
+ 
+ #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
+ #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
ia64_first_cycle_multipass_dfa_lookahead
+ 
+ #undef TARGET_SCHED_INIT_DFA_PRE_CYCLE_INSN
+ #define TARGET_SCHED_INIT_DFA_PRE_CYCLE_INSN
ia64_init_dfa_pre_cycle_insn
+ #undef TARGET_SCHED_DFA_PRE_CYCLE_INSN
+ #define TARGET_SCHED_DFA_PRE_CYCLE_INSN ia64_dfa_pre_cycle_insn
+ 
  #ifdef HAVE_AS_TLS
  #undef TARGET_HAVE_TLS
  #define TARGET_HAVE_TLS true
*************** emit_all_insn_group_barriers (dump, insn
*** 5164,5169 ****
--- 5184,5190 ----
        }
      }
  }
+ 
  
  static int errata_find_address_regs PARAMS ((rtx *, void *));
  static void errata_emit_nops PARAMS ((rtx));
*************** ia64_sched_init (dump, sched_verbose, ma
*** 5882,5887 ****
--- 5903,5911 ----
  {
    static int initialized = 0;
  
+   if (!reload_completed)
+     return;
+ 
    if (! initialized)
      {
        int b1, b2, i;
*************** ia64_sched_reorder (dump, sched_verbose,
*** 6553,6558 ****
--- 6577,6584 ----
       int *pn_ready;
       int clock_var;
  {
+   if (!reload_completed)
+     return 1;
    return ia64_internal_sched_reorder (dump, sched_verbose, ready,
                                      pn_ready, 0, clock_var);
  }
*************** ia64_sched_reorder2 (dump, sched_verbose
*** 6568,6573 ****
--- 6594,6602 ----
       int *pn_ready;
       int clock_var;
  {
+   if (!reload_completed)
+     return 1;
+ 
    if (sched_data.last_was_stop)
      return 0;
  
*************** ia64_variable_issue (dump, sched_verbose
*** 6697,6702 ****
--- 6726,6734 ----
  {
    enum attr_type t = ia64_safe_type (insn);
  
+   if (!reload_completed)
+     return 1;
+ 
    if (sched_data.last_was_stop)
      {
        int t = sched_data.first_slot;
*************** ia64_sched_finish (dump, sched_verbose)
*** 6755,6764 ****
--- 6787,6902 ----
  {
    if (sched_verbose)
      fprintf (dump, "// Finishing schedule.\n");
+   if (!reload_completed)
+     return;
    rotate_two_bundles (NULL);
    free (sched_types);
    free (sched_ready);
  }
+ 
+ 
+ 
+ /* If the following function returns TRUE, we will use the the DFA
+    insn scheduler.  */
+ static int
+ ia64_use_dfa_pipeline_interface ()
+ {
+   return !reload_completed;
+ }
+ 
+ /* If the following function returns TRUE, we will use the the DFA
+    insn scheduler.  */
+ static int
+ ia64_first_cycle_multipass_dfa_lookahead ()
+ {
+   return (!reload_completed ? 4 : 0);
+ }
+ 
+ /* The following variable value is pseudo-insn used by the DFA insn
+    scheduler to change the DFA state when the simulated clock is
+    increased.  */
+ static GTY (()) rtx dfa_pre_cycle_insn;
+ 
+ /* The following function initiates variable `dfa_pre_cycle_insn'.  */
+ static void
+ ia64_init_dfa_pre_cycle_insn ()
+ {
+   dfa_pre_cycle_insn = make_insn_raw (gen_pre_cycle ());
+   PREV_INSN (dfa_pre_cycle_insn) = NEXT_INSN (dfa_pre_cycle_insn) =
NULL_RTX;
+   recog_memoized (dfa_pre_cycle_insn);
+ }
+ 
+ /* The following function returns the pseudo insn DFA_PRE_CYCLE_INSN
+    used by the DFA insn scheduler.  */
+ static rtx
+ ia64_dfa_pre_cycle_insn ()
+ {
+   return dfa_pre_cycle_insn;
+ }
+ 
+ /* The following function returns TRUE if PRODUCER (of type ilog or
+    ld) produces address for CONSUMER (of type st or stf). */
+ int
+ ia64_st_address_bypass_p (producer, consumer)
+      rtx producer;
+      rtx consumer;
+ {
+   rtx dest, reg, mem;
+ 
+   if (producer == NULL_RTX || consumer == NULL_RTX)
+     abort ();
+   dest = ia64_single_set (producer);
+   if (dest == NULL_RTX || (reg = SET_DEST (dest)) == NULL_RTX
+       || (GET_CODE (reg) != REG && GET_CODE (reg) != SUBREG))
+     abort ();
+   if (GET_CODE (reg) == SUBREG)
+     reg = SUBREG_REG (reg);
+   dest = ia64_single_set (consumer);
+   if (dest == NULL_RTX || (mem = SET_DEST (dest)) == NULL_RTX
+       || GET_CODE (mem) != MEM)
+     abort ();
+   return reg_mentioned_p (reg, mem);
+ }
+ 
+ /* The following function returns TRUE if PRODUCER (of type ilog or
+    ld) produces address for CONSUMER (of type ld or fld). */
+ int
+ ia64_ld_address_bypass_p (producer, consumer)
+      rtx producer;
+      rtx consumer;
+ {
+   rtx dest, src, reg, mem;
+ 
+   if (producer == NULL_RTX || consumer == NULL_RTX)
+     abort ();
+   dest = ia64_single_set (producer);
+   if (dest == NULL_RTX || (reg = SET_DEST (dest)) == NULL_RTX
+       || (GET_CODE (reg) != REG && GET_CODE (reg) != SUBREG))
+     abort ();
+   if (GET_CODE (reg) == SUBREG)
+     reg = SUBREG_REG (reg);
+   src = ia64_single_set (consumer);
+   if (src == NULL_RTX || (mem = SET_SRC (src)) == NULL_RTX)
+     abort ();
+   if (GET_CODE (mem) == UNSPEC && XVECLEN (mem, 0) > 0)
+     mem = XVECEXP (mem, 0, 0);
+   while (GET_CODE (mem) == SUBREG || GET_CODE (mem) == ZERO_EXTEND)
+     mem = XEXP (mem, 0);
+   if (GET_CODE (mem) != MEM)
+     abort ();
+   return reg_mentioned_p (reg, mem);
+ }
+ 
+ /* The following function returns TRUE if INSN produces address for a
+    load/store insn.  We will place such insns into M slot because it
+    decreases its latency time. */
+ int
+ ia64_produce_address_p (insn)
+      rtx insn;
+ {
+   return insn->call;
+ }
+ 
  
  /* Emit pseudo-ops for the assembler to describe predicate relations.
     At present this assumes that we only consider predicate pairs to
Index: config/ia64/ia64.md
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/ia64/ia64.md,v
retrieving revision 1.90
diff -c -p -r1.90 ia64.md
*** config/ia64/ia64.md 16 Jul 2002 16:07:13 -0000      1.90
--- config/ia64/ia64.md 23 Sep 2002 18:27:54 -0000
***************
*** 110,117 ****
  (define_attr "itanium_class"
"unknown,ignore,stop_bit,br,fcmp,fcvtfx,fld,
        fmac,fmisc,frar_i,frar_m,frbr,frfr,frpr,ialu,icmp,ilog,ishf,ld,
        chk_s,long_i,mmmul,mmshf,mmshfi,rse_m,scall,sem,stf,st,syst_m0,
!       syst_m,tbit,toar_i,toar_m,tobr,tofr,topr,xmpy,xtd,nop_b,nop_f,
!       nop_i,nop_m,nop_x,lfetch"
    (const_string "unknown"))
  
  ;; chk_s has an I and an M form; use type A for convenience.
--- 110,117 ----
  (define_attr "itanium_class"
"unknown,ignore,stop_bit,br,fcmp,fcvtfx,fld,
        fmac,fmisc,frar_i,frar_m,frbr,frfr,frpr,ialu,icmp,ilog,ishf,ld,
        chk_s,long_i,mmmul,mmshf,mmshfi,rse_m,scall,sem,stf,st,syst_m0,
!      
syst_m,tbit,toar_i,toar_m,tobr,tofr,topr,xmpy,xtd,nop,nop_b,nop_f,
!       nop_i,nop_m,nop_x,lfetch,pre_cycle"
    (const_string "unknown"))
  
  ;; chk_s has an I and an M form; use type A for convenience.
***************
*** 145,151 ****
  
  (define_attr "predicable" "no,yes" (const_string "yes"))
  
- 
  ;; ::::::::::::::::::::
  ;; ::
  ;; :: Function Units
--- 145,150 ----
***************
*** 207,212 ****
--- 206,212 ----
  (define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "xmpy")   7
0)
  (define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "xtd")    1
0)
  
+ (define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "nop")    0
0)
  (define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "nop_m")  0
0)
  (define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "nop_i")  0
0)
  (define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "nop_f")  0
0)
***************
*** 216,221 ****
--- 216,1127 ----
  (define_function_unit "stop_bit" 1 1 (eq_attr "itanium_class"
"stop_bit") 0 0)
  (define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "ignore") 0
0)
  (define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "unknown")
0 0)
+ 
+ 
+ 
+ /* This is description of pipeline hazards based on DFA.  The
+    following constructions can be used for this:
+    
+    o define_cpu_unit string [string]) describes a cpu functional unit
+      (separated by comma).
+ 
+      1st operand: Names of cpu function units.
+      2nd operand: Name of automaton (see comments for
+      DEFINE_AUTOMATON).
+ 
+      All define_reservations and define_cpu_units should have unique
+      names which can not be "nothing".
+ 
+    o (exclusion_set string string) means that each CPU function unit
+      in the first string can not be reserved simultaneously with each
+      unit whose name is in the second string and vise versa.  CPU
+      units in the string are separated by commas. For example, it is
+      useful for description CPU with fully pipelined floating point
+      functional unit which can execute simultaneously only single
+      floating point insns or only double floating point insns.
+ 
+    o (presence_set string string) means that each CPU function unit in
+      the first string can not be reserved unless at least one of
+      pattern of units whose names are in the second string is
+      reserved.  This is an asymmetric relation.  CPU units or unit
+      patterns in the strings are separated by commas.  Pattern is one
+      unit name or unit names separated by white-spaces.
+  
+      For example, it is useful for description that slot1 is reserved
+      after slot0 reservation for a VLIW processor.  We could describe
+      it by the following construction
+ 
+          (presence_set "slot1" "slot0")
+ 
+      Or slot1 is reserved only after slot0 and unit b0 reservation.
+      In this case we could write
+ 
+          (presence_set "slot1" "slot0 b0")
+ 
+      All CPU functional units in a set should belong to the same
+      automaton.
+ 
+    o (final_presence_set string string) is analogous to
+      `presence_set'.  The difference between them is when checking is
+      done.  When an instruction is issued in given automaton state
+      reflecting all current and planned unit reservations, the
+      automaton state is changed.  The first state is a source state,
+      the second one is a result state.  Checking for `presence_set' is
+      done on the source state reservation, checking for
+      `final_presence_set' is done on the result reservation.  This
+      construction is useful to describe a reservation which is
+      actually two subsequent reservations.  For example, if we use
+ 
+          (presence_set "slot1" "slot0")
+ 
+      the following insn will be never issued (because slot1 requires
+      slot0 which is absent in the source state).
+ 
+          (define_reservation "insn_and_nop" "slot0 + slot1")
+ 
+      but it can be issued if we use analogous `final_presence_set'.
+ 
+    o (absence_set string string) means that each CPU function unit in
+      the first string can be reserved only if each pattern of units
+      whose names are in the second string is not reserved.  This is an
+      asymmetric relation (actually exclusion set is analogous to this
+      one but it is symmetric).  CPU units or unit patterns in the
+      string are separated by commas.  Pattern is one unit name or unit
+      names separated by white-spaces.
+ 
+      For example, it is useful for description that slot0 can not be
+      reserved after slot1 or slot2 reservation for a VLIW processor.
+      We could describe it by the following construction
+ 
+         (absence_set "slot2" "slot0, slot1")
+ 
+      Or slot2 can not be reserved if slot0 and unit b0 are reserved or
+      slot1 and unit b1 are reserved .  In this case we could write
+ 
+         (absence_set "slot2" "slot0 b0, slot1 b1")
+ 
+      All CPU functional units in a set should to belong the same
+      automaton.
+ 
+    o (final_absence_set string string) is analogous to `absence_set'
but
+      checking is done on the result (state) reservation.  See comments
+      for final_presence_set.
+ 
+    o (define_bypass number out_insn_names in_insn_names) names bypass
with
+      given latency (the first number) from insns given by the first
+      string (see define_insn_reservation) into insns given by the
+      second string.  Insn names in the strings are separated by
+      commas.
+ 
+    o (define_automaton string) describes names of an automaton
+      generated and used for pipeline hazards recognition.  The names
+      are separated by comma.  Actually it is possibly to generate the
+      single automaton but unfortunately it can be very large.  If we
+      use more one automata, the summary size of the automata usually
+      is less than the single one.  The automaton name is used in
+      define_cpu_unit.  All automata should have unique names.
+ 
+    o (automata_option string) describes option for generation of
+      automata.  Currently there are the following options:
+ 
+      o "no-minimization" which makes no minimization of automata.
+        This is only worth to do when we are debugging the description
+        and need to look more accurately at reservations of states.
+ 
+      o "ndfa" which makes automata with nondetermenistic reservation
+         by insns.
+ 
+    o (define_reservation string string) names reservation (the first
+      string) of cpu functional units (the 2nd string).  Sometimes unit
+      reservations for different insns contain common parts.  In such
+      case, you describe common part and use one its name (the 1st
+      parameter) in regular expression in define_insn_reservation.  All
+      define_reservations, define results and define_cpu_units should
+      have unique names which can not be "nothing".
+ 
+    o (define_insn_reservation name default_latency condition regexpr)
+      describes reservation of cpu functional units (the 3nd operand)
+      for instruction which is selected by the condition (the 2nd
+      parameter).  The first parameter is used for output of debugging
+      information.  The reservations are described by a regular
+      expression according the following syntax:
+ 
+        regexp = regexp "," oneof
+               | oneof
+ 
+        oneof = oneof "|" allof
+              | allof
+ 
+        allof = allof "+" repeat
+              | repeat
+  
+        repeat = element "*" number
+               | element
+ 
+        element = cpu_function_name
+                | reservation_name
+                | result_name
+                | "nothing"
+                | "(" regexp ")"
+ 
+        1. "," is used for describing start of the next cycle in
+           reservation.
+ 
+        2. "|" is used for describing the reservation described by the
+           first regular expression *or* the reservation described by
+           the second regular expression *or* etc.
+ 
+        3. "+" is used for describing the reservation described by the
+           first regular expression *and* the reservation described by
+           the second regular expression *and* etc.
+ 
+        4. "*" is used for convinience and simply means sequence in
+           which the regular expression are repeated NUMBER times with
+           cycle advancing (see ",").
+ 
+        5. cpu function unit name which means reservation.
+ 
+        6. reservation name -- see define_reservation.
+ 
+        7. string "nothing" means no units reservation.
+ 
+ */
+ 
+ (automata_option "ndfa")
+ (automata_option "v")
+ (automata_option "w")
+ 
+
;;============================================================================
+ ;;
+ ;;                        Itanium 1
+ ;;
+
;;============================================================================
+ 
+ (define_automaton "one")
+ 
+ ;;   All possible combinations of bundles/syllables
+ (define_cpu_unit "1_0m.ii, 1_0m.mi, 1_0m.fi, 1_0m.mf, 1_0b.bb,
1_0m.bb,\
+                   1_0m.ib, 1_0m.mb, 1_0m.fb, 1_0m.lx" "one")
+ (define_cpu_unit "1_0mi.i, 1_0mm.i, 1_0mf.i, 1_0mm.f, 1_0bb.b,
1_0mb.b,\
+                   1_0mi.b, 1_0mm.b, 1_0mf.b, 1_0mlx." "one")
+ (define_cpu_unit "1_0mii., 1_0mmi., 1_0mfi., 1_0mmf., 1_0bbb.,
1_0mbb.,\
+                   1_0mib., 1_0mmb., 1_0mfb." "one")
+ 
+ (define_cpu_unit "1_1m.ii, 1_1m.mi, 1_1m.fi, 1_1b.bb, 1_1m.bb,\
+                   1_1m.ib, 1_1m.mb, 1_1m.fb, 1_1m.lx" "one")
+ (define_cpu_unit "1_1mi.i, 1_1mm.i, 1_1mf.i, 1_1bb.b, 1_1mb.b,\
+                   1_1mi.b, 1_1mm.b, 1_1mf.b, 1_1mlx." "one")
+ (define_cpu_unit "1_1mii., 1_1mmi., 1_1mfi., 1_1bbb., 1_1mbb.,\
+                   1_1mib., 1_1mmb., 1_1mfb." "one")
+ 
+ ;; Slot 1
+ (exclusion_set "1_0m.ii"
+    "1_0m.mi, 1_0m.fi, 1_0m.mf, 1_0b.bb, 1_0m.bb, 1_0m.ib, 1_0m.mb,
1_0m.fb,\
+     1_0m.lx")
+ (exclusion_set "1_0m.mi"
+    "1_0m.fi, 1_0m.mf, 1_0b.bb, 1_0m.bb, 1_0m.ib, 1_0m.mb, 1_0m.fb,
1_0m.lx")
+ (exclusion_set "1_0m.fi"
+    "1_0m.mf, 1_0b.bb, 1_0m.bb, 1_0m.ib, 1_0m.mb, 1_0m.fb, 1_0m.lx")
+ (exclusion_set "1_0m.mf"
+    "1_0b.bb, 1_0m.bb, 1_0m.ib, 1_0m.mb, 1_0m.fb, 1_0m.lx")
+ (exclusion_set "1_0b.bb" "1_0m.bb, 1_0m.ib, 1_0m.mb, 1_0m.fb,
1_0m.lx")
+ (exclusion_set "1_0m.bb" "1_0m.ib, 1_0m.mb, 1_0m.fb, 1_0m.lx")
+ (exclusion_set "1_0m.ib" "1_0m.mb, 1_0m.fb, 1_0m.lx")
+ (exclusion_set "1_0m.mb" "1_0m.fb, 1_0m.lx")
+ (exclusion_set "1_0m.fb" "1_0m.lx")
+ 
+ ;; Slot 2
+ (exclusion_set "1_0mi.i"
+    "1_0mm.i, 1_0mf.i, 1_0mm.f, 1_0bb.b, 1_0mb.b, 1_0mi.b, 1_0mm.b,
1_0mf.b,\
+     1_0mlx.")
+ (exclusion_set "1_0mm.i"
+    "1_0mf.i, 1_0mm.f, 1_0bb.b, 1_0mb.b, 1_0mi.b, 1_0mm.b, 1_0mf.b,
1_0mlx.")
+ (exclusion_set "1_0mf.i"
+    "1_0mm.f, 1_0bb.b, 1_0mb.b, 1_0mi.b, 1_0mm.b, 1_0mf.b, 1_0mlx.")
+ (exclusion_set "1_0mm.f"
+    "1_0bb.b, 1_0mb.b, 1_0mi.b, 1_0mm.b, 1_0mf.b, 1_0mlx.")
+ (exclusion_set "1_0bb.b" "1_0mb.b, 1_0mi.b, 1_0mm.b, 1_0mf.b,
1_0mlx.")
+ (exclusion_set "1_0mb.b" "1_0mi.b, 1_0mm.b, 1_0mf.b, 1_0mlx.")
+ (exclusion_set "1_0mi.b" "1_0mm.b, 1_0mf.b, 1_0mlx.")
+ (exclusion_set "1_0mm.b" "1_0mf.b, 1_0mlx.")
+ (exclusion_set "1_0mf.b" "1_0mlx.")
+ 
+ ;; Slot 3
+ (exclusion_set "1_0mii."
+    "1_0mmi., 1_0mfi., 1_0mmf., 1_0bbb., 1_0mbb., 1_0mib., 1_0mmb.,
1_0mfb.,\
+     1_0mlx.")
+ (exclusion_set "1_0mmi."
+    "1_0mfi., 1_0mmf., 1_0bbb., 1_0mbb., 1_0mib., 1_0mmb., 1_0mfb.,
1_0mlx.")
+ (exclusion_set "1_0mfi."
+    "1_0mmf., 1_0bbb., 1_0mbb., 1_0mib., 1_0mmb., 1_0mfb., 1_0mlx.")
+ (exclusion_set "1_0mmf."
+    "1_0bbb., 1_0mbb., 1_0mib., 1_0mmb., 1_0mfb., 1_0mlx.")
+ (exclusion_set "1_0bbb." "1_0mbb., 1_0mib., 1_0mmb., 1_0mfb.,
1_0mlx.")
+ (exclusion_set "1_0mbb." "1_0mib., 1_0mmb., 1_0mfb., 1_0mlx.")
+ (exclusion_set "1_0mib." "1_0mmb., 1_0mfb., 1_0mlx.")
+ (exclusion_set "1_0mmb." "1_0mfb., 1_0mlx.")
+ (exclusion_set "1_0mfb." "1_0mlx.")
+ 
+ ;; Slot 4
+ (exclusion_set "1_1m.ii"
+    "1_1m.mi, 1_1m.fi, 1_1b.bb, 1_1m.bb, 1_1m.ib, 1_1m.mb, 1_1m.fb,
1_1m.lx")
+ (exclusion_set "1_1m.mi"
+    "1_1m.fi, 1_1b.bb, 1_1m.bb, 1_1m.ib, 1_1m.mb, 1_1m.fb, 1_1m.lx")
+ (exclusion_set "1_1m.fi"
+    "1_1b.bb, 1_1m.bb, 1_1m.ib, 1_1m.mb, 1_1m.fb, 1_1m.lx")
+ (exclusion_set "1_1b.bb" "1_1m.bb, 1_1m.ib, 1_1m.mb, 1_1m.fb,
1_1m.lx")
+ (exclusion_set "1_1m.bb" "1_1m.ib, 1_1m.mb, 1_1m.fb, 1_1m.lx")
+ (exclusion_set "1_1m.ib" "1_1m.mb, 1_1m.fb, 1_1m.lx")
+ (exclusion_set "1_1m.mb" "1_1m.fb, 1_1m.lx")
+ (exclusion_set "1_1m.fb" "1_1m.lx")
+ 
+ ;; Slot 5
+ (exclusion_set "1_1mi.i"
+    "1_1mm.i, 1_1mf.i, 1_1bb.b, 1_1mb.b, 1_1mi.b, 1_1mm.b, 1_1mf.b,
1_1mlx.")
+ (exclusion_set "1_1mm.i"
+    "1_1mf.i, 1_1bb.b, 1_1mb.b, 1_1mi.b, 1_1mm.b, 1_1mf.b, 1_1mlx.")
+ (exclusion_set "1_1mf.i"
+    "1_1bb.b, 1_1mb.b, 1_1mi.b, 1_1mm.b, 1_1mf.b, 1_1mlx.")
+ (exclusion_set "1_1bb.b" "1_1mb.b, 1_1mi.b, 1_1mm.b, 1_1mf.b,
1_1mlx.")
+ (exclusion_set "1_1mb.b" "1_1mi.b, 1_1mm.b, 1_1mf.b, 1_1mlx.")
+ (exclusion_set "1_1mi.b" "1_1mm.b, 1_1mf.b, 1_1mlx.")
+ (exclusion_set "1_1mm.b" "1_1mf.b, 1_1mlx.")
+ (exclusion_set "1_1mf.b" "1_1mlx.")
+ 
+ ;; Slot 6
+ (exclusion_set "1_1mii."
+    "1_1mmi., 1_1mfi., 1_1bbb., 1_1mbb., 1_1mib., 1_1mmb., 1_1mfb.,
1_1mlx.")
+ (exclusion_set "1_1mmi."
+    "1_1mfi., 1_1bbb., 1_1mbb., 1_1mib., 1_1mmb., 1_1mfb., 1_1mlx.")
+ (exclusion_set "1_1mfi."
+    "1_1bbb., 1_1mbb., 1_1mib., 1_1mmb., 1_1mfb., 1_1mlx.")
+ (exclusion_set "1_1bbb." "1_1mbb., 1_1mib., 1_1mmb., 1_1mfb.,
1_1mlx.")
+ (exclusion_set "1_1mbb." "1_1mib., 1_1mmb., 1_1mfb., 1_1mlx.")
+ (exclusion_set "1_1mib." "1_1mmb., 1_1mfb., 1_1mlx.")
+ (exclusion_set "1_1mmb." "1_1mfb., 1_1mlx.")
+ (exclusion_set "1_1mfb." "1_1mlx.")
+ 
+ (final_presence_set "1_0mi.i" "1_0m.ii")
+ (final_presence_set "1_0mii." "1_0mi.i")
+ (final_presence_set "1_1mi.i" "1_1m.ii")
+ (final_presence_set "1_1mii." "1_1mi.i")
+ 
+ (final_presence_set "1_0mm.i" "1_0m.mi")
+ (final_presence_set "1_0mmi." "1_0mm.i")
+ (final_presence_set "1_1mm.i" "1_1m.mi")
+ (final_presence_set "1_1mmi." "1_1mm.i")
+ 
+ (final_presence_set "1_0mf.i" "1_0m.fi")
+ (final_presence_set "1_0mfi." "1_0mf.i")
+ (final_presence_set "1_1mf.i" "1_1m.fi")
+ (final_presence_set "1_1mfi." "1_1mf.i")
+ 
+ (final_presence_set "1_0mm.f" "1_0m.mf")
+ (final_presence_set "1_0mmf." "1_0mm.f")
+ 
+ (final_presence_set "1_0bb.b" "1_0b.bb")
+ (final_presence_set "1_0bbb." "1_0bb.b")
+ (final_presence_set "1_1bb.b" "1_1b.bb")
+ (final_presence_set "1_1bbb." "1_1bb.b")
+ 
+ (final_presence_set "1_0mb.b" "1_0m.bb")
+ (final_presence_set "1_0mbb." "1_0mb.b")
+ (final_presence_set "1_1mb.b" "1_1m.bb")
+ (final_presence_set "1_1mbb." "1_1mb.b")
+ 
+ (final_presence_set "1_0mi.b" "1_0m.ib")
+ (final_presence_set "1_0mib." "1_0mi.b")
+ (final_presence_set "1_1mi.b" "1_1m.ib")
+ (final_presence_set "1_1mib." "1_1mi.b")
+ 
+ (final_presence_set "1_0mm.b" "1_0m.mb")
+ (final_presence_set "1_0mmb." "1_0mm.b")
+ (final_presence_set "1_1mm.b" "1_1m.mb")
+ (final_presence_set "1_1mmb." "1_1mm.b")
+ 
+ (final_presence_set "1_0mf.b" "1_0m.fb")
+ (final_presence_set "1_0mfb." "1_0mf.b")
+ (final_presence_set "1_1mf.b" "1_1m.fb")
+ (final_presence_set "1_1mfb." "1_1mf.b")
+ 
+ (final_presence_set "1_0mlx." "1_0m.lx")
+ (final_presence_set "1_1mlx." "1_1m.lx")
+ 
+ (final_presence_set
+   
"1_1m.ii,1_1m.mi,1_1m.fi,1_1b.bb,1_1m.bb,1_1m.ib,1_1m.mb,1_1m.fb,1_1m.lx"
+   
"1_0mii.,1_0mmi.,1_0mfi.,1_0mmf.,1_0bbb.,1_0mbb.,1_0mib.,1_0mmb.,1_0mfb.,\
+     1_0mlx.")
+ 
+ ;;  Microarchitecture units:
+ (define_cpu_unit
+    "1_um0, 1_um1, 1_ui0, 1_ui1, 1_uf0, 1_uf1, 1_ub0, 1_ub1, 1_ub2,\
+     1_unb0, 1_unb1, 1_unb2" "one")
+ 
+ (exclusion_set "1_ub0" "1_unb0")
+ (exclusion_set "1_ub1" "1_unb1")
+ (exclusion_set "1_ub2" "1_unb2")
+ 
+ ;; The following rules are used to decrease number of alternatives.
+ ;; They are consequences of Itanium microarchitecture.  They also
+ ;; describe the following rules mentioned in Itanium
+ ;; microarchitecture: rules mentioned in Itanium microarchitecture:
+ ;; o "MMF: Always splits issue before the first M and after F
regardless
+ ;;   of surrounding bundles and stops".
+ ;; o "BBB/MBB: Always splits issue after either of these bundles".
+ ;; o "MIB BBB: Split issue after the first bundle in this pair".
+ 
+ (exclusion_set "1_0m.mf,1_0mm.f,1_0mmf."
+   
"1_1m.ii,1_1m.mi,1_1m.fi,1_1b.bb,1_1m.bb,1_1m.ib,1_1m.mb,1_1m.fb,1_1m.lx")
+ (exclusion_set "1_0b.bb,1_0bb.b,1_0bbb.,1_0m.bb,1_0mb.b,1_0mbb."
+   
"1_1m.ii,1_1m.mi,1_1m.fi,1_1b.bb,1_1m.bb,1_1m.ib,1_1m.mb,1_1m.fb,1_1m.lx")
+ (exclusion_set "1_0m.ib,1_0mi.b,1_0mib." "1_1b.bb")
+ 
+ ;;  For exceptions of M, I, B, F insns:
+ (define_cpu_unit "1_not_um1, 1_not_ui1, 1_not_uf1" "one")
+ 
+ (final_absence_set "1_not_um1"  "1_um1")
+ (final_absence_set "1_not_ui1"  "1_ui1")
+ (final_absence_set "1_not_uf1"  "1_uf1")
+ 
+ ;;; "MIB/MFB/MMB: Splits issue after any of these bundles unless the
+ ;;; B-slot contains a nop.b or a brp instruction".
+ ;;;   "The B in an MIB/MFB/MMB bundle disperses to B0 if it is a brp
or
+ ;;; nop.b, otherwise it disperses to B2".
+ (final_absence_set
+    "1_1m.ii, 1_1m.mi, 1_1m.fi, 1_1b.bb, 1_1m.bb, 1_1m.ib, 1_1m.mb,
1_1m.fb,\
+     1_1m.lx"
+    "1_0mib. 1_ub2, 1_0mfb. 1_ub2, 1_0mmb. 1_ub2")
+ 
+ ;; This is necessary to start new processor cycle when we meet stop
bit.
+ (define_cpu_unit "1_stop" "one")
+ (final_absence_set
+   
"1_0m.ii,1_0mi.i,1_0mii.,1_0m.mi,1_0mm.i,1_0mmi.,1_0m.fi,1_0mf.i,1_0mfi.,\
+    
1_0m.mf,1_0mm.f,1_0mmf.,1_0b.bb,1_0bb.b,1_0bbb.,1_0m.bb,1_0mb.b,1_0mbb.,\
+    
1_0m.ib,1_0mi.b,1_0mib.,1_0m.mb,1_0mm.b,1_0mmb.,1_0m.fb,1_0mf.b,1_0mfb.,\
+     1_0m.lx,1_0mlx., \
+    
1_1m.ii,1_1mi.i,1_1mii.,1_1m.mi,1_1mm.i,1_1mmi.,1_1m.fi,1_1mf.i,1_1mfi.,\
+    
1_1b.bb,1_1bb.b,1_1bbb.,1_1m.bb,1_1mb.b,1_1mbb.,1_1m.ib,1_1mi.b,1_1mib.,\
+     1_1m.mb,1_1mm.b,1_1mmb.,1_1m.fb,1_1mf.b,1_1mfb.,1_1m.lx,1_1mlx."
+    "1_stop")
+ 
+ ;; M and I instruction is dispersed to the lowest numbered M or I unit
+ ;; not already in use.  An I slot in the 3rd position of 2nd bundle is
+ ;; always dispersed to I1
+ (final_presence_set "1_um1" "1_um0")
+ (final_presence_set "1_ui1" "1_ui0, 1_1mii., 1_1mmi., 1_1mfi.")
+ 
+ ;; Insns
+ 
+ ;; M and I instruction is dispersed to the lowest numbered M or I unit
+ ;; not already in use.  An I slot in the 3rd position of 2nd bundle is
+ ;; always dispersed to I1
+ (define_reservation "1_M0"
+   "1_0m.ii+1_um0|1_0m.mi+1_um0|1_0mm.i+(1_um0|1_um1)\
+    |1_0m.fi+1_um0|1_0m.mf+1_um0|1_0mm.f+1_um1\
+    |1_0m.bb+1_um0|1_0m.ib+1_um0|1_0m.mb+1_um0\
+    |1_0mm.b+1_um1|1_0m.fb+1_um0|1_0m.lx+1_um0\
+    |1_1mm.i+1_um1|1_1mm.b+1_um1\
+    |(1_1m.ii|1_1m.mi|1_1m.fi|1_1m.bb|1_1m.ib|1_1m.mb|1_1m.fb|1_1m.lx)\
+     +(1_um0|1_um1)")
+ 
+ (define_reservation "1_M1"
+   "(1_0mii.+(1_ui0|1_ui1)|1_0mmi.+1_ui0|1_0mfi.+1_ui0\
+     |1_0mib.+1_unb0|1_0mfb.+1_unb0|1_0mmb.+1_unb0)\
+     
+(1_1m.ii|1_1m.mi|1_1m.fi|1_1m.bb|1_1m.ib|1_1m.mb|1_1m.fb|1_1m.lx)\
+      +(1_um0|1_um1)")
+ 
+ (define_reservation "1_M" "1_M0|1_M1")
+ 
+ ;;  Exceptions for dispersal rules.
+ ;; "An I slot in the 3rd position of 2nd bundle is always dispersed to
I1".
+ (define_reservation "1_I0"
+   "1_0mi.i+1_ui0|1_0mii.+(1_ui0|1_ui1)|1_0mmi.+1_ui0|1_0mfi.+1_ui0\
+    |1_0mi.b+1_ui0|(1_1mi.i|1_1mi.b)+(1_ui0|1_ui1)\
+    |1_1mii.+1_ui1|1_1mmi.+1_ui1|1_1mfi.+1_ui1")
+ 
+ (define_reservation "1_I1"
+   "1_0m.ii+1_um0+1_0mi.i+1_ui0|1_0mm.i+(1_um0|1_um1)+1_0mmi.+1_ui0\
+    |1_0mf.i+1_uf0+1_0mfi.+1_ui0|1_0m.ib+1_um0+1_0mi.b+1_ui0\
+    |(1_1m.ii+(1_um0|1_um1)+1_1mi.i\
+    |1_1m.ib+(1_um0|1_um1)+1_1mi.b)+(1_ui0|1_ui1)\
+    |1_1mm.i+1_um1+1_1mmi.+1_ui1|1_1mf.i+1_uf1+1_1mfi.+1_ui1")
+ 
+ (define_reservation "1_I" "1_I0|1_I1")
+ 
+ ;; "An F slot in the 1st bundle disperses to F0".
+ ;; "An F slot in the 2st bundle disperses to F1".
+ (define_reservation "1_F0"
+   
"1_0mf.i+1_uf0|1_0mmf.+1_uf0|1_0mf.b+1_uf0|1_1mf.i+1_uf1|1_1mf.b+1_uf1")
+ 
+ (define_reservation "1_F1"
+    "1_0m.fi+1_um0+1_0mf.i+1_uf0|1_0mm.f+(1_um0|1_um1)+1_0mmf.+1_uf0\
+     |1_0m.fb+1_um0+1_0mf.b+1_uf0|1_1m.fi+(1_um0|1_um1)+1_1mf.i+1_uf1\
+     |1_1m.fb+(1_um0|1_um1)+1_1mf.b+1_uf1")
+ 
+ (define_reservation "1_F2"
+    "1_0m.mf+1_um0+1_0mm.f+1_um1+1_0mmf.+1_uf0\
+     |(1_0mii.+(1_ui0|1_ui1)|1_0mmi.+1_ui0|1_0mfi.+1_ui0\
+       |1_0mib.+1_unb0|1_0mmb.+1_unb0|1_0mfb.+1_unb0)\
+      +(1_1m.fi+(1_um0|1_um1)+1_1mf.i+1_uf1\
+        |1_1m.fb+(1_um0|1_um1)+1_1mf.b+1_uf1)")
+ 
+ (define_reservation "1_F" "1_F0|1_F1|1_F2")
+ 
+ ;;; "Each B slot in MBB or BBB bundle disperses to the corresponding B
+ ;;; unit. That is, a B slot in 1st position is despersed to B0.  In
the
+ ;;; 2nd position it is dispersed to B2".
+ (define_reservation "1_NB"
+     "1_0b.bb+1_unb0|1_0bb.b+1_unb1|1_0bbb.+1_unb2\
+      |1_0mb.b+1_unb1|1_0mbb.+1_unb2\
+      |1_0mib.+1_unb0|1_0mmb.+1_unb0|1_0mfb.+1_unb0\
+      |1_1b.bb+1_unb0|1_1bb.b+1_unb1\
+      |1_1bbb.+1_unb2|1_1mb.b+1_unb1|1_1mbb.+1_unb2|1_1mib.+1_unb0\
+      |1_1mmb.+1_unb0|1_1mfb.+1_unb0")
+ 
+ (define_reservation "1_B0"
+    "1_0b.bb+1_ub0|1_0bb.b+1_ub1|1_0bbb.+1_ub2\
+     |1_0mb.b+1_ub1|1_0mbb.+1_ub2|1_0mib.+1_ub2\
+     |1_0mfb.+1_ub2|1_1b.bb+1_ub0|1_1bb.b+1_ub1\
+     |1_1bbb.+1_ub2|1_1mb.b+1_ub1\
+     |1_1mib.+1_ub2|1_1mmb.+1_ub2|1_1mfb.+1_ub2")
+ 
+ (define_reservation "1_B1"
+    "1_0m.bb+1_um0+1_0mb.b+1_ub1|1_0mi.b+1_ui0+1_0mib.+1_ub2\
+     |1_0mf.b+1_uf0+1_0mfb.+1_ub2\
+    
|(1_0mii.+(1_ui0|1_ui1)|1_0mmi.+1_ui0|1_0mfi.+1_ui0)+1_1b.bb+1_ub0\
+     |1_1m.bb+(1_um0|1_um1)+1_1mb.b+1_ub1\
+     |1_1mi.b+(1_ui0|1_ui1)+1_1mib.+1_ub2\
+     |1_1mm.b+1_um1+1_1mmb.+1_ub2\
+     |1_1mf.b+1_uf1+1_1mfb.+1_ub2")
+ 
+ (define_reservation "1_B" "1_B0|1_B1")
+ 
+ ;; MLX bunlde uses ports equivalent to MFI bundles.
+ (define_reservation "1_L0"
"1_0mlx.+1_ui0+1_uf0|1_1mlx.+(1_ui0|1_ui1)+1_uf1")
+ (define_reservation "1_L1"
+    "1_0m.lx+1_um0+1_0mlx.+1_ui0+1_uf0\
+    |1_1m.lx+(1_um0|1_um1)+1_1mlx.+(1_ui0|1_ui1)+1_uf1")
+ (define_reservation "1_L2"
+    "(1_0mii.+(1_ui0|1_ui1)|1_0mmi.+1_ui0|1_0mfi.+1_ui0\
+      |1_0mib.+1_unb0|1_0mmb.+1_unb0|1_0mfb.+1_unb0)
+     +1_1m.lx+(1_um0|1_um1)+1_1mlx.+1_ui1+1_uf1")
+ (define_reservation "1_L" "1_L0|1_L1|1_L2")
+ 
+ (define_reservation "1_A" "1_M|1_I")
+ 
+ (define_insn_reservation "1_stop_bit" 0
+   (and (eq_attr "itanium_class" "stop_bit")
+        (eq (symbol_ref "bundling_p") (const_int 0)))
+   "1_stop|1_m0_stop|1_m1_stop|1_mi0_stop|1_mi1_stop")
+ 
+ (define_insn_reservation "1_br"      0
+   (and (eq_attr "itanium_class" "br")
+        (eq (symbol_ref "bundling_p") (const_int 0))) "1_B")
+ (define_insn_reservation "1_scall"   0
+   (and (eq_attr "itanium_class" "scall")
+        (eq (symbol_ref "bundling_p") (const_int 0))) "1_B")
+ (define_insn_reservation "1_fcmp"    2
+   (and (eq_attr "itanium_class" "fcmp")
+        (eq (symbol_ref "bundling_p") (const_int 0)))
+   "1_F+1_not_uf1")
+ (define_insn_reservation "1_fcvtfx"  7
+   (and (eq_attr "itanium_class" "fcvtfx")
+        (eq (symbol_ref "bundling_p") (const_int 0))) "1_F")
+ (define_insn_reservation "1_fld"     9
+   (and (eq_attr "itanium_class" "fld")
+        (eq (symbol_ref "bundling_p") (const_int 0))) "1_M")
+ (define_insn_reservation "1_fmac"    5
+   (and (eq_attr "itanium_class" "fmac")
+        (eq (symbol_ref "bundling_p") (const_int 0))) "1_F")
+ (define_insn_reservation "1_fmisc"   5
+   (and (eq_attr "itanium_class" "fmisc")
+        (eq (symbol_ref "bundling_p") (const_int 0)))
+   "1_F+1_not_uf1")
+ 
+ ;; There is only one insn `mov = ar.bsp' for frar_i:
+ (define_insn_reservation "1_frar_i" 13
+   (and (eq_attr "itanium_class" "frar_i")
+        (eq (symbol_ref "bundling_p") (const_int 0)))
+   "1_I+1_not_ui1")
+ ;; There is only two insns `mov = ar.unat' or `mov = ar.ccv' for
frar_m:
+ (define_insn_reservation "1_frar_m"  6
+   (and (eq_attr "itanium_class" "frar_m")
+        (eq (symbol_ref "bundling_p") (const_int 0)))
+   "1_M+1_not_um1")
+ (define_insn_reservation "1_frbr"    2
+   (and (eq_attr "itanium_class" "frbr")
+        (eq (symbol_ref "bundling_p") (const_int 0)))
+   "1_I+1_not_ui1")
+ (define_insn_reservation "1_frfr"    2
+   (and (eq_attr "itanium_class" "frfr")
+        (eq (symbol_ref "bundling_p") (const_int 0)))
+   "1_M+1_not_um1")
+ (define_insn_reservation "1_frpr"    2
+   (and (eq_attr "itanium_class" "frpr")
+        (eq (symbol_ref "bundling_p") (const_int 0)))
+   "1_I+1_not_ui1")
+ 
+ (define_insn_reservation "1_ialu"      1
+     (and (eq_attr "itanium_class" "ialu")
+          (eq (symbol_ref
+               "bundling_p || ia64_produce_address_p (insn)")
+               (const_int 0)))
+     "1_A")
+ (define_insn_reservation "1_ialu_addr" 1
+     (and (eq_attr "itanium_class" "ialu")
+          (eq (symbol_ref
+               "!bundling_p && ia64_produce_address_p (insn)")
+              (const_int 1)))
+     "1_M")
+ (define_insn_reservation "1_icmp"    1
+   (and (eq_attr "itanium_class" "icmp")
+        (eq (symbol_ref "bundling_p") (const_int 0))) "1_A")
+ (define_insn_reservation "1_ilog"    1
+   (and (eq_attr "itanium_class" "ilog")
+        (eq (symbol_ref "bundling_p") (const_int 0))) "1_A")
+ (define_insn_reservation "1_ishf"    1
+   (and (eq_attr "itanium_class" "ishf")
+        (eq (symbol_ref "bundling_p") (const_int 0)))
+     "1_I+1_not_ui1")
+ (define_insn_reservation "1_ld"      2
+   (and (eq_attr "itanium_class" "ld")
+        (eq (symbol_ref "bundling_p") (const_int 0))) "1_M")
+ (define_insn_reservation "1_long_i"  1
+   (and (eq_attr "itanium_class" "long_i")
+        (eq (symbol_ref "bundling_p") (const_int 0))) "1_L")
+ (define_insn_reservation "1_mmmul"   2
+   (and (eq_attr "itanium_class" "mmmul")
+        (eq (symbol_ref "bundling_p") (const_int 0)))
+   "1_I+1_not_ui1")
+ (define_insn_reservation "1_mmshf"   2
+   (and (eq_attr "itanium_class" "mmshf")
+        (eq (symbol_ref "bundling_p") (const_int 0))) "1_I")
+ (define_insn_reservation "1_mmshfi"  1
+   (and (eq_attr "itanium_class" "mmshfi")
+        (eq (symbol_ref "bundling_p") (const_int 0))) "1_I")
+ 
+ ;; Now we have only one insn (flushrs) of such class.  We assume that
flushrs
+ ;; is the 1st syllable of the bundle after stop bit.
+ (define_insn_reservation "1_rse_m"   0
+   (and (eq_attr "itanium_class" "rse_m")
+        (eq (symbol_ref "bundling_p") (const_int 0)))
+   "(1_0m.ii|1_0m.mi|1_0m.fi|1_0m.mf|1_0b.bb|1_0m.bb\
+     |1_0m.ib|1_0m.mb|1_0m.fb|1_0m.lx)+1_um0")
+ (define_insn_reservation "1_sem"     0
+   (and (eq_attr "itanium_class" "sem")
+        (eq (symbol_ref "bundling_p") (const_int 0)))
+   "1_M+1_not_um1")
+ (define_insn_reservation "1_stf"     1
+   (and (eq_attr "itanium_class" "stf")
+        (eq (symbol_ref "bundling_p") (const_int 0))) "1_M")
+ (define_insn_reservation "1_st"      1
+   (and (eq_attr "itanium_class" "st")
+        (eq (symbol_ref "bundling_p") (const_int 0))) "1_M")
+ (define_insn_reservation "1_syst_m0" 0
+   (and (eq_attr "itanium_class" "syst_m0")
+        (eq (symbol_ref "bundling_p") (const_int 0)))
+   "1_M+1_not_um1")
+ (define_insn_reservation "1_syst_m"  0
+   (and (eq_attr "itanium_class" "syst_m")
+        (eq (symbol_ref "bundling_p") (const_int 0))) "1_M")
+ (define_insn_reservation "1_tbit"    1
+   (and (eq_attr "itanium_class" "tbit")
+        (eq (symbol_ref "bundling_p") (const_int 0)))
+   "1_I+1_not_ui1")
+ 
+ ;; There is only ony insn `mov ar.pfs =' for toar_i:
+ (define_insn_reservation "1_toar_i"  0
+   (and (eq_attr "itanium_class" "toar_i")
+        (eq (symbol_ref "bundling_p") (const_int 0)))
+   "1_I+1_not_ui1")
+ ;; There are only ony 2 insns `mov ar.ccv =' and `mov ar.unat =' for
toar_m:
+ (define_insn_reservation "1_toar_m"  5
+   (and (eq_attr "itanium_class" "toar_m")
+        (eq (symbol_ref "bundling_p") (const_int 0)))
+   "1_M+1_not_um1")
+ (define_insn_reservation "1_tobr"    1
+   (and (eq_attr "itanium_class" "tobr")
+        (eq (symbol_ref "bundling_p") (const_int 0)))
+   "1_I+1_not_ui1")
+ (define_insn_reservation "1_tofr"    9
+   (and (eq_attr "itanium_class" "tofr")
+        (eq (symbol_ref "bundling_p") (const_int 0))) "1_M")
+ (define_insn_reservation "1_topr"    1
+   (and (eq_attr "itanium_class" "topr")
+        (eq (symbol_ref "bundling_p") (const_int 0)))
+   "1_I+1_not_ui1")
+ (define_insn_reservation "1_xmpy"    7
+   (and (eq_attr "itanium_class" "xmpy")
+        (eq (symbol_ref "bundling_p") (const_int 0))) "1_F")
+ (define_insn_reservation "1_xtd"     1
+   (and (eq_attr "itanium_class" "xtd")
+        (eq (symbol_ref "bundling_p") (const_int 0))) "1_I")
+ 
+ (define_insn_reservation "1_chk_s"   0
+   (and (eq_attr "itanium_class" "chk_s")
+        (eq (symbol_ref "bundling_p") (const_int 0))) "1_A")
+ (define_insn_reservation "1_lfetch"  0
+   (and (eq_attr "itanium_class" "lfetch")
+        (eq (symbol_ref "bundling_p") (const_int 0))) "1_M")
+ 
+ (define_insn_reservation "1_nop_m"   0
+   (and (eq_attr "itanium_class" "nop_m")
+        (eq (symbol_ref "bundling_p") (const_int 0))) "1_M0")
+ (define_insn_reservation "1_nop_b"   0
+   (and (eq_attr "itanium_class" "nop_b")
+        (eq (symbol_ref "bundling_p") (const_int 0))) "1_NB")
+ (define_insn_reservation "1_nop_i"   0
+   (and (eq_attr "itanium_class" "nop_i")
+        (eq (symbol_ref "bundling_p") (const_int 0))) "1_I0")
+ (define_insn_reservation "1_nop_f"   0
+   (and (eq_attr "itanium_class" "nop_f")
+        (eq (symbol_ref "bundling_p") (const_int 0))) "1_F0")
+ (define_insn_reservation "1_nop_x"   0
+   (and (eq_attr "itanium_class" "nop_x")
+        (eq (symbol_ref "bundling_p") (const_int 0))) "1_L0")
+ 
+ ;; We assume that there is no insn issued on the same cycle as unknown
insn.
+ (define_cpu_unit "1_empty" "one")
+ (exclusion_set "1_empty"
+    
"1_0m.ii,1_0m.mi,1_0m.fi,1_0m.mf,1_0b.bb,1_0m.bb,1_0m.ib,1_0m.mb,1_0m.fb,\
+      1_0m.lx")
+ 
+ (define_insn_reservation "1_unknown" 1
+   (and (eq_attr "itanium_class" "unknown")
+        (eq (symbol_ref "bundling_p") (const_int 0))) "1_empty")
+ 
+ (define_insn_reservation "1_nop" 1
+   (and (eq_attr "itanium_class" "nop")
+        (eq (symbol_ref "bundling_p") (const_int 0)))
+   "1_M0|1_NB|1_I0|1_F0")
+ 
+ (define_insn_reservation "1_ignore" 0
+   (and (eq_attr "itanium_class" "ignore")
+        (eq (symbol_ref "bundling_p") (const_int 0))) "nothing")
+ 
+ 
+ (define_cpu_unit
+    "1_0m_bs, 1_0mi_bs, 1_0mm_bs, 1_0mf_bs, 1_0b_bs, 1_0bb_bs,
1_0mb_bs"
+    "one")
+ (define_cpu_unit
+    "1_1m_bs, 1_1mi_bs, 1_1mm_bs, 1_1mf_bs, 1_1b_bs, 1_1bb_bs,
1_1mb_bs"
+    "one")
+ 
+ (define_cpu_unit "1_m_cont, 1_mi_cont, 1_mm_cont, 1_mf_cont,
1_mb_cont,\
+                 1_b_cont, 1_bb_cont" "one")
+ 
+ ;; For stop in the middle of the bundles.
+ (define_cpu_unit "1_m_stop, 1_m0_stop, 1_m1_stop, 1_0mmi_cont" "one")
+ (define_cpu_unit "1_mi_stop, 1_mi0_stop, 1_mi1_stop, 1_0mii_cont"
"one")
+ 
+ (final_presence_set "1_0m_bs"
+    "1_0m.ii, 1_0m.mi, 1_0m.mf, 1_0m.fi, 1_0m.bb,\
+     1_0m.ib, 1_0m.fb, 1_0m.mb, 1_0m.lx")
+ (final_presence_set "1_1m_bs"
+    "1_1m.ii, 1_1m.mi, 1_1m.fi, 1_1m.bb, 1_1m.ib, 1_1m.fb, 1_1m.mb,\
+     1_1m.lx")
+ (final_presence_set "1_0mi_bs"  "1_0mi.i, 1_0mi.i")
+ (final_presence_set "1_1mi_bs"  "1_1mi.i, 1_1mi.i")
+ (final_presence_set "1_0mm_bs"  "1_0mm.i, 1_0mm.f, 1_0mm.b")
+ (final_presence_set "1_1mm_bs"  "1_1mm.i, 1_1mm.b")
+ (final_presence_set "1_0mf_bs"  "1_0mf.i, 1_0mf.b")
+ (final_presence_set "1_1mf_bs"  "1_1mf.i, 1_1mf.b")
+ (final_presence_set "1_0b_bs"  "1_0b.bb")
+ (final_presence_set "1_1b_bs"  "1_1b.bb")
+ (final_presence_set "1_0bb_bs"  "1_0bb.b")
+ (final_presence_set "1_1bb_bs"  "1_1bb.b")
+ (final_presence_set "1_0mb_bs"  "1_0mb.b")
+ (final_presence_set "1_1mb_bs"  "1_1mb.b")
+ 
+ (exclusion_set "1_0m_bs"
+    "1_0mi.i, 1_0mm.i, 1_0mm.f, 1_0mf.i, 1_0mb.b,\
+     1_0mi.b, 1_0mf.b, 1_0mm.b, 1_0mlx., 1_m0_stop")
+ (exclusion_set "1_1m_bs"
+    "1_1mi.i, 1_1mm.i, 1_1mf.i, 1_1mb.b, 1_1mi.b, 1_1mf.b, 1_1mm.b,\
+     1_1mlx., 1_m1_stop")
+ (exclusion_set "1_0mi_bs"  "1_0mii., 1_0mib., 1_mi0_stop")
+ (exclusion_set "1_1mi_bs"  "1_1mii., 1_1mib., 1_mi1_stop")
+ (exclusion_set "1_0mm_bs"  "1_0mmi., 1_0mmf., 1_0mmb.")
+ (exclusion_set "1_1mm_bs"  "1_1mmi., 1_1mmb.")
+ (exclusion_set "1_0mf_bs"  "1_0mfi., 1_0mfb.")
+ (exclusion_set "1_1mf_bs"  "1_1mfi., 1_1mfb.")
+ (exclusion_set "1_0b_bs"  "1_0bb.b")
+ (exclusion_set "1_1b_bs"  "1_1bb.b")
+ (exclusion_set "1_0bb_bs"  "1_0bbb.")
+ (exclusion_set "1_1bb_bs"  "1_1bbb.")
+ (exclusion_set "1_0mb_bs"  "1_0mbb.")
+ (exclusion_set "1_1mb_bs"  "1_1mbb.")
+ 
+ (exclusion_set
+    "1_0m_bs, 1_0mi_bs, 1_0mm_bs, 1_0mf_bs, 1_0b_bs, 1_0bb_bs,
1_0mb_bs,
+     1_1m_bs, 1_1mi_bs, 1_1mm_bs, 1_1mf_bs, 1_1b_bs, 1_1bb_bs,
1_1mb_bs"
+    "1_stop")
+ 
+ (final_presence_set
+    "1_0mi.i, 1_0mm.i, 1_0mf.i, 1_0mm.f, 1_0mb.b,\
+     1_0mi.b, 1_0mm.b, 1_0mf.b, 1_0mlx."
+    "1_m_cont")
+ (final_presence_set "1_0mii., 1_0mib." "1_mi_cont")
+ (final_presence_set "1_0mmi., 1_0mmf., 1_0mmb." "1_mm_cont")
+ (final_presence_set "1_0mfi., 1_0mfb." "1_mf_cont")
+ (final_presence_set "1_0bb.b" "1_b_cont")
+ (final_presence_set "1_0bbb." "1_bb_cont")
+ (final_presence_set "1_0mbb." "1_mb_cont")
+ 
+ (exclusion_set
+    "1_0m.ii, 1_0m.mi, 1_0m.fi, 1_0m.mf, 1_0b.bb, 1_0m.bb,\
+     1_0m.ib, 1_0m.mb, 1_0m.fb, 1_0m.lx"
+    "1_m_cont, 1_mi_cont, 1_mm_cont, 1_mf_cont,\
+     1_mb_cont, 1_b_cont, 1_bb_cont")
+ 
+ (exclusion_set "1_empty"
+                "1_m_cont,1_mi_cont,1_mm_cont,1_mf_cont,\
+                 1_mb_cont,1_b_cont,1_bb_cont")
+ 
+ ;; For m;mi bundle
+ (final_presence_set "1_m0_stop" "1_0m.mi")
+ (final_presence_set "1_0mm.i" "1_0mmi_cont")
+ (exclusion_set "1_0mmi_cont"
+    "1_0m.ii, 1_0m.mi, 1_0m.fi, 1_0m.mf, 1_0b.bb, 1_0m.bb,\
+     1_0m.ib, 1_0m.mb, 1_0m.fb, 1_0m.lx")
+ (exclusion_set "1_m0_stop" "1_0mm.i")
+ (final_presence_set "1_m1_stop" "1_1m.mi")
+ (exclusion_set "1_m1_stop" "1_1mm.i")
+ (final_presence_set "1_m_stop" "1_m0_stop, 1_m1_stop")
+ 
+ ;; For mi;i bundle
+ (final_presence_set "1_mi0_stop" "1_0mi.i")
+ (final_presence_set "1_0mii." "1_0mii_cont")
+ (exclusion_set "1_0mii_cont"
+    "1_0m.ii, 1_0m.mi, 1_0m.fi, 1_0m.mf, 1_0b.bb, 1_0m.bb,\
+     1_0m.ib, 1_0m.mb, 1_0m.fb, 1_0m.lx")
+ (exclusion_set "1_mi0_stop" "1_0mii.")
+ (final_presence_set "1_mi1_stop" "1_1mi.i")
+ (exclusion_set "1_mi1_stop" "1_1mii.")
+ (final_presence_set "1_mi_stop" "1_mi0_stop, 1_mi1_stop")
+ 
+ (final_absence_set
+   
"1_0m.ii,1_0mi.i,1_0mii.,1_0m.mi,1_0mm.i,1_0mmi.,1_0m.fi,1_0mf.i,1_0mfi.,\
+    
1_0m.mf,1_0mm.f,1_0mmf.,1_0b.bb,1_0bb.b,1_0bbb.,1_0m.bb,1_0mb.b,1_0mbb.,\
+    
1_0m.ib,1_0mi.b,1_0mib.,1_0m.mb,1_0mm.b,1_0mmb.,1_0m.fb,1_0mf.b,1_0mfb.,\
+     1_0m.lx,1_0mlx., \
+    
1_1m.ii,1_1mi.i,1_1mii.,1_1m.mi,1_1mm.i,1_1mmi.,1_1m.fi,1_1mf.i,1_1mfi.,\
+     1_1b.bb,1_1bb.b,1_1bbb.,1_1m.bb,1_1mb.b,1_1mbb.,\
+    
1_1m.ib,1_1mi.b,1_1mib.,1_1m.mb,1_1mm.b,1_1mmb.,1_1m.fb,1_1mf.b,1_1mfb.,\
+     1_1m.lx,1_1mlx."
+    "1_m0_stop,1_m1_stop,1_mi0_stop,1_mi1_stop")
+ 
+ (define_cpu_unit "1_m_cont_only, 1_b_cont_only" "one")
+ (define_cpu_unit "1_mi_cont_only, 1_mm_cont_only, 1_mf_cont_only"
"one")
+ (define_cpu_unit "1_mb_cont_only, 1_bb_cont_only" "one")
+ 
+ (final_presence_set "1_m_cont_only" "1_m_cont")
+ (exclusion_set "1_m_cont_only"
+   "1_0mi.i, 1_0mm.i, 1_0mf.i, 1_0mm.f, 1_0mb.b,\
+    1_0mi.b, 1_0mm.b, 1_0mf.b, 1_0mlx.")
+ 
+ (final_presence_set "1_b_cont_only" "1_b_cont")
+ (exclusion_set "1_b_cont_only"  "1_0bb.b")
+ 
+ (final_presence_set "1_mi_cont_only" "1_mi_cont")
+ (exclusion_set "1_mi_cont_only" "1_0mii., 1_0mib.")
+ 
+ (final_presence_set "1_mm_cont_only" "1_mm_cont")
+ (exclusion_set "1_mm_cont_only" "1_0mmi., 1_0mmf., 1_0mmb.")
+ 
+ (final_presence_set "1_mf_cont_only" "1_mf_cont")
+ (exclusion_set "1_mf_cont_only" "1_0mfi., 1_0mfb.")
+ 
+ (final_presence_set "1_mb_cont_only" "1_mb_cont")
+ (exclusion_set "1_mb_cont_only" "1_0mbb.")
+ 
+ (final_presence_set "1_bb_cont_only" "1_bb_cont")
+ (exclusion_set "1_bb_cont_only" "1_0bbb.")
+ 
+ (define_insn_reservation "1_pre_cycle" 0
+    (and (eq_attr "itanium_class" "pre_cycle")
+         (eq (symbol_ref "bundling_p") (const_int 0)))
+                          "(1_0m_bs, 1_m_cont)                     \
+                           | (1_0mi_bs, (1_mi_cont|nothing))       \
+                           | (1_0mm_bs, 1_mm_cont)                 \
+                           | (1_0mf_bs, (1_mf_cont|nothing))       \
+                           | (1_0b_bs, (1_b_cont|nothing))         \
+                           | (1_0bb_bs, (1_bb_cont|nothing))       \
+                           | (1_0mb_bs, (1_mb_cont|nothing))       \
+                           | (1_1m_bs, 1_m_cont)                   \
+                           | (1_1mi_bs, (1_mi_cont|nothing))       \
+                           | (1_1mm_bs, 1_mm_cont)                 \
+                           | (1_1mf_bs, (1_mf_cont|nothing))       \
+                           | (1_1b_bs, (1_b_cont|nothing))         \
+                           | (1_1bb_bs, (1_bb_cont|nothing))       \
+                           | (1_1mb_bs, (1_mb_cont|nothing))       \
+                           | (1_m_cont_only, (1_m_cont|nothing))   \
+                           | (1_b_cont_only,  (1_b_cont|nothing))  \
+                           | (1_mi_cont_only, (1_mi_cont|nothing)) \
+                           | (1_mm_cont_only, (1_mm_cont|nothing)) \
+                           | (1_mf_cont_only, (1_mf_cont|nothing)) \
+                           | (1_mb_cont_only, (1_mb_cont|nothing)) \
+                           | (1_bb_cont_only, (1_bb_cont|nothing)) \
+                           | (1_m_stop, (1_0mmi_cont|nothing))     \
+                           | (1_mi_stop, (1_0mii_cont|nothing))")
+ 
+ ;; Bypasses:
+ (define_bypass  1 "1_fcmp" "1_br,1_scall")
+ ;; ??? I found 7 cycle dealy for 1_fmac -> 1_fcmp for Itanium1
+ (define_bypass  7 "1_fmac" "1_fmisc,1_fcvtfx,1_xmpy,1_fcmp")
+ 
+ ;; ???
+ (define_bypass  3 "1_frbr" "1_mmmul,1_mmshf")
+ (define_bypass 14 "1_frar_i" "1_mmmul,1_mmshf")
+ (define_bypass  7 "1_frar_m" "1_mmmul,1_mmshf")
+ 
+ ;; ????
+ ;; There is only one insn `mov ar.pfs =' for toar_i.
+ (define_bypass  0 "1_tobr,1_topr,1_toar_i" "1_br,1_scall")
+ 
+ (define_bypass  3 "1_ialu,1_ialu_addr" "1_mmmul,1_mmshf")
+ ;; ??? howto describe ialu for I slot only.  We use ialu_addr for that
+ ;;(define_bypass  2 "1_ialu" "1_ld"  "ia64_ld_address_bypass_p")
+ ;; ??? howto describe ialu st/address for I slot only.  We use
ialu_addr
+ ;;   for that.
+ ;;(define_bypass  2 "1_ialu" "1_st"  "ia64_st_address_bypass_p")
+ 
+ (define_bypass  0 "1_icmp" "1_br,1_scall")
+ 
+ (define_bypass  3 "1_ilog" "1_mmmul,1_mmshf")
+ 
+ (define_bypass  2 "1_ilog,1_xtd" "1_ld"  "ia64_ld_address_bypass_p")
+ (define_bypass  2 "1_ilog,1_xtd" "1_st"  "ia64_st_address_bypass_p")
+ 
+ (define_bypass  3 "1_ld" "1_mmmul,1_mmshf")
+ (define_bypass  3 "1_ld" "1_ld"  "ia64_ld_address_bypass_p")
+ (define_bypass  3 "1_ld" "1_st"  "ia64_st_address_bypass_p")
+ 
+ (define_bypass  4 "1_mmmul,1_mmshf" "1_ialu,1_ilog,1_ishf,1_st,1_ld")
+ ;; ??? how to describe that if scheduled < 4 cycle then latency is 10
cycles.
+ ;; (define_bypass  10 "1_mmmul,1_mmshf"
"1_ialu,1_ilog,1_ishf,1_st,1_ld")
+ 
+ (define_bypass  0 "1_tbit" "1_br,1_scall")
+ 
+ (define_bypass  8 "1_tofr"  "1_frfr,1_stf")
+ (define_bypass  7 "1_fmisc,1_fcvtfx,1_fmac,1_xmpy"  "1_frfr")
+ (define_bypass  8 "1_fmisc,1_fcvtfx,1_fmac,1_xmpy"  "1_stf")
+ 
+ ;; We don't use here fcmp because scall may be predicated.
+ (define_bypass  0 "1_fcvtfx,1_fld,1_fmac,1_fmisc,1_frar_i,1_frar_m,\
+                   
1_frbr,1_frfr,1_frpr,1_ialu,1_ialu_addr,1_ilog,1_ishf,\
+                 
1_ld,1_long_i,1_mmmul,1_mmshf,1_mmshfi,1_toar_m,1_tofr,\
+                    1_xmpy,1_xtd" "1_scall")
+ 
+ (define_bypass  0
"1_unknown,1_ignore,1_stop_bit,1_br,1_fcmp,1_fcvtfx,\
+                   
1_fld,1_fmac,1_fmisc,1_frar_i,1_frar_m,1_frbr,1_frfr,\
+                   
1_frpr,1_ialu,1_ialu_addr,1_icmp,1_ilog,1_ishf,1_ld,\
+                    1_chk_s,1_long_i,1_mmmul,1_mmshf,1_mmshfi,1_nop,\
+                   
1_nop_b,1_nop_f,1_nop_i,1_nop_m,1_nop_x,1_rse_m,1_scall,\
+                   
1_sem,1_stf,1_st,1_syst_m0,1_syst_m,1_tbit,1_toar_i,\
+                   
1_toar_m,1_tobr,1_tofr,1_topr,1_xmpy,1_xtd,1_lfetch"
+                   "1_ignore")
+ 
  
  ;; ::::::::::::::::::::
  ;; ::
***************
*** 5097,5103 ****
    [(const_int 0)]
    ""
    "nop 0"
!   [(set_attr "itanium_class" "unknown")])
  
  (define_insn "nop_m"
    [(const_int 1)]
--- 6003,6009 ----
    [(const_int 0)]
    ""
    "nop 0"
!   [(set_attr "itanium_class" "nop")])
  
  (define_insn "nop_m"
    [(const_int 1)]
***************
*** 5128,5133 ****
--- 6034,6047 ----
    ""
    ""
    [(set_attr "itanium_class" "nop_x")])
+ 
+ ;; The following insn will be never generated.  It is used only by
+ ;; insn scheduler to change state before advancing cycle.
+ (define_insn "pre_cycle"
+   [(const_int 6)]
+   ""
+   ""
+   [(set_attr "itanium_class" "pre_cycle")])
  
  (define_insn "bundle_selector"
    [(unspec [(match_operand 0 "const_int_operand" "")]
UNSPEC_BUNDLE_SELECTOR)]



More information about the Gcc-patches mailing list