]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/genautomata.c
Re-factor inclusion of tree.h.
[thirdparty/gcc.git] / gcc / genautomata.c
CommitLineData
bea4bad2 1/* Pipeline hazard description translator.
711789cc 2 Copyright (C) 2000-2013 Free Software Foundation, Inc.
bea4bad2 3
4 Written by Vladimir Makarov <vmakarov@redhat.com>
1a97be37 5
5a8b6e6a 6This file is part of GCC.
bea4bad2 7
5a8b6e6a 8GCC is free software; you can redistribute it and/or modify it
bea4bad2 9under the terms of the GNU General Public License as published by the
8c4c00c1 10Free Software Foundation; either version 3, or (at your option) any
bea4bad2 11later version.
12
5a8b6e6a 13GCC is distributed in the hope that it will be useful, but WITHOUT
bea4bad2 14ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16for more details.
17
18You should have received a copy of the GNU General Public License
8c4c00c1 19along with GCC; see the file COPYING3. If not see
20<http://www.gnu.org/licenses/>. */
bea4bad2 21
22/* References:
1a97be37 23
08ed847d 24 1. The finite state automaton based pipeline hazard recognizer and
25 instruction scheduler in GCC. V. Makarov. Proceedings of GCC
26 summit, 2003.
27
28 2. Detecting pipeline structural hazards quickly. T. Proebsting,
bea4bad2 29 C. Fraser. Proceedings of ACM SIGPLAN-SIGACT Symposium on
30 Principles of Programming Languages, pages 280--286, 1994.
31
32 This article is a good start point to understand usage of finite
33 state automata for pipeline hazard recognizers. But I'd
08ed847d 34 recommend the 1st and 3rd article for more deep understanding.
bea4bad2 35
08ed847d 36 3. Efficient Instruction Scheduling Using Finite State Automata:
bea4bad2 37 V. Bala and N. Rubin, Proceedings of MICRO-28. This is the best
38 article about usage of finite state automata for pipeline hazard
39 recognizers.
40
08ed847d 41 The current implementation is described in the 1st article and it
42 is different from the 3rd article in the following:
bea4bad2 43
44 1. New operator `|' (alternative) is permitted in functional unit
98667efb 45 reservation which can be treated deterministically and
46 non-deterministically.
bea4bad2 47
48 2. Possibility of usage of nondeterministic automata too.
49
50 3. Possibility to query functional unit reservations for given
51 automaton state.
52
53 4. Several constructions to describe impossible reservations
58ada791 54 (`exclusion_set', `presence_set', `final_presence_set',
55 `absence_set', and `final_absence_set').
bea4bad2 56
57 5. No reverse automata are generated. Trace instruction scheduling
58 requires this. It can be easily added in the future if we
59 really need this.
60
61 6. Union of automaton states are not generated yet. It is planned
62 to be implemented. Such feature is needed to make more accurate
63 interlock insn scheduling to get state describing functional
58ada791 64 unit reservation in a joint CFG point. */
bea4bad2 65
66/* This file code processes constructions of machine description file
67 which describes automaton used for recognition of processor pipeline
68 hazards by insn scheduler and can be used for other tasks (such as
69 VLIW insn packing.
70
71 The translator functions `gen_cpu_unit', `gen_query_cpu_unit',
72 `gen_bypass', `gen_excl_set', `gen_presence_set',
58ada791 73 `gen_final_presence_set', `gen_absence_set',
74 `gen_final_absence_set', `gen_automaton', `gen_automata_option',
bea4bad2 75 `gen_reserv', `gen_insn_reserv' are called from file
76 `genattrtab.c'. They transform RTL constructions describing
77 automata in .md file into internal representation convenient for
78 further processing.
1a97be37 79
bea4bad2 80 The translator major function `expand_automata' processes the
81 description internal representation into finite state automaton.
82 It can be divided on:
83
84 o checking correctness of the automaton pipeline description
85 (major function is `check_all_description').
86
87 o generating automaton (automata) from the description (major
88 function is `make_automaton').
89
90 o optional transformation of nondeterministic finite state
91 automata into deterministic ones if the alternative operator
f503d902 92 `|' is treated nondeterministically in the description (major
bea4bad2 93 function is NDFA_to_DFA).
94
95 o optional minimization of the finite state automata by merging
96 equivalent automaton states (major function is `minimize_DFA').
97
98 o forming tables (some as comb vectors) and attributes
99 representing the automata (functions output_..._table).
100
101 Function `write_automata' outputs the created finite state
102 automaton as different tables and functions which works with the
103 automata to inquire automaton state and to change its state. These
104 function are used by gcc instruction scheduler and may be some
105 other gcc code. */
106
805e22b2 107#include "bconfig.h"
bea4bad2 108#include "system.h"
805e22b2 109#include "coretypes.h"
110#include "tm.h"
bea4bad2 111#include "rtl.h"
112#include "obstack.h"
113#include "errors.h"
0f7f3d52 114#include "gensupport.h"
bea4bad2 115
bea4bad2 116#include <math.h>
117#include "hashtab.h"
e7827cef 118#include "vec.h"
2334f0df 119#include "fnmatch.h"
bea4bad2 120
bea4bad2 121#ifndef CHAR_BIT
122#define CHAR_BIT 8
123#endif
bea4bad2 124
bea4bad2 125/* Positions in machine description file. Now they are not used. But
126 they could be used in the future for better diagnostic messages. */
127typedef int pos_t;
128
129/* The following is element of vector of current (and planned in the
130 future) functional unit reservations. */
131typedef unsigned HOST_WIDE_INT set_el_t;
132
133/* Reservations of function units are represented by value of the following
134 type. */
135typedef set_el_t *reserv_sets_t;
aae87fc3 136typedef const set_el_t *const_reserv_sets_t;
bea4bad2 137
bea4bad2 138/* The following structure describes a ticker. */
139struct ticker
140{
141 /* The following member value is time of the ticker creation with
142 taking into account time when the ticker is off. Active time of
143 the ticker is current time minus the value. */
144 int modified_creation_time;
145 /* The following member value is time (incremented by one) when the
146 ticker was off. Zero value means that now the ticker is on. */
147 int incremented_off_time;
148};
149
150/* The ticker is represented by the following type. */
151typedef struct ticker ticker_t;
152
153/* The following type describes elements of output vectors. */
154typedef HOST_WIDE_INT vect_el_t;
155
156/* Forward declaration of structures of internal representation of
157 pipeline description based on NDFA. */
158
159struct unit_decl;
160struct bypass_decl;
161struct result_decl;
162struct automaton_decl;
58ada791 163struct unit_pattern_rel_decl;
bea4bad2 164struct reserv_decl;
165struct insn_reserv_decl;
166struct decl;
167struct unit_regexp;
168struct result_regexp;
169struct reserv_regexp;
170struct nothing_regexp;
171struct sequence_regexp;
172struct repeat_regexp;
173struct allof_regexp;
174struct oneof_regexp;
175struct regexp;
176struct description;
177struct unit_set_el;
58ada791 178struct pattern_set_el;
179struct pattern_reserv;
bea4bad2 180struct state;
181struct alt_state;
182struct arc;
183struct ainsn;
184struct automaton;
185struct state_ainsn_table;
186
187/* The following typedefs are for brevity. */
b35eefd9 188typedef struct unit_decl *unit_decl_t;
aae87fc3 189typedef const struct unit_decl *const_unit_decl_t;
bea4bad2 190typedef struct decl *decl_t;
aae87fc3 191typedef const struct decl *const_decl_t;
bea4bad2 192typedef struct regexp *regexp_t;
193typedef struct unit_set_el *unit_set_el_t;
58ada791 194typedef struct pattern_set_el *pattern_set_el_t;
195typedef struct pattern_reserv *pattern_reserv_t;
bea4bad2 196typedef struct alt_state *alt_state_t;
197typedef struct state *state_t;
aae87fc3 198typedef const struct state *const_state_t;
bea4bad2 199typedef struct arc *arc_t;
200typedef struct ainsn *ainsn_t;
201typedef struct automaton *automaton_t;
202typedef struct automata_list_el *automata_list_el_t;
aae87fc3 203typedef const struct automata_list_el *const_automata_list_el_t;
bea4bad2 204typedef struct state_ainsn_table *state_ainsn_table_t;
205
bea4bad2 206/* Undefined position. */
207static pos_t no_pos = 0;
208
209/* All IR is stored in the following obstack. */
210static struct obstack irp;
211
212\f
e7827cef 213/* Declare vector types for various data structures: */
214
f1f41a6c 215
216typedef vec<vect_el_t> vla_hwint_t;
0f7f3d52 217\f
218/* Forward declarations of functions used before their definitions, only. */
219static regexp_t gen_regexp_sequence (const char *);
220static void reserv_sets_or (reserv_sets_t, reserv_sets_t,
221 reserv_sets_t);
222static reserv_sets_t get_excl_set (reserv_sets_t);
223static int check_presence_pattern_sets (reserv_sets_t,
224 reserv_sets_t, int);
225static int check_absence_pattern_sets (reserv_sets_t, reserv_sets_t,
226 int);
aae87fc3 227static arc_t first_out_arc (const_state_t);
0f7f3d52 228static arc_t next_out_arc (arc_t);
229
bea4bad2 230\f
231
232/* Options with the following names can be set up in automata_option
233 construction. Because the strings occur more one time we use the
234 macros. */
235
236#define NO_MINIMIZATION_OPTION "-no-minimization"
0644a91e 237#define TIME_OPTION "-time"
df04f68e 238#define STATS_OPTION "-stats"
0644a91e 239#define V_OPTION "-v"
bea4bad2 240#define W_OPTION "-w"
bea4bad2 241#define NDFA_OPTION "-ndfa"
8043d8fb 242#define COLLAPSE_OPTION "-collapse-ndfa"
172b69d8 243#define NO_COMB_OPTION "-no-comb-vect"
bccc9ebc 244#define PROGRESS_OPTION "-progress"
245
bea4bad2 246/* The following flags are set up by function `initiate_automaton_gen'. */
247
248/* Make automata with nondeterministic reservation by insns (`-ndfa'). */
249static int ndfa_flag;
250
8043d8fb 251/* When making an NDFA, produce additional transitions that collapse
252 NDFA state into a deterministic one suitable for querying CPU units.
253 Provide avance-state transitions only for deterministic states. */
254static int collapse_flag;
255
bea4bad2 256/* Do not make minimization of DFA (`-no-minimization'). */
257static int no_minimization_flag;
258
172b69d8 259/* Do not try to generate a comb vector (`-no-comb-vect'). */
260static int no_comb_flag;
261
bea4bad2 262/* Value of this variable is number of automata being generated. The
263 actual number of automata may be less this value if there is not
264 sufficient number of units. This value is defined by argument of
265 option `-split' or by constructions automaton if the value is zero
266 (it is default value of the argument). */
267static int split_argument;
268
269/* Flag of output time statistics (`-time'). */
270static int time_flag;
271
df04f68e 272/* Flag of automata statistics (`-stats'). */
273static int stats_flag;
274
bea4bad2 275/* Flag of creation of description file which contains description of
276 result automaton and statistics information (`-v'). */
277static int v_flag;
278
bccc9ebc 279/* Flag of output of a progress bar showing how many states were
280 generated so far for automaton being processed (`-progress'). */
281static int progress_flag;
282
bea4bad2 283/* Flag of generating warning instead of error for non-critical errors
284 (`-w'). */
285static int w_flag;
286
287
288/* Output file for pipeline hazard recognizer (PHR) being generated.
289 The value is NULL if the file is not defined. */
290static FILE *output_file;
291
292/* Description file of PHR. The value is NULL if the file is not
293 created. */
294static FILE *output_description_file;
295
296/* PHR description file name. */
297static char *output_description_file_name;
298
299/* Value of the following variable is node representing description
300 being processed. This is start point of IR. */
301static struct description *description;
302
303\f
304
305/* This page contains description of IR structure (nodes). */
306
307enum decl_mode
308{
309 dm_unit,
310 dm_bypass,
311 dm_automaton,
312 dm_excl,
313 dm_presence,
314 dm_absence,
315 dm_reserv,
316 dm_insn_reserv
317};
318
319/* This describes define_cpu_unit and define_query_cpu_unit (see file
320 rtl.def). */
321struct unit_decl
322{
e7827cef 323 const char *name;
bea4bad2 324 /* NULL if the automaton name is absent. */
e7827cef 325 const char *automaton_name;
bea4bad2 326 /* If the following value is not zero, the cpu unit reservation is
327 described in define_query_cpu_unit. */
328 char query_p;
329
330 /* The following fields are defined by checker. */
331
332 /* The following field value is nonzero if the unit is used in an
333 regexp. */
334 char unit_is_used;
b35eefd9 335
bea4bad2 336 /* The following field value is order number (0, 1, ...) of given
337 unit. */
338 int unit_num;
339 /* The following field value is corresponding declaration of
340 automaton which was given in description. If the field value is
341 NULL then automaton in the unit declaration was absent. */
342 struct automaton_decl *automaton_decl;
343 /* The following field value is maximal cycle number (1, ...) on
344 which given unit occurs in insns. Zero value means that given
345 unit is not used in insns. */
346 int max_occ_cycle_num;
58ada791 347 /* The following field value is minimal cycle number (0, ...) on
348 which given unit occurs in insns. -1 value means that given
349 unit is not used in insns. */
350 int min_occ_cycle_num;
bea4bad2 351 /* The following list contains units which conflict with given
352 unit. */
353 unit_set_el_t excl_list;
58ada791 354 /* The following list contains patterns which are required to
bea4bad2 355 reservation of given unit. */
58ada791 356 pattern_set_el_t presence_list;
357 pattern_set_el_t final_presence_list;
358 /* The following list contains patterns which should be not present
359 in reservation for given unit. */
360 pattern_set_el_t absence_list;
361 pattern_set_el_t final_absence_list;
bea4bad2 362 /* The following is used only when `query_p' has nonzero value.
363 This is query number for the unit. */
364 int query_num;
8bbadced 365 /* The following is the last cycle on which the unit was checked for
366 correct distributions of units to automata in a regexp. */
367 int last_distribution_check_cycle;
bea4bad2 368
369 /* The following fields are defined by automaton generator. */
370
371 /* The following field value is number of the automaton to which
372 given unit belongs. */
373 int corresponding_automaton_num;
58ada791 374 /* If the following value is not zero, the cpu unit is present in a
375 `exclusion_set' or in right part of a `presence_set',
376 `final_presence_set', `absence_set', and
377 `final_absence_set'define_query_cpu_unit. */
378 char in_set_p;
bea4bad2 379};
380
381/* This describes define_bypass (see file rtl.def). */
382struct bypass_decl
383{
384 int latency;
2334f0df 385 const char *out_pattern;
386 const char *in_pattern;
e7827cef 387 const char *bypass_guard_name;
bea4bad2 388
389 /* The following fields are defined by checker. */
390
391 /* output and input insns of given bypass. */
392 struct insn_reserv_decl *out_insn_reserv;
393 struct insn_reserv_decl *in_insn_reserv;
394 /* The next bypass for given output insn. */
395 struct bypass_decl *next;
396};
397
398/* This describes define_automaton (see file rtl.def). */
399struct automaton_decl
400{
e7827cef 401 const char *name;
bea4bad2 402
403 /* The following fields are defined by automaton generator. */
404
405 /* The following field value is nonzero if the automaton is used in
406 an regexp definition. */
407 char automaton_is_used;
408
409 /* The following fields are defined by checker. */
410
411 /* The following field value is the corresponding automaton. This
412 field is not NULL only if the automaton is present in unit
413 declarations and the automatic partition on automata is not
414 used. */
415 automaton_t corresponding_automaton;
416};
417
58ada791 418/* This describes exclusion relations: exclusion_set (see file
419 rtl.def). */
420struct excl_rel_decl
bea4bad2 421{
58ada791 422 int all_names_num;
bea4bad2 423 int first_list_length;
424 char *names [1];
425};
426
58ada791 427/* This describes unit relations: [final_]presence_set or
428 [final_]absence_set (see file rtl.def). */
429struct unit_pattern_rel_decl
430{
431 int final_p;
432 int names_num;
433 int patterns_num;
434 char **names;
435 char ***patterns;
436};
437
bea4bad2 438/* This describes define_reservation (see file rtl.def). */
439struct reserv_decl
440{
e7827cef 441 const char *name;
bea4bad2 442 regexp_t regexp;
443
444 /* The following fields are defined by checker. */
445
446 /* The following field value is nonzero if the unit is used in an
447 regexp. */
448 char reserv_is_used;
449 /* The following field is used to check up cycle in expression
450 definition. */
451 int loop_pass_num;
452};
453
f503d902 454/* This describes define_insn_reservation (see file rtl.def). */
bea4bad2 455struct insn_reserv_decl
456{
457 rtx condexp;
458 int default_latency;
459 regexp_t regexp;
e7827cef 460 const char *name;
bea4bad2 461
462 /* The following fields are defined by checker. */
463
464 /* The following field value is order number (0, 1, ...) of given
465 insn. */
466 int insn_num;
467 /* The following field value is list of bypasses in which given insn
08ed847d 468 is output insn. Bypasses with the same input insn stay one after
469 another in the list in the same order as their occurrences in the
470 description but the bypass without a guard stays always the last
471 in a row of bypasses with the same input insn. */
bea4bad2 472 struct bypass_decl *bypass_list;
473
474 /* The following fields are defined by automaton generator. */
475
476 /* The following field is the insn regexp transformed that
477 the regexp has not optional regexp, repetition regexp, and an
478 reservation name (i.e. reservation identifiers are changed by the
f0b5f617 479 corresponding regexp) and all alternations are the top level
bea4bad2 480 of the regexp. The value can be NULL only if it is special
481 insn `cycle advancing'. */
482 regexp_t transformed_regexp;
483 /* The following field value is list of arcs marked given
f503d902 484 insn. The field is used in transformation NDFA -> DFA. */
bea4bad2 485 arc_t arcs_marked_by_insn;
486 /* The two following fields are used during minimization of a finite state
487 automaton. */
488 /* The field value is number of equivalence class of state into
489 which arc marked by given insn enters from a state (fixed during
490 an automaton minimization). */
491 int equiv_class_num;
bea4bad2 492 /* The following member value is the list to automata which can be
b35eefd9 493 changed by the insn issue. */
bea4bad2 494 automata_list_el_t important_automata_list;
495 /* The following member is used to process insn once for output. */
496 int processed_p;
497};
498
499/* This contains a declaration mentioned above. */
500struct decl
501{
502 /* What node in the union? */
503 enum decl_mode mode;
504 pos_t pos;
505 union
506 {
507 struct unit_decl unit;
508 struct bypass_decl bypass;
509 struct automaton_decl automaton;
58ada791 510 struct excl_rel_decl excl;
511 struct unit_pattern_rel_decl presence;
512 struct unit_pattern_rel_decl absence;
bea4bad2 513 struct reserv_decl reserv;
514 struct insn_reserv_decl insn_reserv;
515 } decl;
516};
517
518/* The following structures represent parsed reservation strings. */
519enum regexp_mode
520{
521 rm_unit,
522 rm_reserv,
523 rm_nothing,
524 rm_sequence,
525 rm_repeat,
526 rm_allof,
527 rm_oneof
528};
529
530/* Cpu unit in reservation. */
531struct unit_regexp
532{
e7827cef 533 const char *name;
b35eefd9 534 unit_decl_t unit_decl;
bea4bad2 535};
536
537/* Define_reservation in a reservation. */
538struct reserv_regexp
539{
e7827cef 540 const char *name;
bea4bad2 541 struct reserv_decl *reserv_decl;
542};
543
544/* Absence of reservation (represented by string `nothing'). */
545struct nothing_regexp
546{
547 /* This used to be empty but ISO C doesn't allow that. */
548 char unused;
549};
550
551/* Representation of reservations separated by ',' (see file
552 rtl.def). */
553struct sequence_regexp
554{
555 int regexps_num;
556 regexp_t regexps [1];
557};
558
559/* Representation of construction `repeat' (see file rtl.def). */
560struct repeat_regexp
561{
562 int repeat_num;
563 regexp_t regexp;
564};
565
566/* Representation of reservations separated by '+' (see file
567 rtl.def). */
568struct allof_regexp
569{
570 int regexps_num;
571 regexp_t regexps [1];
572};
573
574/* Representation of reservations separated by '|' (see file
575 rtl.def). */
576struct oneof_regexp
577{
578 int regexps_num;
579 regexp_t regexps [1];
580};
581
582/* Representation of a reservation string. */
583struct regexp
584{
585 /* What node in the union? */
586 enum regexp_mode mode;
587 pos_t pos;
588 union
589 {
590 struct unit_regexp unit;
591 struct reserv_regexp reserv;
592 struct nothing_regexp nothing;
593 struct sequence_regexp sequence;
594 struct repeat_regexp repeat;
595 struct allof_regexp allof;
596 struct oneof_regexp oneof;
597 } regexp;
598};
599
f503d902 600/* Represents description of pipeline hazard description based on
bea4bad2 601 NDFA. */
602struct description
603{
8043d8fb 604 int decls_num, normal_decls_num;
bea4bad2 605
606 /* The following fields are defined by checker. */
607
608 /* The following fields values are correspondingly number of all
609 units, query units, and insns in the description. */
610 int units_num;
611 int query_units_num;
612 int insns_num;
613 /* The following field value is max length (in cycles) of
614 reservations of insns. The field value is defined only for
615 correct programs. */
616 int max_insn_reserv_cycles;
617
618 /* The following fields are defined by automaton generator. */
619
620 /* The following field value is the first automaton. */
621 automaton_t first_automaton;
622
623 /* The following field is created by pipeline hazard parser and
8043d8fb 624 contains all declarations. We allocate additional entries for
625 two special insns which are added by the automaton generator. */
bea4bad2 626 decl_t decls [1];
627};
628
629
bea4bad2 630/* The following nodes are created in automaton checker. */
631
58ada791 632/* The following nodes represent exclusion set for cpu units. Each
633 element is accessed through only one excl_list. */
bea4bad2 634struct unit_set_el
635{
b35eefd9 636 unit_decl_t unit_decl;
bea4bad2 637 unit_set_el_t next_unit_set_el;
638};
639
58ada791 640/* The following nodes represent presence or absence pattern for cpu
641 units. Each element is accessed through only one presence_list or
642 absence_list. */
643struct pattern_set_el
644{
645 /* The number of units in unit_decls. */
646 int units_num;
647 /* The units forming the pattern. */
648 struct unit_decl **unit_decls;
649 pattern_set_el_t next_pattern_set_el;
650};
bea4bad2 651
652
653/* The following nodes are created in automaton generator. */
654
58ada791 655
656/* The following nodes represent presence or absence pattern for cpu
657 units. Each element is accessed through only one element of
658 unit_presence_set_table or unit_absence_set_table. */
659struct pattern_reserv
660{
661 reserv_sets_t reserv;
662 pattern_reserv_t next_pattern_reserv;
663};
664
bea4bad2 665/* The following node type describes state automaton. The state may
666 be deterministic or non-deterministic. Non-deterministic state has
667 several component states which represent alternative cpu units
668 reservations. The state also is used for describing a
669 deterministic reservation of automaton insn. */
670struct state
671{
672 /* The following member value is nonzero if there is a transition by
673 cycle advancing. */
674 int new_cycle_p;
675 /* The following field is list of processor unit reservations on
676 each cycle. */
677 reserv_sets_t reservs;
678 /* The following field is unique number of given state between other
679 states. */
680 int unique_num;
681 /* The following field value is automaton to which given state
682 belongs. */
683 automaton_t automaton;
684 /* The following field value is the first arc output from given
685 state. */
686 arc_t first_out_arc;
c72f0286 687 unsigned int num_out_arcs;
bea4bad2 688 /* The following field is used to form NDFA. */
689 char it_was_placed_in_stack_for_NDFA_forming;
690 /* The following field is used to form DFA. */
691 char it_was_placed_in_stack_for_DFA_forming;
58ada791 692 /* The following field is used to transform NDFA to DFA and DFA
693 minimization. The field value is not NULL if the state is a
694 compound state. In this case the value of field `unit_sets_list'
695 is NULL. All states in the list are in the hash table. The list
696 is formed through field `next_sorted_alt_state'. We should
697 support only one level of nesting state. */
bea4bad2 698 alt_state_t component_states;
699 /* The following field is used for passing graph of states. */
700 int pass_num;
701 /* The list of states belonging to one equivalence class is formed
702 with the aid of the following field. */
703 state_t next_equiv_class_state;
704 /* The two following fields are used during minimization of a finite
705 state automaton. */
706 int equiv_class_num_1, equiv_class_num_2;
707 /* The following field is used during minimization of a finite state
708 automaton. The field value is state corresponding to equivalence
709 class to which given state belongs. */
710 state_t equiv_class_state;
c72f0286 711 unsigned int *presence_signature;
bea4bad2 712 /* The following field value is the order number of given state.
713 The states in final DFA is enumerated with the aid of the
714 following field. */
715 int order_state_num;
716 /* This member is used for passing states for searching minimal
717 delay time. */
718 int state_pass_num;
719 /* The following member is used to evaluate min issue delay of insn
720 for a state. */
721 int min_insn_issue_delay;
bea4bad2 722};
723
bea4bad2 724/* Automaton arc. */
725struct arc
726{
727 /* The following field refers for the state into which given arc
728 enters. */
729 state_t to_state;
730 /* The following field describes that the insn issue (with cycle
731 advancing for special insn `cycle advancing' and without cycle
732 advancing for others) makes transition from given state to
733 another given state. */
734 ainsn_t insn;
735 /* The following field value is the next arc output from the same
736 state. */
737 arc_t next_out_arc;
738 /* List of arcs marked given insn is formed with the following
f503d902 739 field. The field is used in transformation NDFA -> DFA. */
bea4bad2 740 arc_t next_arc_marked_by_insn;
bea4bad2 741};
742
743/* The following node type describes a deterministic alternative in
744 non-deterministic state which characterizes cpu unit reservations
745 of automaton insn or which is part of NDFA. */
746struct alt_state
747{
98667efb 748 /* The following field is a deterministic state which characterizes
bea4bad2 749 unit reservations of the instruction. */
750 state_t state;
751 /* The following field refers to the next state which characterizes
752 unit reservations of the instruction. */
753 alt_state_t next_alt_state;
754 /* The following field refers to the next state in sorted list. */
755 alt_state_t next_sorted_alt_state;
756};
757
758/* The following node type describes insn of automaton. They are
759 labels of FA arcs. */
760struct ainsn
761{
762 /* The following field value is the corresponding insn declaration
763 of description. */
764 struct insn_reserv_decl *insn_reserv_decl;
765 /* The following field value is the next insn declaration for an
766 automaton. */
767 ainsn_t next_ainsn;
768 /* The following field is states which characterize automaton unit
769 reservations of the instruction. The value can be NULL only if it
770 is special insn `cycle advancing'. */
771 alt_state_t alt_states;
772 /* The following field is sorted list of states which characterize
773 automaton unit reservations of the instruction. The value can be
774 NULL only if it is special insn `cycle advancing'. */
775 alt_state_t sorted_alt_states;
776 /* The following field refers the next automaton insn with
777 the same reservations. */
778 ainsn_t next_same_reservs_insn;
779 /* The following field is flag of the first automaton insn with the
780 same reservations in the declaration list. Only arcs marked such
781 insn is present in the automaton. This significantly decreases
782 memory requirements especially when several automata are
783 formed. */
784 char first_insn_with_same_reservs;
785 /* The following member has nonzero value if there is arc from state of
786 the automaton marked by the ainsn. */
787 char arc_exists_p;
dafdd1c8 788 /* Cyclic list of insns of an equivalence class is formed with the
bea4bad2 789 aid of the following field. */
790 ainsn_t next_equiv_class_insn;
791 /* The following field value is nonzero if the insn declaration is
792 the first insn declaration with given equivalence number. */
069eea26 793 char first_ainsn_with_given_equivalence_num;
bea4bad2 794 /* The following field is number of class of equivalence of insns.
795 It is necessary because many insns may be equivalent with the
796 point of view of pipeline hazards. */
797 int insn_equiv_class_num;
798 /* The following member value is TRUE if there is an arc in the
799 automaton marked by the insn into another state. In other
800 words, the insn can change the state of the automaton. */
801 int important_p;
802};
803
98667efb 804/* The following describes an automaton for PHR. */
bea4bad2 805struct automaton
806{
807 /* The following field value is the list of insn declarations for
808 given automaton. */
809 ainsn_t ainsn_list;
8043d8fb 810 /* Pointers to the ainsns corresponding to the special reservations. */
811 ainsn_t advance_ainsn, collapse_ainsn;
812
bea4bad2 813 /* The following field value is the corresponding automaton
814 declaration. This field is not NULL only if the automatic
815 partition on automata is not used. */
816 struct automaton_decl *corresponding_automaton_decl;
817 /* The following field value is the next automaton. */
818 automaton_t next_automaton;
819 /* The following field is start state of FA. There are not unit
820 reservations in the state. */
821 state_t start_state;
822 /* The following field value is number of equivalence classes of
823 insns (see field `insn_equiv_class_num' in
824 `insn_reserv_decl'). */
825 int insn_equiv_classes_num;
826 /* The following field value is number of states of final DFA. */
827 int achieved_states_num;
828 /* The following field value is the order number (0, 1, ...) of
829 given automaton. */
830 int automaton_order_num;
831 /* The following fields contain statistics information about
832 building automaton. */
833 int NDFA_states_num, DFA_states_num;
834 /* The following field value is defined only if minimization of DFA
835 is used. */
836 int minimal_DFA_states_num;
837 int NDFA_arcs_num, DFA_arcs_num;
838 /* The following field value is defined only if minimization of DFA
839 is used. */
840 int minimal_DFA_arcs_num;
0f7f3d52 841 /* The following member refers for two table state x ainsn -> int.
842 ??? Above sentence is incomprehensible. */
bea4bad2 843 state_ainsn_table_t trans_table;
bea4bad2 844 /* The following member value is maximal value of min issue delay
845 for insns of the automaton. */
846 int max_min_delay;
847 /* Usually min issue delay is small and we can place several (2, 4,
848 8) elements in one vector element. So the compression factor can
849 be 1 (no compression), 2, 4, 8. */
850 int min_issue_delay_table_compression_factor;
c966a2e2 851 /* Total number of locked states in this automaton. */
852 int locked_states;
bea4bad2 853};
854
855/* The following is the element of the list of automata. */
856struct automata_list_el
857{
858 /* The automaton itself. */
859 automaton_t automaton;
860 /* The next automata set element. */
861 automata_list_el_t next_automata_list_el;
862};
863
864/* The following structure describes a table state X ainsn -> int(>= 0). */
865struct state_ainsn_table
866{
867 /* Automaton to which given table belongs. */
868 automaton_t automaton;
869 /* The following tree vectors for comb vector implementation of the
870 table. */
871 vla_hwint_t comb_vect;
872 vla_hwint_t check_vect;
873 vla_hwint_t base_vect;
874 /* This is simple implementation of the table. */
875 vla_hwint_t full_vect;
876 /* Minimal and maximal values of the previous vectors. */
877 int min_comb_vect_el_value, max_comb_vect_el_value;
878 int min_base_vect_el_value, max_base_vect_el_value;
879};
880
2f8ffd86 881/* Macros to access members of unions. Use only them for access to
882 union members of declarations and regexps. */
883
884#if defined ENABLE_CHECKING && (GCC_VERSION >= 2007)
885
886#define DECL_UNIT(d) __extension__ \
aae87fc3 887(({ __typeof (d) const _decl = (d); \
2f8ffd86 888 if (_decl->mode != dm_unit) \
889 decl_mode_check_failed (_decl->mode, "dm_unit", \
890 __FILE__, __LINE__, __FUNCTION__); \
891 &(_decl)->decl.unit; }))
892
893#define DECL_BYPASS(d) __extension__ \
aae87fc3 894(({ __typeof (d) const _decl = (d); \
2f8ffd86 895 if (_decl->mode != dm_bypass) \
896 decl_mode_check_failed (_decl->mode, "dm_bypass", \
897 __FILE__, __LINE__, __FUNCTION__); \
898 &(_decl)->decl.bypass; }))
899
900#define DECL_AUTOMATON(d) __extension__ \
aae87fc3 901(({ __typeof (d) const _decl = (d); \
2f8ffd86 902 if (_decl->mode != dm_automaton) \
903 decl_mode_check_failed (_decl->mode, "dm_automaton", \
904 __FILE__, __LINE__, __FUNCTION__); \
905 &(_decl)->decl.automaton; }))
906
907#define DECL_EXCL(d) __extension__ \
aae87fc3 908(({ __typeof (d) const _decl = (d); \
2f8ffd86 909 if (_decl->mode != dm_excl) \
910 decl_mode_check_failed (_decl->mode, "dm_excl", \
911 __FILE__, __LINE__, __FUNCTION__); \
912 &(_decl)->decl.excl; }))
913
914#define DECL_PRESENCE(d) __extension__ \
aae87fc3 915(({ __typeof (d) const _decl = (d); \
2f8ffd86 916 if (_decl->mode != dm_presence) \
917 decl_mode_check_failed (_decl->mode, "dm_presence", \
918 __FILE__, __LINE__, __FUNCTION__); \
919 &(_decl)->decl.presence; }))
920
921#define DECL_ABSENCE(d) __extension__ \
aae87fc3 922(({ __typeof (d) const _decl = (d); \
2f8ffd86 923 if (_decl->mode != dm_absence) \
924 decl_mode_check_failed (_decl->mode, "dm_absence", \
925 __FILE__, __LINE__, __FUNCTION__); \
926 &(_decl)->decl.absence; }))
927
928#define DECL_RESERV(d) __extension__ \
aae87fc3 929(({ __typeof (d) const _decl = (d); \
2f8ffd86 930 if (_decl->mode != dm_reserv) \
88a6517e 931 decl_mode_check_failed (_decl->mode, "dm_reserv", \
2f8ffd86 932 __FILE__, __LINE__, __FUNCTION__); \
933 &(_decl)->decl.reserv; }))
934
935#define DECL_INSN_RESERV(d) __extension__ \
aae87fc3 936(({ __typeof (d) const _decl = (d); \
2f8ffd86 937 if (_decl->mode != dm_insn_reserv) \
938 decl_mode_check_failed (_decl->mode, "dm_insn_reserv", \
939 __FILE__, __LINE__, __FUNCTION__); \
940 &(_decl)->decl.insn_reserv; }))
941
1a97be37 942static const char *decl_name (enum decl_mode);
943static void decl_mode_check_failed (enum decl_mode, const char *,
a0b604fc 944 const char *, int, const char *)
945 ATTRIBUTE_NORETURN;
2f8ffd86 946
947/* Return string representation of declaration mode MODE. */
948static const char *
1a97be37 949decl_name (enum decl_mode mode)
2f8ffd86 950{
951 static char str [100];
952
953 if (mode == dm_unit)
954 return "dm_unit";
955 else if (mode == dm_bypass)
956 return "dm_bypass";
957 else if (mode == dm_automaton)
958 return "dm_automaton";
959 else if (mode == dm_excl)
960 return "dm_excl";
961 else if (mode == dm_presence)
962 return "dm_presence";
963 else if (mode == dm_absence)
964 return "dm_absence";
965 else if (mode == dm_reserv)
966 return "dm_reserv";
967 else if (mode == dm_insn_reserv)
968 return "dm_insn_reserv";
969 else
970 sprintf (str, "unknown (%d)", (int) mode);
971 return str;
972}
973
974/* The function prints message about unexpected declaration and finish
975 the program. */
976static void
1a97be37 977decl_mode_check_failed (enum decl_mode mode, const char *expected_mode_str,
978 const char *file, int line, const char *func)
2f8ffd86 979{
980 fprintf
981 (stderr,
982 "\n%s: %d: error in %s: DECL check: expected decl %s, have %s\n",
983 file, line, func, expected_mode_str, decl_name (mode));
984 exit (1);
985}
986
987
988#define REGEXP_UNIT(r) __extension__ \
88a6517e 989(({ struct regexp *const _regexp = (r); \
2f8ffd86 990 if (_regexp->mode != rm_unit) \
991 regexp_mode_check_failed (_regexp->mode, "rm_unit", \
992 __FILE__, __LINE__, __FUNCTION__); \
993 &(_regexp)->regexp.unit; }))
994
995#define REGEXP_RESERV(r) __extension__ \
88a6517e 996(({ struct regexp *const _regexp = (r); \
2f8ffd86 997 if (_regexp->mode != rm_reserv) \
998 regexp_mode_check_failed (_regexp->mode, "rm_reserv", \
999 __FILE__, __LINE__, __FUNCTION__); \
1000 &(_regexp)->regexp.reserv; }))
1001
1002#define REGEXP_SEQUENCE(r) __extension__ \
88a6517e 1003(({ struct regexp *const _regexp = (r); \
2f8ffd86 1004 if (_regexp->mode != rm_sequence) \
1005 regexp_mode_check_failed (_regexp->mode, "rm_sequence", \
1006 __FILE__, __LINE__, __FUNCTION__); \
1007 &(_regexp)->regexp.sequence; }))
1008
1009#define REGEXP_REPEAT(r) __extension__ \
88a6517e 1010(({ struct regexp *const _regexp = (r); \
2f8ffd86 1011 if (_regexp->mode != rm_repeat) \
1012 regexp_mode_check_failed (_regexp->mode, "rm_repeat", \
1013 __FILE__, __LINE__, __FUNCTION__); \
1014 &(_regexp)->regexp.repeat; }))
1015
1016#define REGEXP_ALLOF(r) __extension__ \
88a6517e 1017(({ struct regexp *const _regexp = (r); \
2f8ffd86 1018 if (_regexp->mode != rm_allof) \
1019 regexp_mode_check_failed (_regexp->mode, "rm_allof", \
1020 __FILE__, __LINE__, __FUNCTION__); \
1021 &(_regexp)->regexp.allof; }))
1022
1023#define REGEXP_ONEOF(r) __extension__ \
88a6517e 1024(({ struct regexp *const _regexp = (r); \
2f8ffd86 1025 if (_regexp->mode != rm_oneof) \
1026 regexp_mode_check_failed (_regexp->mode, "rm_oneof", \
1027 __FILE__, __LINE__, __FUNCTION__); \
1028 &(_regexp)->regexp.oneof; }))
1029
1a97be37 1030static const char *regexp_name (enum regexp_mode);
1031static void regexp_mode_check_failed (enum regexp_mode, const char *,
1032 const char *, int,
a0b604fc 1033 const char *) ATTRIBUTE_NORETURN;
2f8ffd86 1034
1035
1036/* Return string representation of regexp mode MODE. */
1037static const char *
1a97be37 1038regexp_name (enum regexp_mode mode)
2f8ffd86 1039{
e0a4c0c2 1040 switch (mode)
1041 {
1042 case rm_unit:
1043 return "rm_unit";
1044 case rm_reserv:
1045 return "rm_reserv";
1046 case rm_nothing:
1047 return "rm_nothing";
1048 case rm_sequence:
1049 return "rm_sequence";
1050 case rm_repeat:
1051 return "rm_repeat";
1052 case rm_allof:
1053 return "rm_allof";
1054 case rm_oneof:
1055 return "rm_oneof";
1056 default:
1057 gcc_unreachable ();
1058 }
2f8ffd86 1059}
1060
1061/* The function prints message about unexpected regexp and finish the
1062 program. */
1063static void
1a97be37 1064regexp_mode_check_failed (enum regexp_mode mode,
1065 const char *expected_mode_str,
1066 const char *file, int line, const char *func)
2f8ffd86 1067{
1068 fprintf
1069 (stderr,
1070 "\n%s: %d: error in %s: REGEXP check: expected decl %s, have %s\n",
1071 file, line, func, expected_mode_str, regexp_name (mode));
1072 exit (1);
1073}
1074
1075#else /* #if defined ENABLE_RTL_CHECKING && (GCC_VERSION >= 2007) */
1076
1077#define DECL_UNIT(d) (&(d)->decl.unit)
1078#define DECL_BYPASS(d) (&(d)->decl.bypass)
1079#define DECL_AUTOMATON(d) (&(d)->decl.automaton)
1080#define DECL_EXCL(d) (&(d)->decl.excl)
1081#define DECL_PRESENCE(d) (&(d)->decl.presence)
1082#define DECL_ABSENCE(d) (&(d)->decl.absence)
1083#define DECL_RESERV(d) (&(d)->decl.reserv)
1084#define DECL_INSN_RESERV(d) (&(d)->decl.insn_reserv)
1085
1086#define REGEXP_UNIT(r) (&(r)->regexp.unit)
1087#define REGEXP_RESERV(r) (&(r)->regexp.reserv)
1088#define REGEXP_SEQUENCE(r) (&(r)->regexp.sequence)
1089#define REGEXP_REPEAT(r) (&(r)->regexp.repeat)
1090#define REGEXP_ALLOF(r) (&(r)->regexp.allof)
1091#define REGEXP_ONEOF(r) (&(r)->regexp.oneof)
1092
1093#endif /* #if defined ENABLE_RTL_CHECKING && (GCC_VERSION >= 2007) */
1094
65b198c2 1095#define XCREATENODE(T) ((T *) create_node (sizeof (T)))
1096#define XCREATENODEVEC(T, N) ((T *) create_node (sizeof (T) * (N)))
1097#define XCREATENODEVAR(T, S) ((T *) create_node ((S)))
1098
1099#define XCOPYNODE(T, P) ((T *) copy_node ((P), sizeof (T)))
1100#define XCOPYNODEVEC(T, P, N) ((T *) copy_node ((P), sizeof (T) * (N)))
1101#define XCOPYNODEVAR(T, P, S) ((T *) copy_node ((P), (S)))
1102
bea4bad2 1103/* Create IR structure (node). */
1104static void *
1a97be37 1105create_node (size_t size)
bea4bad2 1106{
1107 void *result;
1108
1109 obstack_blank (&irp, size);
1110 result = obstack_base (&irp);
1111 obstack_finish (&irp);
1112 /* Default values of members are NULL and zero. */
1113 memset (result, 0, size);
1114 return result;
1115}
1116
1117/* Copy IR structure (node). */
1118static void *
1a97be37 1119copy_node (const void *from, size_t size)
bea4bad2 1120{
88a6517e 1121 void *const result = create_node (size);
bea4bad2 1122 memcpy (result, from, size);
1123 return result;
1124}
1125
1126/* The function checks that NAME does not contain quotes (`"'). */
e7827cef 1127static const char *
1128check_name (const char * name, pos_t pos ATTRIBUTE_UNUSED)
bea4bad2 1129{
88a6517e 1130 const char *str;
bea4bad2 1131
1132 for (str = name; *str != '\0'; str++)
1133 if (*str == '\"')
1134 error ("Name `%s' contains quotes", name);
1135 return name;
1136}
1137
f503d902 1138/* Pointers to all declarations during IR generation are stored in the
bea4bad2 1139 following. */
f1f41a6c 1140static vec<decl_t> decls;
bea4bad2 1141
dafdd1c8 1142/* Given a pointer to a (char *) and a separator, return an alloc'ed
bea4bad2 1143 string containing the next separated element, taking parentheses
1144 into account if PAR_FLAG has nonzero value. Advance the pointer to
1145 after the string scanned, or the end-of-string. Return NULL if at
1146 end of string. */
1147static char *
e7827cef 1148next_sep_el (const char **pstr, int sep, int par_flag)
bea4bad2 1149{
1150 char *out_str;
e7827cef 1151 const char *p;
bea4bad2 1152 int pars_num;
1153 int n_spaces;
1154
1155 /* Remove leading whitespaces. */
74863452 1156 while (ISSPACE ((int) **pstr))
bea4bad2 1157 (*pstr)++;
1158
1159 if (**pstr == '\0')
1160 return NULL;
1161
1162 n_spaces = 0;
1163 for (pars_num = 0, p = *pstr; *p != '\0'; p++)
1164 {
1165 if (par_flag && *p == '(')
1166 pars_num++;
1167 else if (par_flag && *p == ')')
1168 pars_num--;
1169 else if (pars_num == 0 && *p == sep)
1170 break;
74863452 1171 if (pars_num == 0 && ISSPACE ((int) *p))
bea4bad2 1172 n_spaces++;
1173 else
1174 {
1175 for (; n_spaces != 0; n_spaces--)
1176 obstack_1grow (&irp, p [-n_spaces]);
1177 obstack_1grow (&irp, *p);
1178 }
1179 }
1180 obstack_1grow (&irp, '\0');
1181 out_str = obstack_base (&irp);
1182 obstack_finish (&irp);
1183
1184 *pstr = p;
1185 if (**pstr == sep)
1186 (*pstr)++;
1187
1188 return out_str;
1189}
1190
1191/* Given a string and a separator, return the number of separated
1192 elements in it, taking parentheses into account if PAR_FLAG has
98667efb 1193 nonzero value. Return 0 for the null string, -1 if parentheses is
bea4bad2 1194 not balanced. */
1195static int
e7827cef 1196n_sep_els (const char *s, int sep, int par_flag)
bea4bad2 1197{
1198 int n;
1199 int pars_num;
1200
1201 if (*s == '\0')
1202 return 0;
1203
1204 for (pars_num = 0, n = 1; *s; s++)
1205 if (par_flag && *s == '(')
1206 pars_num++;
1207 else if (par_flag && *s == ')')
1208 pars_num--;
1209 else if (pars_num == 0 && *s == sep)
1210 n++;
1211
1212 return (pars_num != 0 ? -1 : n);
1213}
1214
1215/* Given a string and a separator, return vector of strings which are
1216 elements in the string and number of elements through els_num.
58ada791 1217 Take parentheses into account if PAREN_P has nonzero value. The
1218 function also inserts the end marker NULL at the end of vector.
d01481af 1219 Return 0 for the null string, -1 if parentheses are not balanced. */
bea4bad2 1220static char **
e7827cef 1221get_str_vect (const char *str, int *els_num, int sep, int paren_p)
bea4bad2 1222{
1223 int i;
1224 char **vect;
e7827cef 1225 const char **pstr;
e0a4c0c2 1226 char *trail;
bea4bad2 1227
58ada791 1228 *els_num = n_sep_els (str, sep, paren_p);
bea4bad2 1229 if (*els_num <= 0)
1230 return NULL;
58ada791 1231 obstack_blank (&irp, sizeof (char *) * (*els_num + 1));
bea4bad2 1232 vect = (char **) obstack_base (&irp);
1233 obstack_finish (&irp);
1234 pstr = &str;
1235 for (i = 0; i < *els_num; i++)
58ada791 1236 vect [i] = next_sep_el (pstr, sep, paren_p);
e0a4c0c2 1237 trail = next_sep_el (pstr, sep, paren_p);
1238 gcc_assert (!trail);
58ada791 1239 vect [i] = NULL;
bea4bad2 1240 return vect;
1241}
1242
1a97be37 1243/* Process a DEFINE_CPU_UNIT.
bea4bad2 1244
1245 This gives information about a unit contained in CPU. We fill a
1246 struct unit_decl with information used later by `expand_automata'. */
0f7f3d52 1247static void
1a97be37 1248gen_cpu_unit (rtx def)
bea4bad2 1249{
1250 decl_t decl;
1251 char **str_cpu_units;
1252 int vect_length;
1253 int i;
1254
e7827cef 1255 str_cpu_units = get_str_vect (XSTR (def, 0), &vect_length, ',', FALSE);
bea4bad2 1256 if (str_cpu_units == NULL)
1257 fatal ("invalid string `%s' in define_cpu_unit", XSTR (def, 0));
1258 for (i = 0; i < vect_length; i++)
1259 {
65b198c2 1260 decl = XCREATENODE (struct decl);
bea4bad2 1261 decl->mode = dm_unit;
1262 decl->pos = 0;
2f8ffd86 1263 DECL_UNIT (decl)->name = check_name (str_cpu_units [i], decl->pos);
e7827cef 1264 DECL_UNIT (decl)->automaton_name = XSTR (def, 1);
2f8ffd86 1265 DECL_UNIT (decl)->query_p = 0;
58ada791 1266 DECL_UNIT (decl)->min_occ_cycle_num = -1;
1267 DECL_UNIT (decl)->in_set_p = 0;
f1f41a6c 1268 decls.safe_push (decl);
bea4bad2 1269 }
1270}
1271
1a97be37 1272/* Process a DEFINE_QUERY_CPU_UNIT.
bea4bad2 1273
1274 This gives information about a unit contained in CPU. We fill a
1275 struct unit_decl with information used later by `expand_automata'. */
0f7f3d52 1276static void
1a97be37 1277gen_query_cpu_unit (rtx def)
bea4bad2 1278{
1279 decl_t decl;
1280 char **str_cpu_units;
1281 int vect_length;
1282 int i;
1283
e7827cef 1284 str_cpu_units = get_str_vect (XSTR (def, 0), &vect_length, ',',
58ada791 1285 FALSE);
bea4bad2 1286 if (str_cpu_units == NULL)
1287 fatal ("invalid string `%s' in define_query_cpu_unit", XSTR (def, 0));
1288 for (i = 0; i < vect_length; i++)
1289 {
65b198c2 1290 decl = XCREATENODE (struct decl);
bea4bad2 1291 decl->mode = dm_unit;
1292 decl->pos = 0;
2f8ffd86 1293 DECL_UNIT (decl)->name = check_name (str_cpu_units [i], decl->pos);
e7827cef 1294 DECL_UNIT (decl)->automaton_name = XSTR (def, 1);
2f8ffd86 1295 DECL_UNIT (decl)->query_p = 1;
f1f41a6c 1296 decls.safe_push (decl);
bea4bad2 1297 }
1298}
1299
1a97be37 1300/* Process a DEFINE_BYPASS.
bea4bad2 1301
1302 This gives information about a unit contained in the CPU. We fill
1303 in a struct bypass_decl with information used later by
1304 `expand_automata'. */
0f7f3d52 1305static void
1a97be37 1306gen_bypass (rtx def)
bea4bad2 1307{
1308 decl_t decl;
2334f0df 1309 char **out_patterns;
bea4bad2 1310 int out_length;
2334f0df 1311 char **in_patterns;
bea4bad2 1312 int in_length;
1313 int i, j;
1314
2334f0df 1315 out_patterns = get_str_vect (XSTR (def, 1), &out_length, ',', FALSE);
1316 if (out_patterns == NULL)
bea4bad2 1317 fatal ("invalid string `%s' in define_bypass", XSTR (def, 1));
2334f0df 1318 in_patterns = get_str_vect (XSTR (def, 2), &in_length, ',', FALSE);
1319 if (in_patterns == NULL)
bea4bad2 1320 fatal ("invalid string `%s' in define_bypass", XSTR (def, 2));
1321 for (i = 0; i < out_length; i++)
1322 for (j = 0; j < in_length; j++)
1323 {
65b198c2 1324 decl = XCREATENODE (struct decl);
bea4bad2 1325 decl->mode = dm_bypass;
1326 decl->pos = 0;
2f8ffd86 1327 DECL_BYPASS (decl)->latency = XINT (def, 0);
2334f0df 1328 DECL_BYPASS (decl)->out_pattern = out_patterns[i];
1329 DECL_BYPASS (decl)->in_pattern = in_patterns[j];
e7827cef 1330 DECL_BYPASS (decl)->bypass_guard_name = XSTR (def, 3);
f1f41a6c 1331 decls.safe_push (decl);
bea4bad2 1332 }
1333}
1334
1a97be37 1335/* Process an EXCLUSION_SET.
bea4bad2 1336
1337 This gives information about a cpu unit conflicts. We fill a
58ada791 1338 struct excl_rel_decl (excl) with information used later by
bea4bad2 1339 `expand_automata'. */
0f7f3d52 1340static void
1a97be37 1341gen_excl_set (rtx def)
bea4bad2 1342{
1343 decl_t decl;
1344 char **first_str_cpu_units;
1345 char **second_str_cpu_units;
1346 int first_vect_length;
1347 int length;
1348 int i;
1349
1350 first_str_cpu_units
e7827cef 1351 = get_str_vect (XSTR (def, 0), &first_vect_length, ',', FALSE);
bea4bad2 1352 if (first_str_cpu_units == NULL)
1353 fatal ("invalid first string `%s' in exclusion_set", XSTR (def, 0));
e7827cef 1354 second_str_cpu_units = get_str_vect (XSTR (def, 1), &length, ',',
58ada791 1355 FALSE);
bea4bad2 1356 if (second_str_cpu_units == NULL)
1357 fatal ("invalid second string `%s' in exclusion_set", XSTR (def, 1));
1358 length += first_vect_length;
65b198c2 1359 decl = XCREATENODEVAR (struct decl, sizeof (struct decl) + (length - 1) * sizeof (char *));
bea4bad2 1360 decl->mode = dm_excl;
1361 decl->pos = 0;
58ada791 1362 DECL_EXCL (decl)->all_names_num = length;
2f8ffd86 1363 DECL_EXCL (decl)->first_list_length = first_vect_length;
bea4bad2 1364 for (i = 0; i < length; i++)
1365 if (i < first_vect_length)
2f8ffd86 1366 DECL_EXCL (decl)->names [i] = first_str_cpu_units [i];
bea4bad2 1367 else
2f8ffd86 1368 DECL_EXCL (decl)->names [i]
1369 = second_str_cpu_units [i - first_vect_length];
f1f41a6c 1370 decls.safe_push (decl);
bea4bad2 1371}
1372
58ada791 1373/* Process a PRESENCE_SET, a FINAL_PRESENCE_SET, an ABSENCE_SET,
1374 FINAL_ABSENCE_SET (it is depended on PRESENCE_P and FINAL_P).
bea4bad2 1375
1376 This gives information about a cpu unit reservation requirements.
58ada791 1377 We fill a struct unit_pattern_rel_decl with information used later
1378 by `expand_automata'. */
1379static void
1a97be37 1380gen_presence_absence_set (rtx def, int presence_p, int final_p)
bea4bad2 1381{
1382 decl_t decl;
58ada791 1383 char **str_cpu_units;
e7827cef 1384 char **str_pattern_lists;
58ada791 1385 char ***str_patterns;
1386 int cpu_units_length;
bea4bad2 1387 int length;
58ada791 1388 int patterns_length;
bea4bad2 1389 int i;
1390
e7827cef 1391 str_cpu_units = get_str_vect (XSTR (def, 0), &cpu_units_length, ',',
58ada791 1392 FALSE);
1393 if (str_cpu_units == NULL)
1394 fatal ((presence_p
1395 ? (final_p
1396 ? "invalid first string `%s' in final_presence_set"
1397 : "invalid first string `%s' in presence_set")
1398 : (final_p
1399 ? "invalid first string `%s' in final_absence_set"
1400 : "invalid first string `%s' in absence_set")),
1401 XSTR (def, 0));
e7827cef 1402 str_pattern_lists = get_str_vect (XSTR (def, 1),
1403 &patterns_length, ',', FALSE);
1404 if (str_pattern_lists == NULL)
58ada791 1405 fatal ((presence_p
1406 ? (final_p
1407 ? "invalid second string `%s' in final_presence_set"
1408 : "invalid second string `%s' in presence_set")
1409 : (final_p
1410 ? "invalid second string `%s' in final_absence_set"
1411 : "invalid second string `%s' in absence_set")), XSTR (def, 1));
65b198c2 1412 str_patterns = XOBNEWVEC (&irp, char **, patterns_length);
58ada791 1413 for (i = 0; i < patterns_length; i++)
1414 {
e7827cef 1415 str_patterns [i] = get_str_vect (str_pattern_lists [i],
1416 &length, ' ', FALSE);
e0a4c0c2 1417 gcc_assert (str_patterns [i]);
58ada791 1418 }
65b198c2 1419 decl = XCREATENODE (struct decl);
bea4bad2 1420 decl->pos = 0;
58ada791 1421 if (presence_p)
1422 {
1423 decl->mode = dm_presence;
1424 DECL_PRESENCE (decl)->names_num = cpu_units_length;
1425 DECL_PRESENCE (decl)->names = str_cpu_units;
1426 DECL_PRESENCE (decl)->patterns = str_patterns;
1427 DECL_PRESENCE (decl)->patterns_num = patterns_length;
1428 DECL_PRESENCE (decl)->final_p = final_p;
1429 }
1430 else
1431 {
1432 decl->mode = dm_absence;
1433 DECL_ABSENCE (decl)->names_num = cpu_units_length;
1434 DECL_ABSENCE (decl)->names = str_cpu_units;
1435 DECL_ABSENCE (decl)->patterns = str_patterns;
1436 DECL_ABSENCE (decl)->patterns_num = patterns_length;
1437 DECL_ABSENCE (decl)->final_p = final_p;
1438 }
f1f41a6c 1439 decls.safe_push (decl);
bea4bad2 1440}
1441
1a97be37 1442/* Process a PRESENCE_SET.
1443
58ada791 1444 This gives information about a cpu unit reservation requirements.
1445 We fill a struct unit_pattern_rel_decl (presence) with information
1446 used later by `expand_automata'. */
0f7f3d52 1447static void
1a97be37 1448gen_presence_set (rtx def)
58ada791 1449{
1450 gen_presence_absence_set (def, TRUE, FALSE);
1451}
1a97be37 1452
1453/* Process a FINAL_PRESENCE_SET.
58ada791 1454
1455 This gives information about a cpu unit reservation requirements.
1456 We fill a struct unit_pattern_rel_decl (presence) with information
1457 used later by `expand_automata'. */
0f7f3d52 1458static void
1a97be37 1459gen_final_presence_set (rtx def)
58ada791 1460{
1461 gen_presence_absence_set (def, TRUE, TRUE);
1462}
1a97be37 1463
58ada791 1464/* Process an ABSENCE_SET.
bea4bad2 1465
1466 This gives information about a cpu unit reservation requirements.
58ada791 1467 We fill a struct unit_pattern_rel_decl (absence) with information
1468 used later by `expand_automata'. */
0f7f3d52 1469static void
1a97be37 1470gen_absence_set (rtx def)
bea4bad2 1471{
58ada791 1472 gen_presence_absence_set (def, FALSE, FALSE);
bea4bad2 1473}
1a97be37 1474
58ada791 1475/* Process a FINAL_ABSENCE_SET.
bea4bad2 1476
58ada791 1477 This gives information about a cpu unit reservation requirements.
1478 We fill a struct unit_pattern_rel_decl (absence) with information
1479 used later by `expand_automata'. */
0f7f3d52 1480static void
1a97be37 1481gen_final_absence_set (rtx def)
58ada791 1482{
1483 gen_presence_absence_set (def, FALSE, TRUE);
1484}
1a97be37 1485
1486/* Process a DEFINE_AUTOMATON.
bea4bad2 1487
1488 This gives information about a finite state automaton used for
1489 recognizing pipeline hazards. We fill a struct automaton_decl
1490 with information used later by `expand_automata'. */
0f7f3d52 1491static void
1a97be37 1492gen_automaton (rtx def)
bea4bad2 1493{
1494 decl_t decl;
1495 char **str_automata;
1496 int vect_length;
1497 int i;
1498
e7827cef 1499 str_automata = get_str_vect (XSTR (def, 0), &vect_length, ',', FALSE);
bea4bad2 1500 if (str_automata == NULL)
1501 fatal ("invalid string `%s' in define_automaton", XSTR (def, 0));
1502 for (i = 0; i < vect_length; i++)
1503 {
65b198c2 1504 decl = XCREATENODE (struct decl);
bea4bad2 1505 decl->mode = dm_automaton;
1506 decl->pos = 0;
2f8ffd86 1507 DECL_AUTOMATON (decl)->name = check_name (str_automata [i], decl->pos);
f1f41a6c 1508 decls.safe_push (decl);
bea4bad2 1509 }
1510}
1511
1a97be37 1512/* Process an AUTOMATA_OPTION.
bea4bad2 1513
1514 This gives information how to generate finite state automaton used
1515 for recognizing pipeline hazards. */
0f7f3d52 1516static void
1a97be37 1517gen_automata_option (rtx def)
bea4bad2 1518{
f0af5a88 1519 if (strcmp (XSTR (def, 0), NO_MINIMIZATION_OPTION + 1) == 0)
bea4bad2 1520 no_minimization_flag = 1;
f0af5a88 1521 else if (strcmp (XSTR (def, 0), TIME_OPTION + 1) == 0)
0644a91e 1522 time_flag = 1;
df04f68e 1523 else if (strcmp (XSTR (def, 0), STATS_OPTION + 1) == 0)
1524 stats_flag = 1;
f0af5a88 1525 else if (strcmp (XSTR (def, 0), V_OPTION + 1) == 0)
0644a91e 1526 v_flag = 1;
f0af5a88 1527 else if (strcmp (XSTR (def, 0), W_OPTION + 1) == 0)
bea4bad2 1528 w_flag = 1;
f0af5a88 1529 else if (strcmp (XSTR (def, 0), NDFA_OPTION + 1) == 0)
bea4bad2 1530 ndfa_flag = 1;
8043d8fb 1531 else if (strcmp (XSTR (def, 0), COLLAPSE_OPTION + 1) == 0)
1532 collapse_flag = 1;
172b69d8 1533 else if (strcmp (XSTR (def, 0), NO_COMB_OPTION + 1) == 0)
1534 no_comb_flag = 1;
bccc9ebc 1535 else if (strcmp (XSTR (def, 0), PROGRESS_OPTION + 1) == 0)
1536 progress_flag = 1;
bea4bad2 1537 else
1538 fatal ("invalid option `%s' in automata_option", XSTR (def, 0));
1539}
1540
1541/* Name in reservation to denote absence reservation. */
1542#define NOTHING_NAME "nothing"
1543
1544/* The following string contains original reservation string being
1545 parsed. */
e7827cef 1546static const char *reserv_str;
bea4bad2 1547
1548/* Parse an element in STR. */
1549static regexp_t
e7827cef 1550gen_regexp_el (const char *str)
bea4bad2 1551{
1552 regexp_t regexp;
e7827cef 1553 char *dstr;
bea4bad2 1554 int len;
1555
1556 if (*str == '(')
1557 {
1558 len = strlen (str);
1559 if (str [len - 1] != ')')
1560 fatal ("garbage after ) in reservation `%s'", reserv_str);
65b198c2 1561 dstr = XALLOCAVAR (char, len - 1);
e7827cef 1562 memcpy (dstr, str + 1, len - 2);
1563 dstr [len-2] = '\0';
1564 regexp = gen_regexp_sequence (dstr);
bea4bad2 1565 }
1566 else if (strcmp (str, NOTHING_NAME) == 0)
1567 {
65b198c2 1568 regexp = XCREATENODE (struct regexp);
bea4bad2 1569 regexp->mode = rm_nothing;
1570 }
1571 else
1572 {
65b198c2 1573 regexp = XCREATENODE (struct regexp);
bea4bad2 1574 regexp->mode = rm_unit;
2f8ffd86 1575 REGEXP_UNIT (regexp)->name = str;
bea4bad2 1576 }
1577 return regexp;
1578}
1579
1580/* Parse construction `repeat' in STR. */
1581static regexp_t
e7827cef 1582gen_regexp_repeat (const char *str)
bea4bad2 1583{
1584 regexp_t regexp;
1585 regexp_t repeat;
1586 char **repeat_vect;
1587 int els_num;
1588 int i;
1589
58ada791 1590 repeat_vect = get_str_vect (str, &els_num, '*', TRUE);
bea4bad2 1591 if (repeat_vect == NULL)
1592 fatal ("invalid `%s' in reservation `%s'", str, reserv_str);
1593 if (els_num > 1)
1594 {
1595 regexp = gen_regexp_el (repeat_vect [0]);
1596 for (i = 1; i < els_num; i++)
1597 {
65b198c2 1598 repeat = XCREATENODE (struct regexp);
bea4bad2 1599 repeat->mode = rm_repeat;
2f8ffd86 1600 REGEXP_REPEAT (repeat)->regexp = regexp;
1601 REGEXP_REPEAT (repeat)->repeat_num = atoi (repeat_vect [i]);
1602 if (REGEXP_REPEAT (repeat)->repeat_num <= 1)
bea4bad2 1603 fatal ("repetition `%s' <= 1 in reservation `%s'",
1604 str, reserv_str);
1605 regexp = repeat;
1606 }
1607 return regexp;
1608 }
1609 else
7f7aff44 1610 return gen_regexp_el (repeat_vect[0]);
bea4bad2 1611}
1612
1613/* Parse reservation STR which possibly contains separator '+'. */
1614static regexp_t
e7827cef 1615gen_regexp_allof (const char *str)
bea4bad2 1616{
1617 regexp_t allof;
1618 char **allof_vect;
1619 int els_num;
1620 int i;
1621
58ada791 1622 allof_vect = get_str_vect (str, &els_num, '+', TRUE);
bea4bad2 1623 if (allof_vect == NULL)
1624 fatal ("invalid `%s' in reservation `%s'", str, reserv_str);
1625 if (els_num > 1)
1626 {
65b198c2 1627 allof = XCREATENODEVAR (struct regexp, sizeof (struct regexp)
1628 + sizeof (regexp_t) * (els_num - 1));
bea4bad2 1629 allof->mode = rm_allof;
2f8ffd86 1630 REGEXP_ALLOF (allof)->regexps_num = els_num;
bea4bad2 1631 for (i = 0; i < els_num; i++)
2f8ffd86 1632 REGEXP_ALLOF (allof)->regexps [i] = gen_regexp_repeat (allof_vect [i]);
bea4bad2 1633 return allof;
1634 }
1635 else
7f7aff44 1636 return gen_regexp_repeat (allof_vect[0]);
bea4bad2 1637}
1638
1639/* Parse reservation STR which possibly contains separator '|'. */
1640static regexp_t
e7827cef 1641gen_regexp_oneof (const char *str)
bea4bad2 1642{
1643 regexp_t oneof;
1644 char **oneof_vect;
1645 int els_num;
1646 int i;
1647
58ada791 1648 oneof_vect = get_str_vect (str, &els_num, '|', TRUE);
bea4bad2 1649 if (oneof_vect == NULL)
1650 fatal ("invalid `%s' in reservation `%s'", str, reserv_str);
1651 if (els_num > 1)
1652 {
65b198c2 1653 oneof = XCREATENODEVAR (struct regexp, sizeof (struct regexp)
1654 + sizeof (regexp_t) * (els_num - 1));
bea4bad2 1655 oneof->mode = rm_oneof;
2f8ffd86 1656 REGEXP_ONEOF (oneof)->regexps_num = els_num;
bea4bad2 1657 for (i = 0; i < els_num; i++)
2f8ffd86 1658 REGEXP_ONEOF (oneof)->regexps [i] = gen_regexp_allof (oneof_vect [i]);
bea4bad2 1659 return oneof;
1660 }
1661 else
7f7aff44 1662 return gen_regexp_allof (oneof_vect[0]);
bea4bad2 1663}
1664
1665/* Parse reservation STR which possibly contains separator ','. */
1666static regexp_t
e7827cef 1667gen_regexp_sequence (const char *str)
bea4bad2 1668{
1669 regexp_t sequence;
1670 char **sequence_vect;
1671 int els_num;
1672 int i;
1673
58ada791 1674 sequence_vect = get_str_vect (str, &els_num, ',', TRUE);
00275eb0 1675 if (els_num == -1)
1676 fatal ("unbalanced parentheses in reservation `%s'", str);
1677 if (sequence_vect == NULL)
1678 fatal ("invalid reservation `%s'", str);
bea4bad2 1679 if (els_num > 1)
1680 {
65b198c2 1681 sequence = XCREATENODEVAR (struct regexp, sizeof (struct regexp)
1682 + sizeof (regexp_t) * (els_num - 1));
bea4bad2 1683 sequence->mode = rm_sequence;
2f8ffd86 1684 REGEXP_SEQUENCE (sequence)->regexps_num = els_num;
bea4bad2 1685 for (i = 0; i < els_num; i++)
2f8ffd86 1686 REGEXP_SEQUENCE (sequence)->regexps [i]
bea4bad2 1687 = gen_regexp_oneof (sequence_vect [i]);
1688 return sequence;
1689 }
1690 else
7f7aff44 1691 return gen_regexp_oneof (sequence_vect[0]);
bea4bad2 1692}
1693
1694/* Parse construction reservation STR. */
1695static regexp_t
e7827cef 1696gen_regexp (const char *str)
bea4bad2 1697{
1698 reserv_str = str;
7f7aff44 1699 return gen_regexp_sequence (str);
bea4bad2 1700}
1701
1702/* Process a DEFINE_RESERVATION.
1703
1704 This gives information about a reservation of cpu units. We fill
1705 in a struct reserv_decl with information used later by
1706 `expand_automata'. */
0f7f3d52 1707static void
1a97be37 1708gen_reserv (rtx def)
bea4bad2 1709{
1710 decl_t decl;
1711
65b198c2 1712 decl = XCREATENODE (struct decl);
bea4bad2 1713 decl->mode = dm_reserv;
1714 decl->pos = 0;
e7827cef 1715 DECL_RESERV (decl)->name = check_name (XSTR (def, 0), decl->pos);
1716 DECL_RESERV (decl)->regexp = gen_regexp (XSTR (def, 1));
f1f41a6c 1717 decls.safe_push (decl);
bea4bad2 1718}
1719
1720/* Process a DEFINE_INSN_RESERVATION.
1721
1722 This gives information about the reservation of cpu units by an
1723 insn. We fill a struct insn_reserv_decl with information used
1724 later by `expand_automata'. */
0f7f3d52 1725static void
1a97be37 1726gen_insn_reserv (rtx def)
bea4bad2 1727{
1728 decl_t decl;
1729
65b198c2 1730 decl = XCREATENODE (struct decl);
bea4bad2 1731 decl->mode = dm_insn_reserv;
1732 decl->pos = 0;
2f8ffd86 1733 DECL_INSN_RESERV (decl)->name
e7827cef 1734 = check_name (XSTR (def, 0), decl->pos);
2f8ffd86 1735 DECL_INSN_RESERV (decl)->default_latency = XINT (def, 1);
1736 DECL_INSN_RESERV (decl)->condexp = XEXP (def, 2);
e7827cef 1737 DECL_INSN_RESERV (decl)->regexp = gen_regexp (XSTR (def, 3));
f1f41a6c 1738 decls.safe_push (decl);
bea4bad2 1739}
1740
1741\f
1742
1743/* The function evaluates hash value (0..UINT_MAX) of string. */
1744static unsigned
1a97be37 1745string_hash (const char *string)
bea4bad2 1746{
1747 unsigned result, i;
1748
1749 for (result = i = 0;*string++ != '\0'; i++)
1750 result += ((unsigned char) *string << (i % CHAR_BIT));
1751 return result;
1752}
1753
1754\f
1755
1756/* This page contains abstract data `table of automaton declarations'.
1757 Elements of the table is nodes representing automaton declarations.
f503d902 1758 Key of the table elements is name of given automaton. Remember
bea4bad2 1759 that automaton names have own space. */
1760
dafdd1c8 1761/* The function evaluates hash value of an automaton declaration. The
bea4bad2 1762 function is used by abstract data `hashtab'. The function returns
1763 hash value (0..UINT_MAX) of given automaton declaration. */
aa77e59f 1764static hashval_t
1a97be37 1765automaton_decl_hash (const void *automaton_decl)
bea4bad2 1766{
aae87fc3 1767 const_decl_t const decl = (const_decl_t) automaton_decl;
bea4bad2 1768
e0a4c0c2 1769 gcc_assert (decl->mode != dm_automaton
1770 || DECL_AUTOMATON (decl)->name);
2f8ffd86 1771 return string_hash (DECL_AUTOMATON (decl)->name);
bea4bad2 1772}
1773
1774/* The function tests automaton declarations on equality of their
1775 keys. The function is used by abstract data `hashtab'. The
1776 function returns 1 if the declarations have the same key, 0
1777 otherwise. */
1778static int
1a97be37 1779automaton_decl_eq_p (const void* automaton_decl_1,
1780 const void* automaton_decl_2)
bea4bad2 1781{
aae87fc3 1782 const_decl_t const decl1 = (const_decl_t) automaton_decl_1;
1783 const_decl_t const decl2 = (const_decl_t) automaton_decl_2;
bea4bad2 1784
e0a4c0c2 1785 gcc_assert (decl1->mode == dm_automaton
1786 && DECL_AUTOMATON (decl1)->name
1787 && decl2->mode == dm_automaton
1788 && DECL_AUTOMATON (decl2)->name);
2f8ffd86 1789 return strcmp (DECL_AUTOMATON (decl1)->name,
1790 DECL_AUTOMATON (decl2)->name) == 0;
bea4bad2 1791}
1792
1793/* The automaton declaration table itself is represented by the
1794 following variable. */
1795static htab_t automaton_decl_table;
1796
1797/* The function inserts automaton declaration into the table. The
1798 function does nothing if an automaton declaration with the same key
1799 exists already in the table. The function returns automaton
1800 declaration node in the table with the same key as given automaton
1801 declaration node. */
1802static decl_t
1a97be37 1803insert_automaton_decl (decl_t automaton_decl)
bea4bad2 1804{
1805 void **entry_ptr;
1806
b9c74b4d 1807 entry_ptr = htab_find_slot (automaton_decl_table, automaton_decl, INSERT);
bea4bad2 1808 if (*entry_ptr == NULL)
1809 *entry_ptr = (void *) automaton_decl;
1810 return (decl_t) *entry_ptr;
1811}
1812
1813/* The following variable value is node representing automaton
1814 declaration. The node used for searching automaton declaration
1815 with given name. */
1816static struct decl work_automaton_decl;
1817
1818/* The function searches for automaton declaration in the table with
1819 the same key as node representing name of the automaton
1820 declaration. The function returns node found in the table, NULL if
1821 such node does not exist in the table. */
1822static decl_t
e7827cef 1823find_automaton_decl (const char *name)
bea4bad2 1824{
1825 void *entry;
1826
2f8ffd86 1827 work_automaton_decl.mode = dm_automaton;
1828 DECL_AUTOMATON (&work_automaton_decl)->name = name;
bea4bad2 1829 entry = htab_find (automaton_decl_table, &work_automaton_decl);
1830 return (decl_t) entry;
1831}
1832
1833/* The function creates empty automaton declaration table and node
1834 representing automaton declaration and used for searching automaton
1835 declaration with given name. The function must be called only once
1836 before any work with the automaton declaration table. */
1837static void
1a97be37 1838initiate_automaton_decl_table (void)
bea4bad2 1839{
1840 work_automaton_decl.mode = dm_automaton;
1841 automaton_decl_table = htab_create (10, automaton_decl_hash,
1842 automaton_decl_eq_p, (htab_del) 0);
1843}
1844
1845/* The function deletes the automaton declaration table. Only call of
1846 function `initiate_automaton_decl_table' is possible immediately
1847 after this function call. */
1848static void
1a97be37 1849finish_automaton_decl_table (void)
bea4bad2 1850{
1851 htab_delete (automaton_decl_table);
1852}
1853
1854\f
1855
1856/* This page contains abstract data `table of insn declarations'.
1857 Elements of the table is nodes representing insn declarations. Key
1858 of the table elements is name of given insn (in corresponding
f503d902 1859 define_insn_reservation). Remember that insn names have own
bea4bad2 1860 space. */
1861
dafdd1c8 1862/* The function evaluates hash value of an insn declaration. The
bea4bad2 1863 function is used by abstract data `hashtab'. The function returns
1864 hash value (0..UINT_MAX) of given insn declaration. */
aa77e59f 1865static hashval_t
1a97be37 1866insn_decl_hash (const void *insn_decl)
bea4bad2 1867{
aae87fc3 1868 const_decl_t const decl = (const_decl_t) insn_decl;
bea4bad2 1869
e0a4c0c2 1870 gcc_assert (decl->mode == dm_insn_reserv
1871 && DECL_INSN_RESERV (decl)->name);
2f8ffd86 1872 return string_hash (DECL_INSN_RESERV (decl)->name);
bea4bad2 1873}
1874
1875/* The function tests insn declarations on equality of their keys.
1876 The function is used by abstract data `hashtab'. The function
1877 returns 1 if declarations have the same key, 0 otherwise. */
1878static int
1a97be37 1879insn_decl_eq_p (const void *insn_decl_1, const void *insn_decl_2)
bea4bad2 1880{
aae87fc3 1881 const_decl_t const decl1 = (const_decl_t) insn_decl_1;
1882 const_decl_t const decl2 = (const_decl_t) insn_decl_2;
bea4bad2 1883
e0a4c0c2 1884 gcc_assert (decl1->mode == dm_insn_reserv
1885 && DECL_INSN_RESERV (decl1)->name
1886 && decl2->mode == dm_insn_reserv
1887 && DECL_INSN_RESERV (decl2)->name);
2f8ffd86 1888 return strcmp (DECL_INSN_RESERV (decl1)->name,
1889 DECL_INSN_RESERV (decl2)->name) == 0;
bea4bad2 1890}
1891
1892/* The insn declaration table itself is represented by the following
1893 variable. The table does not contain insn reservation
1894 declarations. */
1895static htab_t insn_decl_table;
1896
1897/* The function inserts insn declaration into the table. The function
1898 does nothing if an insn declaration with the same key exists
1899 already in the table. The function returns insn declaration node
1900 in the table with the same key as given insn declaration node. */
1901static decl_t
1a97be37 1902insert_insn_decl (decl_t insn_decl)
bea4bad2 1903{
1904 void **entry_ptr;
1905
b9c74b4d 1906 entry_ptr = htab_find_slot (insn_decl_table, insn_decl, INSERT);
bea4bad2 1907 if (*entry_ptr == NULL)
1908 *entry_ptr = (void *) insn_decl;
1909 return (decl_t) *entry_ptr;
1910}
1911
1912/* The following variable value is node representing insn reservation
1913 declaration. The node used for searching insn reservation
1914 declaration with given name. */
1915static struct decl work_insn_decl;
1916
1917/* The function searches for insn reservation declaration in the table
1918 with the same key as node representing name of the insn reservation
1919 declaration. The function returns node found in the table, NULL if
1920 such node does not exist in the table. */
1921static decl_t
e7827cef 1922find_insn_decl (const char *name)
bea4bad2 1923{
1924 void *entry;
1925
2f8ffd86 1926 work_insn_decl.mode = dm_insn_reserv;
1927 DECL_INSN_RESERV (&work_insn_decl)->name = name;
bea4bad2 1928 entry = htab_find (insn_decl_table, &work_insn_decl);
1929 return (decl_t) entry;
1930}
1931
1932/* The function creates empty insn declaration table and node
1933 representing insn declaration and used for searching insn
1934 declaration with given name. The function must be called only once
1935 before any work with the insn declaration table. */
1936static void
1a97be37 1937initiate_insn_decl_table (void)
bea4bad2 1938{
1939 work_insn_decl.mode = dm_insn_reserv;
1940 insn_decl_table = htab_create (10, insn_decl_hash, insn_decl_eq_p,
1941 (htab_del) 0);
1942}
1943
1944/* The function deletes the insn declaration table. Only call of
1945 function `initiate_insn_decl_table' is possible immediately after
1946 this function call. */
1947static void
1a97be37 1948finish_insn_decl_table (void)
bea4bad2 1949{
1950 htab_delete (insn_decl_table);
1951}
1952
1953\f
1954
1955/* This page contains abstract data `table of declarations'. Elements
1956 of the table is nodes representing declarations (of units and
1957 reservations). Key of the table elements is names of given
1958 declarations. */
1959
1960/* The function evaluates hash value of a declaration. The function
1961 is used by abstract data `hashtab'. The function returns hash
1962 value (0..UINT_MAX) of given declaration. */
aa77e59f 1963static hashval_t
1a97be37 1964decl_hash (const void *decl)
bea4bad2 1965{
aae87fc3 1966 const_decl_t const d = (const_decl_t) decl;
bea4bad2 1967
e0a4c0c2 1968 gcc_assert ((d->mode == dm_unit && DECL_UNIT (d)->name)
1969 || (d->mode == dm_reserv && DECL_RESERV (d)->name));
bea4bad2 1970 return string_hash (d->mode == dm_unit
2f8ffd86 1971 ? DECL_UNIT (d)->name : DECL_RESERV (d)->name);
bea4bad2 1972}
1973
1974/* The function tests declarations on equality of their keys. The
e0a4c0c2 1975 function is used by abstract data 'hashtab'. The function
bea4bad2 1976 returns 1 if the declarations have the same key, 0 otherwise. */
1977static int
1a97be37 1978decl_eq_p (const void *decl_1, const void *decl_2)
bea4bad2 1979{
aae87fc3 1980 const_decl_t const d1 = (const_decl_t) decl_1;
1981 const_decl_t const d2 = (const_decl_t) decl_2;
bea4bad2 1982
e0a4c0c2 1983 gcc_assert ((d1->mode == dm_unit && DECL_UNIT (d1)->name)
1984 || (d1->mode == dm_reserv && DECL_RESERV (d1)->name));
1985 gcc_assert ((d2->mode == dm_unit && DECL_UNIT (d2)->name)
1986 || (d2->mode == dm_reserv && DECL_RESERV (d2)->name));
bea4bad2 1987 return strcmp ((d1->mode == dm_unit
2f8ffd86 1988 ? DECL_UNIT (d1)->name : DECL_RESERV (d1)->name),
bea4bad2 1989 (d2->mode == dm_unit
2f8ffd86 1990 ? DECL_UNIT (d2)->name : DECL_RESERV (d2)->name)) == 0;
bea4bad2 1991}
1992
1993/* The declaration table itself is represented by the following
1994 variable. */
1995static htab_t decl_table;
1996
1997/* The function inserts declaration into the table. The function does
1998 nothing if a declaration with the same key exists already in the
1999 table. The function returns declaration node in the table with the
2000 same key as given declaration node. */
2001
2002static decl_t
1a97be37 2003insert_decl (decl_t decl)
bea4bad2 2004{
2005 void **entry_ptr;
2006
b9c74b4d 2007 entry_ptr = htab_find_slot (decl_table, decl, INSERT);
bea4bad2 2008 if (*entry_ptr == NULL)
2009 *entry_ptr = (void *) decl;
2010 return (decl_t) *entry_ptr;
2011}
2012
2013/* The following variable value is node representing declaration. The
2014 node used for searching declaration with given name. */
2015static struct decl work_decl;
2016
2017/* The function searches for declaration in the table with the same
2018 key as node representing name of the declaration. The function
2019 returns node found in the table, NULL if such node does not exist
2020 in the table. */
2021static decl_t
e7827cef 2022find_decl (const char *name)
bea4bad2 2023{
2024 void *entry;
2025
2f8ffd86 2026 work_decl.mode = dm_unit;
2027 DECL_UNIT (&work_decl)->name = name;
bea4bad2 2028 entry = htab_find (decl_table, &work_decl);
2029 return (decl_t) entry;
2030}
2031
2032/* The function creates empty declaration table and node representing
2033 declaration and used for searching declaration with given name.
2034 The function must be called only once before any work with the
2035 declaration table. */
2036static void
1a97be37 2037initiate_decl_table (void)
bea4bad2 2038{
2039 work_decl.mode = dm_unit;
2040 decl_table = htab_create (10, decl_hash, decl_eq_p, (htab_del) 0);
2041}
2042
2043/* The function deletes the declaration table. Only call of function
2044 `initiate_declaration_table' is possible immediately after this
2045 function call. */
2046static void
1a97be37 2047finish_decl_table (void)
bea4bad2 2048{
2049 htab_delete (decl_table);
2050}
2051
2052\f
2053
2054/* This page contains checker of pipeline hazard description. */
2055
2056/* Checking NAMES in an exclusion clause vector and returning formed
2057 unit_set_el_list. */
2058static unit_set_el_t
1a97be37 2059process_excls (char **names, int num, pos_t excl_pos ATTRIBUTE_UNUSED)
bea4bad2 2060{
2061 unit_set_el_t el_list;
2062 unit_set_el_t last_el;
2063 unit_set_el_t new_el;
2064 decl_t decl_in_table;
2065 int i;
2066
2067 el_list = NULL;
2068 last_el = NULL;
2069 for (i = 0; i < num; i++)
2070 {
2071 decl_in_table = find_decl (names [i]);
2072 if (decl_in_table == NULL)
2073 error ("unit `%s' in exclusion is not declared", names [i]);
2074 else if (decl_in_table->mode != dm_unit)
2075 error ("`%s' in exclusion is not unit", names [i]);
2076 else
2077 {
65b198c2 2078 new_el = XCREATENODE (struct unit_set_el);
2f8ffd86 2079 new_el->unit_decl = DECL_UNIT (decl_in_table);
bea4bad2 2080 new_el->next_unit_set_el = NULL;
2081 if (last_el == NULL)
2082 el_list = last_el = new_el;
2083 else
2084 {
2085 last_el->next_unit_set_el = new_el;
2086 last_el = last_el->next_unit_set_el;
2087 }
2088 }
2089 }
2090 return el_list;
2091}
2092
2093/* The function adds each element from SOURCE_LIST to the exclusion
2094 list of the each element from DEST_LIST. Checking situation "unit
2095 excludes itself". */
2096static void
1a97be37 2097add_excls (unit_set_el_t dest_list, unit_set_el_t source_list,
2098 pos_t excl_pos ATTRIBUTE_UNUSED)
bea4bad2 2099{
2100 unit_set_el_t dst;
2101 unit_set_el_t src;
2102 unit_set_el_t curr_el;
2103 unit_set_el_t prev_el;
2104 unit_set_el_t copy;
2105
2106 for (dst = dest_list; dst != NULL; dst = dst->next_unit_set_el)
2107 for (src = source_list; src != NULL; src = src->next_unit_set_el)
2108 {
2109 if (dst->unit_decl == src->unit_decl)
2110 {
2111 error ("unit `%s' excludes itself", src->unit_decl->name);
2112 continue;
2113 }
2114 if (dst->unit_decl->automaton_name != NULL
2115 && src->unit_decl->automaton_name != NULL
2116 && strcmp (dst->unit_decl->automaton_name,
2117 src->unit_decl->automaton_name) != 0)
2118 {
2119 error ("units `%s' and `%s' in exclusion set belong to different automata",
2120 src->unit_decl->name, dst->unit_decl->name);
2121 continue;
2122 }
2123 for (curr_el = dst->unit_decl->excl_list, prev_el = NULL;
2124 curr_el != NULL;
2125 prev_el = curr_el, curr_el = curr_el->next_unit_set_el)
2126 if (curr_el->unit_decl == src->unit_decl)
2127 break;
2128 if (curr_el == NULL)
2129 {
2130 /* Element not found - insert. */
65b198c2 2131 copy = XCOPYNODE (struct unit_set_el, src);
bea4bad2 2132 copy->next_unit_set_el = NULL;
2133 if (prev_el == NULL)
2134 dst->unit_decl->excl_list = copy;
2135 else
2136 prev_el->next_unit_set_el = copy;
2137 }
2138 }
2139}
2140
58ada791 2141/* Checking NAMES in presence/absence clause and returning the
2142 formed unit_set_el_list. The function is called only after
2143 processing all exclusion sets. */
bea4bad2 2144static unit_set_el_t
1a97be37 2145process_presence_absence_names (char **names, int num,
2146 pos_t req_pos ATTRIBUTE_UNUSED,
2147 int presence_p, int final_p)
bea4bad2 2148{
2149 unit_set_el_t el_list;
2150 unit_set_el_t last_el;
2151 unit_set_el_t new_el;
2152 decl_t decl_in_table;
2153 int i;
2154
2155 el_list = NULL;
2156 last_el = NULL;
2157 for (i = 0; i < num; i++)
2158 {
2159 decl_in_table = find_decl (names [i]);
2160 if (decl_in_table == NULL)
2161 error ((presence_p
58ada791 2162 ? (final_p
2163 ? "unit `%s' in final presence set is not declared"
2164 : "unit `%s' in presence set is not declared")
2165 : (final_p
2166 ? "unit `%s' in final absence set is not declared"
2167 : "unit `%s' in absence set is not declared")), names [i]);
bea4bad2 2168 else if (decl_in_table->mode != dm_unit)
2169 error ((presence_p
58ada791 2170 ? (final_p
2171 ? "`%s' in final presence set is not unit"
2172 : "`%s' in presence set is not unit")
2173 : (final_p
2174 ? "`%s' in final absence set is not unit"
2175 : "`%s' in absence set is not unit")), names [i]);
bea4bad2 2176 else
2177 {
65b198c2 2178 new_el = XCREATENODE (struct unit_set_el);
2f8ffd86 2179 new_el->unit_decl = DECL_UNIT (decl_in_table);
bea4bad2 2180 new_el->next_unit_set_el = NULL;
2181 if (last_el == NULL)
2182 el_list = last_el = new_el;
2183 else
2184 {
2185 last_el->next_unit_set_el = new_el;
2186 last_el = last_el->next_unit_set_el;
2187 }
2188 }
2189 }
2190 return el_list;
2191}
2192
58ada791 2193/* Checking NAMES in patterns of a presence/absence clause and
2194 returning the formed pattern_set_el_list. The function is called
2195 only after processing all exclusion sets. */
2196static pattern_set_el_t
1a97be37 2197process_presence_absence_patterns (char ***patterns, int num,
2198 pos_t req_pos ATTRIBUTE_UNUSED,
2199 int presence_p, int final_p)
58ada791 2200{
2201 pattern_set_el_t el_list;
2202 pattern_set_el_t last_el;
2203 pattern_set_el_t new_el;
2204 decl_t decl_in_table;
2205 int i, j;
2206
2207 el_list = NULL;
2208 last_el = NULL;
2209 for (i = 0; i < num; i++)
2210 {
2211 for (j = 0; patterns [i] [j] != NULL; j++)
2212 ;
65b198c2 2213 new_el = XCREATENODEVAR (struct pattern_set_el,
2214 sizeof (struct pattern_set_el)
2215 + sizeof (struct unit_decl *) * j);
58ada791 2216 new_el->unit_decls
2217 = (struct unit_decl **) ((char *) new_el
2218 + sizeof (struct pattern_set_el));
2219 new_el->next_pattern_set_el = NULL;
2220 if (last_el == NULL)
2221 el_list = last_el = new_el;
2222 else
2223 {
2224 last_el->next_pattern_set_el = new_el;
2225 last_el = last_el->next_pattern_set_el;
2226 }
2227 new_el->units_num = 0;
2228 for (j = 0; patterns [i] [j] != NULL; j++)
2229 {
2230 decl_in_table = find_decl (patterns [i] [j]);
2231 if (decl_in_table == NULL)
2232 error ((presence_p
2233 ? (final_p
2234 ? "unit `%s' in final presence set is not declared"
2235 : "unit `%s' in presence set is not declared")
2236 : (final_p
2237 ? "unit `%s' in final absence set is not declared"
2238 : "unit `%s' in absence set is not declared")),
2239 patterns [i] [j]);
2240 else if (decl_in_table->mode != dm_unit)
2241 error ((presence_p
2242 ? (final_p
2243 ? "`%s' in final presence set is not unit"
2244 : "`%s' in presence set is not unit")
2245 : (final_p
2246 ? "`%s' in final absence set is not unit"
2247 : "`%s' in absence set is not unit")),
2248 patterns [i] [j]);
2249 else
2250 {
2251 new_el->unit_decls [new_el->units_num]
2252 = DECL_UNIT (decl_in_table);
2253 new_el->units_num++;
2254 }
2255 }
2256 }
2257 return el_list;
2258}
2259
2260/* The function adds each element from PATTERN_LIST to presence (if
bea4bad2 2261 PRESENCE_P) or absence list of the each element from DEST_LIST.
58ada791 2262 Checking situations "unit requires own absence", and "unit excludes
2263 and requires presence of ...", "unit requires absence and presence
2264 of ...", "units in (final) presence set belong to different
2265 automata", and "units in (final) absence set belong to different
2266 automata". Remember that we process absence sets only after all
2267 presence sets. */
2268static void
1a97be37 2269add_presence_absence (unit_set_el_t dest_list,
2270 pattern_set_el_t pattern_list,
2271 pos_t req_pos ATTRIBUTE_UNUSED,
2272 int presence_p, int final_p)
bea4bad2 2273{
2274 unit_set_el_t dst;
58ada791 2275 pattern_set_el_t pat;
2276 struct unit_decl *unit;
2277 unit_set_el_t curr_excl_el;
2278 pattern_set_el_t curr_pat_el;
2279 pattern_set_el_t prev_el;
2280 pattern_set_el_t copy;
2281 int i;
2282 int no_error_flag;
bea4bad2 2283
2284 for (dst = dest_list; dst != NULL; dst = dst->next_unit_set_el)
58ada791 2285 for (pat = pattern_list; pat != NULL; pat = pat->next_pattern_set_el)
bea4bad2 2286 {
58ada791 2287 for (i = 0; i < pat->units_num; i++)
bea4bad2 2288 {
58ada791 2289 unit = pat->unit_decls [i];
2290 if (dst->unit_decl == unit && pat->units_num == 1 && !presence_p)
2291 {
2292 error ("unit `%s' requires own absence", unit->name);
2293 continue;
2294 }
2295 if (dst->unit_decl->automaton_name != NULL
2296 && unit->automaton_name != NULL
2297 && strcmp (dst->unit_decl->automaton_name,
2298 unit->automaton_name) != 0)
2299 {
2300 error ((presence_p
2301 ? (final_p
2302 ? "units `%s' and `%s' in final presence set belong to different automata"
2303 : "units `%s' and `%s' in presence set belong to different automata")
2304 : (final_p
2305 ? "units `%s' and `%s' in final absence set belong to different automata"
2306 : "units `%s' and `%s' in absence set belong to different automata")),
2307 unit->name, dst->unit_decl->name);
2308 continue;
2309 }
2310 no_error_flag = 1;
bea4bad2 2311 if (presence_p)
58ada791 2312 for (curr_excl_el = dst->unit_decl->excl_list;
2313 curr_excl_el != NULL;
2314 curr_excl_el = curr_excl_el->next_unit_set_el)
bea4bad2 2315 {
58ada791 2316 if (unit == curr_excl_el->unit_decl && pat->units_num == 1)
bea4bad2 2317 {
2318 if (!w_flag)
2319 {
58ada791 2320 error ("unit `%s' excludes and requires presence of `%s'",
2321 dst->unit_decl->name, unit->name);
bea4bad2 2322 no_error_flag = 0;
2323 }
2324 else
86931af8 2325 warning ("unit `%s' excludes and requires presence of `%s'",
58ada791 2326 dst->unit_decl->name, unit->name);
bea4bad2 2327 }
2328 }
58ada791 2329 else if (pat->units_num == 1)
2330 for (curr_pat_el = dst->unit_decl->presence_list;
2331 curr_pat_el != NULL;
2332 curr_pat_el = curr_pat_el->next_pattern_set_el)
2333 if (curr_pat_el->units_num == 1
2334 && unit == curr_pat_el->unit_decls [0])
2335 {
2336 if (!w_flag)
2337 {
86931af8 2338 error ("unit `%s' requires absence and presence of `%s'",
2339 dst->unit_decl->name, unit->name);
58ada791 2340 no_error_flag = 0;
2341 }
2342 else
86931af8 2343 warning ("unit `%s' requires absence and presence of `%s'",
2344 dst->unit_decl->name, unit->name);
58ada791 2345 }
bea4bad2 2346 if (no_error_flag)
2347 {
58ada791 2348 for (prev_el = (presence_p
2349 ? (final_p
2350 ? dst->unit_decl->final_presence_list
2351 : dst->unit_decl->final_presence_list)
2352 : (final_p
2353 ? dst->unit_decl->final_absence_list
2354 : dst->unit_decl->absence_list));
2355 prev_el != NULL && prev_el->next_pattern_set_el != NULL;
2356 prev_el = prev_el->next_pattern_set_el)
2357 ;
65b198c2 2358 copy = XCOPYNODE (struct pattern_set_el, pat);
58ada791 2359 copy->next_pattern_set_el = NULL;
bea4bad2 2360 if (prev_el == NULL)
2361 {
2362 if (presence_p)
58ada791 2363 {
2364 if (final_p)
2365 dst->unit_decl->final_presence_list = copy;
2366 else
2367 dst->unit_decl->presence_list = copy;
2368 }
2369 else if (final_p)
2370 dst->unit_decl->final_absence_list = copy;
bea4bad2 2371 else
2372 dst->unit_decl->absence_list = copy;
2373 }
2374 else
58ada791 2375 prev_el->next_pattern_set_el = copy;
bea4bad2 2376 }
58ada791 2377 }
2378 }
bea4bad2 2379}
2380
58ada791 2381
08ed847d 2382/* The function inserts BYPASS in the list of bypasses of the
2383 corresponding output insn. The order of bypasses in the list is
9d75589a 2384 described in a comment for member `bypass_list' (see above). If
08ed847d 2385 there is already the same bypass in the list the function reports
2386 this and does nothing. */
2387static void
2388insert_bypass (struct bypass_decl *bypass)
bea4bad2 2389{
08ed847d 2390 struct bypass_decl *curr, *last;
2391 struct insn_reserv_decl *out_insn_reserv = bypass->out_insn_reserv;
2392 struct insn_reserv_decl *in_insn_reserv = bypass->in_insn_reserv;
48e1416a 2393
08ed847d 2394 for (curr = out_insn_reserv->bypass_list, last = NULL;
2395 curr != NULL;
2396 last = curr, curr = curr->next)
2397 if (curr->in_insn_reserv == in_insn_reserv)
2398 {
2399 if ((bypass->bypass_guard_name != NULL
2400 && curr->bypass_guard_name != NULL
2401 && ! strcmp (bypass->bypass_guard_name, curr->bypass_guard_name))
2402 || bypass->bypass_guard_name == curr->bypass_guard_name)
2403 {
2404 if (bypass->bypass_guard_name == NULL)
2405 {
2406 if (!w_flag)
2407 error ("the same bypass `%s - %s' is already defined",
2334f0df 2408 bypass->out_pattern, bypass->in_pattern);
08ed847d 2409 else
86931af8 2410 warning ("the same bypass `%s - %s' is already defined",
2334f0df 2411 bypass->out_pattern, bypass->in_pattern);
08ed847d 2412 }
2413 else if (!w_flag)
2414 error ("the same bypass `%s - %s' (guard %s) is already defined",
2334f0df 2415 bypass->out_pattern, bypass->in_pattern,
08ed847d 2416 bypass->bypass_guard_name);
2417 else
2418 warning
86931af8 2419 ("the same bypass `%s - %s' (guard %s) is already defined",
2334f0df 2420 bypass->out_pattern, bypass->in_pattern,
08ed847d 2421 bypass->bypass_guard_name);
2422 return;
2423 }
2424 if (curr->bypass_guard_name == NULL)
2425 break;
2426 if (curr->next == NULL || curr->next->in_insn_reserv != in_insn_reserv)
2427 {
2428 last = curr;
2429 break;
2430 }
48e1416a 2431
08ed847d 2432 }
2433 if (last == NULL)
2434 {
2435 bypass->next = out_insn_reserv->bypass_list;
2436 out_insn_reserv->bypass_list = bypass;
2437 }
2438 else
2439 {
2440 bypass->next = last->next;
2441 last->next = bypass;
2442 }
bea4bad2 2443}
2444
2334f0df 2445/* BYPASS is a define_bypass decl that includes glob pattern PATTERN.
2446 Call FN (BYPASS, INSN, DATA) for each matching instruction INSN. */
2447
2448static void
2449for_each_matching_insn (decl_t bypass, const char *pattern,
2450 void (*fn) (decl_t, decl_t, void *), void *data)
2451{
2452 decl_t insn_reserv;
2453 bool matched_p;
2454 int i;
2455
2456 matched_p = false;
2457 if (strpbrk (pattern, "*?["))
2458 for (i = 0; i < description->decls_num; i++)
2459 {
2460 insn_reserv = description->decls[i];
2461 if (insn_reserv->mode == dm_insn_reserv
2462 && fnmatch (pattern, DECL_INSN_RESERV (insn_reserv)->name, 0) == 0)
2463 {
2464 fn (bypass, insn_reserv, data);
2465 matched_p = true;
2466 }
2467 }
2468 else
2469 {
2470 insn_reserv = find_insn_decl (pattern);
2471 if (insn_reserv)
2472 {
2473 fn (bypass, insn_reserv, data);
2474 matched_p = true;
2475 }
2476 }
2477 if (!matched_p)
2478 error ("there is no insn reservation that matches `%s'", pattern);
2479}
2480
2481/* A subroutine of process_bypass that is called for each pair
2482 of matching instructions. OUT_INSN_RESERV is the output
2483 instruction and DATA is the input instruction. */
2484
2485static void
2486process_bypass_2 (decl_t model, decl_t out_insn_reserv, void *data)
2487{
2488 struct bypass_decl *bypass;
2489 decl_t in_insn_reserv;
2490
2491 in_insn_reserv = (decl_t) data;
2492 if (strcmp (DECL_INSN_RESERV (in_insn_reserv)->name,
2493 DECL_BYPASS (model)->in_pattern) == 0
2494 && strcmp (DECL_INSN_RESERV (out_insn_reserv)->name,
2495 DECL_BYPASS (model)->out_pattern) == 0)
2496 bypass = DECL_BYPASS (model);
2497 else
2498 {
2499 bypass = XCNEW (struct bypass_decl);
2500 bypass->latency = DECL_BYPASS (model)->latency;
2501 bypass->out_pattern = DECL_INSN_RESERV (out_insn_reserv)->name;
2502 bypass->in_pattern = DECL_INSN_RESERV (in_insn_reserv)->name;
2503 bypass->bypass_guard_name = DECL_BYPASS (model)->bypass_guard_name;
2504 }
2505 bypass->out_insn_reserv = DECL_INSN_RESERV (out_insn_reserv);
2506 bypass->in_insn_reserv = DECL_INSN_RESERV (in_insn_reserv);
2507 insert_bypass (bypass);
2508}
2509
2510/* A subroutine of process_bypass that is called for each input
2511 instruction IN_INSN_RESERV. */
2512
2513static void
2514process_bypass_1 (decl_t bypass, decl_t in_insn_reserv,
2515 void *data ATTRIBUTE_UNUSED)
2516{
2517 for_each_matching_insn (bypass, DECL_BYPASS (bypass)->out_pattern,
2518 process_bypass_2, in_insn_reserv);
2519}
2520
2521/* Process define_bypass decl BYPASS, inserting a bypass for each specific
2522 pair of insn reservations. */
2523
2524static void
2525process_bypass (decl_t bypass)
2526{
2527 for_each_matching_insn (bypass, DECL_BYPASS (bypass)->in_pattern,
2528 process_bypass_1, NULL);
2529}
2530
bea4bad2 2531/* The function processes pipeline description declarations, checks
2532 their correctness, and forms exclusion/presence/absence sets. */
2533static void
1a97be37 2534process_decls (void)
bea4bad2 2535{
2536 decl_t decl;
2537 decl_t automaton_decl;
2538 decl_t decl_in_table;
bea4bad2 2539 int automaton_presence;
2540 int i;
2541
2542 /* Checking repeated automata declarations. */
2543 automaton_presence = 0;
2544 for (i = 0; i < description->decls_num; i++)
2545 {
2546 decl = description->decls [i];
2547 if (decl->mode == dm_automaton)
2548 {
2549 automaton_presence = 1;
2550 decl_in_table = insert_automaton_decl (decl);
2551 if (decl_in_table != decl)
2552 {
2553 if (!w_flag)
2554 error ("repeated declaration of automaton `%s'",
2f8ffd86 2555 DECL_AUTOMATON (decl)->name);
bea4bad2 2556 else
86931af8 2557 warning ("repeated declaration of automaton `%s'",
2f8ffd86 2558 DECL_AUTOMATON (decl)->name);
bea4bad2 2559 }
2560 }
2561 }
2562 /* Checking undeclared automata, repeated declarations (except for
2563 automata) and correctness of their attributes (insn latency times
2564 etc.). */
2565 for (i = 0; i < description->decls_num; i++)
2566 {
2567 decl = description->decls [i];
2568 if (decl->mode == dm_insn_reserv)
2569 {
2f8ffd86 2570 if (DECL_INSN_RESERV (decl)->default_latency < 0)
bea4bad2 2571 error ("define_insn_reservation `%s' has negative latency time",
2f8ffd86 2572 DECL_INSN_RESERV (decl)->name);
2573 DECL_INSN_RESERV (decl)->insn_num = description->insns_num;
bea4bad2 2574 description->insns_num++;
2575 decl_in_table = insert_insn_decl (decl);
2576 if (decl_in_table != decl)
2577 error ("`%s' is already used as insn reservation name",
2f8ffd86 2578 DECL_INSN_RESERV (decl)->name);
bea4bad2 2579 }
2580 else if (decl->mode == dm_bypass)
2581 {
2f8ffd86 2582 if (DECL_BYPASS (decl)->latency < 0)
bea4bad2 2583 error ("define_bypass `%s - %s' has negative latency time",
2334f0df 2584 DECL_BYPASS (decl)->out_pattern,
2585 DECL_BYPASS (decl)->in_pattern);
bea4bad2 2586 }
2587 else if (decl->mode == dm_unit || decl->mode == dm_reserv)
2588 {
2589 if (decl->mode == dm_unit)
2590 {
2f8ffd86 2591 DECL_UNIT (decl)->automaton_decl = NULL;
2592 if (DECL_UNIT (decl)->automaton_name != NULL)
bea4bad2 2593 {
2594 automaton_decl
2f8ffd86 2595 = find_automaton_decl (DECL_UNIT (decl)->automaton_name);
bea4bad2 2596 if (automaton_decl == NULL)
2597 error ("automaton `%s' is not declared",
2f8ffd86 2598 DECL_UNIT (decl)->automaton_name);
bea4bad2 2599 else
2600 {
2f8ffd86 2601 DECL_AUTOMATON (automaton_decl)->automaton_is_used = 1;
2602 DECL_UNIT (decl)->automaton_decl
2603 = DECL_AUTOMATON (automaton_decl);
bea4bad2 2604 }
2605 }
2606 else if (automaton_presence)
2607 error ("define_unit `%s' without automaton when one defined",
2f8ffd86 2608 DECL_UNIT (decl)->name);
2609 DECL_UNIT (decl)->unit_num = description->units_num;
bea4bad2 2610 description->units_num++;
2f8ffd86 2611 if (strcmp (DECL_UNIT (decl)->name, NOTHING_NAME) == 0)
bea4bad2 2612 {
2613 error ("`%s' is declared as cpu unit", NOTHING_NAME);
2614 continue;
2615 }
2f8ffd86 2616 decl_in_table = find_decl (DECL_UNIT (decl)->name);
bea4bad2 2617 }
2618 else
2619 {
2f8ffd86 2620 if (strcmp (DECL_RESERV (decl)->name, NOTHING_NAME) == 0)
bea4bad2 2621 {
2622 error ("`%s' is declared as cpu reservation", NOTHING_NAME);
2623 continue;
2624 }
2f8ffd86 2625 decl_in_table = find_decl (DECL_RESERV (decl)->name);
bea4bad2 2626 }
2627 if (decl_in_table == NULL)
2628 decl_in_table = insert_decl (decl);
2629 else
2630 {
2631 if (decl->mode == dm_unit)
2632 error ("repeated declaration of unit `%s'",
2f8ffd86 2633 DECL_UNIT (decl)->name);
bea4bad2 2634 else
2635 error ("repeated declaration of reservation `%s'",
2f8ffd86 2636 DECL_RESERV (decl)->name);
bea4bad2 2637 }
2638 }
2639 }
2640 /* Check bypasses and form list of bypasses for each (output)
2641 insn. */
2642 for (i = 0; i < description->decls_num; i++)
2643 {
2644 decl = description->decls [i];
2645 if (decl->mode == dm_bypass)
2334f0df 2646 process_bypass (decl);
bea4bad2 2647 }
2648
f503d902 2649 /* Check exclusion set declarations and form exclusion sets. */
bea4bad2 2650 for (i = 0; i < description->decls_num; i++)
2651 {
2652 decl = description->decls [i];
2653 if (decl->mode == dm_excl)
2654 {
2655 unit_set_el_t unit_set_el_list;
2656 unit_set_el_t unit_set_el_list_2;
1a97be37 2657
bea4bad2 2658 unit_set_el_list
2f8ffd86 2659 = process_excls (DECL_EXCL (decl)->names,
2660 DECL_EXCL (decl)->first_list_length, decl->pos);
bea4bad2 2661 unit_set_el_list_2
2f8ffd86 2662 = process_excls (&DECL_EXCL (decl)->names
2663 [DECL_EXCL (decl)->first_list_length],
58ada791 2664 DECL_EXCL (decl)->all_names_num
2f8ffd86 2665 - DECL_EXCL (decl)->first_list_length,
bea4bad2 2666 decl->pos);
2667 add_excls (unit_set_el_list, unit_set_el_list_2, decl->pos);
2668 add_excls (unit_set_el_list_2, unit_set_el_list, decl->pos);
2669 }
2670 }
2671
2672 /* Check presence set declarations and form presence sets. */
2673 for (i = 0; i < description->decls_num; i++)
2674 {
2675 decl = description->decls [i];
2676 if (decl->mode == dm_presence)
2677 {
2678 unit_set_el_t unit_set_el_list;
58ada791 2679 pattern_set_el_t pattern_set_el_list;
1a97be37 2680
bea4bad2 2681 unit_set_el_list
58ada791 2682 = process_presence_absence_names
2683 (DECL_PRESENCE (decl)->names, DECL_PRESENCE (decl)->names_num,
2684 decl->pos, TRUE, DECL_PRESENCE (decl)->final_p);
2685 pattern_set_el_list
2686 = process_presence_absence_patterns
2687 (DECL_PRESENCE (decl)->patterns,
2688 DECL_PRESENCE (decl)->patterns_num,
2689 decl->pos, TRUE, DECL_PRESENCE (decl)->final_p);
2690 add_presence_absence (unit_set_el_list, pattern_set_el_list,
2691 decl->pos, TRUE,
2692 DECL_PRESENCE (decl)->final_p);
bea4bad2 2693 }
2694 }
2695
2696 /* Check absence set declarations and form absence sets. */
2697 for (i = 0; i < description->decls_num; i++)
2698 {
2699 decl = description->decls [i];
2700 if (decl->mode == dm_absence)
2701 {
2702 unit_set_el_t unit_set_el_list;
58ada791 2703 pattern_set_el_t pattern_set_el_list;
1a97be37 2704
bea4bad2 2705 unit_set_el_list
58ada791 2706 = process_presence_absence_names
2707 (DECL_ABSENCE (decl)->names, DECL_ABSENCE (decl)->names_num,
2708 decl->pos, FALSE, DECL_ABSENCE (decl)->final_p);
2709 pattern_set_el_list
2710 = process_presence_absence_patterns
2711 (DECL_ABSENCE (decl)->patterns,
2712 DECL_ABSENCE (decl)->patterns_num,
2713 decl->pos, FALSE, DECL_ABSENCE (decl)->final_p);
2714 add_presence_absence (unit_set_el_list, pattern_set_el_list,
2715 decl->pos, FALSE,
2716 DECL_ABSENCE (decl)->final_p);
bea4bad2 2717 }
2718 }
2719}
2720
2721/* The following function checks that declared automaton is used. If
2722 the automaton is not used, the function fixes error/warning. The
2723 following function must be called only after `process_decls'. */
2724static void
1a97be37 2725check_automaton_usage (void)
bea4bad2 2726{
2727 decl_t decl;
2728 int i;
2729
2730 for (i = 0; i < description->decls_num; i++)
2731 {
2732 decl = description->decls [i];
2733 if (decl->mode == dm_automaton
2f8ffd86 2734 && !DECL_AUTOMATON (decl)->automaton_is_used)
bea4bad2 2735 {
2736 if (!w_flag)
2f8ffd86 2737 error ("automaton `%s' is not used", DECL_AUTOMATON (decl)->name);
bea4bad2 2738 else
86931af8 2739 warning ("automaton `%s' is not used",
2f8ffd86 2740 DECL_AUTOMATON (decl)->name);
bea4bad2 2741 }
2742 }
2743}
2744
2745/* The following recursive function processes all regexp in order to
2746 fix usage of units or reservations and to fix errors of undeclared
2747 name. The function may change unit_regexp onto reserv_regexp.
2748 Remember that reserv_regexp does not exist before the function
2749 call. */
2750static regexp_t
1a97be37 2751process_regexp (regexp_t regexp)
bea4bad2 2752{
2753 decl_t decl_in_table;
2754 regexp_t new_regexp;
2755 int i;
1a97be37 2756
e0a4c0c2 2757 switch (regexp->mode)
bea4bad2 2758 {
e0a4c0c2 2759 case rm_unit:
2f8ffd86 2760 decl_in_table = find_decl (REGEXP_UNIT (regexp)->name);
bea4bad2 2761 if (decl_in_table == NULL)
2762 error ("undeclared unit or reservation `%s'",
2f8ffd86 2763 REGEXP_UNIT (regexp)->name);
bea4bad2 2764 else
e0a4c0c2 2765 switch (decl_in_table->mode)
2766 {
2767 case dm_unit:
2768 DECL_UNIT (decl_in_table)->unit_is_used = 1;
2769 REGEXP_UNIT (regexp)->unit_decl = DECL_UNIT (decl_in_table);
2770 break;
2771
2772 case dm_reserv:
2773 DECL_RESERV (decl_in_table)->reserv_is_used = 1;
65b198c2 2774 new_regexp = XCREATENODE (struct regexp);
e0a4c0c2 2775 new_regexp->mode = rm_reserv;
2776 new_regexp->pos = regexp->pos;
2777 REGEXP_RESERV (new_regexp)->name = REGEXP_UNIT (regexp)->name;
2778 REGEXP_RESERV (new_regexp)->reserv_decl
2779 = DECL_RESERV (decl_in_table);
2780 regexp = new_regexp;
2781 break;
2782
2783 default:
2784 gcc_unreachable ();
2785 }
2786 break;
2787 case rm_sequence:
2788 for (i = 0; i <REGEXP_SEQUENCE (regexp)->regexps_num; i++)
2789 REGEXP_SEQUENCE (regexp)->regexps [i]
2790 = process_regexp (REGEXP_SEQUENCE (regexp)->regexps [i]);
2791 break;
2792 case rm_allof:
2793 for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
2794 REGEXP_ALLOF (regexp)->regexps [i]
2795 = process_regexp (REGEXP_ALLOF (regexp)->regexps [i]);
2796 break;
2797 case rm_oneof:
2798 for (i = 0; i < REGEXP_ONEOF (regexp)->regexps_num; i++)
2799 REGEXP_ONEOF (regexp)->regexps [i]
2800 = process_regexp (REGEXP_ONEOF (regexp)->regexps [i]);
2801 break;
2802 case rm_repeat:
2803 REGEXP_REPEAT (regexp)->regexp
2804 = process_regexp (REGEXP_REPEAT (regexp)->regexp);
2805 break;
2806 case rm_nothing:
2807 break;
2808 default:
2809 gcc_unreachable ();
bea4bad2 2810 }
bea4bad2 2811 return regexp;
2812}
2813
2814/* The following function processes regexp of define_reservation and
2815 define_insn_reservation with the aid of function
2816 `process_regexp'. */
2817static void
1a97be37 2818process_regexp_decls (void)
bea4bad2 2819{
2820 decl_t decl;
2821 int i;
2822
2823 for (i = 0; i < description->decls_num; i++)
2824 {
2825 decl = description->decls [i];
2826 if (decl->mode == dm_reserv)
2f8ffd86 2827 DECL_RESERV (decl)->regexp
2828 = process_regexp (DECL_RESERV (decl)->regexp);
bea4bad2 2829 else if (decl->mode == dm_insn_reserv)
2f8ffd86 2830 DECL_INSN_RESERV (decl)->regexp
2831 = process_regexp (DECL_INSN_RESERV (decl)->regexp);
bea4bad2 2832 }
2833}
2834
2835/* The following function checks that declared unit is used. If the
2836 unit is not used, the function fixes errors/warnings. The
2837 following function must be called only after `process_decls',
2838 `process_regexp_decls'. */
2839static void
1a97be37 2840check_usage (void)
bea4bad2 2841{
2842 decl_t decl;
2843 int i;
2844
2845 for (i = 0; i < description->decls_num; i++)
2846 {
2847 decl = description->decls [i];
2f8ffd86 2848 if (decl->mode == dm_unit && !DECL_UNIT (decl)->unit_is_used)
bea4bad2 2849 {
2850 if (!w_flag)
2f8ffd86 2851 error ("unit `%s' is not used", DECL_UNIT (decl)->name);
bea4bad2 2852 else
86931af8 2853 warning ("unit `%s' is not used", DECL_UNIT (decl)->name);
bea4bad2 2854 }
2f8ffd86 2855 else if (decl->mode == dm_reserv && !DECL_RESERV (decl)->reserv_is_used)
bea4bad2 2856 {
2857 if (!w_flag)
2f8ffd86 2858 error ("reservation `%s' is not used", DECL_RESERV (decl)->name);
bea4bad2 2859 else
86931af8 2860 warning ("reservation `%s' is not used", DECL_RESERV (decl)->name);
bea4bad2 2861 }
2862 }
2863}
2864
2865/* The following variable value is number of reservation being
2866 processed on loop recognition. */
2867static int curr_loop_pass_num;
2868
2869/* The following recursive function returns nonzero value if REGEXP
2870 contains given decl or reservations in given regexp refers for
2871 given decl. */
2872static int
1a97be37 2873loop_in_regexp (regexp_t regexp, decl_t start_decl)
bea4bad2 2874{
2875 int i;
2876
2877 if (regexp == NULL)
2878 return 0;
e0a4c0c2 2879 switch (regexp->mode)
bea4bad2 2880 {
e0a4c0c2 2881 case rm_unit:
2882 return 0;
2883
2884 case rm_reserv:
bea4bad2 2885 if (start_decl->mode == dm_reserv
2f8ffd86 2886 && REGEXP_RESERV (regexp)->reserv_decl == DECL_RESERV (start_decl))
bea4bad2 2887 return 1;
2f8ffd86 2888 else if (REGEXP_RESERV (regexp)->reserv_decl->loop_pass_num
bea4bad2 2889 == curr_loop_pass_num)
2890 /* declaration has been processed. */
2891 return 0;
2892 else
2893 {
2f8ffd86 2894 REGEXP_RESERV (regexp)->reserv_decl->loop_pass_num
bea4bad2 2895 = curr_loop_pass_num;
2f8ffd86 2896 return loop_in_regexp (REGEXP_RESERV (regexp)->reserv_decl->regexp,
bea4bad2 2897 start_decl);
2898 }
e0a4c0c2 2899
2900 case rm_sequence:
2f8ffd86 2901 for (i = 0; i <REGEXP_SEQUENCE (regexp)->regexps_num; i++)
2902 if (loop_in_regexp (REGEXP_SEQUENCE (regexp)->regexps [i], start_decl))
bea4bad2 2903 return 1;
2904 return 0;
e0a4c0c2 2905
2906 case rm_allof:
2f8ffd86 2907 for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
2908 if (loop_in_regexp (REGEXP_ALLOF (regexp)->regexps [i], start_decl))
bea4bad2 2909 return 1;
2910 return 0;
e0a4c0c2 2911
2912 case rm_oneof:
2f8ffd86 2913 for (i = 0; i < REGEXP_ONEOF (regexp)->regexps_num; i++)
2914 if (loop_in_regexp (REGEXP_ONEOF (regexp)->regexps [i], start_decl))
bea4bad2 2915 return 1;
2916 return 0;
e0a4c0c2 2917
2918 case rm_repeat:
2919 return loop_in_regexp (REGEXP_REPEAT (regexp)->regexp, start_decl);
2920
2921 case rm_nothing:
bea4bad2 2922 return 0;
e0a4c0c2 2923
2924 default:
2925 gcc_unreachable ();
bea4bad2 2926 }
2927}
2928
2929/* The following function fixes errors "cycle in definition ...". The
2930 function uses function `loop_in_regexp' for that. */
2931static void
1a97be37 2932check_loops_in_regexps (void)
bea4bad2 2933{
2934 decl_t decl;
2935 int i;
2936
2937 for (i = 0; i < description->decls_num; i++)
2938 {
2939 decl = description->decls [i];
2940 if (decl->mode == dm_reserv)
2f8ffd86 2941 DECL_RESERV (decl)->loop_pass_num = 0;
bea4bad2 2942 }
2943 for (i = 0; i < description->decls_num; i++)
2944 {
2945 decl = description->decls [i];
2946 curr_loop_pass_num = i;
1a97be37 2947
bea4bad2 2948 if (decl->mode == dm_reserv)
2949 {
2f8ffd86 2950 DECL_RESERV (decl)->loop_pass_num = curr_loop_pass_num;
2951 if (loop_in_regexp (DECL_RESERV (decl)->regexp, decl))
bea4bad2 2952 {
e0a4c0c2 2953 gcc_assert (DECL_RESERV (decl)->regexp);
bea4bad2 2954 error ("cycle in definition of reservation `%s'",
2f8ffd86 2955 DECL_RESERV (decl)->name);
bea4bad2 2956 }
2957 }
2958 }
2959}
2960
2961/* The function recursively processes IR of reservation and defines
58ada791 2962 max and min cycle for reservation of unit. */
2963static void
1a97be37 2964process_regexp_cycles (regexp_t regexp, int max_start_cycle,
2965 int min_start_cycle, int *max_finish_cycle,
2966 int *min_finish_cycle)
bea4bad2 2967{
2968 int i;
2969
e0a4c0c2 2970 switch (regexp->mode)
bea4bad2 2971 {
e0a4c0c2 2972 case rm_unit:
58ada791 2973 if (REGEXP_UNIT (regexp)->unit_decl->max_occ_cycle_num < max_start_cycle)
2974 REGEXP_UNIT (regexp)->unit_decl->max_occ_cycle_num = max_start_cycle;
2975 if (REGEXP_UNIT (regexp)->unit_decl->min_occ_cycle_num > min_start_cycle
2976 || REGEXP_UNIT (regexp)->unit_decl->min_occ_cycle_num == -1)
2977 REGEXP_UNIT (regexp)->unit_decl->min_occ_cycle_num = min_start_cycle;
2978 *max_finish_cycle = max_start_cycle;
2979 *min_finish_cycle = min_start_cycle;
e0a4c0c2 2980 break;
2981
2982 case rm_reserv:
2983 process_regexp_cycles (REGEXP_RESERV (regexp)->reserv_decl->regexp,
2984 max_start_cycle, min_start_cycle,
2985 max_finish_cycle, min_finish_cycle);
2986 break;
2987
2988 case rm_repeat:
2f8ffd86 2989 for (i = 0; i < REGEXP_REPEAT (regexp)->repeat_num; i++)
58ada791 2990 {
2991 process_regexp_cycles (REGEXP_REPEAT (regexp)->regexp,
2992 max_start_cycle, min_start_cycle,
2993 max_finish_cycle, min_finish_cycle);
2994 max_start_cycle = *max_finish_cycle + 1;
2995 min_start_cycle = *min_finish_cycle + 1;
2996 }
e0a4c0c2 2997 break;
2998
2999 case rm_sequence:
2f8ffd86 3000 for (i = 0; i <REGEXP_SEQUENCE (regexp)->regexps_num; i++)
58ada791 3001 {
3002 process_regexp_cycles (REGEXP_SEQUENCE (regexp)->regexps [i],
3003 max_start_cycle, min_start_cycle,
3004 max_finish_cycle, min_finish_cycle);
3005 max_start_cycle = *max_finish_cycle + 1;
3006 min_start_cycle = *min_finish_cycle + 1;
3007 }
e0a4c0c2 3008 break;
bea4bad2 3009
e0a4c0c2 3010 case rm_allof:
3011 {
3012 int max_cycle = 0;
3013 int min_cycle = 0;
48e1416a 3014
e0a4c0c2 3015 for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
3016 {
3017 process_regexp_cycles (REGEXP_ALLOF (regexp)->regexps [i],
3018 max_start_cycle, min_start_cycle,
3019 max_finish_cycle, min_finish_cycle);
3020 if (max_cycle < *max_finish_cycle)
3021 max_cycle = *max_finish_cycle;
3022 if (i == 0 || min_cycle > *min_finish_cycle)
3023 min_cycle = *min_finish_cycle;
3024 }
3025 *max_finish_cycle = max_cycle;
3026 *min_finish_cycle = min_cycle;
3027 }
3028 break;
bea4bad2 3029
e0a4c0c2 3030 case rm_oneof:
3031 {
3032 int max_cycle = 0;
3033 int min_cycle = 0;
48e1416a 3034
e0a4c0c2 3035 for (i = 0; i < REGEXP_ONEOF (regexp)->regexps_num; i++)
3036 {
3037 process_regexp_cycles (REGEXP_ONEOF (regexp)->regexps [i],
3038 max_start_cycle, min_start_cycle,
3039 max_finish_cycle, min_finish_cycle);
3040 if (max_cycle < *max_finish_cycle)
3041 max_cycle = *max_finish_cycle;
3042 if (i == 0 || min_cycle > *min_finish_cycle)
3043 min_cycle = *min_finish_cycle;
3044 }
3045 *max_finish_cycle = max_cycle;
3046 *min_finish_cycle = min_cycle;
3047 }
3048 break;
3049
3050 case rm_nothing:
58ada791 3051 *max_finish_cycle = max_start_cycle;
3052 *min_finish_cycle = min_start_cycle;
e0a4c0c2 3053 break;
3054
3055 default:
3056 gcc_unreachable ();
bea4bad2 3057 }
3058}
3059
3060/* The following function is called only for correct program. The
3061 function defines max reservation of insns in cycles. */
3062static void
1a97be37 3063evaluate_max_reserv_cycles (void)
bea4bad2 3064{
3065 int max_insn_cycles_num;
58ada791 3066 int min_insn_cycles_num;
bea4bad2 3067 decl_t decl;
3068 int i;
3069
3070 description->max_insn_reserv_cycles = 0;
3071 for (i = 0; i < description->decls_num; i++)
3072 {
3073 decl = description->decls [i];
3074 if (decl->mode == dm_insn_reserv)
3075 {
58ada791 3076 process_regexp_cycles (DECL_INSN_RESERV (decl)->regexp, 0, 0,
3077 &max_insn_cycles_num, &min_insn_cycles_num);
bea4bad2 3078 if (description->max_insn_reserv_cycles < max_insn_cycles_num)
3079 description->max_insn_reserv_cycles = max_insn_cycles_num;
3080 }
3081 }
b35eefd9 3082 description->max_insn_reserv_cycles++;
bea4bad2 3083}
3084
3085/* The following function calls functions for checking all
3086 description. */
3087static void
1a97be37 3088check_all_description (void)
bea4bad2 3089{
3090 process_decls ();
3091 check_automaton_usage ();
3092 process_regexp_decls ();
3093 check_usage ();
3094 check_loops_in_regexps ();
3095 if (!have_error)
3096 evaluate_max_reserv_cycles ();
3097}
3098
3099\f
3100
3101/* The page contains abstract data `ticker'. This data is used to
3102 report time of different phases of building automata. It is
3103 possibly to write a description for which automata will be built
3104 during several minutes even on fast machine. */
3105
3106/* The following function creates ticker and makes it active. */
3107static ticker_t
1a97be37 3108create_ticker (void)
bea4bad2 3109{
3110 ticker_t ticker;
3111
3112 ticker.modified_creation_time = get_run_time ();
3113 ticker.incremented_off_time = 0;
3114 return ticker;
3115}
3116
3117/* The following function switches off given ticker. */
3118static void
1a97be37 3119ticker_off (ticker_t *ticker)
bea4bad2 3120{
3121 if (ticker->incremented_off_time == 0)
3122 ticker->incremented_off_time = get_run_time () + 1;
3123}
3124
3125/* The following function switches on given ticker. */
3126static void
1a97be37 3127ticker_on (ticker_t *ticker)
bea4bad2 3128{
3129 if (ticker->incremented_off_time != 0)
3130 {
3131 ticker->modified_creation_time
3132 += get_run_time () - ticker->incremented_off_time + 1;
3133 ticker->incremented_off_time = 0;
3134 }
3135}
3136
3137/* The following function returns current time in milliseconds since
3138 the moment when given ticker was created. */
3139static int
1a97be37 3140active_time (ticker_t ticker)
bea4bad2 3141{
3142 if (ticker.incremented_off_time != 0)
3143 return ticker.incremented_off_time - 1 - ticker.modified_creation_time;
3144 else
3145 return get_run_time () - ticker.modified_creation_time;
3146}
3147
3148/* The following function returns string representation of active time
3149 of given ticker. The result is string representation of seconds
3150 with accuracy of 1/100 second. Only result of the last call of the
3151 function exists. Therefore the following code is not correct
3152
3153 printf ("parser time: %s\ngeneration time: %s\n",
3154 active_time_string (parser_ticker),
3155 active_time_string (generation_ticker));
3156
3157 Correct code has to be the following
3158
3159 printf ("parser time: %s\n", active_time_string (parser_ticker));
3160 printf ("generation time: %s\n",
3161 active_time_string (generation_ticker));
3162
3163*/
3164static void
1a97be37 3165print_active_time (FILE *f, ticker_t ticker)
bea4bad2 3166{
3167 int msecs;
3168
3169 msecs = active_time (ticker);
3170 fprintf (f, "%d.%06d", msecs / 1000000, msecs % 1000000);
3171}
3172
3173\f
3174
3175/* The following variable value is number of automaton which are
3176 really being created. This value is defined on the base of
3177 argument of option `-split'. If the variable has zero value the
3178 number of automata is defined by the constructions `%automaton'.
f503d902 3179 This case occurs when option `-split' is absent or has zero
bea4bad2 3180 argument. If constructions `define_automaton' is absent only one
3181 automaton is created. */
3182static int automata_num;
3183
3184/* The following variable values are times of
3185 o transformation of regular expressions
3186 o building NDFA (DFA if !ndfa_flag)
3187 o NDFA -> DFA (simply the same automaton if !ndfa_flag)
3188 o DFA minimization
3189 o building insn equivalence classes
3190 o all previous ones
3191 o code output */
3192static ticker_t transform_time;
3193static ticker_t NDFA_time;
3194static ticker_t NDFA_to_DFA_time;
3195static ticker_t minimize_time;
3196static ticker_t equiv_time;
3197static ticker_t automaton_generation_time;
3198static ticker_t output_time;
3199
3200/* The following variable values are times of
3201 all checking
3202 all generation
3203 all pipeline hazard translator work */
3204static ticker_t check_time;
3205static ticker_t generation_time;
3206static ticker_t all_time;
3207
3208\f
3209
3210/* Pseudo insn decl which denotes advancing cycle. */
3211static decl_t advance_cycle_insn_decl;
8043d8fb 3212/* Pseudo insn decl which denotes collapsing the NDFA state. */
3213static decl_t collapse_ndfa_insn_decl;
3214
3215/* Create and record a decl for the special advance-cycle transition. */
bea4bad2 3216static void
1a97be37 3217add_advance_cycle_insn_decl (void)
bea4bad2 3218{
65b198c2 3219 advance_cycle_insn_decl = XCREATENODE (struct decl);
bea4bad2 3220 advance_cycle_insn_decl->mode = dm_insn_reserv;
3221 advance_cycle_insn_decl->pos = no_pos;
2f8ffd86 3222 DECL_INSN_RESERV (advance_cycle_insn_decl)->regexp = NULL;
e7827cef 3223 DECL_INSN_RESERV (advance_cycle_insn_decl)->name = "$advance_cycle";
2f8ffd86 3224 DECL_INSN_RESERV (advance_cycle_insn_decl)->insn_num
3225 = description->insns_num;
bea4bad2 3226 description->decls [description->decls_num] = advance_cycle_insn_decl;
3227 description->decls_num++;
3228 description->insns_num++;
bea4bad2 3229}
3230
8043d8fb 3231/* Create and record a decl for the special collapse-NDFA transition. */
3232static void
3233add_collapse_ndfa_insn_decl (void)
3234{
3235 collapse_ndfa_insn_decl = XCREATENODE (struct decl);
3236 collapse_ndfa_insn_decl->mode = dm_insn_reserv;
3237 collapse_ndfa_insn_decl->pos = no_pos;
3238 DECL_INSN_RESERV (collapse_ndfa_insn_decl)->regexp = NULL;
3239 DECL_INSN_RESERV (collapse_ndfa_insn_decl)->name = "$collapse_ndfa";
3240 DECL_INSN_RESERV (collapse_ndfa_insn_decl)->insn_num
3241 = description->insns_num;
3242 description->decls [description->decls_num] = collapse_ndfa_insn_decl;
3243 description->decls_num++;
3244 description->insns_num++;
3245}
3246
3247/* True if DECL is either of the two special decls we created. */
3248static bool
3249special_decl_p (struct insn_reserv_decl *decl)
3250{
3251 return (decl == DECL_INSN_RESERV (advance_cycle_insn_decl)
3252 || (collapse_flag
3253 && decl == DECL_INSN_RESERV (collapse_ndfa_insn_decl)));
3254}
3255
bea4bad2 3256\f
f503d902 3257/* Abstract data `alternative states' which represents
bea4bad2 3258 nondeterministic nature of the description (see comments for
3259 structures alt_state and state). */
3260
3261/* List of free states. */
3262static alt_state_t first_free_alt_state;
3263
3264#ifndef NDEBUG
3265/* The following variables is maximal number of allocated nodes
3266 alt_state. */
3267static int allocated_alt_states_num = 0;
3268#endif
3269
3270/* The following function returns free node alt_state. It may be new
f503d902 3271 allocated node or node freed earlier. */
1a97be37 3272static alt_state_t
3273get_free_alt_state (void)
bea4bad2 3274{
3275 alt_state_t result;
3276
3277 if (first_free_alt_state != NULL)
3278 {
3279 result = first_free_alt_state;
3280 first_free_alt_state = first_free_alt_state->next_alt_state;
3281 }
3282 else
3283 {
3284#ifndef NDEBUG
3285 allocated_alt_states_num++;
3286#endif
65b198c2 3287 result = XCREATENODE (struct alt_state);
bea4bad2 3288 }
3289 result->state = NULL;
3290 result->next_alt_state = NULL;
3291 result->next_sorted_alt_state = NULL;
3292 return result;
3293}
3294
3295/* The function frees node ALT_STATE. */
3296static void
1a97be37 3297free_alt_state (alt_state_t alt_state)
bea4bad2 3298{
3299 if (alt_state == NULL)
3300 return;
3301 alt_state->next_alt_state = first_free_alt_state;
3302 first_free_alt_state = alt_state;
3303}
3304
3305/* The function frees list started with node ALT_STATE_LIST. */
3306static void
1a97be37 3307free_alt_states (alt_state_t alt_states_list)
bea4bad2 3308{
3309 alt_state_t curr_alt_state;
3310 alt_state_t next_alt_state;
3311
3312 for (curr_alt_state = alt_states_list;
3313 curr_alt_state != NULL;
3314 curr_alt_state = next_alt_state)
3315 {
3316 next_alt_state = curr_alt_state->next_alt_state;
3317 free_alt_state (curr_alt_state);
3318 }
3319}
3320
3321/* The function compares unique numbers of alt states. */
3322static int
1a97be37 3323alt_state_cmp (const void *alt_state_ptr_1, const void *alt_state_ptr_2)
bea4bad2 3324{
aae87fc3 3325 if ((*(const alt_state_t *) alt_state_ptr_1)->state->unique_num
3326 == (*(const alt_state_t *) alt_state_ptr_2)->state->unique_num)
bea4bad2 3327 return 0;
aae87fc3 3328 else if ((*(const alt_state_t *) alt_state_ptr_1)->state->unique_num
3329 < (*(const alt_state_t *) alt_state_ptr_2)->state->unique_num)
bea4bad2 3330 return -1;
3331 else
3332 return 1;
3333}
3334
3335/* The function sorts ALT_STATES_LIST and removes duplicated alt
3336 states from the list. The comparison key is alt state unique
3337 number. */
e7827cef 3338
1a97be37 3339static alt_state_t
3340uniq_sort_alt_states (alt_state_t alt_states_list)
bea4bad2 3341{
3342 alt_state_t curr_alt_state;
f1f41a6c 3343 vec<alt_state_t> alt_states;
bea4bad2 3344 size_t i;
3345 size_t prev_unique_state_ind;
3346 alt_state_t result;
bea4bad2 3347
e7827cef 3348 if (alt_states_list == 0)
3349 return 0;
3350 if (alt_states_list->next_alt_state == 0)
3351 return alt_states_list;
3352
f1f41a6c 3353 alt_states.create (150);
bea4bad2 3354 for (curr_alt_state = alt_states_list;
3355 curr_alt_state != NULL;
3356 curr_alt_state = curr_alt_state->next_alt_state)
f1f41a6c 3357 alt_states.safe_push (curr_alt_state);
e7827cef 3358
f1f41a6c 3359 alt_states.qsort (alt_state_cmp);
e7827cef 3360
3361 prev_unique_state_ind = 0;
f1f41a6c 3362 for (i = 1; i < alt_states.length (); i++)
3363 if (alt_states[prev_unique_state_ind]->state != alt_states[i]->state)
e7827cef 3364 {
3365 prev_unique_state_ind++;
f1f41a6c 3366 alt_states[prev_unique_state_ind] = alt_states[i];
e7827cef 3367 }
f1f41a6c 3368 alt_states.truncate (prev_unique_state_ind + 1);
e7827cef 3369
f1f41a6c 3370 for (i = 1; i < alt_states.length (); i++)
3371 alt_states[i-1]->next_sorted_alt_state
3372 = alt_states[i];
3373 alt_states.last ()->next_sorted_alt_state = 0;
e7827cef 3374
f1f41a6c 3375 result = alt_states[0];
e7827cef 3376
f1f41a6c 3377 alt_states.release ();
bea4bad2 3378 return result;
3379}
3380
3381/* The function checks equality of alt state lists. Remember that the
3382 lists must be already sorted by the previous function. */
3383static int
1a97be37 3384alt_states_eq (alt_state_t alt_states_1, alt_state_t alt_states_2)
bea4bad2 3385{
3386 while (alt_states_1 != NULL && alt_states_2 != NULL
3387 && alt_state_cmp (&alt_states_1, &alt_states_2) == 0)
3388 {
3389 alt_states_1 = alt_states_1->next_sorted_alt_state;
3390 alt_states_2 = alt_states_2->next_sorted_alt_state;
3391 }
3392 return alt_states_1 == alt_states_2;
3393}
3394
3395/* Initialization of the abstract data. */
3396static void
1a97be37 3397initiate_alt_states (void)
bea4bad2 3398{
3399 first_free_alt_state = NULL;
3400}
3401
3402/* Finishing work with the abstract data. */
3403static void
1a97be37 3404finish_alt_states (void)
bea4bad2 3405{
3406}
3407
3408\f
3409
3410/* The page contains macros for work with bits strings. We could use
3411 standard gcc bitmap or sbitmap but it would result in difficulties
3412 of building canadian cross. */
3413
3414/* Set bit number bitno in the bit string. The macro is not side
3415 effect proof. */
08b7917c 3416#define bitmap_set_bit(bitstring, bitno) \
0fd21c35 3417 ((bitstring)[(bitno) / (sizeof (*(bitstring)) * CHAR_BIT)] |= \
3418 (HOST_WIDE_INT)1 << (bitno) % (sizeof (*(bitstring)) * CHAR_BIT))
bea4bad2 3419
58ada791 3420#define CLEAR_BIT(bitstring, bitno) \
0fd21c35 3421 ((bitstring)[(bitno) / (sizeof (*(bitstring)) * CHAR_BIT)] &= \
3422 ~((HOST_WIDE_INT)1 << (bitno) % (sizeof (*(bitstring)) * CHAR_BIT)))
58ada791 3423
bea4bad2 3424/* Test if bit number bitno in the bitstring is set. The macro is not
3425 side effect proof. */
08b7917c 3426#define bitmap_bit_p(bitstring, bitno) \
0fd21c35 3427 ((bitstring)[(bitno) / (sizeof (*(bitstring)) * CHAR_BIT)] >> \
3428 (bitno) % (sizeof (*(bitstring)) * CHAR_BIT) & 1)
bea4bad2 3429
3430\f
3431
3432/* This page contains abstract data `state'. */
3433
b35eefd9 3434/* Maximal length of reservations in cycles (>= 1). */
bea4bad2 3435static int max_cycles_num;
3436
3437/* Number of set elements (see type set_el_t) needed for
3438 representation of one cycle reservation. It is depended on units
3439 number. */
3440static int els_in_cycle_reserv;
3441
3442/* Number of set elements (see type set_el_t) needed for
3443 representation of maximal length reservation. Deterministic
3444 reservation is stored as set (bit string) of length equal to the
3445 variable value * number of bits in set_el_t. */
3446static int els_in_reservs;
3447
e7827cef 3448/* Array of pointers to unit declarations. */
b35eefd9 3449static unit_decl_t *units_array;
bea4bad2 3450
58ada791 3451/* Temporary reservation of maximal length. */
3452static reserv_sets_t temp_reserv;
3453
bea4bad2 3454/* The state table itself is represented by the following variable. */
3455static htab_t state_table;
3456
e7827cef 3457/* Linked list of free 'state' structures to be recycled. The
3458 next_equiv_class_state pointer is borrowed for a free list. */
3459static state_t first_free_state;
bea4bad2 3460
3461static int curr_unique_state_num;
3462
3463#ifndef NDEBUG
3464/* The following variables is maximal number of allocated nodes
3465 `state'. */
3466static int allocated_states_num = 0;
3467#endif
3468
3469/* Allocate new reservation set. */
3470static reserv_sets_t
1a97be37 3471alloc_empty_reserv_sets (void)
bea4bad2 3472{
3473 reserv_sets_t result;
3474
3475 obstack_blank (&irp, els_in_reservs * sizeof (set_el_t));
3476 result = (reserv_sets_t) obstack_base (&irp);
3477 obstack_finish (&irp);
3478 memset (result, 0, els_in_reservs * sizeof (set_el_t));
3479 return result;
3480}
3481
3482/* Hash value of reservation set. */
3483static unsigned
1a97be37 3484reserv_sets_hash_value (reserv_sets_t reservs)
bea4bad2 3485{
8d578a5b 3486 set_el_t hash_value;
3487 unsigned result;
3488 int reservs_num, i;
bea4bad2 3489 set_el_t *reserv_ptr;
3490
3491 hash_value = 0;
3492 reservs_num = els_in_reservs;
3493 reserv_ptr = reservs;
8d578a5b 3494 i = 0;
bea4bad2 3495 while (reservs_num != 0)
3496 {
3497 reservs_num--;
8d578a5b 3498 hash_value += ((*reserv_ptr >> i)
3499 | (*reserv_ptr << (sizeof (set_el_t) * CHAR_BIT - i)));
3500 i++;
3501 if (i == sizeof (set_el_t) * CHAR_BIT)
3502 i = 0;
bea4bad2 3503 reserv_ptr++;
3504 }
490aba6d 3505 if (sizeof (set_el_t) <= sizeof (unsigned))
8d578a5b 3506 return hash_value;
3507 result = 0;
4c6603bd 3508 for (i = sizeof (set_el_t); i > 0; i -= sizeof (unsigned) - 1)
8d578a5b 3509 {
3510 result += (unsigned) hash_value;
4c6603bd 3511 hash_value >>= (sizeof (unsigned) - 1) * CHAR_BIT;
8d578a5b 3512 }
3513 return result;
bea4bad2 3514}
3515
3516/* Comparison of given reservation sets. */
3517static int
aae87fc3 3518reserv_sets_cmp (const_reserv_sets_t reservs_1, const_reserv_sets_t reservs_2)
bea4bad2 3519{
3520 int reservs_num;
aae87fc3 3521 const set_el_t *reserv_ptr_1;
3522 const set_el_t *reserv_ptr_2;
bea4bad2 3523
e0a4c0c2 3524 gcc_assert (reservs_1 && reservs_2);
bea4bad2 3525 reservs_num = els_in_reservs;
3526 reserv_ptr_1 = reservs_1;
3527 reserv_ptr_2 = reservs_2;
3528 while (reservs_num != 0 && *reserv_ptr_1 == *reserv_ptr_2)
3529 {
3530 reservs_num--;
3531 reserv_ptr_1++;
3532 reserv_ptr_2++;
3533 }
3534 if (reservs_num == 0)
3535 return 0;
3536 else if (*reserv_ptr_1 < *reserv_ptr_2)
3537 return -1;
3538 else
3539 return 1;
3540}
3541
3542/* The function checks equality of the reservation sets. */
3543static int
aae87fc3 3544reserv_sets_eq (const_reserv_sets_t reservs_1, const_reserv_sets_t reservs_2)
bea4bad2 3545{
3546 return reserv_sets_cmp (reservs_1, reservs_2) == 0;
3547}
3548
3549/* Set up in the reservation set that unit with UNIT_NUM is used on
3550 CYCLE_NUM. */
3551static void
1a97be37 3552set_unit_reserv (reserv_sets_t reservs, int cycle_num, int unit_num)
bea4bad2 3553{
e0a4c0c2 3554 gcc_assert (cycle_num < max_cycles_num);
08b7917c 3555 bitmap_set_bit (reservs, cycle_num * els_in_cycle_reserv
bea4bad2 3556 * sizeof (set_el_t) * CHAR_BIT + unit_num);
3557}
3558
3559/* Set up in the reservation set RESERVS that unit with UNIT_NUM is
3560 used on CYCLE_NUM. */
3561static int
1a97be37 3562test_unit_reserv (reserv_sets_t reservs, int cycle_num, int unit_num)
bea4bad2 3563{
e0a4c0c2 3564 gcc_assert (cycle_num < max_cycles_num);
08b7917c 3565 return bitmap_bit_p (reservs, cycle_num * els_in_cycle_reserv
bea4bad2 3566 * sizeof (set_el_t) * CHAR_BIT + unit_num);
3567}
3568
bea4bad2 3569/* The function checks that the reservation sets are intersected,
3570 i.e. there is a unit reservation on a cycle in both reservation
3571 sets. */
3572static int
1a97be37 3573reserv_sets_are_intersected (reserv_sets_t operand_1,
3574 reserv_sets_t operand_2)
bea4bad2 3575{
3576 set_el_t *el_ptr_1;
3577 set_el_t *el_ptr_2;
3578 set_el_t *cycle_ptr_1;
3579 set_el_t *cycle_ptr_2;
bea4bad2 3580
e0a4c0c2 3581 gcc_assert (operand_1 && operand_2);
bea4bad2 3582 for (el_ptr_1 = operand_1, el_ptr_2 = operand_2;
3583 el_ptr_1 < operand_1 + els_in_reservs;
3584 el_ptr_1++, el_ptr_2++)
3585 if (*el_ptr_1 & *el_ptr_2)
3586 return 1;
58ada791 3587 reserv_sets_or (temp_reserv, operand_1, operand_2);
bea4bad2 3588 for (cycle_ptr_1 = operand_1, cycle_ptr_2 = operand_2;
3589 cycle_ptr_1 < operand_1 + els_in_reservs;
3590 cycle_ptr_1 += els_in_cycle_reserv, cycle_ptr_2 += els_in_cycle_reserv)
3591 {
3592 for (el_ptr_1 = cycle_ptr_1, el_ptr_2 = get_excl_set (cycle_ptr_2);
3593 el_ptr_1 < cycle_ptr_1 + els_in_cycle_reserv;
3594 el_ptr_1++, el_ptr_2++)
3595 if (*el_ptr_1 & *el_ptr_2)
3596 return 1;
58ada791 3597 if (!check_presence_pattern_sets (cycle_ptr_1, cycle_ptr_2, FALSE))
3598 return 1;
3599 if (!check_presence_pattern_sets (temp_reserv + (cycle_ptr_2
3600 - operand_2),
3601 cycle_ptr_2, TRUE))
3602 return 1;
3603 if (!check_absence_pattern_sets (cycle_ptr_1, cycle_ptr_2, FALSE))
3604 return 1;
3605 if (!check_absence_pattern_sets (temp_reserv + (cycle_ptr_2 - operand_2),
3606 cycle_ptr_2, TRUE))
bea4bad2 3607 return 1;
bea4bad2 3608 }
3609 return 0;
3610}
3611
3612/* The function sets up RESULT bits by bits of OPERAND shifted on one
3613 cpu cycle. The remaining bits of OPERAND (representing the last
98667efb 3614 cycle unit reservations) are not changed. */
bea4bad2 3615static void
1a97be37 3616reserv_sets_shift (reserv_sets_t result, reserv_sets_t operand)
bea4bad2 3617{
3618 int i;
3619
e0a4c0c2 3620 gcc_assert (result && operand && result != operand);
bea4bad2 3621 for (i = els_in_cycle_reserv; i < els_in_reservs; i++)
3622 result [i - els_in_cycle_reserv] = operand [i];
3623}
3624
3625/* OR of the reservation sets. */
3626static void
1a97be37 3627reserv_sets_or (reserv_sets_t result, reserv_sets_t operand_1,
3628 reserv_sets_t operand_2)
bea4bad2 3629{
3630 set_el_t *el_ptr_1;
3631 set_el_t *el_ptr_2;
3632 set_el_t *result_set_el_ptr;
3633
e0a4c0c2 3634 gcc_assert (result && operand_1 && operand_2);
bea4bad2 3635 for (el_ptr_1 = operand_1, el_ptr_2 = operand_2, result_set_el_ptr = result;
3636 el_ptr_1 < operand_1 + els_in_reservs;
3637 el_ptr_1++, el_ptr_2++, result_set_el_ptr++)
3638 *result_set_el_ptr = *el_ptr_1 | *el_ptr_2;
3639}
3640
3641/* AND of the reservation sets. */
3642static void
1a97be37 3643reserv_sets_and (reserv_sets_t result, reserv_sets_t operand_1,
3644 reserv_sets_t operand_2)
bea4bad2 3645{
3646 set_el_t *el_ptr_1;
3647 set_el_t *el_ptr_2;
3648 set_el_t *result_set_el_ptr;
3649
e0a4c0c2 3650 gcc_assert (result && operand_1 && operand_2);
bea4bad2 3651 for (el_ptr_1 = operand_1, el_ptr_2 = operand_2, result_set_el_ptr = result;
3652 el_ptr_1 < operand_1 + els_in_reservs;
3653 el_ptr_1++, el_ptr_2++, result_set_el_ptr++)
3654 *result_set_el_ptr = *el_ptr_1 & *el_ptr_2;
3655}
3656
3657/* The function outputs string representation of units reservation on
3658 cycle START_CYCLE in the reservation set. The function uses repeat
3659 construction if REPETITION_NUM > 1. */
3660static void
1a97be37 3661output_cycle_reservs (FILE *f, reserv_sets_t reservs, int start_cycle,
3662 int repetition_num)
bea4bad2 3663{
3664 int unit_num;
3665 int reserved_units_num;
3666
3667 reserved_units_num = 0;
3668 for (unit_num = 0; unit_num < description->units_num; unit_num++)
08b7917c 3669 if (bitmap_bit_p (reservs, start_cycle * els_in_cycle_reserv
bea4bad2 3670 * sizeof (set_el_t) * CHAR_BIT + unit_num))
3671 reserved_units_num++;
e0a4c0c2 3672 gcc_assert (repetition_num > 0);
bea4bad2 3673 if (repetition_num != 1 && reserved_units_num > 1)
3674 fprintf (f, "(");
3675 reserved_units_num = 0;
3676 for (unit_num = 0;
3677 unit_num < description->units_num;
3678 unit_num++)
08b7917c 3679 if (bitmap_bit_p (reservs, start_cycle * els_in_cycle_reserv
bea4bad2 3680 * sizeof (set_el_t) * CHAR_BIT + unit_num))
3681 {
3682 if (reserved_units_num != 0)
3683 fprintf (f, "+");
3684 reserved_units_num++;
3685 fprintf (f, "%s", units_array [unit_num]->name);
3686 }
3687 if (reserved_units_num == 0)
3688 fprintf (f, NOTHING_NAME);
e0a4c0c2 3689 gcc_assert (repetition_num > 0);
58ada791 3690 if (repetition_num != 1 && reserved_units_num > 1)
8d578a5b 3691 fprintf (f, ")");
3692 if (repetition_num != 1)
3693 fprintf (f, "*%d", repetition_num);
bea4bad2 3694}
3695
3696/* The function outputs string representation of units reservation in
3697 the reservation set. */
3698static void
1a97be37 3699output_reserv_sets (FILE *f, reserv_sets_t reservs)
bea4bad2 3700{
3701 int start_cycle = 0;
3702 int cycle;
3703 int repetition_num;
3704
3705 repetition_num = 0;
3706 for (cycle = 0; cycle < max_cycles_num; cycle++)
3707 if (repetition_num == 0)
3708 {
3709 repetition_num++;
3710 start_cycle = cycle;
3711 }
3712 else if (memcmp
3713 ((char *) reservs + start_cycle * els_in_cycle_reserv
3714 * sizeof (set_el_t),
3715 (char *) reservs + cycle * els_in_cycle_reserv
3716 * sizeof (set_el_t),
3717 els_in_cycle_reserv * sizeof (set_el_t)) == 0)
3718 repetition_num++;
3719 else
3720 {
3721 if (start_cycle != 0)
3722 fprintf (f, ", ");
3723 output_cycle_reservs (f, reservs, start_cycle, repetition_num);
3724 repetition_num = 1;
3725 start_cycle = cycle;
3726 }
3727 if (start_cycle < max_cycles_num)
3728 {
3729 if (start_cycle != 0)
3730 fprintf (f, ", ");
3731 output_cycle_reservs (f, reservs, start_cycle, repetition_num);
3732 }
3733}
3734
3735/* The following function returns free node state for AUTOMATON. It
f503d902 3736 may be new allocated node or node freed earlier. The function also
bea4bad2 3737 allocates reservation set if WITH_RESERVS has nonzero value. */
3738static state_t
1a97be37 3739get_free_state (int with_reservs, automaton_t automaton)
bea4bad2 3740{
3741 state_t result;
3742
e0a4c0c2 3743 gcc_assert (max_cycles_num > 0 && automaton);
e7827cef 3744 if (first_free_state)
bea4bad2 3745 {
e7827cef 3746 result = first_free_state;
3747 first_free_state = result->next_equiv_class_state;
3748
3749 result->next_equiv_class_state = NULL;
bea4bad2 3750 result->automaton = automaton;
3751 result->first_out_arc = NULL;
3752 result->it_was_placed_in_stack_for_NDFA_forming = 0;
3753 result->it_was_placed_in_stack_for_DFA_forming = 0;
3754 result->component_states = NULL;
bea4bad2 3755 }
3756 else
3757 {
3758#ifndef NDEBUG
3759 allocated_states_num++;
3760#endif
65b198c2 3761 result = XCREATENODE (struct state);
bea4bad2 3762 result->automaton = automaton;
3763 result->first_out_arc = NULL;
3764 result->unique_num = curr_unique_state_num;
bea4bad2 3765 curr_unique_state_num++;
3766 }
3767 if (with_reservs)
3768 {
3769 if (result->reservs == NULL)
3770 result->reservs = alloc_empty_reserv_sets ();
3771 else
3772 memset (result->reservs, 0, els_in_reservs * sizeof (set_el_t));
3773 }
3774 return result;
3775}
3776
3777/* The function frees node STATE. */
3778static void
1a97be37 3779free_state (state_t state)
bea4bad2 3780{
3781 free_alt_states (state->component_states);
e7827cef 3782 state->next_equiv_class_state = first_free_state;
3783 first_free_state = state;
bea4bad2 3784}
3785
3786/* Hash value of STATE. If STATE represents deterministic state it is
3787 simply hash value of the corresponding reservation set. Otherwise
3788 it is formed from hash values of the component deterministic
3789 states. One more key is order number of state automaton. */
aa77e59f 3790static hashval_t
1a97be37 3791state_hash (const void *state)
bea4bad2 3792{
3793 unsigned int hash_value;
3794 alt_state_t alt_state;
3795
aae87fc3 3796 if (((const_state_t) state)->component_states == NULL)
3797 hash_value = reserv_sets_hash_value (((const_state_t) state)->reservs);
bea4bad2 3798 else
3799 {
3800 hash_value = 0;
aae87fc3 3801 for (alt_state = ((const_state_t) state)->component_states;
bea4bad2 3802 alt_state != NULL;
3803 alt_state = alt_state->next_sorted_alt_state)
3804 hash_value = (((hash_value >> (sizeof (unsigned) - 1) * CHAR_BIT)
3805 | (hash_value << CHAR_BIT))
3806 + alt_state->state->unique_num);
3807 }
3808 hash_value = (((hash_value >> (sizeof (unsigned) - 1) * CHAR_BIT)
3809 | (hash_value << CHAR_BIT))
aae87fc3 3810 + ((const_state_t) state)->automaton->automaton_order_num);
bea4bad2 3811 return hash_value;
3812}
3813
3814/* Return nonzero value if the states are the same. */
3815static int
1a97be37 3816state_eq_p (const void *state_1, const void *state_2)
bea4bad2 3817{
3818 alt_state_t alt_state_1;
3819 alt_state_t alt_state_2;
3820
aae87fc3 3821 if (((const_state_t) state_1)->automaton != ((const_state_t) state_2)->automaton)
bea4bad2 3822 return 0;
aae87fc3 3823 else if (((const_state_t) state_1)->component_states == NULL
3824 && ((const_state_t) state_2)->component_states == NULL)
3825 return reserv_sets_eq (((const_state_t) state_1)->reservs,
3826 ((const_state_t) state_2)->reservs);
3827 else if (((const_state_t) state_1)->component_states != NULL
3828 && ((const_state_t) state_2)->component_states != NULL)
3829 {
3830 for (alt_state_1 = ((const_state_t) state_1)->component_states,
3831 alt_state_2 = ((const_state_t) state_2)->component_states;
bea4bad2 3832 alt_state_1 != NULL && alt_state_2 != NULL;
3833 alt_state_1 = alt_state_1->next_sorted_alt_state,
3834 alt_state_2 = alt_state_2->next_sorted_alt_state)
3835 /* All state in the list must be already in the hash table.
3836 Also the lists must be sorted. */
3837 if (alt_state_1->state != alt_state_2->state)
3838 return 0;
3839 return alt_state_1 == alt_state_2;
3840 }
3841 else
3842 return 0;
3843}
3844
3845/* Insert STATE into the state table. */
3846static state_t
1a97be37 3847insert_state (state_t state)
bea4bad2 3848{
3849 void **entry_ptr;
3850
b9c74b4d 3851 entry_ptr = htab_find_slot (state_table, (void *) state, INSERT);
bea4bad2 3852 if (*entry_ptr == NULL)
3853 *entry_ptr = (void *) state;
3854 return (state_t) *entry_ptr;
3855}
3856
3857/* Add reservation of unit with UNIT_NUM on cycle CYCLE_NUM to
3858 deterministic STATE. */
3859static void
1a97be37 3860set_state_reserv (state_t state, int cycle_num, int unit_num)
bea4bad2 3861{
3862 set_unit_reserv (state->reservs, cycle_num, unit_num);
3863}
3864
3865/* Return nonzero value if the deterministic states contains a
3866 reservation of the same cpu unit on the same cpu cycle. */
3867static int
1a97be37 3868intersected_state_reservs_p (state_t state1, state_t state2)
bea4bad2 3869{
e0a4c0c2 3870 gcc_assert (state1->automaton == state2->automaton);
bea4bad2 3871 return reserv_sets_are_intersected (state1->reservs, state2->reservs);
3872}
3873
3874/* Return deterministic state (inserted into the table) which
58ada791 3875 representing the automaton state which is union of reservations of
3876 the deterministic states masked by RESERVS. */
bea4bad2 3877static state_t
1a97be37 3878states_union (state_t state1, state_t state2, reserv_sets_t reservs)
bea4bad2 3879{
3880 state_t result;
3881 state_t state_in_table;
3882
e0a4c0c2 3883 gcc_assert (state1->automaton == state2->automaton);
bea4bad2 3884 result = get_free_state (1, state1->automaton);
3885 reserv_sets_or (result->reservs, state1->reservs, state2->reservs);
58ada791 3886 reserv_sets_and (result->reservs, result->reservs, reservs);
bea4bad2 3887 state_in_table = insert_state (result);
3888 if (result != state_in_table)
3889 {
3890 free_state (result);
3891 result = state_in_table;
3892 }
3893 return result;
3894}
3895
3896/* Return deterministic state (inserted into the table) which
3897 represent the automaton state is obtained from deterministic STATE
58ada791 3898 by advancing cpu cycle and masking by RESERVS. */
bea4bad2 3899static state_t
1a97be37 3900state_shift (state_t state, reserv_sets_t reservs)
bea4bad2 3901{
3902 state_t result;
3903 state_t state_in_table;
3904
3905 result = get_free_state (1, state->automaton);
3906 reserv_sets_shift (result->reservs, state->reservs);
58ada791 3907 reserv_sets_and (result->reservs, result->reservs, reservs);
bea4bad2 3908 state_in_table = insert_state (result);
3909 if (result != state_in_table)
3910 {
3911 free_state (result);
3912 result = state_in_table;
3913 }
3914 return result;
3915}
3916
3917/* Initialization of the abstract data. */
3918static void
1a97be37 3919initiate_states (void)
bea4bad2 3920{
3921 decl_t decl;
3922 int i;
3923
e7827cef 3924 if (description->units_num)
4c36ffe6 3925 units_array = XNEWVEC (unit_decl_t, description->units_num);
e7827cef 3926 else
3927 units_array = 0;
3928
bea4bad2 3929 for (i = 0; i < description->decls_num; i++)
3930 {
3931 decl = description->decls [i];
3932 if (decl->mode == dm_unit)
2f8ffd86 3933 units_array [DECL_UNIT (decl)->unit_num] = DECL_UNIT (decl);
bea4bad2 3934 }
3935 max_cycles_num = description->max_insn_reserv_cycles;
bea4bad2 3936 els_in_cycle_reserv
3937 = ((description->units_num + sizeof (set_el_t) * CHAR_BIT - 1)
3938 / (sizeof (set_el_t) * CHAR_BIT));
3939 els_in_reservs = els_in_cycle_reserv * max_cycles_num;
3940 curr_unique_state_num = 0;
3941 initiate_alt_states ();
bea4bad2 3942 state_table = htab_create (1500, state_hash, state_eq_p, (htab_del) 0);
58ada791 3943 temp_reserv = alloc_empty_reserv_sets ();
bea4bad2 3944}
3945
805e22b2 3946/* Finishing work with the abstract data. */
bea4bad2 3947static void
1a97be37 3948finish_states (void)
bea4bad2 3949{
e7827cef 3950 free (units_array);
3951 units_array = 0;
bea4bad2 3952 htab_delete (state_table);
e7827cef 3953 first_free_state = NULL;
bea4bad2 3954 finish_alt_states ();
3955}
3956
3957\f
3958
3959/* Abstract data `arcs'. */
3960
3961/* List of free arcs. */
3962static arc_t first_free_arc;
3963
3964#ifndef NDEBUG
3965/* The following variables is maximal number of allocated nodes
3966 `arc'. */
3967static int allocated_arcs_num = 0;
3968#endif
3969
3970/* The function frees node ARC. */
3971static void
1a97be37 3972free_arc (arc_t arc)
bea4bad2 3973{
3974 arc->next_out_arc = first_free_arc;
3975 first_free_arc = arc;
3976}
3977
3978/* The function removes and frees ARC staring from FROM_STATE. */
3979static void
1a97be37 3980remove_arc (state_t from_state, arc_t arc)
bea4bad2 3981{
3982 arc_t prev_arc;
3983 arc_t curr_arc;
3984
e0a4c0c2 3985 gcc_assert (arc);
bea4bad2 3986 for (prev_arc = NULL, curr_arc = from_state->first_out_arc;
3987 curr_arc != NULL;
3988 prev_arc = curr_arc, curr_arc = curr_arc->next_out_arc)
3989 if (curr_arc == arc)
3990 break;
e0a4c0c2 3991 gcc_assert (curr_arc);
bea4bad2 3992 if (prev_arc == NULL)
3993 from_state->first_out_arc = arc->next_out_arc;
3994 else
3995 prev_arc->next_out_arc = arc->next_out_arc;
c72f0286 3996 from_state->num_out_arcs--;
bea4bad2 3997 free_arc (arc);
3998}
3999
4000/* The functions returns arc with given characteristics (or NULL if
4001 the arc does not exist). */
4002static arc_t
1a97be37 4003find_arc (state_t from_state, state_t to_state, ainsn_t insn)
bea4bad2 4004{
4005 arc_t arc;
4006
4007 for (arc = first_out_arc (from_state); arc != NULL; arc = next_out_arc (arc))
8043d8fb 4008 if (arc->insn == insn
4009 && (arc->to_state == to_state
4010 || (collapse_flag
4011 /* Any arc is good enough for a collapse-ndfa transition. */
4012 && (insn->insn_reserv_decl
4013 == DECL_INSN_RESERV (collapse_ndfa_insn_decl)))))
bea4bad2 4014 return arc;
4015 return NULL;
4016}
4017
002e7d08 4018/* The function adds arc from FROM_STATE to TO_STATE marked by AINSN,
4019 unless such an arc already exists. */
4020static void
0f7f3d52 4021add_arc (state_t from_state, state_t to_state, ainsn_t ainsn)
bea4bad2 4022{
4023 arc_t new_arc;
4024
4025 new_arc = find_arc (from_state, to_state, ainsn);
4026 if (new_arc != NULL)
002e7d08 4027 return;
bea4bad2 4028 if (first_free_arc == NULL)
4029 {
4030#ifndef NDEBUG
4031 allocated_arcs_num++;
4032#endif
65b198c2 4033 new_arc = XCREATENODE (struct arc);
bea4bad2 4034 new_arc->to_state = NULL;
4035 new_arc->insn = NULL;
4036 new_arc->next_out_arc = NULL;
4037 }
4038 else
4039 {
4040 new_arc = first_free_arc;
4041 first_free_arc = first_free_arc->next_out_arc;
4042 }
4043 new_arc->to_state = to_state;
4044 new_arc->insn = ainsn;
4045 ainsn->arc_exists_p = 1;
4046 new_arc->next_out_arc = from_state->first_out_arc;
4047 from_state->first_out_arc = new_arc;
c72f0286 4048 from_state->num_out_arcs++;
bea4bad2 4049 new_arc->next_arc_marked_by_insn = NULL;
bea4bad2 4050}
4051
4052/* The function returns the first arc starting from STATE. */
4053static arc_t
aae87fc3 4054first_out_arc (const_state_t state)
bea4bad2 4055{
4056 return state->first_out_arc;
4057}
4058
4059/* The function returns next out arc after ARC. */
4060static arc_t
1a97be37 4061next_out_arc (arc_t arc)
bea4bad2 4062{
4063 return arc->next_out_arc;
4064}
4065
4066/* Initialization of the abstract data. */
4067static void
1a97be37 4068initiate_arcs (void)
bea4bad2 4069{
4070 first_free_arc = NULL;
4071}
4072
4073/* Finishing work with the abstract data. */
4074static void
1a97be37 4075finish_arcs (void)
bea4bad2 4076{
4077}
4078
4079\f
4080
4081/* Abstract data `automata lists'. */
4082
4083/* List of free states. */
4084static automata_list_el_t first_free_automata_list_el;
4085
4086/* The list being formed. */
4087static automata_list_el_t current_automata_list;
4088
4089/* Hash table of automata lists. */
4090static htab_t automata_list_table;
4091
4092/* The following function returns free automata list el. It may be
4093 new allocated node or node freed earlier. */
1a97be37 4094static automata_list_el_t
4095get_free_automata_list_el (void)
bea4bad2 4096{
4097 automata_list_el_t result;
4098
4099 if (first_free_automata_list_el != NULL)
4100 {
4101 result = first_free_automata_list_el;
4102 first_free_automata_list_el
4103 = first_free_automata_list_el->next_automata_list_el;
4104 }
4105 else
65b198c2 4106 result = XCREATENODE (struct automata_list_el);
bea4bad2 4107 result->automaton = NULL;
4108 result->next_automata_list_el = NULL;
4109 return result;
4110}
4111
4112/* The function frees node AUTOMATA_LIST_EL. */
4113static void
1a97be37 4114free_automata_list_el (automata_list_el_t automata_list_el)
bea4bad2 4115{
4116 if (automata_list_el == NULL)
4117 return;
4118 automata_list_el->next_automata_list_el = first_free_automata_list_el;
4119 first_free_automata_list_el = automata_list_el;
4120}
4121
4122/* The function frees list AUTOMATA_LIST. */
4123static void
1a97be37 4124free_automata_list (automata_list_el_t automata_list)
bea4bad2 4125{
4126 automata_list_el_t curr_automata_list_el;
4127 automata_list_el_t next_automata_list_el;
4128
4129 for (curr_automata_list_el = automata_list;
4130 curr_automata_list_el != NULL;
4131 curr_automata_list_el = next_automata_list_el)
4132 {
4133 next_automata_list_el = curr_automata_list_el->next_automata_list_el;
4134 free_automata_list_el (curr_automata_list_el);
4135 }
4136}
4137
4138/* Hash value of AUTOMATA_LIST. */
aa77e59f 4139static hashval_t
1a97be37 4140automata_list_hash (const void *automata_list)
bea4bad2 4141{
4142 unsigned int hash_value;
aae87fc3 4143 const_automata_list_el_t curr_automata_list_el;
bea4bad2 4144
4145 hash_value = 0;
aae87fc3 4146 for (curr_automata_list_el = (const_automata_list_el_t) automata_list;
bea4bad2 4147 curr_automata_list_el != NULL;
4148 curr_automata_list_el = curr_automata_list_el->next_automata_list_el)
4149 hash_value = (((hash_value >> (sizeof (unsigned) - 1) * CHAR_BIT)
4150 | (hash_value << CHAR_BIT))
4151 + curr_automata_list_el->automaton->automaton_order_num);
4152 return hash_value;
4153}
4154
4155/* Return nonzero value if the automata_lists are the same. */
4156static int
1a97be37 4157automata_list_eq_p (const void *automata_list_1, const void *automata_list_2)
bea4bad2 4158{
aae87fc3 4159 const_automata_list_el_t automata_list_el_1;
4160 const_automata_list_el_t automata_list_el_2;
bea4bad2 4161
aae87fc3 4162 for (automata_list_el_1 = (const_automata_list_el_t) automata_list_1,
4163 automata_list_el_2 = (const_automata_list_el_t) automata_list_2;
bea4bad2 4164 automata_list_el_1 != NULL && automata_list_el_2 != NULL;
4165 automata_list_el_1 = automata_list_el_1->next_automata_list_el,
4166 automata_list_el_2 = automata_list_el_2->next_automata_list_el)
4167 if (automata_list_el_1->automaton != automata_list_el_2->automaton)
4168 return 0;
4169 return automata_list_el_1 == automata_list_el_2;
4170}
4171
4172/* Initialization of the abstract data. */
4173static void
1a97be37 4174initiate_automata_lists (void)
bea4bad2 4175{
4176 first_free_automata_list_el = NULL;
4177 automata_list_table = htab_create (1500, automata_list_hash,
4178 automata_list_eq_p, (htab_del) 0);
4179}
4180
4181/* The following function starts new automata list and makes it the
4182 current one. */
4183static void
1a97be37 4184automata_list_start (void)
bea4bad2 4185{
4186 current_automata_list = NULL;
4187}
4188
4189/* The following function adds AUTOMATON to the current list. */
4190static void
1a97be37 4191automata_list_add (automaton_t automaton)
bea4bad2 4192{
4193 automata_list_el_t el;
4194
4195 el = get_free_automata_list_el ();
4196 el->automaton = automaton;
4197 el->next_automata_list_el = current_automata_list;
4198 current_automata_list = el;
4199}
4200
4201/* The following function finishes forming the current list, inserts
4202 it into the table and returns it. */
4203static automata_list_el_t
1a97be37 4204automata_list_finish (void)
bea4bad2 4205{
4206 void **entry_ptr;
4207
4208 if (current_automata_list == NULL)
4209 return NULL;
4210 entry_ptr = htab_find_slot (automata_list_table,
b9c74b4d 4211 (void *) current_automata_list, INSERT);
bea4bad2 4212 if (*entry_ptr == NULL)
4213 *entry_ptr = (void *) current_automata_list;
4214 else
4215 free_automata_list (current_automata_list);
4216 current_automata_list = NULL;
4217 return (automata_list_el_t) *entry_ptr;
4218}
4219
4220/* Finishing work with the abstract data. */
4221static void
1a97be37 4222finish_automata_lists (void)
bea4bad2 4223{
4224 htab_delete (automata_list_table);
4225}
4226
4227\f
4228
4229/* The page contains abstract data for work with exclusion sets (see
4230 exclusion_set in file rtl.def). */
4231
4232/* The following variable refers to an exclusion set returned by
4233 get_excl_set. This is bit string of length equal to cpu units
4234 number. If exclusion set for given unit contains 1 for a unit,
4235 then simultaneous reservation of the units is prohibited. */
4236static reserv_sets_t excl_set;
4237
4238/* The array contains exclusion sets for each unit. */
4239static reserv_sets_t *unit_excl_set_table;
4240
4241/* The following function forms the array containing exclusion sets
4242 for each unit. */
4243static void
1a97be37 4244initiate_excl_sets (void)
bea4bad2 4245{
4246 decl_t decl;
4247 reserv_sets_t unit_excl_set;
4248 unit_set_el_t el;
4249 int i;
4250
4251 obstack_blank (&irp, els_in_cycle_reserv * sizeof (set_el_t));
4252 excl_set = (reserv_sets_t) obstack_base (&irp);
4253 obstack_finish (&irp);
4254 obstack_blank (&irp, description->units_num * sizeof (reserv_sets_t));
4255 unit_excl_set_table = (reserv_sets_t *) obstack_base (&irp);
4256 obstack_finish (&irp);
4257 /* Evaluate unit exclusion sets. */
4258 for (i = 0; i < description->decls_num; i++)
4259 {
4260 decl = description->decls [i];
4261 if (decl->mode == dm_unit)
4262 {
4263 obstack_blank (&irp, els_in_cycle_reserv * sizeof (set_el_t));
4264 unit_excl_set = (reserv_sets_t) obstack_base (&irp);
4265 obstack_finish (&irp);
4266 memset (unit_excl_set, 0, els_in_cycle_reserv * sizeof (set_el_t));
2f8ffd86 4267 for (el = DECL_UNIT (decl)->excl_list;
bea4bad2 4268 el != NULL;
4269 el = el->next_unit_set_el)
58ada791 4270 {
08b7917c 4271 bitmap_set_bit (unit_excl_set, el->unit_decl->unit_num);
58ada791 4272 el->unit_decl->in_set_p = TRUE;
4273 }
2f8ffd86 4274 unit_excl_set_table [DECL_UNIT (decl)->unit_num] = unit_excl_set;
bea4bad2 4275 }
4276 }
4277}
4278
4279/* The function sets up and return EXCL_SET which is union of
4280 exclusion sets for each unit in IN_SET. */
4281static reserv_sets_t
1a97be37 4282get_excl_set (reserv_sets_t in_set)
bea4bad2 4283{
79be33d4 4284 int el;
4285 unsigned int i;
bea4bad2 4286 int start_unit_num;
4287 int unit_num;
4288
79be33d4 4289 memset (excl_set, 0, els_in_cycle_reserv * sizeof (set_el_t));
4290 for (el = 0; el < els_in_cycle_reserv; el++)
4291 if (in_set[el])
4292 for (i = 0; i < CHAR_BIT * sizeof (set_el_t); i++)
4293 if ((in_set[el] >> i) & 1)
bea4bad2 4294 {
79be33d4 4295 start_unit_num = el * CHAR_BIT * sizeof (set_el_t) + i;
bea4bad2 4296 if (start_unit_num >= description->units_num)
4297 return excl_set;
4298 for (unit_num = 0; unit_num < els_in_cycle_reserv; unit_num++)
4299 {
4300 excl_set [unit_num]
4301 |= unit_excl_set_table [start_unit_num] [unit_num];
4302 }
4303 }
4304 return excl_set;
4305}
4306
4307\f
4308
58ada791 4309/* The page contains abstract data for work with presence/absence
4310 pattern sets (see presence_set/absence_set in file rtl.def). */
bea4bad2 4311
58ada791 4312/* The following arrays contain correspondingly presence, final
4313 presence, absence, and final absence patterns for each unit. */
4314static pattern_reserv_t *unit_presence_set_table;
4315static pattern_reserv_t *unit_final_presence_set_table;
4316static pattern_reserv_t *unit_absence_set_table;
4317static pattern_reserv_t *unit_final_absence_set_table;
4318
4319/* The following function forms list of reservation sets for given
4320 PATTERN_LIST. */
4321static pattern_reserv_t
1a97be37 4322form_reserv_sets_list (pattern_set_el_t pattern_list)
58ada791 4323{
4324 pattern_set_el_t el;
4325 pattern_reserv_t first, curr, prev;
4326 int i;
bea4bad2 4327
58ada791 4328 prev = first = NULL;
4329 for (el = pattern_list; el != NULL; el = el->next_pattern_set_el)
4330 {
65b198c2 4331 curr = XCREATENODE (struct pattern_reserv);
58ada791 4332 curr->reserv = alloc_empty_reserv_sets ();
4333 curr->next_pattern_reserv = NULL;
4334 for (i = 0; i < el->units_num; i++)
4335 {
08b7917c 4336 bitmap_set_bit (curr->reserv, el->unit_decls [i]->unit_num);
58ada791 4337 el->unit_decls [i]->in_set_p = TRUE;
4338 }
4339 if (prev != NULL)
4340 prev->next_pattern_reserv = curr;
4341 else
4342 first = curr;
4343 prev = curr;
4344 }
4345 return first;
4346}
bea4bad2 4347
58ada791 4348 /* The following function forms the array containing presence and
4349 absence pattern sets for each unit. */
bea4bad2 4350static void
1a97be37 4351initiate_presence_absence_pattern_sets (void)
bea4bad2 4352{
4353 decl_t decl;
bea4bad2 4354 int i;
4355
58ada791 4356 obstack_blank (&irp, description->units_num * sizeof (pattern_reserv_t));
4357 unit_presence_set_table = (pattern_reserv_t *) obstack_base (&irp);
bea4bad2 4358 obstack_finish (&irp);
58ada791 4359 obstack_blank (&irp, description->units_num * sizeof (pattern_reserv_t));
4360 unit_final_presence_set_table = (pattern_reserv_t *) obstack_base (&irp);
bea4bad2 4361 obstack_finish (&irp);
58ada791 4362 obstack_blank (&irp, description->units_num * sizeof (pattern_reserv_t));
4363 unit_absence_set_table = (pattern_reserv_t *) obstack_base (&irp);
bea4bad2 4364 obstack_finish (&irp);
58ada791 4365 obstack_blank (&irp, description->units_num * sizeof (pattern_reserv_t));
4366 unit_final_absence_set_table = (pattern_reserv_t *) obstack_base (&irp);
bea4bad2 4367 obstack_finish (&irp);
4368 /* Evaluate unit presence/absence sets. */
4369 for (i = 0; i < description->decls_num; i++)
4370 {
4371 decl = description->decls [i];
4372 if (decl->mode == dm_unit)
4373 {
58ada791 4374 unit_presence_set_table [DECL_UNIT (decl)->unit_num]
4375 = form_reserv_sets_list (DECL_UNIT (decl)->presence_list);
4376 unit_final_presence_set_table [DECL_UNIT (decl)->unit_num]
4377 = form_reserv_sets_list (DECL_UNIT (decl)->final_presence_list);
4378 unit_absence_set_table [DECL_UNIT (decl)->unit_num]
4379 = form_reserv_sets_list (DECL_UNIT (decl)->absence_list);
4380 unit_final_absence_set_table [DECL_UNIT (decl)->unit_num]
4381 = form_reserv_sets_list (DECL_UNIT (decl)->final_absence_list);
bea4bad2 4382 }
4383 }
4384}
4385
58ada791 4386/* The function checks that CHECKED_SET satisfies all presence pattern
f0b5f617 4387 sets for units in ORIGINAL_SET. The function returns TRUE if it
58ada791 4388 is ok. */
4389static int
1a97be37 4390check_presence_pattern_sets (reserv_sets_t checked_set,
f0b5f617 4391 reserv_sets_t original_set,
1a97be37 4392 int final_p)
bea4bad2 4393{
79be33d4 4394 int el;
4395 unsigned int i;
bea4bad2 4396 int start_unit_num;
4397 int unit_num;
58ada791 4398 int presence_p;
4399 pattern_reserv_t pat_reserv;
1a97be37 4400
79be33d4 4401 for (el = 0; el < els_in_cycle_reserv; el++)
4402 if (original_set[el])
4403 for (i = 0; i < CHAR_BIT * sizeof (set_el_t); i++)
4404 if ((original_set[el] >> i) & 1)
58ada791 4405 {
79be33d4 4406 start_unit_num = el * CHAR_BIT * sizeof (set_el_t) + i;
58ada791 4407 if (start_unit_num >= description->units_num)
4408 break;
4409 if ((final_p
4410 && unit_final_presence_set_table [start_unit_num] == NULL)
4411 || (!final_p
4412 && unit_presence_set_table [start_unit_num] == NULL))
4413 continue;
4414 presence_p = FALSE;
4415 for (pat_reserv = (final_p
4416 ? unit_final_presence_set_table [start_unit_num]
4417 : unit_presence_set_table [start_unit_num]);
4418 pat_reserv != NULL;
4419 pat_reserv = pat_reserv->next_pattern_reserv)
4420 {
4421 for (unit_num = 0; unit_num < els_in_cycle_reserv; unit_num++)
4422 if ((checked_set [unit_num] & pat_reserv->reserv [unit_num])
4423 != pat_reserv->reserv [unit_num])
4424 break;
4425 presence_p = presence_p || unit_num >= els_in_cycle_reserv;
4426 }
4427 if (!presence_p)
4428 return FALSE;
4429 }
4430 return TRUE;
4431}
bea4bad2 4432
58ada791 4433/* The function checks that CHECKED_SET satisfies all absence pattern
f0b5f617 4434 sets for units in ORIGINAL_SET. The function returns TRUE if it
58ada791 4435 is ok. */
4436static int
1a97be37 4437check_absence_pattern_sets (reserv_sets_t checked_set,
f0b5f617 4438 reserv_sets_t original_set,
1a97be37 4439 int final_p)
58ada791 4440{
79be33d4 4441 int el;
4442 unsigned int i;
58ada791 4443 int start_unit_num;
4444 int unit_num;
4445 pattern_reserv_t pat_reserv;
1a97be37 4446
79be33d4 4447 for (el = 0; el < els_in_cycle_reserv; el++)
4448 if (original_set[el])
4449 for (i = 0; i < CHAR_BIT * sizeof (set_el_t); i++)
4450 if ((original_set[el] >> i) & 1)
bea4bad2 4451 {
79be33d4 4452 start_unit_num = el * CHAR_BIT * sizeof (set_el_t) + i;
bea4bad2 4453 if (start_unit_num >= description->units_num)
58ada791 4454 break;
4455 for (pat_reserv = (final_p
4456 ? unit_final_absence_set_table [start_unit_num]
4457 : unit_absence_set_table [start_unit_num]);
4458 pat_reserv != NULL;
4459 pat_reserv = pat_reserv->next_pattern_reserv)
4460 {
4461 for (unit_num = 0; unit_num < els_in_cycle_reserv; unit_num++)
4462 if ((checked_set [unit_num] & pat_reserv->reserv [unit_num])
4463 != pat_reserv->reserv [unit_num]
4464 && pat_reserv->reserv [unit_num])
4465 break;
4466 if (unit_num >= els_in_cycle_reserv)
4467 return FALSE;
4468 }
bea4bad2 4469 }
58ada791 4470 return TRUE;
bea4bad2 4471}
4472
4473\f
4474
4475/* This page contains code for transformation of original reservations
4476 described in .md file. The main goal of transformations is
4477 simplifying reservation and lifting up all `|' on the top of IR
4478 reservation representation. */
4479
4480
4481/* The following function makes copy of IR representation of
4482 reservation. The function also substitutes all reservations
4483 defined by define_reservation by corresponding value during making
4484 the copy. */
4485static regexp_t
1a97be37 4486copy_insn_regexp (regexp_t regexp)
bea4bad2 4487{
4488 regexp_t result;
4489 int i;
4490
e0a4c0c2 4491 switch (regexp->mode)
bea4bad2 4492 {
e0a4c0c2 4493 case rm_reserv:
4494 result = copy_insn_regexp (REGEXP_RESERV (regexp)->reserv_decl->regexp);
4495 break;
4496
4497 case rm_unit:
65b198c2 4498 result = XCOPYNODE (struct regexp, regexp);
e0a4c0c2 4499 break;
4500
4501 case rm_repeat:
65b198c2 4502 result = XCOPYNODE (struct regexp, regexp);
2f8ffd86 4503 REGEXP_REPEAT (result)->regexp
4504 = copy_insn_regexp (REGEXP_REPEAT (regexp)->regexp);
e0a4c0c2 4505 break;
4506
4507 case rm_sequence:
65b198c2 4508 result = XCOPYNODEVAR (struct regexp, regexp,
4509 sizeof (struct regexp) + sizeof (regexp_t)
4510 * (REGEXP_SEQUENCE (regexp)->regexps_num - 1));
2f8ffd86 4511 for (i = 0; i <REGEXP_SEQUENCE (regexp)->regexps_num; i++)
4512 REGEXP_SEQUENCE (result)->regexps [i]
4513 = copy_insn_regexp (REGEXP_SEQUENCE (regexp)->regexps [i]);
e0a4c0c2 4514 break;
4515
4516 case rm_allof:
65b198c2 4517 result = XCOPYNODEVAR (struct regexp, regexp,
4518 sizeof (struct regexp) + sizeof (regexp_t)
4519 * (REGEXP_ALLOF (regexp)->regexps_num - 1));
2f8ffd86 4520 for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
4521 REGEXP_ALLOF (result)->regexps [i]
4522 = copy_insn_regexp (REGEXP_ALLOF (regexp)->regexps [i]);
e0a4c0c2 4523 break;
4524
4525 case rm_oneof:
65b198c2 4526 result = XCOPYNODEVAR (struct regexp, regexp,
4527 sizeof (struct regexp) + sizeof (regexp_t)
4528 * (REGEXP_ONEOF (regexp)->regexps_num - 1));
2f8ffd86 4529 for (i = 0; i < REGEXP_ONEOF (regexp)->regexps_num; i++)
4530 REGEXP_ONEOF (result)->regexps [i]
4531 = copy_insn_regexp (REGEXP_ONEOF (regexp)->regexps [i]);
e0a4c0c2 4532 break;
4533
4534 case rm_nothing:
65b198c2 4535 result = XCOPYNODE (struct regexp, regexp);
e0a4c0c2 4536 break;
4537
4538 default:
4539 gcc_unreachable ();
bea4bad2 4540 }
4541 return result;
4542}
4543
4544/* The following variable is set up 1 if a transformation has been
4545 applied. */
4546static int regexp_transformed_p;
4547
4548/* The function makes transformation
4549 A*N -> A, A, ... */
4550static regexp_t
1a97be37 4551transform_1 (regexp_t regexp)
bea4bad2 4552{
4553 int i;
4554 int repeat_num;
4555 regexp_t operand;
4556 pos_t pos;
4557
4558 if (regexp->mode == rm_repeat)
4559 {
2f8ffd86 4560 repeat_num = REGEXP_REPEAT (regexp)->repeat_num;
e0a4c0c2 4561 gcc_assert (repeat_num > 1);
2f8ffd86 4562 operand = REGEXP_REPEAT (regexp)->regexp;
bea4bad2 4563 pos = regexp->mode;
65b198c2 4564 regexp = XCREATENODEVAR (struct regexp, sizeof (struct regexp)
4565 + sizeof (regexp_t) * (repeat_num - 1));
bea4bad2 4566 regexp->mode = rm_sequence;
4567 regexp->pos = pos;
2f8ffd86 4568 REGEXP_SEQUENCE (regexp)->regexps_num = repeat_num;
bea4bad2 4569 for (i = 0; i < repeat_num; i++)
2f8ffd86 4570 REGEXP_SEQUENCE (regexp)->regexps [i] = copy_insn_regexp (operand);
bea4bad2 4571 regexp_transformed_p = 1;
4572 }
4573 return regexp;
4574}
4575
4576/* The function makes transformations
4577 ...,(A,B,...),C,... -> ...,A,B,...,C,...
4578 ...+(A+B+...)+C+... -> ...+A+B+...+C+...
4579 ...|(A|B|...)|C|... -> ...|A|B|...|C|... */
4580static regexp_t
1a97be37 4581transform_2 (regexp_t regexp)
bea4bad2 4582{
4583 if (regexp->mode == rm_sequence)
4584 {
0644a91e 4585 regexp_t sequence = NULL;
bea4bad2 4586 regexp_t result;
0644a91e 4587 int sequence_index = 0;
bea4bad2 4588 int i, j;
4589
2f8ffd86 4590 for (i = 0; i < REGEXP_SEQUENCE (regexp)->regexps_num; i++)
4591 if (REGEXP_SEQUENCE (regexp)->regexps [i]->mode == rm_sequence)
bea4bad2 4592 {
4593 sequence_index = i;
2f8ffd86 4594 sequence = REGEXP_SEQUENCE (regexp)->regexps [i];
bea4bad2 4595 break;
4596 }
2f8ffd86 4597 if (i < REGEXP_SEQUENCE (regexp)->regexps_num)
bea4bad2 4598 {
e0a4c0c2 4599 gcc_assert (REGEXP_SEQUENCE (sequence)->regexps_num > 1
4600 && REGEXP_SEQUENCE (regexp)->regexps_num > 1);
65b198c2 4601 result = XCREATENODEVAR (struct regexp, sizeof (struct regexp)
4602 + sizeof (regexp_t)
4603 * (REGEXP_SEQUENCE (regexp)->regexps_num
4604 + REGEXP_SEQUENCE (sequence)->regexps_num
4605 - 2));
bea4bad2 4606 result->mode = rm_sequence;
4607 result->pos = regexp->pos;
2f8ffd86 4608 REGEXP_SEQUENCE (result)->regexps_num
4609 = (REGEXP_SEQUENCE (regexp)->regexps_num
4610 + REGEXP_SEQUENCE (sequence)->regexps_num - 1);
4611 for (i = 0; i < REGEXP_SEQUENCE (regexp)->regexps_num; i++)
bea4bad2 4612 if (i < sequence_index)
2f8ffd86 4613 REGEXP_SEQUENCE (result)->regexps [i]
4614 = copy_insn_regexp (REGEXP_SEQUENCE (regexp)->regexps [i]);
bea4bad2 4615 else if (i > sequence_index)
2f8ffd86 4616 REGEXP_SEQUENCE (result)->regexps
4617 [i + REGEXP_SEQUENCE (sequence)->regexps_num - 1]
4618 = copy_insn_regexp (REGEXP_SEQUENCE (regexp)->regexps [i]);
bea4bad2 4619 else
2f8ffd86 4620 for (j = 0; j < REGEXP_SEQUENCE (sequence)->regexps_num; j++)
4621 REGEXP_SEQUENCE (result)->regexps [i + j]
4622 = copy_insn_regexp (REGEXP_SEQUENCE (sequence)->regexps [j]);
bea4bad2 4623 regexp_transformed_p = 1;
4624 regexp = result;
4625 }
4626 }
4627 else if (regexp->mode == rm_allof)
4628 {
0644a91e 4629 regexp_t allof = NULL;
bea4bad2 4630 regexp_t result;
0644a91e 4631 int allof_index = 0;
bea4bad2 4632 int i, j;
4633
2f8ffd86 4634 for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
4635 if (REGEXP_ALLOF (regexp)->regexps [i]->mode == rm_allof)
bea4bad2 4636 {
4637 allof_index = i;
2f8ffd86 4638 allof = REGEXP_ALLOF (regexp)->regexps [i];
bea4bad2 4639 break;
4640 }
2f8ffd86 4641 if (i < REGEXP_ALLOF (regexp)->regexps_num)
bea4bad2 4642 {
e0a4c0c2 4643 gcc_assert (REGEXP_ALLOF (allof)->regexps_num > 1
4644 && REGEXP_ALLOF (regexp)->regexps_num > 1);
65b198c2 4645 result = XCREATENODEVAR (struct regexp, sizeof (struct regexp)
4646 + sizeof (regexp_t)
4647 * (REGEXP_ALLOF (regexp)->regexps_num
4648 + REGEXP_ALLOF (allof)->regexps_num - 2));
bea4bad2 4649 result->mode = rm_allof;
4650 result->pos = regexp->pos;
2f8ffd86 4651 REGEXP_ALLOF (result)->regexps_num
4652 = (REGEXP_ALLOF (regexp)->regexps_num
4653 + REGEXP_ALLOF (allof)->regexps_num - 1);
4654 for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
bea4bad2 4655 if (i < allof_index)
2f8ffd86 4656 REGEXP_ALLOF (result)->regexps [i]
4657 = copy_insn_regexp (REGEXP_ALLOF (regexp)->regexps [i]);
bea4bad2 4658 else if (i > allof_index)
2f8ffd86 4659 REGEXP_ALLOF (result)->regexps
4660 [i + REGEXP_ALLOF (allof)->regexps_num - 1]
4661 = copy_insn_regexp (REGEXP_ALLOF (regexp)->regexps [i]);
bea4bad2 4662 else
2f8ffd86 4663 for (j = 0; j < REGEXP_ALLOF (allof)->regexps_num; j++)
4664 REGEXP_ALLOF (result)->regexps [i + j]
4665 = copy_insn_regexp (REGEXP_ALLOF (allof)->regexps [j]);
bea4bad2 4666 regexp_transformed_p = 1;
4667 regexp = result;
4668 }
4669 }
4670 else if (regexp->mode == rm_oneof)
4671 {
0644a91e 4672 regexp_t oneof = NULL;
bea4bad2 4673 regexp_t result;
0644a91e 4674 int oneof_index = 0;
bea4bad2 4675 int i, j;
4676
2f8ffd86 4677 for (i = 0; i < REGEXP_ONEOF (regexp)->regexps_num; i++)
4678 if (REGEXP_ONEOF (regexp)->regexps [i]->mode == rm_oneof)
bea4bad2 4679 {
4680 oneof_index = i;
2f8ffd86 4681 oneof = REGEXP_ONEOF (regexp)->regexps [i];
bea4bad2 4682 break;
4683 }
2f8ffd86 4684 if (i < REGEXP_ONEOF (regexp)->regexps_num)
bea4bad2 4685 {
e0a4c0c2 4686 gcc_assert (REGEXP_ONEOF (oneof)->regexps_num > 1
4687 && REGEXP_ONEOF (regexp)->regexps_num > 1);
65b198c2 4688 result = XCREATENODEVAR (struct regexp, sizeof (struct regexp)
4689 + sizeof (regexp_t)
4690 * (REGEXP_ONEOF (regexp)->regexps_num
4691 + REGEXP_ONEOF (oneof)->regexps_num - 2));
bea4bad2 4692 result->mode = rm_oneof;
4693 result->pos = regexp->pos;
2f8ffd86 4694 REGEXP_ONEOF (result)->regexps_num
4695 = (REGEXP_ONEOF (regexp)->regexps_num
4696 + REGEXP_ONEOF (oneof)->regexps_num - 1);
4697 for (i = 0; i < REGEXP_ONEOF (regexp)->regexps_num; i++)
bea4bad2 4698 if (i < oneof_index)
2f8ffd86 4699 REGEXP_ONEOF (result)->regexps [i]
4700 = copy_insn_regexp (REGEXP_ONEOF (regexp)->regexps [i]);
bea4bad2 4701 else if (i > oneof_index)
2f8ffd86 4702 REGEXP_ONEOF (result)->regexps
4703 [i + REGEXP_ONEOF (oneof)->regexps_num - 1]
4704 = copy_insn_regexp (REGEXP_ONEOF (regexp)->regexps [i]);
bea4bad2 4705 else
2f8ffd86 4706 for (j = 0; j < REGEXP_ONEOF (oneof)->regexps_num; j++)
4707 REGEXP_ONEOF (result)->regexps [i + j]
4708 = copy_insn_regexp (REGEXP_ONEOF (oneof)->regexps [j]);
bea4bad2 4709 regexp_transformed_p = 1;
4710 regexp = result;
4711 }
4712 }
4713 return regexp;
4714}
4715
4716/* The function makes transformations
4717 ...,A|B|...,C,... -> (...,A,C,...)|(...,B,C,...)|...
f1308295 4718 ...+(A|B|...)+C+... -> (...+A+C+...)|(...+B+C+...)|...
8d578a5b 4719 ...+(A,B,...)+C+... -> (...+A+C+...),B,...
4720 ...+(A,B,...)+(C,D,...) -> (A+C),(B+D),... */
bea4bad2 4721static regexp_t
1a97be37 4722transform_3 (regexp_t regexp)
bea4bad2 4723{
4724 if (regexp->mode == rm_sequence)
4725 {
0644a91e 4726 regexp_t oneof = NULL;
4727 int oneof_index = 0;
bea4bad2 4728 regexp_t result;
4729 regexp_t sequence;
4730 int i, j;
4731
2f8ffd86 4732 for (i = 0; i <REGEXP_SEQUENCE (regexp)->regexps_num; i++)
4733 if (REGEXP_SEQUENCE (regexp)->regexps [i]->mode == rm_oneof)
bea4bad2 4734 {
4735 oneof_index = i;
2f8ffd86 4736 oneof = REGEXP_SEQUENCE (regexp)->regexps [i];
bea4bad2 4737 break;
4738 }
2f8ffd86 4739 if (i < REGEXP_SEQUENCE (regexp)->regexps_num)
bea4bad2 4740 {
e0a4c0c2 4741 gcc_assert (REGEXP_ONEOF (oneof)->regexps_num > 1
4742 && REGEXP_SEQUENCE (regexp)->regexps_num > 1);
65b198c2 4743 result = XCREATENODEVAR (struct regexp, sizeof (struct regexp)
4744 + sizeof (regexp_t)
4745 * (REGEXP_ONEOF (oneof)->regexps_num - 1));
bea4bad2 4746 result->mode = rm_oneof;
4747 result->pos = regexp->pos;
2f8ffd86 4748 REGEXP_ONEOF (result)->regexps_num
4749 = REGEXP_ONEOF (oneof)->regexps_num;
4750 for (i = 0; i < REGEXP_ONEOF (result)->regexps_num; i++)
bea4bad2 4751 {
4752 sequence
65b198c2 4753 = XCREATENODEVAR (struct regexp, sizeof (struct regexp)
4754 + sizeof (regexp_t)
4755 * (REGEXP_SEQUENCE (regexp)->regexps_num - 1));
bea4bad2 4756 sequence->mode = rm_sequence;
4757 sequence->pos = regexp->pos;
2f8ffd86 4758 REGEXP_SEQUENCE (sequence)->regexps_num
4759 = REGEXP_SEQUENCE (regexp)->regexps_num;
4760 REGEXP_ONEOF (result)->regexps [i] = sequence;
4761 for (j = 0; j < REGEXP_SEQUENCE (sequence)->regexps_num; j++)
bea4bad2 4762 if (j != oneof_index)
2f8ffd86 4763 REGEXP_SEQUENCE (sequence)->regexps [j]
4764 = copy_insn_regexp (REGEXP_SEQUENCE (regexp)->regexps [j]);
bea4bad2 4765 else
2f8ffd86 4766 REGEXP_SEQUENCE (sequence)->regexps [j]
4767 = copy_insn_regexp (REGEXP_ONEOF (oneof)->regexps [i]);
bea4bad2 4768 }
4769 regexp_transformed_p = 1;
4770 regexp = result;
4771 }
4772 }
4773 else if (regexp->mode == rm_allof)
4774 {
58ada791 4775 regexp_t oneof = NULL;
4776 regexp_t seq;
4777 int oneof_index = 0;
4778 int max_seq_length, allof_length;
bea4bad2 4779 regexp_t result;
58ada791 4780 regexp_t allof = NULL;
4781 regexp_t allof_op = NULL;
bea4bad2 4782 int i, j;
4783
2f8ffd86 4784 for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
4785 if (REGEXP_ALLOF (regexp)->regexps [i]->mode == rm_oneof)
bea4bad2 4786 {
4787 oneof_index = i;
2f8ffd86 4788 oneof = REGEXP_ALLOF (regexp)->regexps [i];
bea4bad2 4789 break;
4790 }
2f8ffd86 4791 if (i < REGEXP_ALLOF (regexp)->regexps_num)
bea4bad2 4792 {
e0a4c0c2 4793 gcc_assert (REGEXP_ONEOF (oneof)->regexps_num > 1
4794 && REGEXP_ALLOF (regexp)->regexps_num > 1);
65b198c2 4795 result = XCREATENODEVAR (struct regexp, sizeof (struct regexp)
4796 + sizeof (regexp_t)
4797 * (REGEXP_ONEOF (oneof)->regexps_num - 1));
bea4bad2 4798 result->mode = rm_oneof;
4799 result->pos = regexp->pos;
2f8ffd86 4800 REGEXP_ONEOF (result)->regexps_num
4801 = REGEXP_ONEOF (oneof)->regexps_num;
4802 for (i = 0; i < REGEXP_ONEOF (result)->regexps_num; i++)
bea4bad2 4803 {
4804 allof
65b198c2 4805 = XCREATENODEVAR (struct regexp, sizeof (struct regexp)
4806 + sizeof (regexp_t)
4807 * (REGEXP_ALLOF (regexp)->regexps_num - 1));
bea4bad2 4808 allof->mode = rm_allof;
4809 allof->pos = regexp->pos;
2f8ffd86 4810 REGEXP_ALLOF (allof)->regexps_num
4811 = REGEXP_ALLOF (regexp)->regexps_num;
4812 REGEXP_ONEOF (result)->regexps [i] = allof;
4813 for (j = 0; j < REGEXP_ALLOF (allof)->regexps_num; j++)
bea4bad2 4814 if (j != oneof_index)
2f8ffd86 4815 REGEXP_ALLOF (allof)->regexps [j]
4816 = copy_insn_regexp (REGEXP_ALLOF (regexp)->regexps [j]);
bea4bad2 4817 else
2f8ffd86 4818 REGEXP_ALLOF (allof)->regexps [j]
4819 = copy_insn_regexp (REGEXP_ONEOF (oneof)->regexps [i]);
bea4bad2 4820 }
4821 regexp_transformed_p = 1;
4822 regexp = result;
4823 }
8d578a5b 4824 max_seq_length = 0;
2f8ffd86 4825 if (regexp->mode == rm_allof)
4826 for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
6a1c27c3 4827 {
e0a4c0c2 4828 switch (REGEXP_ALLOF (regexp)->regexps [i]->mode)
6a1c27c3 4829 {
e0a4c0c2 4830 case rm_sequence:
6a1c27c3 4831 seq = REGEXP_ALLOF (regexp)->regexps [i];
4832 if (max_seq_length < REGEXP_SEQUENCE (seq)->regexps_num)
4833 max_seq_length = REGEXP_SEQUENCE (seq)->regexps_num;
6a1c27c3 4834 break;
e0a4c0c2 4835
4836 case rm_unit:
4837 case rm_nothing:
4838 break;
4839
4840 default:
4841 max_seq_length = 0;
4842 goto break_for;
6a1c27c3 4843 }
4844 }
e0a4c0c2 4845 break_for:
8d578a5b 4846 if (max_seq_length != 0)
f1308295 4847 {
e0a4c0c2 4848 gcc_assert (max_seq_length != 1
4849 && REGEXP_ALLOF (regexp)->regexps_num > 1);
65b198c2 4850 result = XCREATENODEVAR (struct regexp, sizeof (struct regexp)
4851 + sizeof (regexp_t) * (max_seq_length - 1));
f1308295 4852 result->mode = rm_sequence;
4853 result->pos = regexp->pos;
2f8ffd86 4854 REGEXP_SEQUENCE (result)->regexps_num = max_seq_length;
8d578a5b 4855 for (i = 0; i < max_seq_length; i++)
4856 {
4857 allof_length = 0;
2f8ffd86 4858 for (j = 0; j < REGEXP_ALLOF (regexp)->regexps_num; j++)
e0a4c0c2 4859 switch (REGEXP_ALLOF (regexp)->regexps [j]->mode)
8d578a5b 4860 {
e0a4c0c2 4861 case rm_sequence:
4862 if (i < (REGEXP_SEQUENCE (REGEXP_ALLOF (regexp)
4863 ->regexps [j])->regexps_num))
4864 {
4865 allof_op
4866 = (REGEXP_SEQUENCE (REGEXP_ALLOF (regexp)
4867 ->regexps [j])
4868 ->regexps [i]);
4869 allof_length++;
4870 }
4871 break;
4872 case rm_unit:
4873 case rm_nothing:
4874 if (i == 0)
4875 {
4876 allof_op = REGEXP_ALLOF (regexp)->regexps [j];
4877 allof_length++;
4878 }
4879 break;
4880 default:
4881 break;
8d578a5b 4882 }
48e1416a 4883
8d578a5b 4884 if (allof_length == 1)
2f8ffd86 4885 REGEXP_SEQUENCE (result)->regexps [i] = allof_op;
8d578a5b 4886 else
4887 {
65b198c2 4888 allof = XCREATENODEVAR (struct regexp, sizeof (struct regexp)
4889 + sizeof (regexp_t)
4890 * (allof_length - 1));
8d578a5b 4891 allof->mode = rm_allof;
4892 allof->pos = regexp->pos;
2f8ffd86 4893 REGEXP_ALLOF (allof)->regexps_num = allof_length;
4894 REGEXP_SEQUENCE (result)->regexps [i] = allof;
8d578a5b 4895 allof_length = 0;
2f8ffd86 4896 for (j = 0; j < REGEXP_ALLOF (regexp)->regexps_num; j++)
4897 if (REGEXP_ALLOF (regexp)->regexps [j]->mode == rm_sequence
4898 && (i <
4899 (REGEXP_SEQUENCE (REGEXP_ALLOF (regexp)
4900 ->regexps [j])->regexps_num)))
8d578a5b 4901 {
2f8ffd86 4902 allof_op = (REGEXP_SEQUENCE (REGEXP_ALLOF (regexp)
4903 ->regexps [j])
4904 ->regexps [i]);
4905 REGEXP_ALLOF (allof)->regexps [allof_length]
4906 = allof_op;
8d578a5b 4907 allof_length++;
4908 }
4909 else if (i == 0
2f8ffd86 4910 && (REGEXP_ALLOF (regexp)->regexps [j]->mode
58ada791 4911 == rm_unit
4912 || (REGEXP_ALLOF (regexp)->regexps [j]->mode
4913 == rm_nothing)))
8d578a5b 4914 {
2f8ffd86 4915 allof_op = REGEXP_ALLOF (regexp)->regexps [j];
4916 REGEXP_ALLOF (allof)->regexps [allof_length]
4917 = allof_op;
8d578a5b 4918 allof_length++;
4919 }
4920 }
4921 }
f1308295 4922 regexp_transformed_p = 1;
4923 regexp = result;
4924 }
bea4bad2 4925 }
4926 return regexp;
4927}
4928
4929/* The function traverses IR of reservation and applies transformations
4930 implemented by FUNC. */
4931static regexp_t
1a97be37 4932regexp_transform_func (regexp_t regexp, regexp_t (*func) (regexp_t regexp))
bea4bad2 4933{
4934 int i;
4935
e0a4c0c2 4936 switch (regexp->mode)
4937 {
4938 case rm_sequence:
4939 for (i = 0; i < REGEXP_SEQUENCE (regexp)->regexps_num; i++)
4940 REGEXP_SEQUENCE (regexp)->regexps [i]
4941 = regexp_transform_func (REGEXP_SEQUENCE (regexp)->regexps [i],
4942 func);
4943 break;
4944
4945 case rm_allof:
4946 for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
4947 REGEXP_ALLOF (regexp)->regexps [i]
4948 = regexp_transform_func (REGEXP_ALLOF (regexp)->regexps [i], func);
4949 break;
4950
4951 case rm_oneof:
4952 for (i = 0; i < REGEXP_ONEOF (regexp)->regexps_num; i++)
4953 REGEXP_ONEOF (regexp)->regexps [i]
4954 = regexp_transform_func (REGEXP_ONEOF (regexp)->regexps [i], func);
4955 break;
4956
4957 case rm_repeat:
4958 REGEXP_REPEAT (regexp)->regexp
4959 = regexp_transform_func (REGEXP_REPEAT (regexp)->regexp, func);
4960 break;
4961
4962 case rm_nothing:
4963 case rm_unit:
4964 break;
4965
4966 default:
4967 gcc_unreachable ();
4968 }
bea4bad2 4969 return (*func) (regexp);
4970}
4971
4972/* The function applies all transformations for IR representation of
4973 reservation REGEXP. */
4974static regexp_t
1a97be37 4975transform_regexp (regexp_t regexp)
bea4bad2 4976{
1a97be37 4977 regexp = regexp_transform_func (regexp, transform_1);
bea4bad2 4978 do
4979 {
4980 regexp_transformed_p = 0;
4981 regexp = regexp_transform_func (regexp, transform_2);
4982 regexp = regexp_transform_func (regexp, transform_3);
4983 }
4984 while (regexp_transformed_p);
4985 return regexp;
4986}
4987
98667efb 4988/* The function applies all transformations for reservations of all
bea4bad2 4989 insn declarations. */
4990static void
1a97be37 4991transform_insn_regexps (void)
bea4bad2 4992{
4993 decl_t decl;
4994 int i;
4995
b35eefd9 4996 transform_time = create_ticker ();
4997 add_advance_cycle_insn_decl ();
8043d8fb 4998 if (collapse_flag)
4999 add_collapse_ndfa_insn_decl ();
bccc9ebc 5000 if (progress_flag)
5001 fprintf (stderr, "Reservation transformation...");
8043d8fb 5002 for (i = 0; i < description->normal_decls_num; i++)
bea4bad2 5003 {
5004 decl = description->decls [i];
8043d8fb 5005 if (decl->mode == dm_insn_reserv)
2f8ffd86 5006 DECL_INSN_RESERV (decl)->transformed_regexp
bea4bad2 5007 = transform_regexp (copy_insn_regexp
2f8ffd86 5008 (DECL_INSN_RESERV (decl)->regexp));
bea4bad2 5009 }
bccc9ebc 5010 if (progress_flag)
5011 fprintf (stderr, "done\n");
b35eefd9 5012 ticker_off (&transform_time);
b35eefd9 5013}
5014
5015\f
5016
58ada791 5017/* The following variable value is TRUE if the first annotated message
5018 about units to automata distribution has been output. */
5019static int annotation_message_reported_p;
b35eefd9 5020
48ca7187 5021/* The vector contains all decls which are automata. */
f1f41a6c 5022static vec<decl_t> automaton_decls;
48ca7187 5023
8bbadced 5024/* The following structure describes usage of a unit in a reservation. */
5025struct unit_usage
5026{
5027 unit_decl_t unit_decl;
5028 /* The following forms a list of units used on the same cycle in the
48ca7187 5029 same alternative. The list is ordered by the correspdoning unit
5030 declarations and there is no unit declaration duplication in the
5031 list. */
8bbadced 5032 struct unit_usage *next;
5033};
e7827cef 5034typedef struct unit_usage *unit_usage_t;
5035
8bbadced 5036
5037/* Obstack for unit_usage structures. */
5038static struct obstack unit_usages;
5039
5040/* VLA for representation of array of pointers to unit usage
5041 structures. There is an element for each combination of
5042 (alternative number, cycle). Unit usages on given cycle in
5043 alternative with given number are referred through element with
48ca7187 5044 index equals to the cycle * number of all alternatives in the
5045 regexp + the alternative number. */
f1f41a6c 5046static vec<unit_usage_t> cycle_alt_unit_usages;
8bbadced 5047
5048/* The following function creates the structure unit_usage for UNIT on
5049 CYCLE in REGEXP alternative with ALT_NUM. The structure is made
5050 accessed through cycle_alt_unit_usages. */
b35eefd9 5051static void
1a97be37 5052store_alt_unit_usage (regexp_t regexp, regexp_t unit, int cycle,
5053 int alt_num)
b35eefd9 5054{
e7827cef 5055 size_t length;
58ada791 5056 unit_decl_t unit_decl;
48ca7187 5057 unit_usage_t unit_usage_ptr, curr, prev;
8bbadced 5058 int index;
b35eefd9 5059
e0a4c0c2 5060 gcc_assert (regexp && regexp->mode == rm_oneof
5061 && alt_num < REGEXP_ONEOF (regexp)->regexps_num);
2f8ffd86 5062 unit_decl = REGEXP_UNIT (unit)->unit_decl;
e7827cef 5063
8bbadced 5064 length = (cycle + 1) * REGEXP_ONEOF (regexp)->regexps_num;
f1f41a6c 5065 while (cycle_alt_unit_usages.length () < length)
5066 cycle_alt_unit_usages.safe_push (NULL);
48e1416a 5067
48ca7187 5068 index = cycle * REGEXP_ONEOF (regexp)->regexps_num + alt_num;
5069 prev = NULL;
f1f41a6c 5070 for (curr = cycle_alt_unit_usages[index];
48ca7187 5071 curr != NULL;
5072 prev = curr, curr = curr->next)
5073 if (curr->unit_decl >= unit_decl)
5074 break;
5075 if (curr != NULL && curr->unit_decl == unit_decl)
5076 return;
8bbadced 5077 obstack_blank (&unit_usages, sizeof (struct unit_usage));
5078 unit_usage_ptr = (struct unit_usage *) obstack_base (&unit_usages);
5079 obstack_finish (&unit_usages);
5080 unit_usage_ptr->unit_decl = unit_decl;
8bbadced 5081 unit_decl->last_distribution_check_cycle = -1; /* undefined */
48ca7187 5082 unit_usage_ptr->next = curr;
5083 if (prev == NULL)
f1f41a6c 5084 cycle_alt_unit_usages[index] = unit_usage_ptr;
48ca7187 5085 else
5086 prev->next = unit_usage_ptr;
5087}
5088
5089/* Return true if unit UNIT_DECL is present on the LIST. */
5090static bool
5091unit_present_on_list_p (unit_usage_t list, unit_decl_t unit_decl)
5092{
5093 while (list != NULL)
5094 {
5095 if (list->unit_decl == unit_decl)
5096 return true;
5097 list = list->next;
5098 }
5099 return false;
5100}
5101
5102/* The function returns true if reservations of alternatives ALT1 and
5103 ALT2 are equal after excluding reservations of units of
5104 EXCLUDED_AUTOMATON_DECL. */
5105static bool
5106equal_alternatives_p (int alt1, int alt2, int n_alts,
5107 struct automaton_decl *excluded_automaton_decl)
5108{
5109 int i;
5110 unit_usage_t list1, list2;
5111
5112 for (i = 0;
f1f41a6c 5113 i < (int) cycle_alt_unit_usages.length ();
48ca7187 5114 i += n_alts)
5115 {
f1f41a6c 5116 for (list1 = cycle_alt_unit_usages[i + alt1],
5117 list2 = cycle_alt_unit_usages[i + alt2];;
48ca7187 5118 list1 = list1->next, list2 = list2->next)
5119 {
5120 while (list1 != NULL
5121 && list1->unit_decl->automaton_decl == excluded_automaton_decl)
5122 list1 = list1->next;
5123 while (list2 != NULL
5124 && list2->unit_decl->automaton_decl == excluded_automaton_decl)
5125 list2 = list2->next;
5126 if (list1 == NULL || list2 == NULL)
5127 {
5128 if (list1 != list2)
5129 return false;
5130 else
5131 break;
5132 }
5133 if (list1->unit_decl != list2->unit_decl)
5134 return false;
5135 }
5136 }
5137 return true;
b35eefd9 5138}
5139
48ca7187 5140
58ada791 5141/* The function processes given REGEXP to find units with the wrong
5142 distribution. */
b35eefd9 5143static void
1a97be37 5144check_regexp_units_distribution (const char *insn_reserv_name,
5145 regexp_t regexp)
b35eefd9 5146{
1e4adcfc 5147 int i, j, k, cycle, start, n_alts, alt, alt2;
48ca7187 5148 bool annotation_reservation_message_reported_p;
b35eefd9 5149 regexp_t seq, allof, unit;
48ca7187 5150 struct unit_usage *unit_usage_ptr;
f1f41a6c 5151 vec<int> marked;
b35eefd9 5152
5153 if (regexp == NULL || regexp->mode != rm_oneof)
5154 return;
8bbadced 5155 /* Store all unit usages in the regexp: */
5156 obstack_init (&unit_usages);
f1f41a6c 5157 cycle_alt_unit_usages.create (10);
e7827cef 5158
2f8ffd86 5159 for (i = REGEXP_ONEOF (regexp)->regexps_num - 1; i >= 0; i--)
b35eefd9 5160 {
2f8ffd86 5161 seq = REGEXP_ONEOF (regexp)->regexps [i];
e0a4c0c2 5162 switch (seq->mode)
5163 {
5164 case rm_sequence:
5165 for (j = 0; j < REGEXP_SEQUENCE (seq)->regexps_num; j++)
5166 {
5167 allof = REGEXP_SEQUENCE (seq)->regexps [j];
5168 switch (allof->mode)
b35eefd9 5169 {
e0a4c0c2 5170 case rm_allof:
5171 for (k = 0; k < REGEXP_ALLOF (allof)->regexps_num; k++)
5172 {
5173 unit = REGEXP_ALLOF (allof)->regexps [k];
5174 if (unit->mode == rm_unit)
5175 store_alt_unit_usage (regexp, unit, j, i);
5176 else
5177 gcc_assert (unit->mode == rm_nothing);
5178 }
5179 break;
48e1416a 5180
e0a4c0c2 5181 case rm_unit:
5182 store_alt_unit_usage (regexp, allof, j, i);
5183 break;
48e1416a 5184
e0a4c0c2 5185 case rm_nothing:
5186 break;
48e1416a 5187
e0a4c0c2 5188 default:
5189 gcc_unreachable ();
b35eefd9 5190 }
e0a4c0c2 5191 }
5192 break;
5193
5194 case rm_allof:
5195 for (k = 0; k < REGEXP_ALLOF (seq)->regexps_num; k++)
5196 {
5197 unit = REGEXP_ALLOF (seq)->regexps [k];
5198 switch (unit->mode)
5199 {
5200 case rm_unit:
5201 store_alt_unit_usage (regexp, unit, 0, i);
5202 break;
48e1416a 5203
e0a4c0c2 5204 case rm_nothing:
5205 break;
48e1416a 5206
e0a4c0c2 5207 default:
5208 gcc_unreachable ();
5209 }
5210 }
5211 break;
5212
5213 case rm_unit:
5214 store_alt_unit_usage (regexp, seq, 0, i);
5215 break;
5216
5217 case rm_nothing:
5218 break;
5219
5220 default:
5221 gcc_unreachable ();
5222 }
b35eefd9 5223 }
8bbadced 5224 /* Check distribution: */
f1f41a6c 5225 for (i = 0; i < (int) cycle_alt_unit_usages.length (); i++)
5226 for (unit_usage_ptr = cycle_alt_unit_usages[i];
48ca7187 5227 unit_usage_ptr != NULL;
5228 unit_usage_ptr = unit_usage_ptr->next)
5229 unit_usage_ptr->unit_decl->last_distribution_check_cycle = -1;
5230 n_alts = REGEXP_ONEOF (regexp)->regexps_num;
f1f41a6c 5231 marked.create (n_alts);
48ca7187 5232 for (i = 0; i < n_alts; i++)
f1f41a6c 5233 marked.safe_push (0);
48ca7187 5234 annotation_reservation_message_reported_p = false;
f1f41a6c 5235 for (i = 0; i < (int) cycle_alt_unit_usages.length (); i++)
8bbadced 5236 {
48ca7187 5237 cycle = i / n_alts;
5238 start = cycle * n_alts;
f1f41a6c 5239 for (unit_usage_ptr = cycle_alt_unit_usages[i];
8bbadced 5240 unit_usage_ptr != NULL;
5241 unit_usage_ptr = unit_usage_ptr->next)
48ca7187 5242 {
5243 if (unit_usage_ptr->unit_decl->last_distribution_check_cycle == cycle)
5244 continue;
5245 unit_usage_ptr->unit_decl->last_distribution_check_cycle = cycle;
5246 for (alt = 0; alt < n_alts; alt++)
f1f41a6c 5247 if (! unit_present_on_list_p (cycle_alt_unit_usages[start + alt],
48ca7187 5248 unit_usage_ptr->unit_decl))
5249 break;
5250 if (alt >= n_alts)
5251 continue;
f1f41a6c 5252 memset (marked.address (), 0, n_alts * sizeof (int));
48ca7187 5253 for (alt = 0; alt < n_alts; alt++)
5254 {
f1f41a6c 5255 if (! unit_present_on_list_p (cycle_alt_unit_usages[start + alt],
48ca7187 5256 unit_usage_ptr->unit_decl))
5257 continue;
5258 for (j = 0;
f1f41a6c 5259 j < (int) cycle_alt_unit_usages.length ();
48ca7187 5260 j++)
5261 {
48ca7187 5262 alt2 = j % n_alts;
5263 if (! unit_present_on_list_p
f1f41a6c 5264 (cycle_alt_unit_usages[start + alt2],
48ca7187 5265 unit_usage_ptr->unit_decl)
5266 && equal_alternatives_p (alt, alt2, n_alts,
5267 unit_usage_ptr
5268 ->unit_decl->automaton_decl))
5269 {
f1f41a6c 5270 marked[alt] = 1;
5271 marked[alt2] = 1;
48ca7187 5272 }
5273 }
5274 }
f1f41a6c 5275 for (alt = 0; alt < n_alts && marked[alt]; alt++)
48ca7187 5276 ;
5277 if (alt < n_alts && 0)
5278 {
5279 if (! annotation_message_reported_p)
5280 {
5281 fprintf (stderr, "\n");
5282 error ("The following units do not satisfy units-automata distribution rule");
5283 error ("(Unit presence on one alt and its absence on other alt\n");
5284 error (" result in different other automata reservations)");
5285 annotation_message_reported_p = TRUE;
5286 }
5287 if (! annotation_reservation_message_reported_p)
5288 {
5289 error ("Reserv %s:", insn_reserv_name);
5290 annotation_reservation_message_reported_p = true;
5291 }
5292 error (" Unit %s, cycle %d, alt %d, another alt %d",
5293 unit_usage_ptr->unit_decl->name, cycle, i % n_alts, alt);
5294 }
5295 }
8bbadced 5296 }
f1f41a6c 5297 marked.release ();
5298 cycle_alt_unit_usages.release ();
8bbadced 5299 obstack_free (&unit_usages, NULL);
b35eefd9 5300}
5301
58ada791 5302/* The function finds units which violates units to automata
5303 distribution rule. If the units exist, report about them. */
b35eefd9 5304static void
1a97be37 5305check_unit_distributions_to_automata (void)
b35eefd9 5306{
5307 decl_t decl;
b35eefd9 5308 int i;
5309
bccc9ebc 5310 if (progress_flag)
5311 fprintf (stderr, "Check unit distributions to automata...");
f1f41a6c 5312 automaton_decls.create (0);
b35eefd9 5313 for (i = 0; i < description->decls_num; i++)
5314 {
5315 decl = description->decls [i];
48ca7187 5316 if (decl->mode == dm_automaton)
f1f41a6c 5317 automaton_decls.safe_push (decl);
48ca7187 5318 }
f1f41a6c 5319 if (automaton_decls.length () > 1)
48ca7187 5320 {
5321 annotation_message_reported_p = FALSE;
5322 for (i = 0; i < description->decls_num; i++)
5323 {
5324 decl = description->decls [i];
5325 if (decl->mode == dm_insn_reserv)
5326 check_regexp_units_distribution
5327 (DECL_INSN_RESERV (decl)->name,
5328 DECL_INSN_RESERV (decl)->transformed_regexp);
5329 }
b35eefd9 5330 }
f1f41a6c 5331 automaton_decls.release ();
bccc9ebc 5332 if (progress_flag)
5333 fprintf (stderr, "done\n");
bea4bad2 5334}
5335
5336\f
5337
5338/* The page contains code for building alt_states (see comments for
5339 IR) describing all possible insns reservations of an automaton. */
5340
5341/* Current state being formed for which the current alt_state
5342 refers. */
5343static state_t state_being_formed;
5344
5345/* Current alt_state being formed. */
5346static alt_state_t alt_state_being_formed;
1a97be37 5347
bea4bad2 5348/* This recursive function processes `,' and units in reservation
5349 REGEXP for forming alt_states of AUTOMATON. It is believed that
5350 CURR_CYCLE is start cycle of all reservation REGEXP. */
5351static int
1a97be37 5352process_seq_for_forming_states (regexp_t regexp, automaton_t automaton,
5353 int curr_cycle)
bea4bad2 5354{
5355 int i;
5356
5357 if (regexp == NULL)
5358 return curr_cycle;
e0a4c0c2 5359
5360 switch (regexp->mode)
bea4bad2 5361 {
e0a4c0c2 5362 case rm_unit:
2f8ffd86 5363 if (REGEXP_UNIT (regexp)->unit_decl->corresponding_automaton_num
bea4bad2 5364 == automaton->automaton_order_num)
5365 set_state_reserv (state_being_formed, curr_cycle,
2f8ffd86 5366 REGEXP_UNIT (regexp)->unit_decl->unit_num);
bea4bad2 5367 return curr_cycle;
48e1416a 5368
e0a4c0c2 5369 case rm_sequence:
2f8ffd86 5370 for (i = 0; i < REGEXP_SEQUENCE (regexp)->regexps_num; i++)
bea4bad2 5371 curr_cycle
5372 = process_seq_for_forming_states
2f8ffd86 5373 (REGEXP_SEQUENCE (regexp)->regexps [i], automaton, curr_cycle) + 1;
bea4bad2 5374 return curr_cycle;
bea4bad2 5375
e0a4c0c2 5376 case rm_allof:
5377 {
5378 int finish_cycle = 0;
5379 int cycle;
48e1416a 5380
e0a4c0c2 5381 for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
5382 {
5383 cycle = process_seq_for_forming_states (REGEXP_ALLOF (regexp)
5384 ->regexps [i],
5385 automaton, curr_cycle);
5386 if (finish_cycle < cycle)
5387 finish_cycle = cycle;
5388 }
5389 return finish_cycle;
5390 }
5391
5392 case rm_nothing:
bea4bad2 5393 return curr_cycle;
e0a4c0c2 5394
5395 default:
5396 gcc_unreachable ();
bea4bad2 5397 }
5398}
5399
5400/* This recursive function finishes forming ALT_STATE of AUTOMATON and
5401 inserts alt_state into the table. */
5402static void
1a97be37 5403finish_forming_alt_state (alt_state_t alt_state,
5404 automaton_t automaton ATTRIBUTE_UNUSED)
bea4bad2 5405{
5406 state_t state_in_table;
5407 state_t corresponding_state;
5408
5409 corresponding_state = alt_state->state;
5410 state_in_table = insert_state (corresponding_state);
5411 if (state_in_table != corresponding_state)
5412 {
5413 free_state (corresponding_state);
5414 alt_state->state = state_in_table;
5415 }
5416}
5417
5418/* The following variable value is current automaton insn for whose
5419 reservation the alt states are created. */
5420static ainsn_t curr_ainsn;
5421
5422/* This recursive function processes `|' in reservation REGEXP for
5423 forming alt_states of AUTOMATON. List of the alt states should
5424 have the same order as in the description. */
5425static void
1a97be37 5426process_alts_for_forming_states (regexp_t regexp, automaton_t automaton,
5427 int inside_oneof_p)
bea4bad2 5428{
5429 int i;
5430
5431 if (regexp->mode != rm_oneof)
5432 {
5433 alt_state_being_formed = get_free_alt_state ();
5434 state_being_formed = get_free_state (1, automaton);
5435 alt_state_being_formed->state = state_being_formed;
5436 /* We inserts in reverse order but we process alternatives also
5437 in reverse order. So we have the same order of alternative
5438 as in the description. */
5439 alt_state_being_formed->next_alt_state = curr_ainsn->alt_states;
5440 curr_ainsn->alt_states = alt_state_being_formed;
5441 (void) process_seq_for_forming_states (regexp, automaton, 0);
5442 finish_forming_alt_state (alt_state_being_formed, automaton);
5443 }
5444 else
5445 {
e0a4c0c2 5446 gcc_assert (!inside_oneof_p);
bea4bad2 5447 /* We processes it in reverse order to get list with the same
5448 order as in the description. See also the previous
5449 commentary. */
2f8ffd86 5450 for (i = REGEXP_ONEOF (regexp)->regexps_num - 1; i >= 0; i--)
5451 process_alts_for_forming_states (REGEXP_ONEOF (regexp)->regexps [i],
bea4bad2 5452 automaton, 1);
5453 }
5454}
5455
5456/* Create nodes alt_state for all AUTOMATON insns. */
5457static void
1a97be37 5458create_alt_states (automaton_t automaton)
bea4bad2 5459{
5460 struct insn_reserv_decl *reserv_decl;
5461
5462 for (curr_ainsn = automaton->ainsn_list;
5463 curr_ainsn != NULL;
5464 curr_ainsn = curr_ainsn->next_ainsn)
5465 {
5466 reserv_decl = curr_ainsn->insn_reserv_decl;
8043d8fb 5467 if (!special_decl_p (reserv_decl))
bea4bad2 5468 {
5469 curr_ainsn->alt_states = NULL;
5470 process_alts_for_forming_states (reserv_decl->transformed_regexp,
5471 automaton, 0);
5472 curr_ainsn->sorted_alt_states
5473 = uniq_sort_alt_states (curr_ainsn->alt_states);
5474 }
5475 }
5476}
5477
5478\f
5479
5480/* The page contains major code for building DFA(s) for fast pipeline
5481 hazards recognition. */
5482
5483/* The function forms list of ainsns of AUTOMATON with the same
5484 reservation. */
e7827cef 5485
bea4bad2 5486static void
1a97be37 5487form_ainsn_with_same_reservs (automaton_t automaton)
bea4bad2 5488{
5489 ainsn_t curr_ainsn;
5490 size_t i;
f1f41a6c 5491 vec<ainsn_t> last_insns;
5492 last_insns.create (150);
bea4bad2 5493
bea4bad2 5494 for (curr_ainsn = automaton->ainsn_list;
5495 curr_ainsn != NULL;
5496 curr_ainsn = curr_ainsn->next_ainsn)
8043d8fb 5497 if (special_decl_p (curr_ainsn->insn_reserv_decl))
bea4bad2 5498 {
5499 curr_ainsn->next_same_reservs_insn = NULL;
5500 curr_ainsn->first_insn_with_same_reservs = 1;
5501 }
5502 else
5503 {
f1f41a6c 5504 for (i = 0; i < last_insns.length (); i++)
bea4bad2 5505 if (alt_states_eq
5506 (curr_ainsn->sorted_alt_states,
f1f41a6c 5507 last_insns[i]->sorted_alt_states))
bea4bad2 5508 break;
5509 curr_ainsn->next_same_reservs_insn = NULL;
f1f41a6c 5510 if (i < last_insns.length ())
bea4bad2 5511 {
5512 curr_ainsn->first_insn_with_same_reservs = 0;
f1f41a6c 5513 last_insns[i]->next_same_reservs_insn = curr_ainsn;
5514 last_insns[i] = curr_ainsn;
bea4bad2 5515 }
5516 else
5517 {
f1f41a6c 5518 last_insns.safe_push (curr_ainsn);
bea4bad2 5519 curr_ainsn->first_insn_with_same_reservs = 1;
5520 }
5521 }
f1f41a6c 5522 last_insns.release ();
bea4bad2 5523}
5524
58ada791 5525/* Forming unit reservations which can affect creating the automaton
5526 states achieved from a given state. It permits to build smaller
5527 automata in many cases. We would have the same automata after
5528 the minimization without such optimization, but the automaton
5529 right after the building could be huge. So in other words, usage
5530 of reservs_matter means some minimization during building the
5531 automaton. */
5532static reserv_sets_t
1a97be37 5533form_reservs_matter (automaton_t automaton)
58ada791 5534{
5535 int cycle, unit;
9af5ce0c 5536 reserv_sets_t reservs_matter = alloc_empty_reserv_sets ();
58ada791 5537
5538 for (cycle = 0; cycle < max_cycles_num; cycle++)
5539 for (unit = 0; unit < description->units_num; unit++)
5540 if (units_array [unit]->automaton_decl
5541 == automaton->corresponding_automaton_decl
5542 && (cycle >= units_array [unit]->min_occ_cycle_num
5543 /* We can not remove queried unit from reservations. */
5544 || units_array [unit]->query_p
5545 /* We can not remove units which are used
5546 `exclusion_set', `presence_set',
5547 `final_presence_set', `absence_set', and
5548 `final_absence_set'. */
5549 || units_array [unit]->in_set_p))
5550 set_unit_reserv (reservs_matter, cycle, unit);
5551 return reservs_matter;
5552}
5553
e7827cef 5554/* The following function creates all states of nondeterministic AUTOMATON. */
bea4bad2 5555static void
1a97be37 5556make_automaton (automaton_t automaton)
bea4bad2 5557{
5558 ainsn_t ainsn;
5559 struct insn_reserv_decl *insn_reserv_decl;
5560 alt_state_t alt_state;
5561 state_t state;
5562 state_t start_state;
5563 state_t state2;
f1f41a6c 5564 vec<state_t> state_stack;
5565 state_stack.create (150);
58ada791 5566 int states_n;
5567 reserv_sets_t reservs_matter = form_reservs_matter (automaton);
bea4bad2 5568
bea4bad2 5569 /* Create the start state (empty state). */
5570 start_state = insert_state (get_free_state (1, automaton));
5571 automaton->start_state = start_state;
5572 start_state->it_was_placed_in_stack_for_NDFA_forming = 1;
f1f41a6c 5573 state_stack.safe_push (start_state);
58ada791 5574 states_n = 1;
f1f41a6c 5575 while (state_stack.length () != 0)
bea4bad2 5576 {
f1f41a6c 5577 state = state_stack.pop ();
bea4bad2 5578 for (ainsn = automaton->ainsn_list;
5579 ainsn != NULL;
5580 ainsn = ainsn->next_ainsn)
5581 if (ainsn->first_insn_with_same_reservs)
5582 {
5583 insn_reserv_decl = ainsn->insn_reserv_decl;
8043d8fb 5584 if (!special_decl_p (insn_reserv_decl))
bea4bad2 5585 {
5586 /* We process alt_states in the same order as they are
5587 present in the description. */
bea4bad2 5588 for (alt_state = ainsn->alt_states;
5589 alt_state != NULL;
5590 alt_state = alt_state->next_alt_state)
5591 {
5592 state2 = alt_state->state;
5593 if (!intersected_state_reservs_p (state, state2))
5594 {
58ada791 5595 state2 = states_union (state, state2, reservs_matter);
bea4bad2 5596 if (!state2->it_was_placed_in_stack_for_NDFA_forming)
5597 {
5598 state2->it_was_placed_in_stack_for_NDFA_forming
5599 = 1;
f1f41a6c 5600 state_stack.safe_push (state2);
58ada791 5601 states_n++;
bccc9ebc 5602 if (progress_flag && states_n % 100 == 0)
b0effe67 5603 fprintf (stderr, ".");
bea4bad2 5604 }
002e7d08 5605 add_arc (state, state2, ainsn);
bea4bad2 5606 if (!ndfa_flag)
5607 break;
5608 }
5609 }
bea4bad2 5610 }
bea4bad2 5611 }
5612 /* Add transition to advance cycle. */
58ada791 5613 state2 = state_shift (state, reservs_matter);
bea4bad2 5614 if (!state2->it_was_placed_in_stack_for_NDFA_forming)
5615 {
5616 state2->it_was_placed_in_stack_for_NDFA_forming = 1;
f1f41a6c 5617 state_stack.safe_push (state2);
58ada791 5618 states_n++;
bccc9ebc 5619 if (progress_flag && states_n % 100 == 0)
b0effe67 5620 fprintf (stderr, ".");
bea4bad2 5621 }
8043d8fb 5622 add_arc (state, state2, automaton->advance_ainsn);
bea4bad2 5623 }
f1f41a6c 5624 state_stack.release ();
bea4bad2 5625}
5626
f0b5f617 5627/* Form lists of all arcs of STATE marked by the same ainsn. */
bea4bad2 5628static void
1a97be37 5629form_arcs_marked_by_insn (state_t state)
bea4bad2 5630{
5631 decl_t decl;
5632 arc_t arc;
5633 int i;
5634
5635 for (i = 0; i < description->decls_num; i++)
5636 {
5637 decl = description->decls [i];
5638 if (decl->mode == dm_insn_reserv)
2f8ffd86 5639 DECL_INSN_RESERV (decl)->arcs_marked_by_insn = NULL;
bea4bad2 5640 }
5641 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
5642 {
e0a4c0c2 5643 gcc_assert (arc->insn);
bea4bad2 5644 arc->next_arc_marked_by_insn
5645 = arc->insn->insn_reserv_decl->arcs_marked_by_insn;
5646 arc->insn->insn_reserv_decl->arcs_marked_by_insn = arc;
5647 }
5648}
5649
5650/* The function creates composed state (see comments for IR) from
5651 ORIGINAL_STATE and list of arcs ARCS_MARKED_BY_INSN marked by the
5652 same insn. If the composed state is not in STATE_STACK yet, it is
58ada791 5653 pushed into STATE_STACK. */
e7827cef 5654
58ada791 5655static int
1a97be37 5656create_composed_state (state_t original_state, arc_t arcs_marked_by_insn,
f1f41a6c 5657 vec<state_t> *state_stack)
bea4bad2 5658{
5659 state_t state;
58ada791 5660 alt_state_t alt_state, curr_alt_state;
bea4bad2 5661 alt_state_t new_alt_state;
5662 arc_t curr_arc;
5663 arc_t next_arc;
5664 state_t state_in_table;
5665 state_t temp_state;
5666 alt_state_t canonical_alt_states_list;
5667 int alts_number;
58ada791 5668 int new_state_p = 0;
bea4bad2 5669
5670 if (arcs_marked_by_insn == NULL)
58ada791 5671 return new_state_p;
bea4bad2 5672 if (arcs_marked_by_insn->next_arc_marked_by_insn == NULL)
5673 state = arcs_marked_by_insn->to_state;
5674 else
5675 {
e0a4c0c2 5676 gcc_assert (ndfa_flag);
bea4bad2 5677 /* Create composed state. */
5678 state = get_free_state (0, arcs_marked_by_insn->to_state->automaton);
5679 curr_alt_state = NULL;
5680 for (curr_arc = arcs_marked_by_insn;
5681 curr_arc != NULL;
5682 curr_arc = curr_arc->next_arc_marked_by_insn)
58ada791 5683 if (curr_arc->to_state->component_states == NULL)
5684 {
5685 new_alt_state = get_free_alt_state ();
5686 new_alt_state->next_alt_state = curr_alt_state;
5687 new_alt_state->state = curr_arc->to_state;
5688 curr_alt_state = new_alt_state;
5689 }
5690 else
5691 for (alt_state = curr_arc->to_state->component_states;
5692 alt_state != NULL;
5693 alt_state = alt_state->next_sorted_alt_state)
5694 {
5695 new_alt_state = get_free_alt_state ();
5696 new_alt_state->next_alt_state = curr_alt_state;
5697 new_alt_state->state = alt_state->state;
e0a4c0c2 5698 gcc_assert (!alt_state->state->component_states);
58ada791 5699 curr_alt_state = new_alt_state;
5700 }
bea4bad2 5701 /* There are not identical sets in the alt state list. */
5702 canonical_alt_states_list = uniq_sort_alt_states (curr_alt_state);
5703 if (canonical_alt_states_list->next_sorted_alt_state == NULL)
5704 {
5705 temp_state = state;
5706 state = canonical_alt_states_list->state;
5707 free_state (temp_state);
5708 }
5709 else
5710 {
5711 state->component_states = canonical_alt_states_list;
5712 state_in_table = insert_state (state);
5713 if (state_in_table != state)
5714 {
e0a4c0c2 5715 gcc_assert
5716 (state_in_table->it_was_placed_in_stack_for_DFA_forming);
bea4bad2 5717 free_state (state);
5718 state = state_in_table;
5719 }
5720 else
5721 {
e0a4c0c2 5722 gcc_assert (!state->it_was_placed_in_stack_for_DFA_forming);
58ada791 5723 new_state_p = 1;
bea4bad2 5724 for (curr_alt_state = state->component_states;
5725 curr_alt_state != NULL;
5726 curr_alt_state = curr_alt_state->next_sorted_alt_state)
5727 for (curr_arc = first_out_arc (curr_alt_state->state);
5728 curr_arc != NULL;
5729 curr_arc = next_out_arc (curr_arc))
8043d8fb 5730 if (!collapse_flag
5731 /* When producing collapse-NDFA transitions, we
5732 only add advance-cycle transitions to the
5733 collapsed states. */
5734 || (curr_arc->insn->insn_reserv_decl
5735 != DECL_INSN_RESERV (advance_cycle_insn_decl)))
5736 add_arc (state, curr_arc->to_state, curr_arc->insn);
bea4bad2 5737 }
5738 arcs_marked_by_insn->to_state = state;
5739 for (alts_number = 0,
5740 curr_arc = arcs_marked_by_insn->next_arc_marked_by_insn;
5741 curr_arc != NULL;
5742 curr_arc = next_arc)
5743 {
5744 next_arc = curr_arc->next_arc_marked_by_insn;
5745 remove_arc (original_state, curr_arc);
5746 alts_number++;
5747 }
bea4bad2 5748 }
5749 }
5750 if (!state->it_was_placed_in_stack_for_DFA_forming)
5751 {
5752 state->it_was_placed_in_stack_for_DFA_forming = 1;
f1f41a6c 5753 state_stack->safe_push (state);
bea4bad2 5754 }
58ada791 5755 return new_state_p;
bea4bad2 5756}
5757
f503d902 5758/* The function transforms nondeterministic AUTOMATON into
bea4bad2 5759 deterministic. */
e7827cef 5760
bea4bad2 5761static void
1a97be37 5762NDFA_to_DFA (automaton_t automaton)
bea4bad2 5763{
5764 state_t start_state;
5765 state_t state;
5766 decl_t decl;
f1f41a6c 5767 vec<state_t> state_stack;
bea4bad2 5768 int i;
58ada791 5769 int states_n;
bea4bad2 5770
f1f41a6c 5771 state_stack.create (0);
e7827cef 5772
bea4bad2 5773 /* Create the start state (empty state). */
5774 start_state = automaton->start_state;
5775 start_state->it_was_placed_in_stack_for_DFA_forming = 1;
f1f41a6c 5776 state_stack.safe_push (start_state);
58ada791 5777 states_n = 1;
f1f41a6c 5778 while (state_stack.length () != 0)
bea4bad2 5779 {
f1f41a6c 5780 state = state_stack.pop ();
bea4bad2 5781 form_arcs_marked_by_insn (state);
5782 for (i = 0; i < description->decls_num; i++)
5783 {
5784 decl = description->decls [i];
58ada791 5785 if (decl->mode == dm_insn_reserv
8043d8fb 5786 && decl != collapse_ndfa_insn_decl
58ada791 5787 && create_composed_state
5788 (state, DECL_INSN_RESERV (decl)->arcs_marked_by_insn,
5789 &state_stack))
5790 {
5791 states_n++;
bccc9ebc 5792 if (progress_flag && states_n % 100 == 0)
b0effe67 5793 fprintf (stderr, ".");
58ada791 5794 }
bea4bad2 5795 }
8043d8fb 5796 /* Add a transition to collapse the NDFA. */
5797 if (collapse_flag)
5798 {
5799 if (state->component_states != NULL)
5800 {
5801 state_t state2 = state->component_states->state;
5802 if (!state2->it_was_placed_in_stack_for_DFA_forming)
5803 {
5804 state2->it_was_placed_in_stack_for_DFA_forming = 1;
f1f41a6c 5805 state_stack.safe_push (state2);
8043d8fb 5806 }
5807 add_arc (state, state2, automaton->collapse_ainsn);
5808 }
5809 else
5810 add_arc (state, state, automaton->collapse_ainsn);
5811 }
bea4bad2 5812 }
f1f41a6c 5813 state_stack.release ();
bea4bad2 5814}
5815
5816/* The following variable value is current number (1, 2, ...) of passing
5817 graph of states. */
5818static int curr_state_graph_pass_num;
5819
5820/* This recursive function passes all states achieved from START_STATE
5821 and applies APPLIED_FUNC to them. */
5822static void
1a97be37 5823pass_state_graph (state_t start_state, void (*applied_func) (state_t state))
bea4bad2 5824{
5825 arc_t arc;
5826
5827 if (start_state->pass_num == curr_state_graph_pass_num)
5828 return;
5829 start_state->pass_num = curr_state_graph_pass_num;
5830 (*applied_func) (start_state);
5831 for (arc = first_out_arc (start_state);
5832 arc != NULL;
5833 arc = next_out_arc (arc))
5834 pass_state_graph (arc->to_state, applied_func);
5835}
5836
5837/* This recursive function passes all states of AUTOMATON and applies
5838 APPLIED_FUNC to them. */
5839static void
1a97be37 5840pass_states (automaton_t automaton, void (*applied_func) (state_t state))
bea4bad2 5841{
5842 curr_state_graph_pass_num++;
5843 pass_state_graph (automaton->start_state, applied_func);
5844}
5845
5846/* The function initializes code for passing of all states. */
5847static void
1a97be37 5848initiate_pass_states (void)
bea4bad2 5849{
5850 curr_state_graph_pass_num = 0;
5851}
5852
5853/* The following vla is used for storing pointers to all achieved
5854 states. */
f1f41a6c 5855static vec<state_t> all_achieved_states;
bea4bad2 5856
5857/* This function is called by function pass_states to add an achieved
5858 STATE. */
5859static void
1a97be37 5860add_achieved_state (state_t state)
bea4bad2 5861{
f1f41a6c 5862 all_achieved_states.safe_push (state);
bea4bad2 5863}
5864
5865/* The function sets up equivalence numbers of insns which mark all
5866 out arcs of STATE by equiv_class_num_1 (if ODD_ITERATION_FLAG has
8043d8fb 5867 nonzero value) or by equiv_class_num_2 of the destination state. */
c72f0286 5868static void
1a97be37 5869set_out_arc_insns_equiv_num (state_t state, int odd_iteration_flag)
bea4bad2 5870{
bea4bad2 5871 arc_t arc;
5872
bea4bad2 5873 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
5874 {
0f7f3d52 5875 gcc_assert (!arc->insn->insn_reserv_decl->equiv_class_num);
bea4bad2 5876 arc->insn->insn_reserv_decl->equiv_class_num
5877 = (odd_iteration_flag
5878 ? arc->to_state->equiv_class_num_1
5879 : arc->to_state->equiv_class_num_2);
0f7f3d52 5880 gcc_assert (arc->insn->insn_reserv_decl->equiv_class_num);
bea4bad2 5881 }
bea4bad2 5882}
5883
5884/* The function clears equivalence numbers and alt_states in all insns
5885 which mark all out arcs of STATE. */
5886static void
1a97be37 5887clear_arc_insns_equiv_num (state_t state)
bea4bad2 5888{
5889 arc_t arc;
5890
5891 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
0f7f3d52 5892 arc->insn->insn_reserv_decl->equiv_class_num = 0;
bea4bad2 5893}
5894
bea4bad2 5895
58ada791 5896/* The following function returns TRUE if STATE reserves the unit with
5897 UNIT_NUM on the first cycle. */
5898static int
1a97be37 5899first_cycle_unit_presence (state_t state, int unit_num)
58ada791 5900{
17d386e4 5901 alt_state_t alt_state;
58ada791 5902
5903 if (state->component_states == NULL)
17d386e4 5904 return test_unit_reserv (state->reservs, 0, unit_num);
58ada791 5905 else
17d386e4 5906 {
5907 for (alt_state = state->component_states;
5908 alt_state != NULL;
5909 alt_state = alt_state->next_sorted_alt_state)
5910 if (test_unit_reserv (alt_state->state->reservs, 0, unit_num))
5911 return true;
5912 }
5913 return false;
58ada791 5914}
5915
c72f0286 5916/* This fills in the presence_signature[] member of STATE. */
5917static void
5918cache_presence (state_t state)
5919{
5920 int i, num = 0;
5921 unsigned int sz;
5922 sz = (description->query_units_num + sizeof (int) * CHAR_BIT - 1)
5923 / (sizeof (int) * CHAR_BIT);
48e1416a 5924
65b198c2 5925 state->presence_signature = XCREATENODEVEC (unsigned int, sz);
c72f0286 5926 for (i = 0; i < description->units_num; i++)
5927 if (units_array [i]->query_p)
5928 {
5929 int presence1_p = first_cycle_unit_presence (state, i);
5930 state->presence_signature[num / (sizeof (int) * CHAR_BIT)]
5931 |= (!!presence1_p) << (num % (sizeof (int) * CHAR_BIT));
5932 num++;
5933 }
5934}
5935
bea4bad2 5936/* The function returns nonzero value if STATE is not equivalent to
58ada791 5937 ANOTHER_STATE from the same current partition on equivalence
5938 classes. Another state has ANOTHER_STATE_OUT_ARCS_NUM number of
bea4bad2 5939 output arcs. Iteration of making equivalence partition is defined
5940 by ODD_ITERATION_FLAG. */
5941static int
1a97be37 5942state_is_differed (state_t state, state_t another_state,
c72f0286 5943 int odd_iteration_flag)
bea4bad2 5944{
5945 arc_t arc;
c72f0286 5946 unsigned int sz, si;
5947
5948 gcc_assert (state->num_out_arcs == another_state->num_out_arcs);
5949
5950 sz = (description->query_units_num + sizeof (int) * CHAR_BIT - 1)
5951 / (sizeof (int) * CHAR_BIT);
5952
5953 for (si = 0; si < sz; si++)
5954 gcc_assert (state->presence_signature[si]
5955 == another_state->presence_signature[si]);
bea4bad2 5956
bea4bad2 5957 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
5958 {
bea4bad2 5959 if ((odd_iteration_flag
5960 ? arc->to_state->equiv_class_num_1
5961 : arc->to_state->equiv_class_num_2)
0f7f3d52 5962 != arc->insn->insn_reserv_decl->equiv_class_num)
bea4bad2 5963 return 1;
5964 }
c72f0286 5965
5966 return 0;
5967}
5968
5969/* Compares two states pointed to by STATE_PTR_1 and STATE_PTR_2
5970 and return -1, 0 or 1. This function can be used as predicate for
5971 qsort(). It requires the member presence_signature[] of both
5972 states be filled. */
5973static int
5974compare_states_for_equiv (const void *state_ptr_1,
5975 const void *state_ptr_2)
5976{
aae87fc3 5977 const_state_t const s1 = *(const_state_t const*)state_ptr_1;
5978 const_state_t const s2 = *(const_state_t const*)state_ptr_2;
c72f0286 5979 unsigned int sz, si;
5980 if (s1->num_out_arcs < s2->num_out_arcs)
5981 return -1;
5982 else if (s1->num_out_arcs > s2->num_out_arcs)
58ada791 5983 return 1;
c72f0286 5984
5985 sz = (description->query_units_num + sizeof (int) * CHAR_BIT - 1)
5986 / (sizeof (int) * CHAR_BIT);
5987
5988 for (si = 0; si < sz; si++)
5989 if (s1->presence_signature[si] < s2->presence_signature[si])
5990 return -1;
5991 else if (s1->presence_signature[si] > s2->presence_signature[si])
5992 return 1;
58ada791 5993 return 0;
bea4bad2 5994}
5995
5996/* The function makes initial partition of STATES on equivalent
f1f41a6c 5997 classes and saves it into CLASSES. This function requires the input
c72f0286 5998 to be sorted via compare_states_for_equiv(). */
5999static int
f1f41a6c 6000init_equiv_class (vec<state_t> states, vec<state_t> *classes)
bea4bad2 6001{
e7827cef 6002 size_t i;
6003 state_t prev = 0;
c72f0286 6004 int class_num = 1;
bea4bad2 6005
f1f41a6c 6006 classes->create (150);
6007 for (i = 0; i < states.length (); i++)
bea4bad2 6008 {
f1f41a6c 6009 state_t state = states[i];
c72f0286 6010 if (prev)
6011 {
6012 if (compare_states_for_equiv (&prev, &state) != 0)
6013 {
f1f41a6c 6014 classes->safe_push (prev);
c72f0286 6015 class_num++;
6016 prev = NULL;
6017 }
6018 }
6019 state->equiv_class_num_1 = class_num;
6020 state->next_equiv_class_state = prev;
6021 prev = state;
bea4bad2 6022 }
c72f0286 6023 if (prev)
f1f41a6c 6024 classes->safe_push (prev);
c72f0286 6025 return class_num;
bea4bad2 6026}
6027
e7827cef 6028/* The function copies pointers to equivalent states from vla FROM
6029 into vla TO. */
6030static void
f1f41a6c 6031copy_equiv_class (vec<state_t> *to, vec<state_t> from)
e7827cef 6032{
f1f41a6c 6033 to->release ();
6034 *to = from.copy ();
e7827cef 6035}
c72f0286 6036
e7827cef 6037/* The function processes equivalence class given by its first state,
6038 FIRST_STATE, on odd iteration if ODD_ITERATION_FLAG. If there
f503d902 6039 are not equivalent states, the function partitions the class
bea4bad2 6040 removing nonequivalent states and placing them in
6041 *NEXT_ITERATION_CLASSES, increments *NEW_EQUIV_CLASS_NUM_PTR ans
6042 assigns it to the state equivalence number. If the class has been
b35eefd9 6043 partitioned, the function returns nonzero value. */
bea4bad2 6044static int
e7827cef 6045partition_equiv_class (state_t first_state, int odd_iteration_flag,
f1f41a6c 6046 vec<state_t> *next_iteration_classes,
1a97be37 6047 int *new_equiv_class_num_ptr)
bea4bad2 6048{
6049 state_t new_equiv_class;
6050 int partition_p;
bea4bad2 6051 state_t curr_state;
6052 state_t prev_state;
6053 state_t next_state;
bea4bad2 6054
6055 partition_p = 0;
e7827cef 6056
6057 while (first_state != NULL)
bea4bad2 6058 {
6059 new_equiv_class = NULL;
6060 if (first_state->next_equiv_class_state != NULL)
6061 {
6062 /* There are more one states in the class equivalence. */
c72f0286 6063 set_out_arc_insns_equiv_num (first_state, odd_iteration_flag);
bea4bad2 6064 for (prev_state = first_state,
6065 curr_state = first_state->next_equiv_class_state;
6066 curr_state != NULL;
6067 curr_state = next_state)
6068 {
6069 next_state = curr_state->next_equiv_class_state;
48e1416a 6070 if (state_is_differed (curr_state, first_state,
bea4bad2 6071 odd_iteration_flag))
6072 {
6073 /* Remove curr state from the class equivalence. */
6074 prev_state->next_equiv_class_state = next_state;
6075 /* Add curr state to the new class equivalence. */
6076 curr_state->next_equiv_class_state = new_equiv_class;
6077 if (new_equiv_class == NULL)
6078 (*new_equiv_class_num_ptr)++;
6079 if (odd_iteration_flag)
6080 curr_state->equiv_class_num_2 = *new_equiv_class_num_ptr;
6081 else
6082 curr_state->equiv_class_num_1 = *new_equiv_class_num_ptr;
6083 new_equiv_class = curr_state;
6084 partition_p = 1;
6085 }
6086 else
6087 prev_state = curr_state;
6088 }
6089 clear_arc_insns_equiv_num (first_state);
6090 }
6091 if (new_equiv_class != NULL)
f1f41a6c 6092 next_iteration_classes->safe_push (new_equiv_class);
e7827cef 6093 first_state = new_equiv_class;
bea4bad2 6094 }
6095 return partition_p;
6096}
6097
6098/* The function finds equivalent states of AUTOMATON. */
6099static void
f1f41a6c 6100evaluate_equiv_classes (automaton_t automaton, vec<state_t> *equiv_classes)
bea4bad2 6101{
bea4bad2 6102 int new_equiv_class_num;
6103 int odd_iteration_flag;
6104 int finish_flag;
f1f41a6c 6105 vec<state_t> next_iteration_classes;
e7827cef 6106 size_t i;
1a97be37 6107
f1f41a6c 6108 all_achieved_states.create (1500);
bea4bad2 6109 pass_states (automaton, add_achieved_state);
c72f0286 6110 pass_states (automaton, cache_presence);
f1f41a6c 6111 all_achieved_states.qsort (compare_states_for_equiv);
e7827cef 6112
c72f0286 6113 odd_iteration_flag = 0;
6114 new_equiv_class_num = init_equiv_class (all_achieved_states,
6115 &next_iteration_classes);
e7827cef 6116
bea4bad2 6117 do
6118 {
6119 odd_iteration_flag = !odd_iteration_flag;
6120 finish_flag = 1;
e7827cef 6121 copy_equiv_class (equiv_classes, next_iteration_classes);
6122
bea4bad2 6123 /* Transfer equiv numbers for the next iteration. */
f1f41a6c 6124 for (i = 0; i < all_achieved_states.length (); i++)
bea4bad2 6125 if (odd_iteration_flag)
f1f41a6c 6126 all_achieved_states[i]->equiv_class_num_2
6127 = all_achieved_states[i]->equiv_class_num_1;
bea4bad2 6128 else
f1f41a6c 6129 all_achieved_states[i]->equiv_class_num_1
6130 = all_achieved_states[i]->equiv_class_num_2;
e7827cef 6131
f1f41a6c 6132 for (i = 0; i < equiv_classes->length (); i++)
6133 if (partition_equiv_class ((*equiv_classes)[i],
e7827cef 6134 odd_iteration_flag,
bea4bad2 6135 &next_iteration_classes,
6136 &new_equiv_class_num))
6137 finish_flag = 0;
6138 }
6139 while (!finish_flag);
f1f41a6c 6140 next_iteration_classes.release ();
6141 all_achieved_states.release ();
bea4bad2 6142}
6143
6144/* The function merges equivalent states of AUTOMATON. */
6145static void
f1f41a6c 6146merge_states (automaton_t automaton, vec<state_t> equiv_classes)
bea4bad2 6147{
bea4bad2 6148 state_t curr_state;
6149 state_t new_state;
6150 state_t first_class_state;
6151 alt_state_t alt_states;
58ada791 6152 alt_state_t alt_state, new_alt_state;
bea4bad2 6153 arc_t curr_arc;
6154 arc_t next_arc;
e7827cef 6155 size_t i;
bea4bad2 6156
6157 /* Create states corresponding to equivalence classes containing two
6158 or more states. */
f1f41a6c 6159 for (i = 0; i < equiv_classes.length (); i++)
e7827cef 6160 {
f1f41a6c 6161 curr_state = equiv_classes[i];
e7827cef 6162 if (curr_state->next_equiv_class_state != NULL)
6163 {
6164 /* There are more one states in the class equivalence. */
6165 /* Create new compound state. */
6166 new_state = get_free_state (0, automaton);
6167 alt_states = NULL;
6168 first_class_state = curr_state;
6169 for (curr_state = first_class_state;
6170 curr_state != NULL;
6171 curr_state = curr_state->next_equiv_class_state)
6172 {
6173 curr_state->equiv_class_state = new_state;
6174 if (curr_state->component_states == NULL)
58ada791 6175 {
6176 new_alt_state = get_free_alt_state ();
e7827cef 6177 new_alt_state->state = curr_state;
58ada791 6178 new_alt_state->next_alt_state = alt_states;
6179 alt_states = new_alt_state;
6180 }
e7827cef 6181 else
6182 for (alt_state = curr_state->component_states;
6183 alt_state != NULL;
6184 alt_state = alt_state->next_sorted_alt_state)
6185 {
6186 new_alt_state = get_free_alt_state ();
6187 new_alt_state->state = alt_state->state;
6188 new_alt_state->next_alt_state = alt_states;
6189 alt_states = new_alt_state;
6190 }
6191 }
6192 /* Its is important that alt states were sorted before and
6193 after merging to have the same querying results. */
6194 new_state->component_states = uniq_sort_alt_states (alt_states);
6195 }
6196 else
6197 curr_state->equiv_class_state = curr_state;
6198 }
6199
f1f41a6c 6200 for (i = 0; i < equiv_classes.length (); i++)
e7827cef 6201 {
f1f41a6c 6202 curr_state = equiv_classes[i];
e7827cef 6203 if (curr_state->next_equiv_class_state != NULL)
6204 {
6205 first_class_state = curr_state;
6206 /* Create new arcs output from the state corresponding to
6207 equiv class. */
6208 for (curr_arc = first_out_arc (first_class_state);
6209 curr_arc != NULL;
6210 curr_arc = next_out_arc (curr_arc))
6211 add_arc (first_class_state->equiv_class_state,
6212 curr_arc->to_state->equiv_class_state,
0f7f3d52 6213 curr_arc->insn);
e7827cef 6214 /* Delete output arcs from states of given class equivalence. */
6215 for (curr_state = first_class_state;
6216 curr_state != NULL;
6217 curr_state = curr_state->next_equiv_class_state)
6218 {
6219 if (automaton->start_state == curr_state)
6220 automaton->start_state = curr_state->equiv_class_state;
6221 /* Delete the state and its output arcs. */
6222 for (curr_arc = first_out_arc (curr_state);
6223 curr_arc != NULL;
6224 curr_arc = next_arc)
6225 {
6226 next_arc = next_out_arc (curr_arc);
6227 free_arc (curr_arc);
6228 }
6229 }
6230 }
6231 else
6232 {
6233 /* Change `to_state' of arcs output from the state of given
6234 equivalence class. */
6235 for (curr_arc = first_out_arc (curr_state);
6236 curr_arc != NULL;
6237 curr_arc = next_out_arc (curr_arc))
6238 curr_arc->to_state = curr_arc->to_state->equiv_class_state;
6239 }
6240 }
bea4bad2 6241}
6242
6243/* The function sets up new_cycle_p for states if there is arc to the
6244 state marked by advance_cycle_insn_decl. */
6245static void
1a97be37 6246set_new_cycle_flags (state_t state)
bea4bad2 6247{
6248 arc_t arc;
6249
6250 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
6251 if (arc->insn->insn_reserv_decl
2f8ffd86 6252 == DECL_INSN_RESERV (advance_cycle_insn_decl))
bea4bad2 6253 arc->to_state->new_cycle_p = 1;
6254}
6255
6256/* The top level function for minimization of deterministic
6257 AUTOMATON. */
6258static void
1a97be37 6259minimize_DFA (automaton_t automaton)
bea4bad2 6260{
1e094109 6261 vec<state_t> equiv_classes = vNULL;
bea4bad2 6262
bea4bad2 6263 evaluate_equiv_classes (automaton, &equiv_classes);
e7827cef 6264 merge_states (automaton, equiv_classes);
bea4bad2 6265 pass_states (automaton, set_new_cycle_flags);
e7827cef 6266
f1f41a6c 6267 equiv_classes.release ();
bea4bad2 6268}
6269
6270/* Values of two variables are counted number of states and arcs in an
6271 automaton. */
6272static int curr_counted_states_num;
6273static int curr_counted_arcs_num;
6274
6275/* The function is called by function `pass_states' to count states
6276 and arcs of an automaton. */
6277static void
1a97be37 6278incr_states_and_arcs_nums (state_t state)
bea4bad2 6279{
6280 arc_t arc;
6281
6282 curr_counted_states_num++;
6283 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
6284 curr_counted_arcs_num++;
6285}
6286
6287/* The function counts states and arcs of AUTOMATON. */
6288static void
1a97be37 6289count_states_and_arcs (automaton_t automaton, int *states_num,
6290 int *arcs_num)
bea4bad2 6291{
6292 curr_counted_states_num = 0;
6293 curr_counted_arcs_num = 0;
6294 pass_states (automaton, incr_states_and_arcs_nums);
6295 *states_num = curr_counted_states_num;
6296 *arcs_num = curr_counted_arcs_num;
6297}
6298
6299/* The function builds one DFA AUTOMATON for fast pipeline hazards
6300 recognition after checking and simplifying IR of the
6301 description. */
6302static void
1a97be37 6303build_automaton (automaton_t automaton)
bea4bad2 6304{
6305 int states_num;
6306 int arcs_num;
6307
6308 ticker_on (&NDFA_time);
bccc9ebc 6309 if (progress_flag)
6310 {
6311 if (automaton->corresponding_automaton_decl == NULL)
6312 fprintf (stderr, "Create anonymous automaton");
6313 else
6314 fprintf (stderr, "Create automaton `%s'",
6315 automaton->corresponding_automaton_decl->name);
6316 fprintf (stderr, " (1 dot is 100 new states):");
6317 }
bea4bad2 6318 make_automaton (automaton);
bccc9ebc 6319 if (progress_flag)
6320 fprintf (stderr, " done\n");
bea4bad2 6321 ticker_off (&NDFA_time);
6322 count_states_and_arcs (automaton, &states_num, &arcs_num);
6323 automaton->NDFA_states_num = states_num;
6324 automaton->NDFA_arcs_num = arcs_num;
6325 ticker_on (&NDFA_to_DFA_time);
bccc9ebc 6326 if (progress_flag)
6327 {
6328 if (automaton->corresponding_automaton_decl == NULL)
6329 fprintf (stderr, "Make anonymous DFA");
6330 else
6331 fprintf (stderr, "Make DFA `%s'",
6332 automaton->corresponding_automaton_decl->name);
6333 fprintf (stderr, " (1 dot is 100 new states):");
6334 }
bea4bad2 6335 NDFA_to_DFA (automaton);
bccc9ebc 6336 if (progress_flag)
6337 fprintf (stderr, " done\n");
bea4bad2 6338 ticker_off (&NDFA_to_DFA_time);
6339 count_states_and_arcs (automaton, &states_num, &arcs_num);
6340 automaton->DFA_states_num = states_num;
6341 automaton->DFA_arcs_num = arcs_num;
6342 if (!no_minimization_flag)
6343 {
6344 ticker_on (&minimize_time);
bccc9ebc 6345 if (progress_flag)
6346 {
6347 if (automaton->corresponding_automaton_decl == NULL)
6348 fprintf (stderr, "Minimize anonymous DFA...");
6349 else
6350 fprintf (stderr, "Minimize DFA `%s'...",
6351 automaton->corresponding_automaton_decl->name);
6352 }
bea4bad2 6353 minimize_DFA (automaton);
bccc9ebc 6354 if (progress_flag)
6355 fprintf (stderr, "done\n");
bea4bad2 6356 ticker_off (&minimize_time);
6357 count_states_and_arcs (automaton, &states_num, &arcs_num);
6358 automaton->minimal_DFA_states_num = states_num;
6359 automaton->minimal_DFA_arcs_num = arcs_num;
6360 }
6361}
6362
6363\f
6364
6365/* The page contains code for enumeration of all states of an automaton. */
6366
6367/* Variable used for enumeration of all states of an automaton. Its
6368 value is current number of automaton states. */
6369static int curr_state_order_num;
6370
6371/* The function is called by function `pass_states' for enumerating
6372 states. */
6373static void
1a97be37 6374set_order_state_num (state_t state)
bea4bad2 6375{
6376 state->order_state_num = curr_state_order_num;
6377 curr_state_order_num++;
6378}
6379
6380/* The function enumerates all states of AUTOMATON. */
6381static void
1a97be37 6382enumerate_states (automaton_t automaton)
bea4bad2 6383{
6384 curr_state_order_num = 0;
6385 pass_states (automaton, set_order_state_num);
6386 automaton->achieved_states_num = curr_state_order_num;
6387}
6388
6389\f
6390
6391/* The page contains code for finding equivalent automaton insns
6392 (ainsns). */
6393
6394/* The function inserts AINSN into cyclic list
6395 CYCLIC_EQUIV_CLASS_INSN_LIST of ainsns. */
6396static ainsn_t
1a97be37 6397insert_ainsn_into_equiv_class (ainsn_t ainsn,
6398 ainsn_t cyclic_equiv_class_insn_list)
bea4bad2 6399{
6400 if (cyclic_equiv_class_insn_list == NULL)
6401 ainsn->next_equiv_class_insn = ainsn;
6402 else
6403 {
6404 ainsn->next_equiv_class_insn
6405 = cyclic_equiv_class_insn_list->next_equiv_class_insn;
6406 cyclic_equiv_class_insn_list->next_equiv_class_insn = ainsn;
6407 }
6408 return ainsn;
6409}
6410
6411/* The function deletes equiv_class_insn into cyclic list of
6412 equivalent ainsns. */
6413static void
1a97be37 6414delete_ainsn_from_equiv_class (ainsn_t equiv_class_insn)
bea4bad2 6415{
6416 ainsn_t curr_equiv_class_insn;
6417 ainsn_t prev_equiv_class_insn;
6418
6419 prev_equiv_class_insn = equiv_class_insn;
6420 for (curr_equiv_class_insn = equiv_class_insn->next_equiv_class_insn;
6421 curr_equiv_class_insn != equiv_class_insn;
6422 curr_equiv_class_insn = curr_equiv_class_insn->next_equiv_class_insn)
6423 prev_equiv_class_insn = curr_equiv_class_insn;
6424 if (prev_equiv_class_insn != equiv_class_insn)
6425 prev_equiv_class_insn->next_equiv_class_insn
6426 = equiv_class_insn->next_equiv_class_insn;
6427}
6428
6429/* The function processes AINSN of a state in order to find equivalent
6430 ainsns. INSN_ARCS_ARRAY is table: code of insn -> out arc of the
6431 state. */
6432static void
1a97be37 6433process_insn_equiv_class (ainsn_t ainsn, arc_t *insn_arcs_array)
bea4bad2 6434{
6435 ainsn_t next_insn;
6436 ainsn_t curr_insn;
6437 ainsn_t cyclic_insn_list;
6438 arc_t arc;
6439
e0a4c0c2 6440 gcc_assert (insn_arcs_array [ainsn->insn_reserv_decl->insn_num]);
bea4bad2 6441 curr_insn = ainsn;
6442 /* New class of ainsns which are not equivalent to given ainsn. */
6443 cyclic_insn_list = NULL;
6444 do
6445 {
6446 next_insn = curr_insn->next_equiv_class_insn;
6447 arc = insn_arcs_array [curr_insn->insn_reserv_decl->insn_num];
6448 if (arc == NULL
6449 || (insn_arcs_array [ainsn->insn_reserv_decl->insn_num]->to_state
6450 != arc->to_state))
6451 {
6452 delete_ainsn_from_equiv_class (curr_insn);
6453 cyclic_insn_list = insert_ainsn_into_equiv_class (curr_insn,
6454 cyclic_insn_list);
6455 }
6456 curr_insn = next_insn;
6457 }
6458 while (curr_insn != ainsn);
6459}
6460
6461/* The function processes STATE in order to find equivalent ainsns. */
6462static void
1a97be37 6463process_state_for_insn_equiv_partition (state_t state)
bea4bad2 6464{
6465 arc_t arc;
4c36ffe6 6466 arc_t *insn_arcs_array = XCNEWVEC (arc_t, description->insns_num);
bea4bad2 6467
bea4bad2 6468 /* Process insns of the arcs. */
bea4bad2 6469 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
6470 insn_arcs_array [arc->insn->insn_reserv_decl->insn_num] = arc;
6471 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
6472 process_insn_equiv_class (arc->insn, insn_arcs_array);
e7827cef 6473
6474 free (insn_arcs_array);
bea4bad2 6475}
6476
6477/* The function searches for equivalent ainsns of AUTOMATON. */
6478static void
1a97be37 6479set_insn_equiv_classes (automaton_t automaton)
bea4bad2 6480{
6481 ainsn_t ainsn;
6482 ainsn_t first_insn;
6483 ainsn_t curr_insn;
6484 ainsn_t cyclic_insn_list;
6485 ainsn_t insn_with_same_reservs;
6486 int equiv_classes_num;
6487
6488 /* All insns are included in one equivalence class. */
6489 cyclic_insn_list = NULL;
6490 for (ainsn = automaton->ainsn_list; ainsn != NULL; ainsn = ainsn->next_ainsn)
6491 if (ainsn->first_insn_with_same_reservs)
6492 cyclic_insn_list = insert_ainsn_into_equiv_class (ainsn,
6493 cyclic_insn_list);
6494 /* Process insns in order to make equivalence partition. */
6495 pass_states (automaton, process_state_for_insn_equiv_partition);
6496 /* Enumerate equiv classes. */
6497 for (ainsn = automaton->ainsn_list; ainsn != NULL; ainsn = ainsn->next_ainsn)
6498 /* Set undefined value. */
6499 ainsn->insn_equiv_class_num = -1;
6500 equiv_classes_num = 0;
6501 for (ainsn = automaton->ainsn_list; ainsn != NULL; ainsn = ainsn->next_ainsn)
6502 if (ainsn->insn_equiv_class_num < 0)
6503 {
6504 first_insn = ainsn;
e0a4c0c2 6505 gcc_assert (first_insn->first_insn_with_same_reservs);
069eea26 6506 first_insn->first_ainsn_with_given_equivalence_num = 1;
bea4bad2 6507 curr_insn = first_insn;
6508 do
6509 {
6510 for (insn_with_same_reservs = curr_insn;
6511 insn_with_same_reservs != NULL;
6512 insn_with_same_reservs
6513 = insn_with_same_reservs->next_same_reservs_insn)
6514 insn_with_same_reservs->insn_equiv_class_num = equiv_classes_num;
6515 curr_insn = curr_insn->next_equiv_class_insn;
6516 }
6517 while (curr_insn != first_insn);
6518 equiv_classes_num++;
6519 }
6520 automaton->insn_equiv_classes_num = equiv_classes_num;
6521}
6522
6523\f
6524
6525/* This page contains code for creating DFA(s) and calls functions
6526 building them. */
6527
6528
6529/* The following value is used to prevent floating point overflow for
6530 estimating an automaton bound. The value should be less DBL_MAX on
6531 the host machine. We use here approximate minimum of maximal
6532 double floating point value required by ANSI C standard. It
6533 will work for non ANSI sun compiler too. */
6534
6535#define MAX_FLOATING_POINT_VALUE_FOR_AUTOMATON_BOUND 1.0E37
6536
6537/* The function estimate size of the single DFA used by PHR (pipeline
6538 hazards recognizer). */
6539static double
1a97be37 6540estimate_one_automaton_bound (void)
bea4bad2 6541{
6542 decl_t decl;
6543 double one_automaton_estimation_bound;
6544 double root_value;
6545 int i;
6546
6547 one_automaton_estimation_bound = 1.0;
6548 for (i = 0; i < description->decls_num; i++)
6549 {
6550 decl = description->decls [i];
6551 if (decl->mode == dm_unit)
6552 {
58ada791 6553 root_value = exp (log (DECL_UNIT (decl)->max_occ_cycle_num
6554 - DECL_UNIT (decl)->min_occ_cycle_num + 1.0)
bea4bad2 6555 / automata_num);
6556 if (MAX_FLOATING_POINT_VALUE_FOR_AUTOMATON_BOUND / root_value
6557 > one_automaton_estimation_bound)
6558 one_automaton_estimation_bound *= root_value;
6559 }
6560 }
6561 return one_automaton_estimation_bound;
6562}
6563
f503d902 6564/* The function compares unit declarations according to their maximal
bea4bad2 6565 cycle in reservations. */
6566static int
1a97be37 6567compare_max_occ_cycle_nums (const void *unit_decl_1,
6568 const void *unit_decl_2)
bea4bad2 6569{
aae87fc3 6570 if ((DECL_UNIT (*(const_decl_t const*) unit_decl_1)->max_occ_cycle_num)
6571 < (DECL_UNIT (*(const_decl_t const*) unit_decl_2)->max_occ_cycle_num))
bea4bad2 6572 return 1;
aae87fc3 6573 else if ((DECL_UNIT (*(const_decl_t const*) unit_decl_1)->max_occ_cycle_num)
6574 == (DECL_UNIT (*(const_decl_t const*) unit_decl_2)->max_occ_cycle_num))
bea4bad2 6575 return 0;
6576 else
6577 return -1;
6578}
6579
6580/* The function makes heuristic assigning automata to units. Actually
6581 efficacy of the algorithm has been checked yet??? */
e7827cef 6582
bea4bad2 6583static void
1a97be37 6584units_to_automata_heuristic_distr (void)
bea4bad2 6585{
6586 double estimation_bound;
bea4bad2 6587 int automaton_num;
6588 int rest_units_num;
6589 double bound_value;
e7827cef 6590 unit_decl_t *unit_decls;
6591 int i, j;
bea4bad2 6592
6593 if (description->units_num == 0)
6594 return;
6595 estimation_bound = estimate_one_automaton_bound ();
4c36ffe6 6596 unit_decls = XNEWVEC (unit_decl_t, description->units_num);
e7827cef 6597
6598 for (i = 0, j = 0; i < description->decls_num; i++)
6599 if (description->decls[i]->mode == dm_unit)
6600 unit_decls[j++] = DECL_UNIT (description->decls[i]);
6601 gcc_assert (j == description->units_num);
6602
6603 qsort (unit_decls, description->units_num,
6604 sizeof (unit_decl_t), compare_max_occ_cycle_nums);
6605
bea4bad2 6606 automaton_num = 0;
e7827cef 6607 bound_value = unit_decls[0]->max_occ_cycle_num;
6608 unit_decls[0]->corresponding_automaton_num = automaton_num;
6609
6610 for (i = 1; i < description->units_num; i++)
6611 {
6612 rest_units_num = description->units_num - i + 1;
e0a4c0c2 6613 gcc_assert (automata_num - automaton_num - 1 <= rest_units_num);
bea4bad2 6614 if (automaton_num < automata_num - 1
6615 && ((automata_num - automaton_num - 1 == rest_units_num)
6616 || (bound_value
6617 > (estimation_bound
e7827cef 6618 / unit_decls[i]->max_occ_cycle_num))))
bea4bad2 6619 {
e7827cef 6620 bound_value = unit_decls[i]->max_occ_cycle_num;
bea4bad2 6621 automaton_num++;
6622 }
6623 else
e7827cef 6624 bound_value *= unit_decls[i]->max_occ_cycle_num;
6625 unit_decls[i]->corresponding_automaton_num = automaton_num;
bea4bad2 6626 }
e0a4c0c2 6627 gcc_assert (automaton_num == automata_num - 1);
e7827cef 6628 free (unit_decls);
bea4bad2 6629}
6630
6631/* The functions creates automaton insns for each automata. Automaton
6632 insn is simply insn for given automaton which makes reservation
6633 only of units of the automaton. */
8043d8fb 6634static void
6635create_ainsns (automaton_t automaton)
bea4bad2 6636{
6637 decl_t decl;
6638 ainsn_t first_ainsn;
6639 ainsn_t curr_ainsn;
6640 ainsn_t prev_ainsn;
6641 int i;
6642
6643 first_ainsn = NULL;
6644 prev_ainsn = NULL;
6645 for (i = 0; i < description->decls_num; i++)
6646 {
6647 decl = description->decls [i];
6648 if (decl->mode == dm_insn_reserv)
6649 {
65b198c2 6650 curr_ainsn = XCREATENODE (struct ainsn);
2f8ffd86 6651 curr_ainsn->insn_reserv_decl = DECL_INSN_RESERV (decl);
bea4bad2 6652 curr_ainsn->important_p = FALSE;
6653 curr_ainsn->next_ainsn = NULL;
6654 if (prev_ainsn == NULL)
6655 first_ainsn = curr_ainsn;
6656 else
6657 prev_ainsn->next_ainsn = curr_ainsn;
8043d8fb 6658 if (decl == advance_cycle_insn_decl)
6659 automaton->advance_ainsn = curr_ainsn;
6660 else if (decl == collapse_ndfa_insn_decl)
6661 automaton->collapse_ainsn = curr_ainsn;
bea4bad2 6662 prev_ainsn = curr_ainsn;
6663 }
6664 }
8043d8fb 6665 automaton->ainsn_list = first_ainsn;
bea4bad2 6666}
6667
6668/* The function assigns automata to units according to constructions
6669 `define_automaton' in the description. */
6670static void
1a97be37 6671units_to_automata_distr (void)
bea4bad2 6672{
6673 decl_t decl;
6674 int i;
1a97be37 6675
bea4bad2 6676 for (i = 0; i < description->decls_num; i++)
6677 {
6678 decl = description->decls [i];
6679 if (decl->mode == dm_unit)
6680 {
2f8ffd86 6681 if (DECL_UNIT (decl)->automaton_decl == NULL
6682 || (DECL_UNIT (decl)->automaton_decl->corresponding_automaton
bea4bad2 6683 == NULL))
6684 /* Distribute to the first automaton. */
2f8ffd86 6685 DECL_UNIT (decl)->corresponding_automaton_num = 0;
bea4bad2 6686 else
2f8ffd86 6687 DECL_UNIT (decl)->corresponding_automaton_num
6688 = (DECL_UNIT (decl)->automaton_decl
bea4bad2 6689 ->corresponding_automaton->automaton_order_num);
6690 }
6691 }
6692}
6693
6694/* The function creates DFA(s) for fast pipeline hazards recognition
6695 after checking and simplifying IR of the description. */
6696static void
1a97be37 6697create_automata (void)
bea4bad2 6698{
6699 automaton_t curr_automaton;
6700 automaton_t prev_automaton;
6701 decl_t decl;
6702 int curr_automaton_num;
6703 int i;
6704
6705 if (automata_num != 0)
6706 {
6707 units_to_automata_heuristic_distr ();
6708 for (prev_automaton = NULL, curr_automaton_num = 0;
6709 curr_automaton_num < automata_num;
6710 curr_automaton_num++, prev_automaton = curr_automaton)
6711 {
65b198c2 6712 curr_automaton = XCREATENODE (struct automaton);
8043d8fb 6713 create_ainsns (curr_automaton);
bea4bad2 6714 curr_automaton->corresponding_automaton_decl = NULL;
6715 curr_automaton->next_automaton = NULL;
6716 curr_automaton->automaton_order_num = curr_automaton_num;
6717 if (prev_automaton == NULL)
6718 description->first_automaton = curr_automaton;
6719 else
6720 prev_automaton->next_automaton = curr_automaton;
6721 }
6722 }
6723 else
6724 {
6725 curr_automaton_num = 0;
6726 prev_automaton = NULL;
6727 for (i = 0; i < description->decls_num; i++)
6728 {
6729 decl = description->decls [i];
6730 if (decl->mode == dm_automaton
2f8ffd86 6731 && DECL_AUTOMATON (decl)->automaton_is_used)
bea4bad2 6732 {
65b198c2 6733 curr_automaton = XCREATENODE (struct automaton);
8043d8fb 6734 create_ainsns (curr_automaton);
bea4bad2 6735 curr_automaton->corresponding_automaton_decl
2f8ffd86 6736 = DECL_AUTOMATON (decl);
bea4bad2 6737 curr_automaton->next_automaton = NULL;
2f8ffd86 6738 DECL_AUTOMATON (decl)->corresponding_automaton = curr_automaton;
bea4bad2 6739 curr_automaton->automaton_order_num = curr_automaton_num;
6740 if (prev_automaton == NULL)
6741 description->first_automaton = curr_automaton;
6742 else
6743 prev_automaton->next_automaton = curr_automaton;
6744 curr_automaton_num++;
6745 prev_automaton = curr_automaton;
6746 }
6747 }
6748 if (curr_automaton_num == 0)
6749 {
65b198c2 6750 curr_automaton = XCREATENODE (struct automaton);
8043d8fb 6751 create_ainsns (curr_automaton);
bea4bad2 6752 curr_automaton->corresponding_automaton_decl = NULL;
6753 curr_automaton->next_automaton = NULL;
6754 description->first_automaton = curr_automaton;
6755 }
6756 units_to_automata_distr ();
6757 }
6758 NDFA_time = create_ticker ();
6759 ticker_off (&NDFA_time);
6760 NDFA_to_DFA_time = create_ticker ();
6761 ticker_off (&NDFA_to_DFA_time);
6762 minimize_time = create_ticker ();
6763 ticker_off (&minimize_time);
6764 equiv_time = create_ticker ();
6765 ticker_off (&equiv_time);
6766 for (curr_automaton = description->first_automaton;
6767 curr_automaton != NULL;
6768 curr_automaton = curr_automaton->next_automaton)
6769 {
bccc9ebc 6770 if (progress_flag)
6771 {
6772 if (curr_automaton->corresponding_automaton_decl == NULL)
6773 fprintf (stderr, "Prepare anonymous automaton creation ... ");
6774 else
6775 fprintf (stderr, "Prepare automaton `%s' creation...",
6776 curr_automaton->corresponding_automaton_decl->name);
6777 }
bea4bad2 6778 create_alt_states (curr_automaton);
6779 form_ainsn_with_same_reservs (curr_automaton);
bccc9ebc 6780 if (progress_flag)
6781 fprintf (stderr, "done\n");
bea4bad2 6782 build_automaton (curr_automaton);
6783 enumerate_states (curr_automaton);
6784 ticker_on (&equiv_time);
6785 set_insn_equiv_classes (curr_automaton);
6786 ticker_off (&equiv_time);
bea4bad2 6787 }
6788}
6789
6790\f
6791
6792/* This page contains code for forming string representation of
6793 regexp. The representation is formed on IR obstack. So you should
6794 not work with IR obstack between regexp_representation and
6795 finish_regexp_representation calls. */
6796
6797/* This recursive function forms string representation of regexp
6798 (without tailing '\0'). */
6799static void
1a97be37 6800form_regexp (regexp_t regexp)
bea4bad2 6801{
6802 int i;
1a97be37 6803
e0a4c0c2 6804 switch (regexp->mode)
bea4bad2 6805 {
e0a4c0c2 6806 case rm_unit: case rm_reserv:
bea4bad2 6807 {
e0a4c0c2 6808 const char *name = (regexp->mode == rm_unit
6809 ? REGEXP_UNIT (regexp)->name
6810 : REGEXP_RESERV (regexp)->name);
48e1416a 6811
e0a4c0c2 6812 obstack_grow (&irp, name, strlen (name));
6813 break;
bea4bad2 6814 }
48e1416a 6815
e0a4c0c2 6816 case rm_sequence:
6817 for (i = 0; i < REGEXP_SEQUENCE (regexp)->regexps_num; i++)
6818 {
6819 if (i != 0)
6820 obstack_1grow (&irp, ',');
6821 form_regexp (REGEXP_SEQUENCE (regexp)->regexps [i]);
6822 }
6823 break;
6824
6825 case rm_allof:
bea4bad2 6826 obstack_1grow (&irp, '(');
2f8ffd86 6827 for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
bea4bad2 6828 {
6829 if (i != 0)
6830 obstack_1grow (&irp, '+');
2f8ffd86 6831 if (REGEXP_ALLOF (regexp)->regexps[i]->mode == rm_sequence
6832 || REGEXP_ALLOF (regexp)->regexps[i]->mode == rm_oneof)
bea4bad2 6833 obstack_1grow (&irp, '(');
2f8ffd86 6834 form_regexp (REGEXP_ALLOF (regexp)->regexps [i]);
6835 if (REGEXP_ALLOF (regexp)->regexps[i]->mode == rm_sequence
6836 || REGEXP_ALLOF (regexp)->regexps[i]->mode == rm_oneof)
bea4bad2 6837 obstack_1grow (&irp, ')');
6838 }
6839 obstack_1grow (&irp, ')');
e0a4c0c2 6840 break;
48e1416a 6841
e0a4c0c2 6842 case rm_oneof:
6843 for (i = 0; i < REGEXP_ONEOF (regexp)->regexps_num; i++)
6844 {
6845 if (i != 0)
6846 obstack_1grow (&irp, '|');
6847 if (REGEXP_ONEOF (regexp)->regexps[i]->mode == rm_sequence)
6848 obstack_1grow (&irp, '(');
6849 form_regexp (REGEXP_ONEOF (regexp)->regexps [i]);
6850 if (REGEXP_ONEOF (regexp)->regexps[i]->mode == rm_sequence)
bea4bad2 6851 obstack_1grow (&irp, ')');
e0a4c0c2 6852 }
6853 break;
48e1416a 6854
e0a4c0c2 6855 case rm_repeat:
6856 {
6857 char digits [30];
48e1416a 6858
e0a4c0c2 6859 if (REGEXP_REPEAT (regexp)->regexp->mode == rm_sequence
6860 || REGEXP_REPEAT (regexp)->regexp->mode == rm_allof
6861 || REGEXP_REPEAT (regexp)->regexp->mode == rm_oneof)
6862 obstack_1grow (&irp, '(');
6863 form_regexp (REGEXP_REPEAT (regexp)->regexp);
6864 if (REGEXP_REPEAT (regexp)->regexp->mode == rm_sequence
6865 || REGEXP_REPEAT (regexp)->regexp->mode == rm_allof
6866 || REGEXP_REPEAT (regexp)->regexp->mode == rm_oneof)
6867 obstack_1grow (&irp, ')');
6868 sprintf (digits, "*%d", REGEXP_REPEAT (regexp)->repeat_num);
6869 obstack_grow (&irp, digits, strlen (digits));
6870 break;
bea4bad2 6871 }
e0a4c0c2 6872
6873 case rm_nothing:
6874 obstack_grow (&irp, NOTHING_NAME, strlen (NOTHING_NAME));
6875 break;
6876
6877 default:
6878 gcc_unreachable ();
6879 }
bea4bad2 6880}
6881
6882/* The function returns string representation of REGEXP on IR
6883 obstack. */
6884static const char *
1a97be37 6885regexp_representation (regexp_t regexp)
bea4bad2 6886{
6887 form_regexp (regexp);
6888 obstack_1grow (&irp, '\0');
6889 return obstack_base (&irp);
6890}
6891
6892/* The function frees memory allocated for last formed string
6893 representation of regexp. */
6894static void
1a97be37 6895finish_regexp_representation (void)
bea4bad2 6896{
6897 int length = obstack_object_size (&irp);
1a97be37 6898
bea4bad2 6899 obstack_blank_fast (&irp, -length);
6900}
6901
6902\f
6903
6904/* This page contains code for output PHR (pipeline hazards recognizer). */
6905
6906/* The function outputs minimal C type which is sufficient for
6907 representation numbers in range min_range_value and
6908 max_range_value. Because host machine and build machine may be
6909 different, we use here minimal values required by ANSI C standard
6910 instead of UCHAR_MAX, SHRT_MAX, SHRT_MIN, etc. This is a good
6911 approximation. */
6912
6913static void
1a97be37 6914output_range_type (FILE *f, long int min_range_value,
6915 long int max_range_value)
bea4bad2 6916{
6917 if (min_range_value >= 0 && max_range_value <= 255)
6918 fprintf (f, "unsigned char");
6919 else if (min_range_value >= -127 && max_range_value <= 127)
6920 fprintf (f, "signed char");
6921 else if (min_range_value >= 0 && max_range_value <= 65535)
6922 fprintf (f, "unsigned short");
6923 else if (min_range_value >= -32767 && max_range_value <= 32767)
6924 fprintf (f, "short");
6925 else
6926 fprintf (f, "int");
6927}
6928
e7827cef 6929/* The function outputs all initialization values of VECT. */
bea4bad2 6930static void
e7827cef 6931output_vect (vla_hwint_t vect)
bea4bad2 6932{
6933 int els_on_line;
f1f41a6c 6934 size_t vect_length = vect.length ();
e7827cef 6935 size_t i;
bea4bad2 6936
6937 els_on_line = 1;
6938 if (vect_length == 0)
e7827cef 6939 fputs ("0 /* This is dummy el because the vect is empty */", output_file);
bea4bad2 6940 else
e7827cef 6941 for (i = 0; i < vect_length; i++)
6942 {
f1f41a6c 6943 fprintf (output_file, "%5ld", (long) vect[i]);
e7827cef 6944 if (els_on_line == 10)
6945 {
6946 els_on_line = 0;
6947 fputs (",\n", output_file);
6948 }
6949 else if (i < vect_length-1)
6950 fputs (", ", output_file);
6951 els_on_line++;
6952 }
bea4bad2 6953}
6954
6955/* The following is name of the structure which represents DFA(s) for
6956 PHR. */
6957#define CHIP_NAME "DFA_chip"
6958
6959/* The following is name of member which represents state of a DFA for
6960 PHR. */
6961static void
1a97be37 6962output_chip_member_name (FILE *f, automaton_t automaton)
bea4bad2 6963{
6964 if (automaton->corresponding_automaton_decl == NULL)
6965 fprintf (f, "automaton_state_%d", automaton->automaton_order_num);
6966 else
6967 fprintf (f, "%s_automaton_state",
6968 automaton->corresponding_automaton_decl->name);
6969}
6970
6971/* The following is name of temporary variable which stores state of a
6972 DFA for PHR. */
6973static void
1a97be37 6974output_temp_chip_member_name (FILE *f, automaton_t automaton)
bea4bad2 6975{
6976 fprintf (f, "_");
6977 output_chip_member_name (f, automaton);
6978}
6979
8043d8fb 6980/* This is name of macro value which is code of pseudo_insns
6981 representing advancing cpu cycle and collapsing the NDFA.
6982 Its value is used as internal code unknown insn. */
bea4bad2 6983#define ADVANCE_CYCLE_VALUE_NAME "DFA__ADVANCE_CYCLE"
8043d8fb 6984#define COLLAPSE_NDFA_VALUE_NAME "NDFA__COLLAPSE"
bea4bad2 6985
6986/* Output name of translate vector for given automaton. */
6987static void
1a97be37 6988output_translate_vect_name (FILE *f, automaton_t automaton)
bea4bad2 6989{
6990 if (automaton->corresponding_automaton_decl == NULL)
6991 fprintf (f, "translate_%d", automaton->automaton_order_num);
6992 else
6993 fprintf (f, "%s_translate", automaton->corresponding_automaton_decl->name);
6994}
6995
6996/* Output name for simple transition table representation. */
6997static void
1a97be37 6998output_trans_full_vect_name (FILE *f, automaton_t automaton)
bea4bad2 6999{
7000 if (automaton->corresponding_automaton_decl == NULL)
7001 fprintf (f, "transitions_%d", automaton->automaton_order_num);
7002 else
7003 fprintf (f, "%s_transitions",
7004 automaton->corresponding_automaton_decl->name);
7005}
7006
7007/* Output name of comb vector of the transition table for given
7008 automaton. */
7009static void
1a97be37 7010output_trans_comb_vect_name (FILE *f, automaton_t automaton)
bea4bad2 7011{
7012 if (automaton->corresponding_automaton_decl == NULL)
7013 fprintf (f, "transitions_%d", automaton->automaton_order_num);
7014 else
7015 fprintf (f, "%s_transitions",
7016 automaton->corresponding_automaton_decl->name);
7017}
7018
7019/* Output name of check vector of the transition table for given
7020 automaton. */
7021static void
1a97be37 7022output_trans_check_vect_name (FILE *f, automaton_t automaton)
bea4bad2 7023{
7024 if (automaton->corresponding_automaton_decl == NULL)
7025 fprintf (f, "check_%d", automaton->automaton_order_num);
7026 else
7027 fprintf (f, "%s_check", automaton->corresponding_automaton_decl->name);
7028}
7029
7030/* Output name of base vector of the transition table for given
7031 automaton. */
7032static void
1a97be37 7033output_trans_base_vect_name (FILE *f, automaton_t automaton)
bea4bad2 7034{
7035 if (automaton->corresponding_automaton_decl == NULL)
7036 fprintf (f, "base_%d", automaton->automaton_order_num);
7037 else
7038 fprintf (f, "%s_base", automaton->corresponding_automaton_decl->name);
7039}
7040
bea4bad2 7041/* Output name of simple min issue delay table representation. */
7042static void
1a97be37 7043output_min_issue_delay_vect_name (FILE *f, automaton_t automaton)
bea4bad2 7044{
7045 if (automaton->corresponding_automaton_decl == NULL)
7046 fprintf (f, "min_issue_delay_%d", automaton->automaton_order_num);
7047 else
7048 fprintf (f, "%s_min_issue_delay",
7049 automaton->corresponding_automaton_decl->name);
7050}
7051
7052/* Output name of deadlock vector for given automaton. */
7053static void
1a97be37 7054output_dead_lock_vect_name (FILE *f, automaton_t automaton)
bea4bad2 7055{
7056 if (automaton->corresponding_automaton_decl == NULL)
7057 fprintf (f, "dead_lock_%d", automaton->automaton_order_num);
7058 else
7059 fprintf (f, "%s_dead_lock", automaton->corresponding_automaton_decl->name);
7060}
7061
7062/* Output name of reserved units table for AUTOMATON into file F. */
7063static void
1a97be37 7064output_reserved_units_table_name (FILE *f, automaton_t automaton)
bea4bad2 7065{
7066 if (automaton->corresponding_automaton_decl == NULL)
7067 fprintf (f, "reserved_units_%d", automaton->automaton_order_num);
7068 else
7069 fprintf (f, "%s_reserved_units",
7070 automaton->corresponding_automaton_decl->name);
7071}
7072
bea4bad2 7073/* Name of the PHR interface macro. */
7074#define CPU_UNITS_QUERY_MACRO_NAME "CPU_UNITS_QUERY"
7075
7076/* Names of an internal functions: */
7077#define INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME "internal_min_issue_delay"
7078
7079/* This is external type of DFA(s) state. */
7080#define STATE_TYPE_NAME "state_t"
7081
7082#define INTERNAL_TRANSITION_FUNC_NAME "internal_state_transition"
7083
bea4bad2 7084#define INTERNAL_RESET_FUNC_NAME "internal_reset"
7085
7086#define INTERNAL_DEAD_LOCK_FUNC_NAME "internal_state_dead_lock_p"
7087
7088#define INTERNAL_INSN_LATENCY_FUNC_NAME "internal_insn_latency"
7089
7090/* Name of cache of insn dfa codes. */
7091#define DFA_INSN_CODES_VARIABLE_NAME "dfa_insn_codes"
7092
b35eefd9 7093/* Name of length of cache of insn dfa codes. */
bea4bad2 7094#define DFA_INSN_CODES_LENGTH_VARIABLE_NAME "dfa_insn_codes_length"
7095
7096/* Names of the PHR interface functions: */
7097#define SIZE_FUNC_NAME "state_size"
7098
7099#define TRANSITION_FUNC_NAME "state_transition"
7100
bea4bad2 7101#define MIN_ISSUE_DELAY_FUNC_NAME "min_issue_delay"
7102
7103#define MIN_INSN_CONFLICT_DELAY_FUNC_NAME "min_insn_conflict_delay"
7104
7105#define DEAD_LOCK_FUNC_NAME "state_dead_lock_p"
7106
7107#define RESET_FUNC_NAME "state_reset"
7108
7109#define INSN_LATENCY_FUNC_NAME "insn_latency"
7110
7111#define PRINT_RESERVATION_FUNC_NAME "print_reservation"
7112
7113#define GET_CPU_UNIT_CODE_FUNC_NAME "get_cpu_unit_code"
7114
7115#define CPU_UNIT_RESERVATION_P_FUNC_NAME "cpu_unit_reservation_p"
7116
07317795 7117#define INSN_HAS_DFA_RESERVATION_P_FUNC_NAME "insn_has_dfa_reservation_p"
7118
58ada791 7119#define DFA_CLEAN_INSN_CACHE_FUNC_NAME "dfa_clean_insn_cache"
7120
6a1cdb4d 7121#define DFA_CLEAR_SINGLE_INSN_CACHE_FUNC_NAME "dfa_clear_single_insn_cache"
7122
bea4bad2 7123#define DFA_START_FUNC_NAME "dfa_start"
7124
7125#define DFA_FINISH_FUNC_NAME "dfa_finish"
7126
7127/* Names of parameters of the PHR interface functions. */
7128#define STATE_NAME "state"
7129
7130#define INSN_PARAMETER_NAME "insn"
7131
7132#define INSN2_PARAMETER_NAME "insn2"
7133
7134#define CHIP_PARAMETER_NAME "chip"
7135
7136#define FILE_PARAMETER_NAME "f"
7137
7138#define CPU_UNIT_NAME_PARAMETER_NAME "cpu_unit_name"
7139
7140#define CPU_CODE_PARAMETER_NAME "cpu_unit_code"
7141
7142/* Names of the variables whose values are internal insn code of rtx
7143 insn. */
7144#define INTERNAL_INSN_CODE_NAME "insn_code"
7145
7146#define INTERNAL_INSN2_CODE_NAME "insn2_code"
7147
7148/* Names of temporary variables in some functions. */
7149#define TEMPORARY_VARIABLE_NAME "temp"
7150
7151#define I_VARIABLE_NAME "i"
7152
7153/* Name of result variable in some functions. */
7154#define RESULT_VARIABLE_NAME "res"
7155
bea4bad2 7156/* Name of function (attribute) to translate insn into internal insn
7157 code. */
7158#define INTERNAL_DFA_INSN_CODE_FUNC_NAME "internal_dfa_insn_code"
7159
7160/* Name of function (attribute) to translate insn into internal insn
7161 code with caching. */
7162#define DFA_INSN_CODE_FUNC_NAME "dfa_insn_code"
7163
bea4bad2 7164/* Output C type which is used for representation of codes of states
7165 of AUTOMATON. */
7166static void
1a97be37 7167output_state_member_type (FILE *f, automaton_t automaton)
bea4bad2 7168{
7169 output_range_type (f, 0, automaton->achieved_states_num);
7170}
7171
7172/* Output definition of the structure representing current DFA(s)
7173 state(s). */
7174static void
1a97be37 7175output_chip_definitions (void)
bea4bad2 7176{
7177 automaton_t automaton;
7178
7179 fprintf (output_file, "struct %s\n{\n", CHIP_NAME);
7180 for (automaton = description->first_automaton;
7181 automaton != NULL;
7182 automaton = automaton->next_automaton)
7183 {
7184 fprintf (output_file, " ");
7185 output_state_member_type (output_file, automaton);
7186 fprintf (output_file, " ");
7187 output_chip_member_name (output_file, automaton);
7188 fprintf (output_file, ";\n");
7189 }
7190 fprintf (output_file, "};\n\n");
7191#if 0
7192 fprintf (output_file, "static struct %s %s;\n\n", CHIP_NAME, CHIP_NAME);
7193#endif
7194}
7195
7196
7197/* The function outputs translate vector of internal insn code into
7198 insn equivalence class number. The equivalence class number is
f503d902 7199 used to access to table and vectors representing DFA(s). */
bea4bad2 7200static void
1a97be37 7201output_translate_vect (automaton_t automaton)
bea4bad2 7202{
7203 ainsn_t ainsn;
7204 int insn_value;
7205 vla_hwint_t translate_vect;
7206
f1f41a6c 7207 translate_vect.create (description->insns_num);
e7827cef 7208
34701e91 7209 for (insn_value = 0; insn_value < description->insns_num; insn_value++)
bea4bad2 7210 /* Undefined value */
f1f41a6c 7211 translate_vect.quick_push (automaton->insn_equiv_classes_num);
e7827cef 7212
bea4bad2 7213 for (ainsn = automaton->ainsn_list; ainsn != NULL; ainsn = ainsn->next_ainsn)
f1f41a6c 7214 translate_vect[ainsn->insn_reserv_decl->insn_num] =
7215 ainsn->insn_equiv_class_num;
e7827cef 7216
bea4bad2 7217 fprintf (output_file,
7218 "/* Vector translating external insn codes to internal ones.*/\n");
7219 fprintf (output_file, "static const ");
7220 output_range_type (output_file, 0, automaton->insn_equiv_classes_num);
7221 fprintf (output_file, " ");
7222 output_translate_vect_name (output_file, automaton);
72d3c9a0 7223 fprintf (output_file, "[] ATTRIBUTE_UNUSED = {\n");
e7827cef 7224 output_vect (translate_vect);
bea4bad2 7225 fprintf (output_file, "};\n\n");
f1f41a6c 7226 translate_vect.release ();
bea4bad2 7227}
7228
7229/* The value in a table state x ainsn -> something which represents
7230 undefined value. */
7231static int undefined_vect_el_value;
7232
7233/* The following function returns nonzero value if the best
7234 representation of the table is comb vector. */
7235static int
1a97be37 7236comb_vect_p (state_ainsn_table_t tab)
bea4bad2 7237{
172b69d8 7238 if (no_comb_flag)
7239 return false;
f1f41a6c 7240 return (2 * tab->full_vect.length () > 5 * tab->comb_vect.length ());
bea4bad2 7241}
7242
7243/* The following function creates new table for AUTOMATON. */
7244static state_ainsn_table_t
1a97be37 7245create_state_ainsn_table (automaton_t automaton)
bea4bad2 7246{
7247 state_ainsn_table_t tab;
7248 int full_vect_length;
7249 int i;
7250
65b198c2 7251 tab = XCREATENODE (struct state_ainsn_table);
bea4bad2 7252 tab->automaton = automaton;
e7827cef 7253
f1f41a6c 7254 tab->comb_vect.create (10000);
7255 tab->check_vect.create (10000);
e7827cef 7256
f1f41a6c 7257 tab->base_vect.create (0);
7258 tab->base_vect.safe_grow (automaton->achieved_states_num);
e7827cef 7259
bea4bad2 7260 full_vect_length = (automaton->insn_equiv_classes_num
7261 * automaton->achieved_states_num);
f1f41a6c 7262 tab->full_vect.create (full_vect_length);
bea4bad2 7263 for (i = 0; i < full_vect_length; i++)
f1f41a6c 7264 tab->full_vect.quick_push (undefined_vect_el_value);
e7827cef 7265
bea4bad2 7266 tab->min_base_vect_el_value = 0;
7267 tab->max_base_vect_el_value = 0;
7268 tab->min_comb_vect_el_value = 0;
7269 tab->max_comb_vect_el_value = 0;
7270 return tab;
7271}
7272
7273/* The following function outputs the best C representation of the
7274 table TAB of given TABLE_NAME. */
7275static void
e7827cef 7276output_state_ainsn_table (state_ainsn_table_t tab, const char *table_name,
1a97be37 7277 void (*output_full_vect_name_func) (FILE *, automaton_t),
7278 void (*output_comb_vect_name_func) (FILE *, automaton_t),
7279 void (*output_check_vect_name_func) (FILE *, automaton_t),
7280 void (*output_base_vect_name_func) (FILE *, automaton_t))
bea4bad2 7281{
7282 if (!comb_vect_p (tab))
7283 {
7284 fprintf (output_file, "/* Vector for %s. */\n", table_name);
7285 fprintf (output_file, "static const ");
7286 output_range_type (output_file, tab->min_comb_vect_el_value,
7287 tab->max_comb_vect_el_value);
7288 fprintf (output_file, " ");
7289 (*output_full_vect_name_func) (output_file, tab->automaton);
72d3c9a0 7290 fprintf (output_file, "[] ATTRIBUTE_UNUSED = {\n");
e7827cef 7291 output_vect (tab->full_vect);
bea4bad2 7292 fprintf (output_file, "};\n\n");
7293 }
7294 else
7295 {
7296 fprintf (output_file, "/* Comb vector for %s. */\n", table_name);
7297 fprintf (output_file, "static const ");
7298 output_range_type (output_file, tab->min_comb_vect_el_value,
7299 tab->max_comb_vect_el_value);
7300 fprintf (output_file, " ");
7301 (*output_comb_vect_name_func) (output_file, tab->automaton);
72d3c9a0 7302 fprintf (output_file, "[] ATTRIBUTE_UNUSED = {\n");
e7827cef 7303 output_vect (tab->comb_vect);
bea4bad2 7304 fprintf (output_file, "};\n\n");
7305 fprintf (output_file, "/* Check vector for %s. */\n", table_name);
7306 fprintf (output_file, "static const ");
7307 output_range_type (output_file, 0, tab->automaton->achieved_states_num);
7308 fprintf (output_file, " ");
7309 (*output_check_vect_name_func) (output_file, tab->automaton);
7310 fprintf (output_file, "[] = {\n");
e7827cef 7311 output_vect (tab->check_vect);
bea4bad2 7312 fprintf (output_file, "};\n\n");
7313 fprintf (output_file, "/* Base vector for %s. */\n", table_name);
7314 fprintf (output_file, "static const ");
7315 output_range_type (output_file, tab->min_base_vect_el_value,
7316 tab->max_base_vect_el_value);
7317 fprintf (output_file, " ");
7318 (*output_base_vect_name_func) (output_file, tab->automaton);
7319 fprintf (output_file, "[] = {\n");
e7827cef 7320 output_vect (tab->base_vect);
bea4bad2 7321 fprintf (output_file, "};\n\n");
7322 }
7323}
7324
e7827cef 7325/* The following function adds vector VECT to table TAB as its line
7326 with number VECT_NUM. */
bea4bad2 7327static void
e7827cef 7328add_vect (state_ainsn_table_t tab, int vect_num, vla_hwint_t vect)
bea4bad2 7329{
e7827cef 7330 int vect_length;
7331 size_t real_vect_length;
bea4bad2 7332 int comb_vect_index;
7333 int comb_vect_els_num;
7334 int vect_index;
7335 int first_unempty_vect_index;
7336 int additional_els_num;
7337 int no_state_value;
7338 vect_el_t vect_el;
7339 int i;
8f00993e 7340 unsigned long vect_mask, comb_vect_mask;
bea4bad2 7341
f1f41a6c 7342 vect_length = vect.length ();
e0a4c0c2 7343 gcc_assert (vect_length);
f1f41a6c 7344 gcc_assert (vect.last () != undefined_vect_el_value);
bea4bad2 7345 real_vect_length = tab->automaton->insn_equiv_classes_num;
bea4bad2 7346 /* Form full vector in the table: */
e7827cef 7347 {
7348 size_t full_base = tab->automaton->insn_equiv_classes_num * vect_num;
f1f41a6c 7349 if (tab->full_vect.length () < full_base + vect_length)
7350 tab->full_vect.safe_grow (full_base + vect_length);
e7827cef 7351 for (i = 0; i < vect_length; i++)
f1f41a6c 7352 tab->full_vect[full_base + i] = vect[i];
e7827cef 7353 }
172b69d8 7354
7355 /* The comb_vect min/max values are also used for the full vector, so
7356 compute them now. */
7357 for (vect_index = 0; vect_index < vect_length; vect_index++)
f1f41a6c 7358 if (vect[vect_index] != undefined_vect_el_value)
172b69d8 7359 {
f1f41a6c 7360 vect_el_t x = vect[vect_index];
172b69d8 7361 gcc_assert (x >= 0);
7362 if (tab->max_comb_vect_el_value < x)
7363 tab->max_comb_vect_el_value = x;
7364 if (tab->min_comb_vect_el_value > x)
7365 tab->min_comb_vect_el_value = x;
7366 }
7367 if (no_comb_flag)
7368 return;
7369
bea4bad2 7370 /* Form comb vector in the table: */
f1f41a6c 7371 gcc_assert (tab->comb_vect.length () == tab->check_vect.length ());
e7827cef 7372
f1f41a6c 7373 comb_vect_els_num = tab->comb_vect.length ();
bea4bad2 7374 for (first_unempty_vect_index = 0;
7375 first_unempty_vect_index < vect_length;
7376 first_unempty_vect_index++)
f1f41a6c 7377 if (vect[first_unempty_vect_index]
e7827cef 7378 != undefined_vect_el_value)
bea4bad2 7379 break;
8f00993e 7380
bea4bad2 7381 /* Search for the place in comb vect for the inserted vect. */
8f00993e 7382
7383 /* Slow case. */
7384 if (vect_length - first_unempty_vect_index >= SIZEOF_LONG * CHAR_BIT)
7385 {
7386 for (comb_vect_index = 0;
7387 comb_vect_index < comb_vect_els_num;
7388 comb_vect_index++)
7389 {
7390 for (vect_index = first_unempty_vect_index;
7391 vect_index < vect_length
7392 && vect_index + comb_vect_index < comb_vect_els_num;
7393 vect_index++)
f1f41a6c 7394 if (vect[vect_index]
e7827cef 7395 != undefined_vect_el_value
f1f41a6c 7396 && (tab->comb_vect[vect_index + comb_vect_index]
8f00993e 7397 != undefined_vect_el_value))
7398 break;
7399 if (vect_index >= vect_length
7400 || vect_index + comb_vect_index >= comb_vect_els_num)
7401 break;
7402 }
7403 goto found;
bea4bad2 7404 }
8f00993e 7405
7406 /* Fast case. */
7407 vect_mask = 0;
7408 for (vect_index = first_unempty_vect_index;
7409 vect_index < vect_length;
7410 vect_index++)
7411 {
7412 vect_mask = vect_mask << 1;
f1f41a6c 7413 if (vect[vect_index] != undefined_vect_el_value)
8f00993e 7414 vect_mask |= 1;
7415 }
7416
7417 /* Search for the place in comb vect for the inserted vect. */
7418 comb_vect_index = 0;
7419 if (comb_vect_els_num == 0)
7420 goto found;
7421
7422 comb_vect_mask = 0;
7423 for (vect_index = first_unempty_vect_index;
7424 vect_index < vect_length && vect_index < comb_vect_els_num;
7425 vect_index++)
7426 {
7427 comb_vect_mask <<= 1;
7428 if (vect_index + comb_vect_index < comb_vect_els_num
f1f41a6c 7429 && tab->comb_vect[vect_index + comb_vect_index]
8f00993e 7430 != undefined_vect_el_value)
7431 comb_vect_mask |= 1;
7432 }
7433 if ((vect_mask & comb_vect_mask) == 0)
7434 goto found;
7435
7436 for (comb_vect_index = 1, i = vect_length; i < comb_vect_els_num;
7437 comb_vect_index++, i++)
7438 {
7439 comb_vect_mask = (comb_vect_mask << 1) | 1;
f1f41a6c 7440 comb_vect_mask ^= (tab->comb_vect[i]
e7827cef 7441 == undefined_vect_el_value);
8f00993e 7442 if ((vect_mask & comb_vect_mask) == 0)
7443 goto found;
7444 }
7445 for ( ; comb_vect_index < comb_vect_els_num; comb_vect_index++)
7446 {
7447 comb_vect_mask <<= 1;
7448 if ((vect_mask & comb_vect_mask) == 0)
7449 goto found;
7450 }
7451
e0a4c0c2 7452 found:
bea4bad2 7453 /* Slot was found. */
7454 additional_els_num = comb_vect_index + real_vect_length - comb_vect_els_num;
7455 if (additional_els_num < 0)
7456 additional_els_num = 0;
7457 /* Expand comb and check vectors. */
7458 vect_el = undefined_vect_el_value;
7459 no_state_value = tab->automaton->achieved_states_num;
7460 while (additional_els_num > 0)
7461 {
f1f41a6c 7462 tab->comb_vect.safe_push (vect_el);
7463 tab->check_vect.safe_push (no_state_value);
bea4bad2 7464 additional_els_num--;
7465 }
f1f41a6c 7466 gcc_assert (tab->comb_vect.length ()
e7827cef 7467 >= comb_vect_index + real_vect_length);
bea4bad2 7468 /* Fill comb and check vectors. */
7469 for (vect_index = 0; vect_index < vect_length; vect_index++)
f1f41a6c 7470 if (vect[vect_index] != undefined_vect_el_value)
bea4bad2 7471 {
f1f41a6c 7472 vect_el_t x = vect[vect_index];
7473 gcc_assert (tab->comb_vect[comb_vect_index + vect_index]
e0a4c0c2 7474 == undefined_vect_el_value);
e7827cef 7475 gcc_assert (x >= 0);
f1f41a6c 7476 tab->comb_vect[comb_vect_index + vect_index] = x;
7477 tab->check_vect[comb_vect_index + vect_index] = vect_num;
bea4bad2 7478 }
c9407b73 7479 if (tab->max_comb_vect_el_value < undefined_vect_el_value)
7480 tab->max_comb_vect_el_value = undefined_vect_el_value;
7481 if (tab->min_comb_vect_el_value > undefined_vect_el_value)
7482 tab->min_comb_vect_el_value = undefined_vect_el_value;
bea4bad2 7483 if (tab->max_base_vect_el_value < comb_vect_index)
7484 tab->max_base_vect_el_value = comb_vect_index;
7485 if (tab->min_base_vect_el_value > comb_vect_index)
7486 tab->min_base_vect_el_value = comb_vect_index;
e7827cef 7487
f1f41a6c 7488 tab->base_vect[vect_num] = comb_vect_index;
bea4bad2 7489}
7490
7491/* Return number of out arcs of STATE. */
7492static int
aae87fc3 7493out_state_arcs_num (const_state_t state)
bea4bad2 7494{
7495 int result;
7496 arc_t arc;
7497
7498 result = 0;
7499 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
7500 {
e0a4c0c2 7501 gcc_assert (arc->insn);
069eea26 7502 if (arc->insn->first_ainsn_with_given_equivalence_num)
bea4bad2 7503 result++;
7504 }
7505 return result;
7506}
7507
7508/* Compare number of possible transitions from the states. */
7509static int
1a97be37 7510compare_transition_els_num (const void *state_ptr_1,
7511 const void *state_ptr_2)
bea4bad2 7512{
aae87fc3 7513 const int transition_els_num_1
7514 = out_state_arcs_num (*(const_state_t const*) state_ptr_1);
7515 const int transition_els_num_2
7516 = out_state_arcs_num (*(const_state_t const*) state_ptr_2);
bea4bad2 7517
bea4bad2 7518 if (transition_els_num_1 < transition_els_num_2)
7519 return 1;
7520 else if (transition_els_num_1 == transition_els_num_2)
7521 return 0;
7522 else
7523 return -1;
7524}
7525
7526/* The function adds element EL_VALUE to vector VECT for a table state
7527 x AINSN. */
7528static void
f1f41a6c 7529add_vect_el (vla_hwint_t &vect, ainsn_t ainsn, int el_value)
bea4bad2 7530{
7531 int equiv_class_num;
7532 int vect_index;
7533
e0a4c0c2 7534 gcc_assert (ainsn);
bea4bad2 7535 equiv_class_num = ainsn->insn_equiv_class_num;
f1f41a6c 7536 for (vect_index = vect.length ();
bea4bad2 7537 vect_index <= equiv_class_num;
7538 vect_index++)
f1f41a6c 7539 vect.safe_push (undefined_vect_el_value);
7540 vect[equiv_class_num] = el_value;
bea4bad2 7541}
7542
7543/* This is for forming vector of states of an automaton. */
f1f41a6c 7544static vec<state_t> output_states_vect;
bea4bad2 7545
7546/* The function is called by function pass_states. The function adds
7547 STATE to `output_states_vect'. */
7548static void
1a97be37 7549add_states_vect_el (state_t state)
bea4bad2 7550{
f1f41a6c 7551 output_states_vect.safe_push (state);
bea4bad2 7552}
7553
7554/* Form and output vectors (comb, check, base or full vector)
7555 representing transition table of AUTOMATON. */
7556static void
1a97be37 7557output_trans_table (automaton_t automaton)
bea4bad2 7558{
e7827cef 7559 size_t i;
bea4bad2 7560 arc_t arc;
9af5ce0c 7561 vla_hwint_t transition_vect = vla_hwint_t ();
bea4bad2 7562
7563 undefined_vect_el_value = automaton->achieved_states_num;
7564 automaton->trans_table = create_state_ainsn_table (automaton);
7565 /* Create vect of pointers to states ordered by num of transitions
7566 from the state (state with the maximum num is the first). */
f1f41a6c 7567 output_states_vect.create (0);
bea4bad2 7568 pass_states (automaton, add_states_vect_el);
f1f41a6c 7569 output_states_vect.qsort (compare_transition_els_num);
e7827cef 7570
f1f41a6c 7571 for (i = 0; i < output_states_vect.length (); i++)
bea4bad2 7572 {
f1f41a6c 7573 transition_vect.truncate (0);
7574 for (arc = first_out_arc (output_states_vect[i]);
bea4bad2 7575 arc != NULL;
7576 arc = next_out_arc (arc))
7577 {
e0a4c0c2 7578 gcc_assert (arc->insn);
069eea26 7579 if (arc->insn->first_ainsn_with_given_equivalence_num)
f1f41a6c 7580 add_vect_el (transition_vect, arc->insn,
bea4bad2 7581 arc->to_state->order_state_num);
7582 }
e7827cef 7583 add_vect (automaton->trans_table,
f1f41a6c 7584 output_states_vect[i]->order_state_num,
e7827cef 7585 transition_vect);
bea4bad2 7586 }
7587 output_state_ainsn_table
e7827cef 7588 (automaton->trans_table, "state transitions",
bea4bad2 7589 output_trans_full_vect_name, output_trans_comb_vect_name,
7590 output_trans_check_vect_name, output_trans_base_vect_name);
e7827cef 7591
f1f41a6c 7592 output_states_vect.release ();
7593 transition_vect.release ();
bea4bad2 7594}
7595
bea4bad2 7596/* Form and output vectors representing minimal issue delay table of
7597 AUTOMATON. The table is state x ainsn -> minimal issue delay of
7598 the ainsn. */
7599static void
1a97be37 7600output_min_issue_delay_table (automaton_t automaton)
bea4bad2 7601{
7602 vla_hwint_t min_issue_delay_vect;
7603 vla_hwint_t compressed_min_issue_delay_vect;
bea4bad2 7604 ainsn_t ainsn;
4618c188 7605 size_t i;
7606 size_t min_issue_delay_len, compressed_min_issue_delay_len;
e7827cef 7607 size_t cfactor;
4618c188 7608 int changed;
bea4bad2 7609
7610 /* Create vect of pointers to states ordered by num of transitions
7611 from the state (state with the maximum num is the first). */
f1f41a6c 7612 output_states_vect.create (0);
bea4bad2 7613 pass_states (automaton, add_states_vect_el);
e7827cef 7614
f1f41a6c 7615 min_issue_delay_len = (output_states_vect.length ()
e7827cef 7616 * automaton->insn_equiv_classes_num);
f1f41a6c 7617 min_issue_delay_vect.create (min_issue_delay_len);
e7827cef 7618 for (i = 0; i < min_issue_delay_len; i++)
f1f41a6c 7619 min_issue_delay_vect.quick_push (-1);
e7827cef 7620
bea4bad2 7621 automaton->max_min_delay = 0;
4618c188 7622
7623 do
7624 {
7625 size_t state_no;
7626
7627 changed = 0;
7628
f1f41a6c 7629 for (state_no = 0; state_no < output_states_vect.length ();
4618c188 7630 state_no++)
7631 {
f1f41a6c 7632 state_t s = output_states_vect[state_no];
4618c188 7633 arc_t arc;
7634
7635 for (arc = first_out_arc (s); arc; arc = next_out_arc (arc))
7636 {
7637 int k;
7638
7639 size_t asn = s->order_state_num
7640 * automaton->insn_equiv_classes_num
7641 + arc->insn->insn_equiv_class_num;
7642
f1f41a6c 7643 if (min_issue_delay_vect[asn])
4618c188 7644 {
f1f41a6c 7645 min_issue_delay_vect[asn] = (vect_el_t) 0;
4618c188 7646 changed = 1;
7647 }
7648
7649 for (k = 0; k < automaton->insn_equiv_classes_num; k++)
7650 {
7651 size_t n0, n1;
7652 vect_el_t delay0, delay1;
7653
7654 n0 = s->order_state_num
7655 * automaton->insn_equiv_classes_num
7656 + k;
7657 n1 = arc->to_state->order_state_num
7658 * automaton->insn_equiv_classes_num
7659 + k;
f1f41a6c 7660 delay0 = min_issue_delay_vect[n0];
7661 delay1 = min_issue_delay_vect[n1];
4618c188 7662 if (delay1 != -1)
7663 {
7664 if (arc->insn->insn_reserv_decl
7665 == DECL_INSN_RESERV (advance_cycle_insn_decl))
7666 delay1++;
7667 if (delay1 < delay0 || delay0 == -1)
7668 {
f1f41a6c 7669 min_issue_delay_vect[n0] = delay1;
4618c188 7670 changed = 1;
7671 }
7672 }
7673 }
7674 }
7675 }
7676 }
7677 while (changed);
7678
7679 automaton->max_min_delay = 0;
7680
7681 for (ainsn = automaton->ainsn_list; ainsn; ainsn = ainsn->next_ainsn)
069eea26 7682 if (ainsn->first_ainsn_with_given_equivalence_num)
7b6da3db 7683 {
f1f41a6c 7684 for (i = 0; i < output_states_vect.length (); i++)
7b6da3db 7685 {
f1f41a6c 7686 state_t s = output_states_vect[i];
4618c188 7687 size_t np = s->order_state_num
7688 * automaton->insn_equiv_classes_num
7689 + ainsn->insn_equiv_class_num;
f1f41a6c 7690 vect_el_t x = min_issue_delay_vect[np];
4618c188 7691
7692 if (automaton->max_min_delay < x)
7693 automaton->max_min_delay = x;
7694 if (x == -1)
f1f41a6c 7695 min_issue_delay_vect[np] = (vect_el_t) 0;
bea4bad2 7696 }
7b6da3db 7697 }
4618c188 7698
58ada791 7699 fprintf (output_file, "/* Vector of min issue delay of insns. */\n");
bea4bad2 7700 fprintf (output_file, "static const ");
7701 output_range_type (output_file, 0, automaton->max_min_delay);
7702 fprintf (output_file, " ");
7703 output_min_issue_delay_vect_name (output_file, automaton);
72d3c9a0 7704 fprintf (output_file, "[] ATTRIBUTE_UNUSED = {\n");
2358393e 7705 /* Compress the vector. */
bea4bad2 7706 if (automaton->max_min_delay < 2)
e7827cef 7707 cfactor = 8;
bea4bad2 7708 else if (automaton->max_min_delay < 4)
e7827cef 7709 cfactor = 4;
bea4bad2 7710 else if (automaton->max_min_delay < 16)
e7827cef 7711 cfactor = 2;
bea4bad2 7712 else
e7827cef 7713 cfactor = 1;
7714 automaton->min_issue_delay_table_compression_factor = cfactor;
7715
7716 compressed_min_issue_delay_len = (min_issue_delay_len+cfactor-1) / cfactor;
f1f41a6c 7717 compressed_min_issue_delay_vect.create (compressed_min_issue_delay_len);
e7827cef 7718
7719 for (i = 0; i < compressed_min_issue_delay_len; i++)
f1f41a6c 7720 compressed_min_issue_delay_vect.quick_push (0);
e7827cef 7721
7722 for (i = 0; i < min_issue_delay_len; i++)
7723 {
7724 size_t ci = i / cfactor;
f1f41a6c 7725 vect_el_t x = min_issue_delay_vect[i];
7726 vect_el_t cx = compressed_min_issue_delay_vect[ci];
e7827cef 7727
7728 cx |= x << (8 - (i % cfactor + 1) * (8 / cfactor));
f1f41a6c 7729 compressed_min_issue_delay_vect[ci] = cx;
e7827cef 7730 }
7731 output_vect (compressed_min_issue_delay_vect);
bea4bad2 7732 fprintf (output_file, "};\n\n");
f1f41a6c 7733 output_states_vect.release ();
7734 min_issue_delay_vect.release ();
7735 compressed_min_issue_delay_vect.release ();
bea4bad2 7736}
7737
bea4bad2 7738/* Form and output vector representing the locked states of
7739 AUTOMATON. */
7740static void
1a97be37 7741output_dead_lock_vect (automaton_t automaton)
bea4bad2 7742{
e7827cef 7743 size_t i;
bea4bad2 7744 arc_t arc;
9af5ce0c 7745 vla_hwint_t dead_lock_vect = vla_hwint_t ();
bea4bad2 7746
7747 /* Create vect of pointers to states ordered by num of
7748 transitions from the state (state with the maximum num is the
7749 first). */
c966a2e2 7750 automaton->locked_states = 0;
f1f41a6c 7751 output_states_vect.create (0);
bea4bad2 7752 pass_states (automaton, add_states_vect_el);
e7827cef 7753
f1f41a6c 7754 dead_lock_vect.safe_grow (output_states_vect.length ());
7755 for (i = 0; i < output_states_vect.length (); i++)
bea4bad2 7756 {
f1f41a6c 7757 state_t s = output_states_vect[i];
e7827cef 7758 arc = first_out_arc (s);
e0a4c0c2 7759 gcc_assert (arc);
c966a2e2 7760 if (next_out_arc (arc) == NULL
7761 && (arc->insn->insn_reserv_decl
7762 == DECL_INSN_RESERV (advance_cycle_insn_decl)))
7763 {
f1f41a6c 7764 dead_lock_vect[s->order_state_num] = 1;
c966a2e2 7765 automaton->locked_states++;
7766 }
7767 else
f1f41a6c 7768 dead_lock_vect[s->order_state_num] = (vect_el_t) 0;
bea4bad2 7769 }
c966a2e2 7770 if (automaton->locked_states == 0)
7771 return;
7772
bea4bad2 7773 fprintf (output_file, "/* Vector for locked state flags. */\n");
7774 fprintf (output_file, "static const ");
7775 output_range_type (output_file, 0, 1);
7776 fprintf (output_file, " ");
7777 output_dead_lock_vect_name (output_file, automaton);
7778 fprintf (output_file, "[] = {\n");
e7827cef 7779 output_vect (dead_lock_vect);
bea4bad2 7780 fprintf (output_file, "};\n\n");
f1f41a6c 7781 output_states_vect.release ();
7782 dead_lock_vect.release ();
bea4bad2 7783}
7784
7785/* Form and output vector representing reserved units of the states of
7786 AUTOMATON. */
7787static void
1a97be37 7788output_reserved_units_table (automaton_t automaton)
bea4bad2 7789{
9af5ce0c 7790 vla_hwint_t reserved_units_table = vla_hwint_t ();
e7827cef 7791 int state_byte_size;
7792 int reserved_units_size;
7793 size_t n;
bea4bad2 7794 int i;
7795
a1d6c3db 7796 if (description->query_units_num == 0)
7797 return;
7798
bea4bad2 7799 /* Create vect of pointers to states. */
f1f41a6c 7800 output_states_vect.create (0);
bea4bad2 7801 pass_states (automaton, add_states_vect_el);
7802 /* Create vector. */
bea4bad2 7803 state_byte_size = (description->query_units_num + 7) / 8;
f1f41a6c 7804 reserved_units_size = (output_states_vect.length ()
e7827cef 7805 * state_byte_size);
7806
f1f41a6c 7807 reserved_units_table.create (reserved_units_size);
48e1416a 7808
e7827cef 7809 for (i = 0; i < reserved_units_size; i++)
f1f41a6c 7810 reserved_units_table.quick_push (0);
7811 for (n = 0; n < output_states_vect.length (); n++)
bea4bad2 7812 {
f1f41a6c 7813 state_t s = output_states_vect[n];
bea4bad2 7814 for (i = 0; i < description->units_num; i++)
58ada791 7815 if (units_array [i]->query_p
e7827cef 7816 && first_cycle_unit_presence (s, i))
7817 {
7818 int ri = (s->order_state_num * state_byte_size
7819 + units_array [i]->query_num / 8);
f1f41a6c 7820 vect_el_t x = reserved_units_table[ri];
e7827cef 7821
7822 x += 1 << (units_array [i]->query_num % 8);
f1f41a6c 7823 reserved_units_table[ri] = x;
e7827cef 7824 }
bea4bad2 7825 }
0f7f3d52 7826 fprintf (output_file, "\n#if %s\n", CPU_UNITS_QUERY_MACRO_NAME);
bea4bad2 7827 fprintf (output_file, "/* Vector for reserved units of states. */\n");
7828 fprintf (output_file, "static const ");
7829 output_range_type (output_file, 0, 255);
7830 fprintf (output_file, " ");
7831 output_reserved_units_table_name (output_file, automaton);
7832 fprintf (output_file, "[] = {\n");
e7827cef 7833 output_vect (reserved_units_table);
a1d6c3db 7834 fprintf (output_file, "};\n#endif /* #if %s */\n\n",
0f7f3d52 7835 CPU_UNITS_QUERY_MACRO_NAME);
e7827cef 7836
f1f41a6c 7837 output_states_vect.release ();
7838 reserved_units_table.release ();
bea4bad2 7839}
7840
7841/* The function outputs all tables representing DFA(s) used for fast
7842 pipeline hazards recognition. */
7843static void
1a97be37 7844output_tables (void)
bea4bad2 7845{
7846 automaton_t automaton;
7847
bea4bad2 7848 for (automaton = description->first_automaton;
7849 automaton != NULL;
7850 automaton = automaton->next_automaton)
7851 {
7852 output_translate_vect (automaton);
7853 output_trans_table (automaton);
bea4bad2 7854 output_min_issue_delay_table (automaton);
7855 output_dead_lock_vect (automaton);
58ada791 7856 output_reserved_units_table (automaton);
bea4bad2 7857 }
7858 fprintf (output_file, "\n#define %s %d\n\n", ADVANCE_CYCLE_VALUE_NAME,
2f8ffd86 7859 DECL_INSN_RESERV (advance_cycle_insn_decl)->insn_num);
8043d8fb 7860 if (collapse_flag)
7861 fprintf (output_file, "\n#define %s %d\n\n", COLLAPSE_NDFA_VALUE_NAME,
7862 DECL_INSN_RESERV (collapse_ndfa_insn_decl)->insn_num);
bea4bad2 7863}
7864
7865/* The function outputs definition and value of PHR interface variable
3edc722e 7866 `max_insn_queue_index'. Its value is not less than maximal queue
7867 length needed for the insn scheduler. */
bea4bad2 7868static void
1a97be37 7869output_max_insn_queue_index_def (void)
bea4bad2 7870{
3edc722e 7871 int i, max, latency;
7872 decl_t decl;
bea4bad2 7873
3edc722e 7874 max = description->max_insn_reserv_cycles;
7875 for (i = 0; i < description->decls_num; i++)
7876 {
7877 decl = description->decls [i];
7878 if (decl->mode == dm_insn_reserv && decl != advance_cycle_insn_decl)
7879 {
7880 latency = DECL_INSN_RESERV (decl)->default_latency;
7881 if (latency > max)
7882 max = latency;
7883 }
7884 else if (decl->mode == dm_bypass)
7885 {
7886 latency = DECL_BYPASS (decl)->latency;
7887 if (latency > max)
7888 max = latency;
7889 }
7890 }
7891 for (i = 0; (1 << i) <= max; i++)
bea4bad2 7892 ;
e0a4c0c2 7893 gcc_assert (i >= 0);
c966a2e2 7894 fprintf (output_file, "\nconst int max_insn_queue_index = %d;\n\n",
7895 (1 << i) - 1);
bea4bad2 7896}
7897
98667efb 7898/* The function outputs switch cases for insn reservations using
bea4bad2 7899 function *output_automata_list_code. */
7900static void
1a97be37 7901output_insn_code_cases (void (*output_automata_list_code)
7902 (automata_list_el_t))
bea4bad2 7903{
2f8ffd86 7904 decl_t decl, decl2;
bea4bad2 7905 int i, j;
7906
7907 for (i = 0; i < description->decls_num; i++)
7908 {
7909 decl = description->decls [i];
7910 if (decl->mode == dm_insn_reserv)
2f8ffd86 7911 DECL_INSN_RESERV (decl)->processed_p = FALSE;
bea4bad2 7912 }
7913 for (i = 0; i < description->decls_num; i++)
7914 {
7915 decl = description->decls [i];
2f8ffd86 7916 if (decl->mode == dm_insn_reserv
7917 && !DECL_INSN_RESERV (decl)->processed_p)
bea4bad2 7918 {
7919 for (j = i; j < description->decls_num; j++)
7920 {
2f8ffd86 7921 decl2 = description->decls [j];
7922 if (decl2->mode == dm_insn_reserv
7923 && (DECL_INSN_RESERV (decl2)->important_automata_list
7924 == DECL_INSN_RESERV (decl)->important_automata_list))
bea4bad2 7925 {
2f8ffd86 7926 DECL_INSN_RESERV (decl2)->processed_p = TRUE;
bea4bad2 7927 fprintf (output_file, " case %d: /* %s */\n",
2f8ffd86 7928 DECL_INSN_RESERV (decl2)->insn_num,
7929 DECL_INSN_RESERV (decl2)->name);
bea4bad2 7930 }
7931 }
7932 (*output_automata_list_code)
2f8ffd86 7933 (DECL_INSN_RESERV (decl)->important_automata_list);
bea4bad2 7934 }
7935 }
7936}
7937
7938
7939/* The function outputs a code for evaluation of a minimal delay of
7940 issue of insns which have reservations in given AUTOMATA_LIST. */
7941static void
1a97be37 7942output_automata_list_min_issue_delay_code (automata_list_el_t automata_list)
bea4bad2 7943{
7944 automata_list_el_t el;
7945 automaton_t automaton;
7946
7947 for (el = automata_list; el != NULL; el = el->next_automata_list_el)
7948 {
7949 automaton = el->automaton;
7950 fprintf (output_file, "\n %s = ", TEMPORARY_VARIABLE_NAME);
7951 output_min_issue_delay_vect_name (output_file, automaton);
7952 fprintf (output_file,
7953 (automaton->min_issue_delay_table_compression_factor != 1
7954 ? " [(" : " ["));
7955 output_translate_vect_name (output_file, automaton);
7956 fprintf (output_file, " [%s] + ", INTERNAL_INSN_CODE_NAME);
7957 fprintf (output_file, "%s->", CHIP_PARAMETER_NAME);
7958 output_chip_member_name (output_file, automaton);
7959 fprintf (output_file, " * %d", automaton->insn_equiv_classes_num);
7960 if (automaton->min_issue_delay_table_compression_factor == 1)
7961 fprintf (output_file, "];\n");
7962 else
7963 {
7964 fprintf (output_file, ") / %d];\n",
7965 automaton->min_issue_delay_table_compression_factor);
103aa124 7966 fprintf (output_file, " %s = (%s >> (8 - ((",
bea4bad2 7967 TEMPORARY_VARIABLE_NAME, TEMPORARY_VARIABLE_NAME);
7968 output_translate_vect_name (output_file, automaton);
103aa124 7969 fprintf (output_file, " [%s] + ", INTERNAL_INSN_CODE_NAME);
7970 fprintf (output_file, "%s->", CHIP_PARAMETER_NAME);
7971 output_chip_member_name (output_file, automaton);
7972 fprintf (output_file, " * %d)", automaton->insn_equiv_classes_num);
bea4bad2 7973 fprintf
103aa124 7974 (output_file, " %% %d + 1) * %d)) & %d;\n",
bea4bad2 7975 automaton->min_issue_delay_table_compression_factor,
7976 8 / automaton->min_issue_delay_table_compression_factor,
7977 (1 << (8 / automaton->min_issue_delay_table_compression_factor))
7978 - 1);
7979 }
7980 if (el == automata_list)
7981 fprintf (output_file, " %s = %s;\n",
7982 RESULT_VARIABLE_NAME, TEMPORARY_VARIABLE_NAME);
7983 else
7984 {
7985 fprintf (output_file, " if (%s > %s)\n",
7986 TEMPORARY_VARIABLE_NAME, RESULT_VARIABLE_NAME);
7987 fprintf (output_file, " %s = %s;\n",
7988 RESULT_VARIABLE_NAME, TEMPORARY_VARIABLE_NAME);
7989 }
7990 }
7991 fprintf (output_file, " break;\n\n");
7992}
7993
7994/* Output function `internal_min_issue_delay'. */
7995static void
1a97be37 7996output_internal_min_issue_delay_func (void)
bea4bad2 7997{
bea4bad2 7998 fprintf (output_file,
69dc4d00 7999 "static int\n%s (int %s, struct %s *%s ATTRIBUTE_UNUSED)\n",
bea4bad2 8000 INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME, INTERNAL_INSN_CODE_NAME,
69dc4d00 8001 CHIP_NAME, CHIP_PARAMETER_NAME);
72d3c9a0 8002 fprintf (output_file, "{\n int %s ATTRIBUTE_UNUSED;\n int %s = -1;\n",
bea4bad2 8003 TEMPORARY_VARIABLE_NAME, RESULT_VARIABLE_NAME);
8004 fprintf (output_file, "\n switch (%s)\n {\n", INTERNAL_INSN_CODE_NAME);
8005 output_insn_code_cases (output_automata_list_min_issue_delay_code);
8006 fprintf (output_file,
8007 "\n default:\n %s = -1;\n break;\n }\n",
8008 RESULT_VARIABLE_NAME);
8009 fprintf (output_file, " return %s;\n", RESULT_VARIABLE_NAME);
8010 fprintf (output_file, "}\n\n");
8011}
8012
8013/* The function outputs a code changing state after issue of insns
8014 which have reservations in given AUTOMATA_LIST. */
8015static void
1a97be37 8016output_automata_list_transition_code (automata_list_el_t automata_list)
bea4bad2 8017{
8018 automata_list_el_t el, next_el;
8019
8020 fprintf (output_file, " {\n");
8021 if (automata_list != NULL && automata_list->next_automata_list_el != NULL)
8022 for (el = automata_list;; el = next_el)
8023 {
8024 next_el = el->next_automata_list_el;
8025 if (next_el == NULL)
8026 break;
8027 fprintf (output_file, " ");
8028 output_state_member_type (output_file, el->automaton);
8029 fprintf (output_file, " ");
8030 output_temp_chip_member_name (output_file, el->automaton);
8031 fprintf (output_file, ";\n");
8032 }
8033 for (el = automata_list; el != NULL; el = el->next_automata_list_el)
8034 if (comb_vect_p (el->automaton->trans_table))
8035 {
8036 fprintf (output_file, "\n %s = ", TEMPORARY_VARIABLE_NAME);
8037 output_trans_base_vect_name (output_file, el->automaton);
8038 fprintf (output_file, " [%s->", CHIP_PARAMETER_NAME);
8039 output_chip_member_name (output_file, el->automaton);
8040 fprintf (output_file, "] + ");
8041 output_translate_vect_name (output_file, el->automaton);
8042 fprintf (output_file, " [%s];\n", INTERNAL_INSN_CODE_NAME);
8043 fprintf (output_file, " if (");
8044 output_trans_check_vect_name (output_file, el->automaton);
8045 fprintf (output_file, " [%s] != %s->",
8046 TEMPORARY_VARIABLE_NAME, CHIP_PARAMETER_NAME);
8047 output_chip_member_name (output_file, el->automaton);
8048 fprintf (output_file, ")\n");
8049 fprintf (output_file, " return %s (%s, %s);\n",
8050 INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME, INTERNAL_INSN_CODE_NAME,
8051 CHIP_PARAMETER_NAME);
8052 fprintf (output_file, " else\n");
8053 fprintf (output_file, " ");
8054 if (el->next_automata_list_el != NULL)
8055 output_temp_chip_member_name (output_file, el->automaton);
8056 else
8057 {
8058 fprintf (output_file, "%s->", CHIP_PARAMETER_NAME);
8059 output_chip_member_name (output_file, el->automaton);
8060 }
8061 fprintf (output_file, " = ");
8062 output_trans_comb_vect_name (output_file, el->automaton);
8063 fprintf (output_file, " [%s];\n", TEMPORARY_VARIABLE_NAME);
8064 }
8065 else
8066 {
8067 fprintf (output_file, "\n %s = ", TEMPORARY_VARIABLE_NAME);
8068 output_trans_full_vect_name (output_file, el->automaton);
8069 fprintf (output_file, " [");
8070 output_translate_vect_name (output_file, el->automaton);
8071 fprintf (output_file, " [%s] + ", INTERNAL_INSN_CODE_NAME);
8072 fprintf (output_file, "%s->", CHIP_PARAMETER_NAME);
8073 output_chip_member_name (output_file, el->automaton);
8074 fprintf (output_file, " * %d];\n",
8075 el->automaton->insn_equiv_classes_num);
8076 fprintf (output_file, " if (%s >= %d)\n",
8077 TEMPORARY_VARIABLE_NAME, el->automaton->achieved_states_num);
8078 fprintf (output_file, " return %s (%s, %s);\n",
8079 INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME, INTERNAL_INSN_CODE_NAME,
8080 CHIP_PARAMETER_NAME);
8081 fprintf (output_file, " else\n ");
8082 if (el->next_automata_list_el != NULL)
8083 output_temp_chip_member_name (output_file, el->automaton);
8084 else
8085 {
8086 fprintf (output_file, "%s->", CHIP_PARAMETER_NAME);
8087 output_chip_member_name (output_file, el->automaton);
8088 }
8089 fprintf (output_file, " = %s;\n", TEMPORARY_VARIABLE_NAME);
8090 }
8091 if (automata_list != NULL && automata_list->next_automata_list_el != NULL)
8092 for (el = automata_list;; el = next_el)
8093 {
8094 next_el = el->next_automata_list_el;
8095 if (next_el == NULL)
8096 break;
8097 fprintf (output_file, " %s->", CHIP_PARAMETER_NAME);
8098 output_chip_member_name (output_file, el->automaton);
8099 fprintf (output_file, " = ");
8100 output_temp_chip_member_name (output_file, el->automaton);
8101 fprintf (output_file, ";\n");
8102 }
8103 fprintf (output_file, " return -1;\n");
8104 fprintf (output_file, " }\n");
8105}
8106
8107/* Output function `internal_state_transition'. */
8108static void
1a97be37 8109output_internal_trans_func (void)
bea4bad2 8110{
bea4bad2 8111 fprintf (output_file,
69dc4d00 8112 "static int\n%s (int %s, struct %s *%s ATTRIBUTE_UNUSED)\n",
bea4bad2 8113 INTERNAL_TRANSITION_FUNC_NAME, INTERNAL_INSN_CODE_NAME,
bea4bad2 8114 CHIP_NAME, CHIP_PARAMETER_NAME);
26638275 8115 fprintf (output_file, "{\n int %s ATTRIBUTE_UNUSED;\n", TEMPORARY_VARIABLE_NAME);
bea4bad2 8116 fprintf (output_file, "\n switch (%s)\n {\n", INTERNAL_INSN_CODE_NAME);
8117 output_insn_code_cases (output_automata_list_transition_code);
8118 fprintf (output_file, "\n default:\n return -1;\n }\n");
8119 fprintf (output_file, "}\n\n");
8120}
8121
8122/* Output code
8123
8124 if (insn != 0)
8125 {
8126 insn_code = dfa_insn_code (insn);
8127 if (insn_code > DFA__ADVANCE_CYCLE)
8128 return code;
8129 }
8130 else
8131 insn_code = DFA__ADVANCE_CYCLE;
8132
8133 where insn denotes INSN_NAME, insn_code denotes INSN_CODE_NAME, and
8134 code denotes CODE. */
8135static void
1a97be37 8136output_internal_insn_code_evaluation (const char *insn_name,
8137 const char *insn_code_name,
8138 int code)
bea4bad2 8139{
8043d8fb 8140 fprintf (output_file, "\n if (%s == 0)\n", insn_name);
8141 fprintf (output_file, " %s = %s;\n\n",
8142 insn_code_name, ADVANCE_CYCLE_VALUE_NAME);
8143 if (collapse_flag)
8144 {
8145 fprintf (output_file, "\n else if (%s == const0_rtx)\n", insn_name);
8146 fprintf (output_file, " %s = %s;\n\n",
8147 insn_code_name, COLLAPSE_NDFA_VALUE_NAME);
8148 }
8149 fprintf (output_file, "\n else\n {\n");
bea4bad2 8150 fprintf (output_file, " %s = %s (%s);\n", insn_code_name,
8151 DFA_INSN_CODE_FUNC_NAME, insn_name);
8043d8fb 8152 fprintf (output_file, " if (%s > %s)\n return %d;\n }\n",
bea4bad2 8153 insn_code_name, ADVANCE_CYCLE_VALUE_NAME, code);
bea4bad2 8154}
8155
8156
cf5aea47 8157/* This function outputs `dfa_insn_code' and its helper function
8158 `dfa_insn_code_enlarge'. */
bea4bad2 8159static void
1a97be37 8160output_dfa_insn_code_func (void)
bea4bad2 8161{
cf5aea47 8162 /* Emacs c-mode gets really confused if there's a { or } in column 0
8163 inside a string, so don't do that. */
8164 fprintf (output_file, "\
cf5aea47 8165static void\n\
69dc4d00 8166dfa_insn_code_enlarge (int uid)\n\
8167{\n\
cf5aea47 8168 int i = %s;\n\
8169 %s = 2 * uid;\n\
65b198c2 8170 %s = XRESIZEVEC (int, %s,\n\
8171 %s);\n\
cf5aea47 8172 for (; i < %s; i++)\n\
8173 %s[i] = -1;\n}\n\n",
1a97be37 8174 DFA_INSN_CODES_LENGTH_VARIABLE_NAME,
8175 DFA_INSN_CODES_LENGTH_VARIABLE_NAME,
8176 DFA_INSN_CODES_VARIABLE_NAME, DFA_INSN_CODES_VARIABLE_NAME,
8177 DFA_INSN_CODES_LENGTH_VARIABLE_NAME,
8178 DFA_INSN_CODES_LENGTH_VARIABLE_NAME,
8179 DFA_INSN_CODES_VARIABLE_NAME);
cf5aea47 8180 fprintf (output_file, "\
69dc4d00 8181static inline int\n%s (rtx %s)\n\
8182{\n\
8183 int uid = INSN_UID (%s);\n\
8184 int %s;\n\n",
8185 DFA_INSN_CODE_FUNC_NAME, INSN_PARAMETER_NAME,
8186 INSN_PARAMETER_NAME, INTERNAL_INSN_CODE_NAME);
cf5aea47 8187
8188 fprintf (output_file,
8189 " if (uid >= %s)\n dfa_insn_code_enlarge (uid);\n\n",
8190 DFA_INSN_CODES_LENGTH_VARIABLE_NAME);
8191 fprintf (output_file, " %s = %s[uid];\n",
8192 INTERNAL_INSN_CODE_NAME, DFA_INSN_CODES_VARIABLE_NAME);
8193 fprintf (output_file, "\
8194 if (%s < 0)\n\
8195 {\n\
8196 %s = %s (%s);\n\
8197 %s[uid] = %s;\n\
8198 }\n",
8199 INTERNAL_INSN_CODE_NAME,
8200 INTERNAL_INSN_CODE_NAME,
8201 INTERNAL_DFA_INSN_CODE_FUNC_NAME, INSN_PARAMETER_NAME,
8202 DFA_INSN_CODES_VARIABLE_NAME, INTERNAL_INSN_CODE_NAME);
8203 fprintf (output_file, " return %s;\n}\n\n", INTERNAL_INSN_CODE_NAME);
bea4bad2 8204}
8205
8206/* The function outputs PHR interface function `state_transition'. */
8207static void
1a97be37 8208output_trans_func (void)
bea4bad2 8209{
69dc4d00 8210 fprintf (output_file, "int\n%s (%s %s, rtx %s)\n",
8211 TRANSITION_FUNC_NAME, STATE_TYPE_NAME, STATE_NAME,
8212 INSN_PARAMETER_NAME);
bea4bad2 8213 fprintf (output_file, "{\n int %s;\n", INTERNAL_INSN_CODE_NAME);
8214 output_internal_insn_code_evaluation (INSN_PARAMETER_NAME,
8215 INTERNAL_INSN_CODE_NAME, -1);
65b198c2 8216 fprintf (output_file, " return %s (%s, (struct %s *) %s);\n}\n\n",
8217 INTERNAL_TRANSITION_FUNC_NAME, INTERNAL_INSN_CODE_NAME, CHIP_NAME, STATE_NAME);
bea4bad2 8218}
8219
bea4bad2 8220/* Output function `min_issue_delay'. */
8221static void
1a97be37 8222output_min_issue_delay_func (void)
bea4bad2 8223{
69dc4d00 8224 fprintf (output_file, "int\n%s (%s %s, rtx %s)\n",
8225 MIN_ISSUE_DELAY_FUNC_NAME, STATE_TYPE_NAME, STATE_NAME,
8226 INSN_PARAMETER_NAME);
bea4bad2 8227 fprintf (output_file, "{\n int %s;\n", INTERNAL_INSN_CODE_NAME);
8228 fprintf (output_file, "\n if (%s != 0)\n {\n", INSN_PARAMETER_NAME);
8229 fprintf (output_file, " %s = %s (%s);\n", INTERNAL_INSN_CODE_NAME,
8230 DFA_INSN_CODE_FUNC_NAME, INSN_PARAMETER_NAME);
8231 fprintf (output_file, " if (%s > %s)\n return 0;\n",
8232 INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME);
8233 fprintf (output_file, " }\n else\n %s = %s;\n",
8234 INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME);
65b198c2 8235 fprintf (output_file, "\n return %s (%s, (struct %s *) %s);\n",
1a97be37 8236 INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME, INTERNAL_INSN_CODE_NAME,
65b198c2 8237 CHIP_NAME, STATE_NAME);
bea4bad2 8238 fprintf (output_file, "}\n\n");
8239}
8240
8241/* Output function `internal_dead_lock'. */
8242static void
1a97be37 8243output_internal_dead_lock_func (void)
bea4bad2 8244{
8245 automaton_t automaton;
8246
c966a2e2 8247 fprintf (output_file, "static int\n%s (struct %s *ARG_UNUSED (%s))\n",
69dc4d00 8248 INTERNAL_DEAD_LOCK_FUNC_NAME, CHIP_NAME, CHIP_PARAMETER_NAME);
bea4bad2 8249 fprintf (output_file, "{\n");
8250 for (automaton = description->first_automaton;
8251 automaton != NULL;
8252 automaton = automaton->next_automaton)
c966a2e2 8253 if (automaton->locked_states)
8254 {
8255 fprintf (output_file, " if (");
8256 output_dead_lock_vect_name (output_file, automaton);
8257 fprintf (output_file, " [%s->", CHIP_PARAMETER_NAME);
8258 output_chip_member_name (output_file, automaton);
8259 fprintf (output_file, "])\n return 1/* TRUE */;\n");
8260 }
bea4bad2 8261 fprintf (output_file, " return 0/* FALSE */;\n}\n\n");
8262}
8263
8264/* The function outputs PHR interface function `state_dead_lock_p'. */
8265static void
1a97be37 8266output_dead_lock_func (void)
bea4bad2 8267{
69dc4d00 8268 fprintf (output_file, "int\n%s (%s %s)\n",
8269 DEAD_LOCK_FUNC_NAME, STATE_TYPE_NAME, STATE_NAME);
65b198c2 8270 fprintf (output_file, "{\n return %s ((struct %s *) %s);\n}\n\n",
8271 INTERNAL_DEAD_LOCK_FUNC_NAME, CHIP_NAME, STATE_NAME);
bea4bad2 8272}
8273
8274/* Output function `internal_reset'. */
8275static void
1a97be37 8276output_internal_reset_func (void)
bea4bad2 8277{
7492620d 8278 fprintf (output_file, "static inline void\n%s (struct %s *%s)\n",
69dc4d00 8279 INTERNAL_RESET_FUNC_NAME, CHIP_NAME, CHIP_PARAMETER_NAME);
bea4bad2 8280 fprintf (output_file, "{\n memset (%s, 0, sizeof (struct %s));\n}\n\n",
8281 CHIP_PARAMETER_NAME, CHIP_NAME);
8282}
8283
8284/* The function outputs PHR interface function `state_size'. */
8285static void
1a97be37 8286output_size_func (void)
bea4bad2 8287{
69dc4d00 8288 fprintf (output_file, "int\n%s (void)\n", SIZE_FUNC_NAME);
bea4bad2 8289 fprintf (output_file, "{\n return sizeof (struct %s);\n}\n\n", CHIP_NAME);
8290}
8291
8292/* The function outputs PHR interface function `state_reset'. */
8293static void
1a97be37 8294output_reset_func (void)
bea4bad2 8295{
69dc4d00 8296 fprintf (output_file, "void\n%s (%s %s)\n",
8297 RESET_FUNC_NAME, STATE_TYPE_NAME, STATE_NAME);
65b198c2 8298 fprintf (output_file, "{\n %s ((struct %s *) %s);\n}\n\n", INTERNAL_RESET_FUNC_NAME,
8299 CHIP_NAME, STATE_NAME);
bea4bad2 8300}
8301
8302/* Output function `min_insn_conflict_delay'. */
8303static void
1a97be37 8304output_min_insn_conflict_delay_func (void)
bea4bad2 8305{
8306 fprintf (output_file,
69dc4d00 8307 "int\n%s (%s %s, rtx %s, rtx %s)\n",
8308 MIN_INSN_CONFLICT_DELAY_FUNC_NAME, STATE_TYPE_NAME,
8309 STATE_NAME, INSN_PARAMETER_NAME, INSN2_PARAMETER_NAME);
e0a4c0c2 8310 fprintf (output_file, "{\n struct %s %s;\n int %s, %s, transition;\n",
bea4bad2 8311 CHIP_NAME, CHIP_NAME, INTERNAL_INSN_CODE_NAME,
8312 INTERNAL_INSN2_CODE_NAME);
8313 output_internal_insn_code_evaluation (INSN_PARAMETER_NAME,
8314 INTERNAL_INSN_CODE_NAME, 0);
8315 output_internal_insn_code_evaluation (INSN2_PARAMETER_NAME,
8316 INTERNAL_INSN2_CODE_NAME, 0);
8317 fprintf (output_file, " memcpy (&%s, %s, sizeof (%s));\n",
8318 CHIP_NAME, STATE_NAME, CHIP_NAME);
8319 fprintf (output_file, " %s (&%s);\n", INTERNAL_RESET_FUNC_NAME, CHIP_NAME);
e0a4c0c2 8320 fprintf (output_file, " transition = %s (%s, &%s);\n",
bea4bad2 8321 INTERNAL_TRANSITION_FUNC_NAME, INTERNAL_INSN_CODE_NAME, CHIP_NAME);
e0a4c0c2 8322 fprintf (output_file, " gcc_assert (transition <= 0);\n");
bea4bad2 8323 fprintf (output_file, " return %s (%s, &%s);\n",
8324 INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME, INTERNAL_INSN2_CODE_NAME,
8325 CHIP_NAME);
8326 fprintf (output_file, "}\n\n");
8327}
8328
48e1416a 8329/* Output the array holding default latency values. These are used in
e1ab7874 8330 insn_latency and maximal_insn_latency function implementations. */
bea4bad2 8331static void
e1ab7874 8332output_default_latencies (void)
bea4bad2 8333{
cf5aea47 8334 int i, j, col;
e1ab7874 8335 decl_t decl;
cf5aea47 8336 const char *tabletype = "unsigned char";
bea4bad2 8337
cf5aea47 8338 /* Find the smallest integer type that can hold all the default
8339 latency values. */
8340 for (i = 0; i < description->decls_num; i++)
8341 if (description->decls[i]->mode == dm_insn_reserv)
8342 {
8343 decl = description->decls[i];
8344 if (DECL_INSN_RESERV (decl)->default_latency > UCHAR_MAX
21dda4ee 8345 && tabletype[0] != 'i') /* Don't shrink it. */
cf5aea47 8346 tabletype = "unsigned short";
8347 if (DECL_INSN_RESERV (decl)->default_latency > USHRT_MAX)
8348 tabletype = "int";
8349 }
1a97be37 8350
cf5aea47 8351 fprintf (output_file, " static const %s default_latencies[] =\n {",
8352 tabletype);
8353
8043d8fb 8354 for (i = 0, j = 0, col = 7; i < description->normal_decls_num; i++)
8355 if (description->decls[i]->mode == dm_insn_reserv)
cf5aea47 8356 {
8357 if ((col = (col+1) % 8) == 0)
8358 fputs ("\n ", output_file);
8359 decl = description->decls[i];
e0a4c0c2 8360 gcc_assert (j++ == DECL_INSN_RESERV (decl)->insn_num);
cf5aea47 8361 fprintf (output_file, "% 4d,",
8362 DECL_INSN_RESERV (decl)->default_latency);
8363 }
8043d8fb 8364 gcc_assert (j == description->insns_num - (collapse_flag ? 2 : 1));
cf5aea47 8365 fputs ("\n };\n", output_file);
e1ab7874 8366}
8367
8368/* Output function `internal_insn_latency'. */
8369static void
8370output_internal_insn_latency_func (void)
8371{
8372 int i;
8373 decl_t decl;
8374 struct bypass_decl *bypass;
8375
8376 fprintf (output_file, "static int\n%s (int %s ATTRIBUTE_UNUSED,\n\tint %s ATTRIBUTE_UNUSED,\n\trtx %s ATTRIBUTE_UNUSED,\n\trtx %s ATTRIBUTE_UNUSED)\n",
8377 INTERNAL_INSN_LATENCY_FUNC_NAME, INTERNAL_INSN_CODE_NAME,
8378 INTERNAL_INSN2_CODE_NAME, INSN_PARAMETER_NAME,
8379 INSN2_PARAMETER_NAME);
8380 fprintf (output_file, "{\n");
8381
8382 if (DECL_INSN_RESERV (advance_cycle_insn_decl)->insn_num == 0)
8383 {
8384 fputs (" return 0;\n}\n\n", output_file);
8385 return;
8386 }
cf5aea47 8387
8388 fprintf (output_file, " if (%s >= %s || %s >= %s)\n return 0;\n",
8389 INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME,
8390 INTERNAL_INSN2_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME);
8391
8392 fprintf (output_file, " switch (%s)\n {\n", INTERNAL_INSN_CODE_NAME);
bea4bad2 8393 for (i = 0; i < description->decls_num; i++)
cf5aea47 8394 if (description->decls[i]->mode == dm_insn_reserv
8395 && DECL_INSN_RESERV (description->decls[i])->bypass_list)
8396 {
8397 decl = description->decls [i];
8398 fprintf (output_file,
8399 " case %d:\n switch (%s)\n {\n",
8400 DECL_INSN_RESERV (decl)->insn_num,
8401 INTERNAL_INSN2_CODE_NAME);
8402 for (bypass = DECL_INSN_RESERV (decl)->bypass_list;
8403 bypass != NULL;
8404 bypass = bypass->next)
8405 {
e0a4c0c2 8406 gcc_assert (bypass->in_insn_reserv->insn_num
8407 != (DECL_INSN_RESERV
8408 (advance_cycle_insn_decl)->insn_num));
cf5aea47 8409 fprintf (output_file, " case %d:\n",
8410 bypass->in_insn_reserv->insn_num);
08ed847d 8411 for (;;)
cf5aea47 8412 {
08ed847d 8413 if (bypass->bypass_guard_name == NULL)
8414 {
8415 gcc_assert (bypass->next == NULL
8416 || (bypass->in_insn_reserv
8417 != bypass->next->in_insn_reserv));
8418 fprintf (output_file, " return %d;\n",
8419 bypass->latency);
8420 }
8421 else
8422 {
8423 fprintf (output_file,
8424 " if (%s (%s, %s))\n",
8425 bypass->bypass_guard_name, INSN_PARAMETER_NAME,
8426 INSN2_PARAMETER_NAME);
8427 fprintf (output_file, " return %d;\n",
8428 bypass->latency);
8429 }
8430 if (bypass->next == NULL
8431 || bypass->in_insn_reserv != bypass->next->in_insn_reserv)
8432 break;
8433 bypass = bypass->next;
cf5aea47 8434 }
08ed847d 8435 if (bypass->bypass_guard_name != NULL)
8436 fprintf (output_file, " break;\n");
cf5aea47 8437 }
929ed800 8438 fputs (" }\n break;\n", output_file);
cf5aea47 8439 }
8440
8441 fprintf (output_file, " }\n return default_latencies[%s];\n}\n\n",
8442 INTERNAL_INSN_CODE_NAME);
bea4bad2 8443}
8444
e1ab7874 8445/* Output function `internal_maximum_insn_latency'. */
8446static void
8447output_internal_maximal_insn_latency_func (void)
8448{
8449 decl_t decl;
8450 struct bypass_decl *bypass;
8451 int i;
8452 int max;
8453
8454 fprintf (output_file, "static int\n%s (int %s ATTRIBUTE_UNUSED,\n\trtx %s ATTRIBUTE_UNUSED)\n",
8455 "internal_maximal_insn_latency", INTERNAL_INSN_CODE_NAME,
8456 INSN_PARAMETER_NAME);
8457 fprintf (output_file, "{\n");
8458
8459 if (DECL_INSN_RESERV (advance_cycle_insn_decl)->insn_num == 0)
8460 {
8461 fputs (" return 0;\n}\n\n", output_file);
8462 return;
8463 }
8464
8465 fprintf (output_file, " switch (%s)\n {\n", INTERNAL_INSN_CODE_NAME);
8466 for (i = 0; i < description->decls_num; i++)
8467 if (description->decls[i]->mode == dm_insn_reserv
8468 && DECL_INSN_RESERV (description->decls[i])->bypass_list)
8469 {
8470 decl = description->decls [i];
8471 max = DECL_INSN_RESERV (decl)->default_latency;
8472 fprintf (output_file,
8473 " case %d: {",
8474 DECL_INSN_RESERV (decl)->insn_num);
8475 for (bypass = DECL_INSN_RESERV (decl)->bypass_list;
8476 bypass != NULL;
8477 bypass = bypass->next)
8478 {
8479 if (bypass->latency > max)
8480 max = bypass->latency;
8481 }
8482 fprintf (output_file, " return %d; }\n break;\n", max);
8483 }
8484
8485 fprintf (output_file, " }\n return default_latencies[%s];\n}\n\n",
8486 INTERNAL_INSN_CODE_NAME);
8487}
8488
bea4bad2 8489/* The function outputs PHR interface function `insn_latency'. */
8490static void
1a97be37 8491output_insn_latency_func (void)
bea4bad2 8492{
69dc4d00 8493 fprintf (output_file, "int\n%s (rtx %s, rtx %s)\n",
8494 INSN_LATENCY_FUNC_NAME, INSN_PARAMETER_NAME, INSN2_PARAMETER_NAME);
bea4bad2 8495 fprintf (output_file, "{\n int %s, %s;\n",
8496 INTERNAL_INSN_CODE_NAME, INTERNAL_INSN2_CODE_NAME);
8497 output_internal_insn_code_evaluation (INSN_PARAMETER_NAME,
8498 INTERNAL_INSN_CODE_NAME, 0);
8499 output_internal_insn_code_evaluation (INSN2_PARAMETER_NAME,
8500 INTERNAL_INSN2_CODE_NAME, 0);
8501 fprintf (output_file, " return %s (%s, %s, %s, %s);\n}\n\n",
8502 INTERNAL_INSN_LATENCY_FUNC_NAME,
8503 INTERNAL_INSN_CODE_NAME, INTERNAL_INSN2_CODE_NAME,
8504 INSN_PARAMETER_NAME, INSN2_PARAMETER_NAME);
8505}
8506
e1ab7874 8507/* The function outputs PHR interface function `maximal_insn_latency'. */
8508static void
8509output_maximal_insn_latency_func (void)
8510{
8511 fprintf (output_file, "int\n%s (rtx %s)\n",
8512 "maximal_insn_latency", INSN_PARAMETER_NAME);
8513 fprintf (output_file, "{\n int %s;\n",
8514 INTERNAL_INSN_CODE_NAME);
8515 output_internal_insn_code_evaluation (INSN_PARAMETER_NAME,
8516 INTERNAL_INSN_CODE_NAME, 0);
8517 fprintf (output_file, " return %s (%s, %s);\n}\n\n",
8518 "internal_maximal_insn_latency",
8519 INTERNAL_INSN_CODE_NAME, INSN_PARAMETER_NAME);
8520}
8521
bea4bad2 8522/* The function outputs PHR interface function `print_reservation'. */
8523static void
1a97be37 8524output_print_reservation_func (void)
bea4bad2 8525{
8526 decl_t decl;
cf5aea47 8527 int i, j;
bea4bad2 8528
84eb7376 8529 fprintf (output_file,
69dc4d00 8530 "void\n%s (FILE *%s, rtx %s ATTRIBUTE_UNUSED)\n{\n",
bea4bad2 8531 PRINT_RESERVATION_FUNC_NAME, FILE_PARAMETER_NAME,
bea4bad2 8532 INSN_PARAMETER_NAME);
cf5aea47 8533
84eb7376 8534 if (DECL_INSN_RESERV (advance_cycle_insn_decl)->insn_num == 0)
8535 {
8536 fprintf (output_file, " fputs (\"%s\", %s);\n}\n\n",
8537 NOTHING_NAME, FILE_PARAMETER_NAME);
8538 return;
8539 }
8540
8541
cf5aea47 8542 fputs (" static const char *const reservation_names[] =\n {",
8543 output_file);
8544
8043d8fb 8545 for (i = 0, j = 0; i < description->normal_decls_num; i++)
bea4bad2 8546 {
8547 decl = description->decls [i];
8043d8fb 8548 if (decl->mode == dm_insn_reserv)
bea4bad2 8549 {
e0a4c0c2 8550 gcc_assert (j == DECL_INSN_RESERV (decl)->insn_num);
8551 j++;
48e1416a 8552
cf5aea47 8553 fprintf (output_file, "\n \"%s\",",
8554 regexp_representation (DECL_INSN_RESERV (decl)->regexp));
8555 finish_regexp_representation ();
8556 }
bea4bad2 8557 }
8043d8fb 8558 gcc_assert (j == description->insns_num - (collapse_flag ? 2 : 1));
1a97be37 8559
cf5aea47 8560 fprintf (output_file, "\n \"%s\"\n };\n int %s;\n\n",
8561 NOTHING_NAME, INTERNAL_INSN_CODE_NAME);
8562
8563 fprintf (output_file, " if (%s == 0)\n %s = %s;\n",
8564 INSN_PARAMETER_NAME,
8565 INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME);
8566 fprintf (output_file, " else\n\
8567 {\n\
8568 %s = %s (%s);\n\
8569 if (%s > %s)\n\
8570 %s = %s;\n\
8571 }\n",
8572 INTERNAL_INSN_CODE_NAME, DFA_INSN_CODE_FUNC_NAME,
8573 INSN_PARAMETER_NAME,
8574 INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME,
8575 INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME);
8576
8577 fprintf (output_file, " fputs (reservation_names[%s], %s);\n}\n\n",
8578 INTERNAL_INSN_CODE_NAME, FILE_PARAMETER_NAME);
bea4bad2 8579}
8580
8581/* The following function is used to sort unit declaration by their
8582 names. */
8583static int
1a97be37 8584units_cmp (const void *unit1, const void *unit2)
bea4bad2 8585{
aae87fc3 8586 const_unit_decl_t const u1 = *(const_unit_decl_t const*) unit1;
8587 const_unit_decl_t const u2 = *(const_unit_decl_t const*) unit2;
bea4bad2 8588
8589 return strcmp (u1->name, u2->name);
8590}
8591
8592/* The following macro value is name of struct containing unit name
8593 and unit code. */
8594#define NAME_CODE_STRUCT_NAME "name_code"
8595
8596/* The following macro value is name of table of struct name_code. */
8597#define NAME_CODE_TABLE_NAME "name_code_table"
8598
8599/* The following macro values are member names for struct name_code. */
8600#define NAME_MEMBER_NAME "name"
8601#define CODE_MEMBER_NAME "code"
8602
8603/* The following macro values are local variable names for function
8604 `get_cpu_unit_code'. */
8605#define CMP_VARIABLE_NAME "cmp"
8606#define LOW_VARIABLE_NAME "l"
8607#define MIDDLE_VARIABLE_NAME "m"
8608#define HIGH_VARIABLE_NAME "h"
8609
8610/* The following function outputs function to obtain internal cpu unit
8611 code by the cpu unit name. */
8612static void
1a97be37 8613output_get_cpu_unit_code_func (void)
bea4bad2 8614{
8615 int i;
b35eefd9 8616 unit_decl_t *units;
1a97be37 8617
dadff31e 8618 fprintf (output_file, "int\n%s (const char *%s)\n",
8619 GET_CPU_UNIT_CODE_FUNC_NAME, CPU_UNIT_NAME_PARAMETER_NAME);
bea4bad2 8620 fprintf (output_file, "{\n struct %s {const char *%s; int %s;};\n",
8621 NAME_CODE_STRUCT_NAME, NAME_MEMBER_NAME, CODE_MEMBER_NAME);
8622 fprintf (output_file, " int %s, %s, %s, %s;\n", CMP_VARIABLE_NAME,
8623 LOW_VARIABLE_NAME, MIDDLE_VARIABLE_NAME, HIGH_VARIABLE_NAME);
8624 fprintf (output_file, " static struct %s %s [] =\n {\n",
8625 NAME_CODE_STRUCT_NAME, NAME_CODE_TABLE_NAME);
65b198c2 8626 units = XNEWVEC (unit_decl_t, description->units_num);
b35eefd9 8627 memcpy (units, units_array, sizeof (unit_decl_t) * description->units_num);
8628 qsort (units, description->units_num, sizeof (unit_decl_t), units_cmp);
bea4bad2 8629 for (i = 0; i < description->units_num; i++)
8630 if (units [i]->query_p)
8631 fprintf (output_file, " {\"%s\", %d},\n",
8632 units[i]->name, units[i]->query_num);
8633 fprintf (output_file, " };\n\n");
8634 fprintf (output_file, " /* The following is binary search: */\n");
8635 fprintf (output_file, " %s = 0;\n", LOW_VARIABLE_NAME);
8636 fprintf (output_file, " %s = sizeof (%s) / sizeof (struct %s) - 1;\n",
8637 HIGH_VARIABLE_NAME, NAME_CODE_TABLE_NAME, NAME_CODE_STRUCT_NAME);
8638 fprintf (output_file, " while (%s <= %s)\n {\n",
8639 LOW_VARIABLE_NAME, HIGH_VARIABLE_NAME);
8640 fprintf (output_file, " %s = (%s + %s) / 2;\n",
8641 MIDDLE_VARIABLE_NAME, LOW_VARIABLE_NAME, HIGH_VARIABLE_NAME);
8642 fprintf (output_file, " %s = strcmp (%s, %s [%s].%s);\n",
8643 CMP_VARIABLE_NAME, CPU_UNIT_NAME_PARAMETER_NAME,
8644 NAME_CODE_TABLE_NAME, MIDDLE_VARIABLE_NAME, NAME_MEMBER_NAME);
8645 fprintf (output_file, " if (%s < 0)\n", CMP_VARIABLE_NAME);
8646 fprintf (output_file, " %s = %s - 1;\n",
8647 HIGH_VARIABLE_NAME, MIDDLE_VARIABLE_NAME);
8648 fprintf (output_file, " else if (%s > 0)\n", CMP_VARIABLE_NAME);
8649 fprintf (output_file, " %s = %s + 1;\n",
8650 LOW_VARIABLE_NAME, MIDDLE_VARIABLE_NAME);
8651 fprintf (output_file, " else\n");
8652 fprintf (output_file, " return %s [%s].%s;\n }\n",
8653 NAME_CODE_TABLE_NAME, MIDDLE_VARIABLE_NAME, CODE_MEMBER_NAME);
8654 fprintf (output_file, " return -1;\n}\n\n");
8655 free (units);
8656}
8657
8658/* The following function outputs function to check reservation of cpu
8659 unit (its internal code will be passed as the function argument) in
8660 given cpu state. */
8661static void
1a97be37 8662output_cpu_unit_reservation_p (void)
bea4bad2 8663{
8664 automaton_t automaton;
8665
dadff31e 8666 fprintf (output_file, "int\n%s (%s %s, int %s)\n",
8667 CPU_UNIT_RESERVATION_P_FUNC_NAME,
8668 STATE_TYPE_NAME, STATE_NAME,
bea4bad2 8669 CPU_CODE_PARAMETER_NAME);
e0a4c0c2 8670 fprintf (output_file, "{\n gcc_assert (%s >= 0 && %s < %d);\n",
bea4bad2 8671 CPU_CODE_PARAMETER_NAME, CPU_CODE_PARAMETER_NAME,
8672 description->query_units_num);
a1d6c3db 8673 if (description->query_units_num > 0)
8674 for (automaton = description->first_automaton;
8675 automaton != NULL;
8676 automaton = automaton->next_automaton)
8677 {
8678 fprintf (output_file, " if ((");
8679 output_reserved_units_table_name (output_file, automaton);
8680 fprintf (output_file, " [((struct %s *) %s)->", CHIP_NAME, STATE_NAME);
8681 output_chip_member_name (output_file, automaton);
8682 fprintf (output_file, " * %d + %s / 8] >> (%s %% 8)) & 1)\n",
8683 (description->query_units_num + 7) / 8,
8684 CPU_CODE_PARAMETER_NAME, CPU_CODE_PARAMETER_NAME);
8685 fprintf (output_file, " return 1;\n");
8686 }
bea4bad2 8687 fprintf (output_file, " return 0;\n}\n\n");
8688}
8689
07317795 8690/* The following function outputs a function to check if insn
8691 has a dfa reservation. */
8692static void
8693output_insn_has_dfa_reservation_p (void)
8694{
8695 fprintf (output_file,
8696 "bool\n%s (rtx %s ATTRIBUTE_UNUSED)\n{\n",
8697 INSN_HAS_DFA_RESERVATION_P_FUNC_NAME,
8698 INSN_PARAMETER_NAME);
8699
8700 if (DECL_INSN_RESERV (advance_cycle_insn_decl)->insn_num == 0)
8701 {
8702 fprintf (output_file, " return false;\n}\n\n");
8703 return;
8704 }
8705
8706 fprintf (output_file, " int %s;\n\n", INTERNAL_INSN_CODE_NAME);
8707
8708 fprintf (output_file, " if (%s == 0)\n %s = %s;\n",
8709 INSN_PARAMETER_NAME,
8710 INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME);
8711 fprintf (output_file, " else\n\
8712 {\n\
8713 %s = %s (%s);\n\
8714 if (%s > %s)\n\
8715 %s = %s;\n\
8716 }\n\n",
8717 INTERNAL_INSN_CODE_NAME, DFA_INSN_CODE_FUNC_NAME,
8718 INSN_PARAMETER_NAME,
8719 INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME,
8720 INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME);
8721
8722 fprintf (output_file, " return %s != %s;\n}\n\n",
8723 INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME);
8724}
8725
6a1cdb4d 8726/* The function outputs PHR interface functions `dfa_clean_insn_cache'
8727 and 'dfa_clear_single_insn_cache'. */
bea4bad2 8728static void
1a97be37 8729output_dfa_clean_insn_cache_func (void)
bea4bad2 8730{
8731 fprintf (output_file,
69dc4d00 8732 "void\n%s (void)\n{\n int %s;\n\n",
58ada791 8733 DFA_CLEAN_INSN_CACHE_FUNC_NAME, I_VARIABLE_NAME);
bea4bad2 8734 fprintf (output_file,
8735 " for (%s = 0; %s < %s; %s++)\n %s [%s] = -1;\n}\n\n",
8736 I_VARIABLE_NAME, I_VARIABLE_NAME,
8737 DFA_INSN_CODES_LENGTH_VARIABLE_NAME, I_VARIABLE_NAME,
8738 DFA_INSN_CODES_VARIABLE_NAME, I_VARIABLE_NAME);
6a1cdb4d 8739
8740 fprintf (output_file,
8741 "void\n%s (rtx %s)\n{\n int %s;\n\n",
8742 DFA_CLEAR_SINGLE_INSN_CACHE_FUNC_NAME, INSN_PARAMETER_NAME,
8743 I_VARIABLE_NAME);
8744 fprintf (output_file,
8745 " %s = INSN_UID (%s);\n if (%s < %s)\n %s [%s] = -1;\n}\n\n",
8746 I_VARIABLE_NAME, INSN_PARAMETER_NAME, I_VARIABLE_NAME,
8747 DFA_INSN_CODES_LENGTH_VARIABLE_NAME, DFA_INSN_CODES_VARIABLE_NAME,
8748 I_VARIABLE_NAME);
bea4bad2 8749}
8750
58ada791 8751/* The function outputs PHR interface function `dfa_start'. */
8752static void
1a97be37 8753output_dfa_start_func (void)
58ada791 8754{
8755 fprintf (output_file,
69dc4d00 8756 "void\n%s (void)\n{\n %s = get_max_uid ();\n",
58ada791 8757 DFA_START_FUNC_NAME, DFA_INSN_CODES_LENGTH_VARIABLE_NAME);
65b198c2 8758 fprintf (output_file, " %s = XNEWVEC (int, %s);\n",
58ada791 8759 DFA_INSN_CODES_VARIABLE_NAME, DFA_INSN_CODES_LENGTH_VARIABLE_NAME);
8760 fprintf (output_file, " %s ();\n}\n\n", DFA_CLEAN_INSN_CACHE_FUNC_NAME);
8761}
8762
bea4bad2 8763/* The function outputs PHR interface function `dfa_finish'. */
8764static void
1a97be37 8765output_dfa_finish_func (void)
bea4bad2 8766{
69dc4d00 8767 fprintf (output_file, "void\n%s (void)\n{\n free (%s);\n}\n\n",
bea4bad2 8768 DFA_FINISH_FUNC_NAME, DFA_INSN_CODES_VARIABLE_NAME);
8769}
8770
8771\f
8772
8773/* The page contains code for output description file (readable
8774 representation of original description and generated DFA(s). */
8775
8776/* The function outputs string representation of IR reservation. */
8777static void
1a97be37 8778output_regexp (regexp_t regexp)
bea4bad2 8779{
8780 fprintf (output_description_file, "%s", regexp_representation (regexp));
8781 finish_regexp_representation ();
8782}
8783
8784/* Output names of units in LIST separated by comma. */
8785static void
1a97be37 8786output_unit_set_el_list (unit_set_el_t list)
bea4bad2 8787{
8788 unit_set_el_t el;
8789
8790 for (el = list; el != NULL; el = el->next_unit_set_el)
8791 {
8792 if (el != list)
58ada791 8793 fprintf (output_description_file, ", ");
bea4bad2 8794 fprintf (output_description_file, "%s", el->unit_decl->name);
8795 }
8796}
8797
58ada791 8798/* Output patterns in LIST separated by comma. */
8799static void
1a97be37 8800output_pattern_set_el_list (pattern_set_el_t list)
58ada791 8801{
8802 pattern_set_el_t el;
8803 int i;
8804
8805 for (el = list; el != NULL; el = el->next_pattern_set_el)
8806 {
8807 if (el != list)
8808 fprintf (output_description_file, ", ");
8809 for (i = 0; i < el->units_num; i++)
8810 fprintf (output_description_file, (i == 0 ? "%s" : " %s"),
8811 el->unit_decls [i]->name);
8812 }
8813}
8814
bea4bad2 8815/* The function outputs string representation of IR define_reservation
8816 and define_insn_reservation. */
8817static void
1a97be37 8818output_description (void)
bea4bad2 8819{
8820 decl_t decl;
8821 int i;
8822
8823 for (i = 0; i < description->decls_num; i++)
8824 {
8825 decl = description->decls [i];
8826 if (decl->mode == dm_unit)
8827 {
2f8ffd86 8828 if (DECL_UNIT (decl)->excl_list != NULL)
bea4bad2 8829 {
f0b5f617 8830 fprintf (output_description_file, "unit %s exclusion_set: ",
2f8ffd86 8831 DECL_UNIT (decl)->name);
8832 output_unit_set_el_list (DECL_UNIT (decl)->excl_list);
bea4bad2 8833 fprintf (output_description_file, "\n");
8834 }
2f8ffd86 8835 if (DECL_UNIT (decl)->presence_list != NULL)
bea4bad2 8836 {
8837 fprintf (output_description_file, "unit %s presence_set: ",
2f8ffd86 8838 DECL_UNIT (decl)->name);
58ada791 8839 output_pattern_set_el_list (DECL_UNIT (decl)->presence_list);
bea4bad2 8840 fprintf (output_description_file, "\n");
8841 }
58ada791 8842 if (DECL_UNIT (decl)->final_presence_list != NULL)
8843 {
8844 fprintf (output_description_file, "unit %s final_presence_set: ",
8845 DECL_UNIT (decl)->name);
8846 output_pattern_set_el_list
8847 (DECL_UNIT (decl)->final_presence_list);
1a97be37 8848 fprintf (output_description_file, "\n");
8849 }
2f8ffd86 8850 if (DECL_UNIT (decl)->absence_list != NULL)
bea4bad2 8851 {
8852 fprintf (output_description_file, "unit %s absence_set: ",
2f8ffd86 8853 DECL_UNIT (decl)->name);
58ada791 8854 output_pattern_set_el_list (DECL_UNIT (decl)->absence_list);
bea4bad2 8855 fprintf (output_description_file, "\n");
8856 }
58ada791 8857 if (DECL_UNIT (decl)->final_absence_list != NULL)
8858 {
8859 fprintf (output_description_file, "unit %s final_absence_set: ",
8860 DECL_UNIT (decl)->name);
8861 output_pattern_set_el_list
8862 (DECL_UNIT (decl)->final_absence_list);
1a97be37 8863 fprintf (output_description_file, "\n");
8864 }
bea4bad2 8865 }
8866 }
8867 fprintf (output_description_file, "\n");
8043d8fb 8868 for (i = 0; i < description->normal_decls_num; i++)
bea4bad2 8869 {
8870 decl = description->decls [i];
8871 if (decl->mode == dm_reserv)
8872 {
0da6cf03 8873 fprintf (output_description_file, "reservation %s: ",
8874 DECL_RESERV (decl)->name);
2f8ffd86 8875 output_regexp (DECL_RESERV (decl)->regexp);
bea4bad2 8876 fprintf (output_description_file, "\n");
8877 }
8043d8fb 8878 else if (decl->mode == dm_insn_reserv)
bea4bad2 8879 {
8880 fprintf (output_description_file, "insn reservation %s ",
2f8ffd86 8881 DECL_INSN_RESERV (decl)->name);
8882 print_rtl (output_description_file,
8883 DECL_INSN_RESERV (decl)->condexp);
bea4bad2 8884 fprintf (output_description_file, ": ");
2f8ffd86 8885 output_regexp (DECL_INSN_RESERV (decl)->regexp);
bea4bad2 8886 fprintf (output_description_file, "\n");
8887 }
8888 else if (decl->mode == dm_bypass)
8889 fprintf (output_description_file, "bypass %d %s %s\n",
2f8ffd86 8890 DECL_BYPASS (decl)->latency,
2334f0df 8891 DECL_BYPASS (decl)->out_pattern,
8892 DECL_BYPASS (decl)->in_pattern);
bea4bad2 8893 }
8894 fprintf (output_description_file, "\n\f\n");
8895}
8896
8897/* The function outputs name of AUTOMATON. */
8898static void
1a97be37 8899output_automaton_name (FILE *f, automaton_t automaton)
bea4bad2 8900{
8901 if (automaton->corresponding_automaton_decl == NULL)
8902 fprintf (f, "#%d", automaton->automaton_order_num);
8903 else
8904 fprintf (f, "`%s'", automaton->corresponding_automaton_decl->name);
8905}
8906
8907/* Maximal length of line for pretty printing into description
8908 file. */
8909#define MAX_LINE_LENGTH 70
8910
8911/* The function outputs units name belonging to AUTOMATON. */
8912static void
1a97be37 8913output_automaton_units (automaton_t automaton)
bea4bad2 8914{
8915 decl_t decl;
e7827cef 8916 const char *name;
bea4bad2 8917 int curr_line_length;
8918 int there_is_an_automaton_unit;
8919 int i;
8920
069eea26 8921 fprintf (output_description_file, "\n Corresponding units:\n");
bea4bad2 8922 fprintf (output_description_file, " ");
8923 curr_line_length = 4;
8924 there_is_an_automaton_unit = 0;
8925 for (i = 0; i < description->decls_num; i++)
8926 {
8927 decl = description->decls [i];
8928 if (decl->mode == dm_unit
2f8ffd86 8929 && (DECL_UNIT (decl)->corresponding_automaton_num
bea4bad2 8930 == automaton->automaton_order_num))
8931 {
8932 there_is_an_automaton_unit = 1;
2f8ffd86 8933 name = DECL_UNIT (decl)->name;
bea4bad2 8934 if (curr_line_length + strlen (name) + 1 > MAX_LINE_LENGTH )
8935 {
8936 curr_line_length = strlen (name) + 4;
8937 fprintf (output_description_file, "\n ");
8938 }
8939 else
8940 {
8941 curr_line_length += strlen (name) + 1;
8942 fprintf (output_description_file, " ");
8943 }
c968ff5c 8944 fprintf (output_description_file, "%s", name);
bea4bad2 8945 }
8946 }
8947 if (!there_is_an_automaton_unit)
8948 fprintf (output_description_file, "<None>");
8949 fprintf (output_description_file, "\n\n");
8950}
8951
8952/* The following variable is used for forming array of all possible cpu unit
8953 reservations described by the current DFA state. */
f1f41a6c 8954static vec<reserv_sets_t> state_reservs;
bea4bad2 8955
8956/* The function forms `state_reservs' for STATE. */
8957static void
1a97be37 8958add_state_reservs (state_t state)
bea4bad2 8959{
8960 alt_state_t curr_alt_state;
bea4bad2 8961
8962 if (state->component_states != NULL)
8963 for (curr_alt_state = state->component_states;
8964 curr_alt_state != NULL;
8965 curr_alt_state = curr_alt_state->next_sorted_alt_state)
8966 add_state_reservs (curr_alt_state->state);
8967 else
f1f41a6c 8968 state_reservs.safe_push (state->reservs);
bea4bad2 8969}
8970
f503d902 8971/* The function outputs readable representation of all out arcs of
bea4bad2 8972 STATE. */
8973static void
1a97be37 8974output_state_arcs (state_t state)
bea4bad2 8975{
8976 arc_t arc;
8977 ainsn_t ainsn;
e7827cef 8978 const char *insn_name;
bea4bad2 8979 int curr_line_length;
8980
8981 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
8982 {
8983 ainsn = arc->insn;
e0a4c0c2 8984 gcc_assert (ainsn->first_insn_with_same_reservs);
bea4bad2 8985 fprintf (output_description_file, " ");
8986 curr_line_length = 7;
8987 fprintf (output_description_file, "%2d: ", ainsn->insn_equiv_class_num);
8988 do
8989 {
8990 insn_name = ainsn->insn_reserv_decl->name;
8991 if (curr_line_length + strlen (insn_name) > MAX_LINE_LENGTH)
8992 {
8993 if (ainsn != arc->insn)
8994 {
8995 fprintf (output_description_file, ",\n ");
8996 curr_line_length = strlen (insn_name) + 6;
8997 }
8998 else
8999 curr_line_length += strlen (insn_name);
9000 }
9001 else
9002 {
9003 curr_line_length += strlen (insn_name);
9004 if (ainsn != arc->insn)
9005 {
9006 curr_line_length += 2;
9007 fprintf (output_description_file, ", ");
9008 }
9009 }
c968ff5c 9010 fprintf (output_description_file, "%s", insn_name);
bea4bad2 9011 ainsn = ainsn->next_same_reservs_insn;
9012 }
9013 while (ainsn != NULL);
0f7f3d52 9014 fprintf (output_description_file, " %d \n",
9015 arc->to_state->order_state_num);
bea4bad2 9016 }
9017 fprintf (output_description_file, "\n");
9018}
9019
9020/* The following function is used for sorting possible cpu unit
9021 reservation of a DFA state. */
9022static int
1a97be37 9023state_reservs_cmp (const void *reservs_ptr_1, const void *reservs_ptr_2)
bea4bad2 9024{
aae87fc3 9025 return reserv_sets_cmp (*(const_reserv_sets_t const*) reservs_ptr_1,
9026 *(const_reserv_sets_t const*) reservs_ptr_2);
bea4bad2 9027}
9028
9029/* The following function is used for sorting possible cpu unit
9030 reservation of a DFA state. */
9031static void
1a97be37 9032remove_state_duplicate_reservs (void)
bea4bad2 9033{
e7827cef 9034 size_t i, j;
bea4bad2 9035
f1f41a6c 9036 for (i = 1, j = 0; i < state_reservs.length (); i++)
9037 if (reserv_sets_cmp (state_reservs[j], state_reservs[i]))
bea4bad2 9038 {
e7827cef 9039 j++;
f1f41a6c 9040 state_reservs[j] = state_reservs[i];
bea4bad2 9041 }
f1f41a6c 9042 state_reservs.truncate (j + 1);
bea4bad2 9043}
9044
9045/* The following function output readable representation of DFA(s)
9046 state used for fast recognition of pipeline hazards. State is
f503d902 9047 described by possible (current and scheduled) cpu unit
bea4bad2 9048 reservations. */
9049static void
1a97be37 9050output_state (state_t state)
bea4bad2 9051{
e7827cef 9052 size_t i;
9053
f1f41a6c 9054 state_reservs.create (0);
bea4bad2 9055
bea4bad2 9056 fprintf (output_description_file, " State #%d", state->order_state_num);
9057 fprintf (output_description_file,
9058 state->new_cycle_p ? " (new cycle)\n" : "\n");
9059 add_state_reservs (state);
f1f41a6c 9060 state_reservs.qsort (state_reservs_cmp);
bea4bad2 9061 remove_state_duplicate_reservs ();
f1f41a6c 9062 for (i = 0; i < state_reservs.length (); i++)
bea4bad2 9063 {
9064 fprintf (output_description_file, " ");
f1f41a6c 9065 output_reserv_sets (output_description_file, state_reservs[i]);
bea4bad2 9066 fprintf (output_description_file, "\n");
9067 }
9068 fprintf (output_description_file, "\n");
9069 output_state_arcs (state);
f1f41a6c 9070 state_reservs.release ();
bea4bad2 9071}
9072
9073/* The following function output readable representation of
9074 DFAs used for fast recognition of pipeline hazards. */
9075static void
1a97be37 9076output_automaton_descriptions (void)
bea4bad2 9077{
9078 automaton_t automaton;
9079
9080 for (automaton = description->first_automaton;
9081 automaton != NULL;
9082 automaton = automaton->next_automaton)
9083 {
9084 fprintf (output_description_file, "\nAutomaton ");
9085 output_automaton_name (output_description_file, automaton);
9086 fprintf (output_description_file, "\n");
9087 output_automaton_units (automaton);
9088 pass_states (automaton, output_state);
9089 }
9090}
9091
9092\f
9093
9094/* The page contains top level function for generation DFA(s) used for
9095 PHR. */
9096
9097/* The function outputs statistics about work of different phases of
9098 DFA generator. */
9099static void
1a97be37 9100output_statistics (FILE *f)
bea4bad2 9101{
9102 automaton_t automaton;
58ada791 9103 int states_num;
bea4bad2 9104#ifndef NDEBUG
9105 int transition_comb_vect_els = 0;
9106 int transition_full_vect_els = 0;
bea4bad2 9107 int min_issue_delay_vect_els = 0;
c966a2e2 9108 int locked_states = 0;
bea4bad2 9109#endif
9110
9111 for (automaton = description->first_automaton;
9112 automaton != NULL;
9113 automaton = automaton->next_automaton)
9114 {
9115 fprintf (f, "\nAutomaton ");
9116 output_automaton_name (f, automaton);
9117 fprintf (f, "\n %5d NDFA states, %5d NDFA arcs\n",
9118 automaton->NDFA_states_num, automaton->NDFA_arcs_num);
9119 fprintf (f, " %5d DFA states, %5d DFA arcs\n",
9120 automaton->DFA_states_num, automaton->DFA_arcs_num);
58ada791 9121 states_num = automaton->DFA_states_num;
bea4bad2 9122 if (!no_minimization_flag)
58ada791 9123 {
9124 fprintf (f, " %5d minimal DFA states, %5d minimal DFA arcs\n",
9125 automaton->minimal_DFA_states_num,
9126 automaton->minimal_DFA_arcs_num);
9127 states_num = automaton->minimal_DFA_states_num;
9128 }
bea4bad2 9129 fprintf (f, " %5d all insns %5d insn equivalence classes\n",
9130 description->insns_num, automaton->insn_equiv_classes_num);
c966a2e2 9131 fprintf (f, " %d locked states\n", automaton->locked_states);
bea4bad2 9132#ifndef NDEBUG
9133 fprintf
9134 (f, "%5ld transition comb vector els, %5ld trans table els: %s\n",
f1f41a6c 9135 (long) automaton->trans_table->comb_vect.length (),
9136 (long) automaton->trans_table->full_vect.length (),
bea4bad2 9137 (comb_vect_p (automaton->trans_table)
9138 ? "use comb vect" : "use simple vect"));
bea4bad2 9139 fprintf
9140 (f, "%5ld min delay table els, compression factor %d\n",
58ada791 9141 (long) states_num * automaton->insn_equiv_classes_num,
bea4bad2 9142 automaton->min_issue_delay_table_compression_factor);
9143 transition_comb_vect_els
f1f41a6c 9144 += automaton->trans_table->comb_vect.length ();
1a97be37 9145 transition_full_vect_els
f1f41a6c 9146 += automaton->trans_table->full_vect.length ();
bea4bad2 9147 min_issue_delay_vect_els
58ada791 9148 += states_num * automaton->insn_equiv_classes_num;
c966a2e2 9149 locked_states
9150 += automaton->locked_states;
bea4bad2 9151#endif
9152 }
9153#ifndef NDEBUG
9154 fprintf (f, "\n%5d all allocated states, %5d all allocated arcs\n",
9155 allocated_states_num, allocated_arcs_num);
9156 fprintf (f, "%5d all allocated alternative states\n",
9157 allocated_alt_states_num);
9158 fprintf (f, "%5d all transition comb vector els, %5d all trans table els\n",
9159 transition_comb_vect_els, transition_full_vect_els);
bea4bad2 9160 fprintf (f, "%5d all min delay table els\n", min_issue_delay_vect_els);
c966a2e2 9161 fprintf (f, "%5d all locked states\n", locked_states);
bea4bad2 9162#endif
9163}
9164
9165/* The function output times of work of different phases of DFA
9166 generator. */
9167static void
1a97be37 9168output_time_statistics (FILE *f)
bea4bad2 9169{
9170 fprintf (f, "\n transformation: ");
9171 print_active_time (f, transform_time);
9172 fprintf (f, (!ndfa_flag ? ", building DFA: " : ", building NDFA: "));
9173 print_active_time (f, NDFA_time);
9174 if (ndfa_flag)
9175 {
9176 fprintf (f, ", NDFA -> DFA: ");
9177 print_active_time (f, NDFA_to_DFA_time);
9178 }
9179 fprintf (f, "\n DFA minimization: ");
9180 print_active_time (f, minimize_time);
9181 fprintf (f, ", making insn equivalence: ");
9182 print_active_time (f, equiv_time);
9183 fprintf (f, "\n all automaton generation: ");
9184 print_active_time (f, automaton_generation_time);
9185 fprintf (f, ", output: ");
9186 print_active_time (f, output_time);
9187 fprintf (f, "\n");
9188}
9189
f503d902 9190/* The function generates DFA (deterministic finite state automaton)
bea4bad2 9191 for fast recognition of pipeline hazards. No errors during
9192 checking must be fixed before this function call. */
9193static void
1a97be37 9194generate (void)
bea4bad2 9195{
9196 automata_num = split_argument;
9197 if (description->units_num < automata_num)
9198 automata_num = description->units_num;
9199 initiate_states ();
9200 initiate_arcs ();
9201 initiate_automata_lists ();
9202 initiate_pass_states ();
9203 initiate_excl_sets ();
58ada791 9204 initiate_presence_absence_pattern_sets ();
bea4bad2 9205 automaton_generation_time = create_ticker ();
bea4bad2 9206 create_automata ();
9207 ticker_off (&automaton_generation_time);
9208}
9209
9210\f
9211
bea4bad2 9212/* This page mainly contains top level functions of pipeline hazards
9213 description translator. */
9214
9215/* The following macro value is suffix of name of description file of
9216 pipeline hazards description translator. */
9217#define STANDARD_OUTPUT_DESCRIPTION_FILE_SUFFIX ".dfa"
9218
9219/* The function returns suffix of given file name. The returned
9220 string can not be changed. */
9221static const char *
1a97be37 9222file_name_suffix (const char *file_name)
bea4bad2 9223{
9224 const char *last_period;
9225
9226 for (last_period = NULL; *file_name != '\0'; file_name++)
9227 if (*file_name == '.')
9228 last_period = file_name;
9229 return (last_period == NULL ? file_name : last_period);
9230}
9231
9232/* The function returns base name of given file name, i.e. pointer to
9233 first char after last `/' (or `\' for WIN32) in given file name,
9234 given file name itself if the directory name is absent. The
9235 returned string can not be changed. */
9236static const char *
1a97be37 9237base_file_name (const char *file_name)
bea4bad2 9238{
9239 int directory_name_length;
9240
9241 directory_name_length = strlen (file_name);
9242#ifdef WIN32
9243 while (directory_name_length >= 0 && file_name[directory_name_length] != '/'
9244 && file_name[directory_name_length] != '\\')
9245#else
9246 while (directory_name_length >= 0 && file_name[directory_name_length] != '/')
9247#endif
9248 directory_name_length--;
9249 return file_name + directory_name_length + 1;
9250}
9251
e9eae8c8 9252/* A function passed as argument to init_rtx_reader_args_cb. It parses the
9253 options available for genautomata. Returns true if the option was
9254 recognized. */
9255static bool
9256parse_automata_opt (const char *str)
9257{
9258 if (strcmp (str, NO_MINIMIZATION_OPTION) == 0)
9259 no_minimization_flag = 1;
9260 else if (strcmp (str, TIME_OPTION) == 0)
9261 time_flag = 1;
9262 else if (strcmp (str, STATS_OPTION) == 0)
9263 stats_flag = 1;
9264 else if (strcmp (str, V_OPTION) == 0)
9265 v_flag = 1;
9266 else if (strcmp (str, W_OPTION) == 0)
9267 w_flag = 1;
9268 else if (strcmp (str, NDFA_OPTION) == 0)
9269 ndfa_flag = 1;
9270 else if (strcmp (str, COLLAPSE_OPTION) == 0)
9271 collapse_flag = 1;
9272 else if (strcmp (str, PROGRESS_OPTION) == 0)
9273 progress_flag = 1;
9274 else if (strcmp (str, "-split") == 0)
9275 {
9276 fatal ("option `-split' has not been implemented yet\n");
9277 /* split_argument = atoi (argument_vect [i + 1]); */
9278 }
9279 else
9280 return false;
9281
9282 return true;
9283}
9284
bea4bad2 9285/* The following is top level function to initialize the work of
9286 pipeline hazards description translator. */
0f7f3d52 9287static void
e9eae8c8 9288initiate_automaton_gen (char **argv)
bea4bad2 9289{
9290 const char *base_name;
e7827cef 9291
bea4bad2 9292 /* Initialize IR storage. */
9293 obstack_init (&irp);
9294 initiate_automaton_decl_table ();
9295 initiate_insn_decl_table ();
9296 initiate_decl_table ();
9297 output_file = stdout;
9298 output_description_file = NULL;
9299 base_name = base_file_name (argv[1]);
9300 obstack_grow (&irp, base_name,
9301 strlen (base_name) - strlen (file_name_suffix (base_name)));
9302 obstack_grow (&irp, STANDARD_OUTPUT_DESCRIPTION_FILE_SUFFIX,
9303 strlen (STANDARD_OUTPUT_DESCRIPTION_FILE_SUFFIX) + 1);
9304 obstack_1grow (&irp, '\0');
9305 output_description_file_name = obstack_base (&irp);
9306 obstack_finish (&irp);
9307}
9308
9309/* The following function checks existence at least one arc marked by
9310 each insn. */
9311static void
1a97be37 9312check_automata_insn_issues (void)
bea4bad2 9313{
9314 automaton_t automaton;
9315 ainsn_t ainsn, reserv_ainsn;
9316
9317 for (automaton = description->first_automaton;
9318 automaton != NULL;
9319 automaton = automaton->next_automaton)
9320 {
9321 for (ainsn = automaton->ainsn_list;
9322 ainsn != NULL;
9323 ainsn = ainsn->next_ainsn)
8043d8fb 9324 if (ainsn->first_insn_with_same_reservs && !ainsn->arc_exists_p
9325 && ainsn != automaton->collapse_ainsn)
bea4bad2 9326 {
9327 for (reserv_ainsn = ainsn;
9328 reserv_ainsn != NULL;
9329 reserv_ainsn = reserv_ainsn->next_same_reservs_insn)
9330 if (automaton->corresponding_automaton_decl != NULL)
9331 {
9332 if (!w_flag)
9333 error ("Automaton `%s': Insn `%s' will never be issued",
9334 automaton->corresponding_automaton_decl->name,
9335 reserv_ainsn->insn_reserv_decl->name);
9336 else
86931af8 9337 warning ("Automaton `%s': Insn `%s' will never be issued",
9338 automaton->corresponding_automaton_decl->name,
9339 reserv_ainsn->insn_reserv_decl->name);
bea4bad2 9340 }
9341 else
9342 {
9343 if (!w_flag)
9344 error ("Insn `%s' will never be issued",
9345 reserv_ainsn->insn_reserv_decl->name);
9346 else
86931af8 9347 warning ("Insn `%s' will never be issued",
bea4bad2 9348 reserv_ainsn->insn_reserv_decl->name);
9349 }
9350 }
9351 }
9352}
9353
9354/* The following vla is used for storing pointers to all achieved
9355 states. */
f1f41a6c 9356static vec<state_t> automaton_states;
bea4bad2 9357
9358/* This function is called by function pass_states to add an achieved
9359 STATE. */
9360static void
1a97be37 9361add_automaton_state (state_t state)
bea4bad2 9362{
f1f41a6c 9363 automaton_states.safe_push (state);
bea4bad2 9364}
9365
9366/* The following function forms list of important automata (whose
9367 states may be changed after the insn issue) for each insn. */
9368static void
1a97be37 9369form_important_insn_automata_lists (void)
bea4bad2 9370{
9371 automaton_t automaton;
bea4bad2 9372 decl_t decl;
9373 ainsn_t ainsn;
9374 arc_t arc;
9375 int i;
e7827cef 9376 size_t n;
bea4bad2 9377
f1f41a6c 9378 automaton_states.create (0);
b35eefd9 9379 /* Mark important ainsns. */
bea4bad2 9380 for (automaton = description->first_automaton;
9381 automaton != NULL;
9382 automaton = automaton->next_automaton)
9383 {
f1f41a6c 9384 automaton_states.truncate (0);
bea4bad2 9385 pass_states (automaton, add_automaton_state);
f1f41a6c 9386 for (n = 0; n < automaton_states.length (); n++)
bea4bad2 9387 {
f1f41a6c 9388 state_t s = automaton_states[n];
e7827cef 9389 for (arc = first_out_arc (s);
bea4bad2 9390 arc != NULL;
9391 arc = next_out_arc (arc))
e7827cef 9392 if (arc->to_state != s)
bea4bad2 9393 {
e0a4c0c2 9394 gcc_assert (arc->insn->first_insn_with_same_reservs);
bea4bad2 9395 for (ainsn = arc->insn;
9396 ainsn != NULL;
9397 ainsn = ainsn->next_same_reservs_insn)
9398 ainsn->important_p = TRUE;
9399 }
9400 }
9401 }
f1f41a6c 9402 automaton_states.release ();
e7827cef 9403
b35eefd9 9404 /* Create automata sets for the insns. */
bea4bad2 9405 for (i = 0; i < description->decls_num; i++)
9406 {
9407 decl = description->decls [i];
9408 if (decl->mode == dm_insn_reserv)
9409 {
9410 automata_list_start ();
9411 for (automaton = description->first_automaton;
9412 automaton != NULL;
9413 automaton = automaton->next_automaton)
9414 for (ainsn = automaton->ainsn_list;
9415 ainsn != NULL;
9416 ainsn = ainsn->next_ainsn)
9417 if (ainsn->important_p
2f8ffd86 9418 && ainsn->insn_reserv_decl == DECL_INSN_RESERV (decl))
bea4bad2 9419 {
9420 automata_list_add (automaton);
9421 break;
9422 }
2f8ffd86 9423 DECL_INSN_RESERV (decl)->important_automata_list
bea4bad2 9424 = automata_list_finish ();
9425 }
9426 }
9427}
9428
9429
9430/* The following is top level function to generate automat(a,on) for
9431 fast recognition of pipeline hazards. */
0f7f3d52 9432static void
1a97be37 9433expand_automata (void)
bea4bad2 9434{
9435 int i;
9436
65b198c2 9437 description = XCREATENODEVAR (struct description,
9438 sizeof (struct description)
8043d8fb 9439 /* Two entries for special insns. */
f1f41a6c 9440 + sizeof (decl_t) * (decls.length () + 1));
9441 description->decls_num = decls.length ();
8043d8fb 9442 description->normal_decls_num = description->decls_num;
bea4bad2 9443 description->query_units_num = 0;
9444 for (i = 0; i < description->decls_num; i++)
9445 {
f1f41a6c 9446 description->decls [i] = decls[i];
bea4bad2 9447 if (description->decls [i]->mode == dm_unit
2f8ffd86 9448 && DECL_UNIT (description->decls [i])->query_p)
9449 DECL_UNIT (description->decls [i])->query_num
bea4bad2 9450 = description->query_units_num++;
9451 }
9452 all_time = create_ticker ();
9453 check_time = create_ticker ();
bccc9ebc 9454 if (progress_flag)
9455 fprintf (stderr, "Check description...");
bea4bad2 9456 check_all_description ();
bccc9ebc 9457 if (progress_flag)
9458 fprintf (stderr, "done\n");
bea4bad2 9459 ticker_off (&check_time);
9460 generation_time = create_ticker ();
b35eefd9 9461 if (!have_error)
9462 {
9463 transform_insn_regexps ();
9464 check_unit_distributions_to_automata ();
9465 }
bea4bad2 9466 if (!have_error)
9467 {
9468 generate ();
b35eefd9 9469 check_automata_insn_issues ();
9470 }
9471 if (!have_error)
9472 {
9473 form_important_insn_automata_lists ();
bea4bad2 9474 }
9475 ticker_off (&generation_time);
bea4bad2 9476}
9477
9478/* The following is top level function to output PHR and to finish
9479 work with pipeline description translator. */
0f7f3d52 9480static void
1a97be37 9481write_automata (void)
bea4bad2 9482{
bea4bad2 9483 output_time = create_ticker ();
bccc9ebc 9484 if (progress_flag)
9485 fprintf (stderr, "Forming and outputting automata tables...");
bea4bad2 9486 output_tables ();
bccc9ebc 9487 if (progress_flag)
9488 {
9489 fprintf (stderr, "done\n");
9490 fprintf (stderr, "Output functions to work with automata...");
9491 }
bea4bad2 9492 output_chip_definitions ();
9493 output_max_insn_queue_index_def ();
9494 output_internal_min_issue_delay_func ();
9495 output_internal_trans_func ();
9496 /* Cache of insn dfa codes: */
9497 fprintf (output_file, "\nstatic int *%s;\n", DFA_INSN_CODES_VARIABLE_NAME);
9498 fprintf (output_file, "\nstatic int %s;\n\n",
9499 DFA_INSN_CODES_LENGTH_VARIABLE_NAME);
9500 output_dfa_insn_code_func ();
9501 output_trans_func ();
bea4bad2 9502 output_min_issue_delay_func ();
9503 output_internal_dead_lock_func ();
9504 output_dead_lock_func ();
9505 output_size_func ();
9506 output_internal_reset_func ();
9507 output_reset_func ();
9508 output_min_insn_conflict_delay_func ();
e1ab7874 9509 output_default_latencies ();
bea4bad2 9510 output_internal_insn_latency_func ();
9511 output_insn_latency_func ();
e1ab7874 9512 output_internal_maximal_insn_latency_func ();
9513 output_maximal_insn_latency_func ();
bea4bad2 9514 output_print_reservation_func ();
58ada791 9515 /* Output function get_cpu_unit_code. */
9516 fprintf (output_file, "\n#if %s\n\n", CPU_UNITS_QUERY_MACRO_NAME);
9517 output_get_cpu_unit_code_func ();
9518 output_cpu_unit_reservation_p ();
07317795 9519 output_insn_has_dfa_reservation_p ();
58ada791 9520 fprintf (output_file, "\n#endif /* #if %s */\n\n",
9521 CPU_UNITS_QUERY_MACRO_NAME);
9522 output_dfa_clean_insn_cache_func ();
bea4bad2 9523 output_dfa_start_func ();
9524 output_dfa_finish_func ();
bccc9ebc 9525 if (progress_flag)
9526 fprintf (stderr, "done\n");
bea4bad2 9527 if (v_flag)
9528 {
9529 output_description_file = fopen (output_description_file_name, "w");
9530 if (output_description_file == NULL)
9531 {
9532 perror (output_description_file_name);
9533 exit (FATAL_EXIT_CODE);
9534 }
bccc9ebc 9535 if (progress_flag)
9536 fprintf (stderr, "Output automata description...");
bea4bad2 9537 output_description ();
9538 output_automaton_descriptions ();
bccc9ebc 9539 if (progress_flag)
9540 fprintf (stderr, "done\n");
bea4bad2 9541 output_statistics (output_description_file);
9542 }
df04f68e 9543 if (stats_flag)
9544 output_statistics (stderr);
bea4bad2 9545 ticker_off (&output_time);
df04f68e 9546 if (time_flag)
9547 output_time_statistics (stderr);
bea4bad2 9548 finish_states ();
9549 finish_arcs ();
9550 finish_automata_lists ();
9551 if (time_flag)
9552 {
9553 fprintf (stderr, "Summary:\n");
9554 fprintf (stderr, " check time ");
9555 print_active_time (stderr, check_time);
9556 fprintf (stderr, ", generation time ");
9557 print_active_time (stderr, generation_time);
9558 fprintf (stderr, ", all time ");
9559 print_active_time (stderr, all_time);
9560 fprintf (stderr, "\n");
9561 }
9562 /* Finish all work. */
9563 if (output_description_file != NULL)
9564 {
9565 fflush (output_description_file);
9566 if (ferror (stdout) != 0)
115875a1 9567 fatal ("Error in writing DFA description file %s: %s",
9568 output_description_file_name, xstrerror (errno));
bea4bad2 9569 fclose (output_description_file);
9570 }
9571 finish_automaton_decl_table ();
9572 finish_insn_decl_table ();
9573 finish_decl_table ();
9574 obstack_free (&irp, NULL);
9575 if (have_error && output_description_file != NULL)
9576 remove (output_description_file_name);
9577}
0f7f3d52 9578
9579int
9580main (int argc, char **argv)
9581{
9582 rtx desc;
9583
9584 progname = "genautomata";
9585
e9eae8c8 9586 if (!init_rtx_reader_args_cb (argc, argv, parse_automata_opt))
0f7f3d52 9587 return (FATAL_EXIT_CODE);
9588
e9eae8c8 9589 initiate_automaton_gen (argv);
0f7f3d52 9590 while (1)
9591 {
9592 int lineno;
9593 int insn_code_number;
9594
9595 desc = read_md_rtx (&lineno, &insn_code_number);
9596 if (desc == NULL)
9597 break;
9598
9599 switch (GET_CODE (desc))
9600 {
9601 case DEFINE_CPU_UNIT:
9602 gen_cpu_unit (desc);
9603 break;
9604
9605 case DEFINE_QUERY_CPU_UNIT:
9606 gen_query_cpu_unit (desc);
9607 break;
9608
9609 case DEFINE_BYPASS:
9610 gen_bypass (desc);
9611 break;
9612
9613 case EXCLUSION_SET:
9614 gen_excl_set (desc);
9615 break;
9616
9617 case PRESENCE_SET:
9618 gen_presence_set (desc);
9619 break;
9620
9621 case FINAL_PRESENCE_SET:
9622 gen_final_presence_set (desc);
9623 break;
9624
9625 case ABSENCE_SET:
9626 gen_absence_set (desc);
9627 break;
9628
9629 case FINAL_ABSENCE_SET:
9630 gen_final_absence_set (desc);
9631 break;
9632
9633 case DEFINE_AUTOMATON:
9634 gen_automaton (desc);
9635 break;
9636
9637 case AUTOMATA_OPTION:
9638 gen_automata_option (desc);
9639 break;
9640
9641 case DEFINE_RESERVATION:
9642 gen_reserv (desc);
9643 break;
9644
9645 case DEFINE_INSN_RESERVATION:
9646 gen_insn_reserv (desc);
9647 break;
9648
9649 default:
9650 break;
9651 }
9652 }
9653
9654 if (have_error)
9655 return FATAL_EXIT_CODE;
9656
f1f41a6c 9657 if (decls.length () > 0)
0f7f3d52 9658 {
9659 expand_automata ();
48ca7187 9660 if (!have_error)
9661 {
9662 puts ("/* Generated automatically by the program `genautomata'\n"
9663 " from the machine description file `md'. */\n\n"
9664 "#include \"config.h\"\n"
9665 "#include \"system.h\"\n"
9666 "#include \"coretypes.h\"\n"
9667 "#include \"tm.h\"\n"
41a8aa41 9668 "#include \"tree.h\"\n"
48ca7187 9669 "#include \"rtl.h\"\n"
9670 "#include \"tm_p.h\"\n"
9671 "#include \"insn-config.h\"\n"
9672 "#include \"recog.h\"\n"
9673 "#include \"regs.h\"\n"
48ca7187 9674 "#include \"output.h\"\n"
9675 "#include \"insn-attr.h\"\n"
c18cb818 9676 "#include \"diagnostic-core.h\"\n"
48ca7187 9677 "#include \"flags.h\"\n"
06f9d6ef 9678 "#include \"function.h\"\n"
9679 "#include \"emit-rtl.h\"\n");
9680 /* FIXME: emit-rtl.h can go away once crtl is in rtl.h. */
48ca7187 9681
9682 write_automata ();
9683 }
0f7f3d52 9684 }
541be8d3 9685 else
9686 {
9687 puts ("/* Generated automatically by the program `genautomata'\n"
9688 " from the machine description file `md'. */\n\n"
9689 "/* There is no automaton, but ISO C forbids empty\n"
9690 " translation units, so include a header file with some\n"
188e2ebd 9691 " declarations, and its pre-requisite header file. */\n"
541be8d3 9692 "#include \"config.h\"\n"
9693 "#include \"system.h\"\n");
9694 }
0f7f3d52 9695
9696 fflush (stdout);
48ca7187 9697 return (ferror (stdout) != 0 || have_error
9698 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);
0f7f3d52 9699}