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