/* Pipeline hazard description translator.
- Copyright (C) 2000, 2001 Free Software Foundation, Inc.
+ Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc.
Written by Vladimir Makarov <vmakarov@redhat.com>
struct state_ainsn_table;
/* The following typedefs are for brevity. */
+typedef struct unit_decl *unit_decl_t;
typedef struct decl *decl_t;
typedef struct regexp *regexp_t;
typedef struct unit_set_el *unit_set_el_t;
static regexp_t transform_regexp PARAMS ((regexp_t));
static void transform_insn_regexps PARAMS ((void));
+static void process_unit_to_form_the_same_automaton_unit_lists
+ PARAMS ((regexp_t, regexp_t, int));
+static void form_the_same_automaton_unit_lists_from_regexp PARAMS ((regexp_t));
+static void form_the_same_automaton_unit_lists PARAMS ((void));
+static void check_unit_distributions_to_automata PARAMS ((void));
+
static int process_seq_for_forming_states PARAMS ((regexp_t, automaton_t,
int));
static void finish_forming_alt_state PARAMS ((alt_state_t,
static void add_states_vect_el PARAMS ((state_t));
static void output_trans_table PARAMS ((automaton_t));
static void output_state_alts_table PARAMS ((automaton_t));
-static void min_issue_delay_pass_states PARAMS ((state_t, ainsn_t));
+static int min_issue_delay_pass_states PARAMS ((state_t, ainsn_t));
static int min_issue_delay PARAMS ((state_t, ainsn_t));
static void initiate_min_issue_delay_pass_states PARAMS ((void));
static void output_min_issue_delay_table PARAMS ((automaton_t));
static void make_bypass_attr PARAMS ((void));
static const char *file_name_suffix PARAMS ((const char *));
static const char *base_file_name PARAMS ((const char *));
-static void check_automata PARAMS ((void));
+static void check_automata_insn_issues PARAMS ((void));
static void add_automaton_state PARAMS ((state_t));
static void form_important_insn_automata_lists PARAMS ((void));
/* The following field value is nonzero if the unit is used in an
regexp. */
char unit_is_used;
+
+ /* The following field value is used to form cyclic lists of units
+ which should be in the same automaton because the unit is
+ reserved not on all alternatives of a regexp on a cycle. */
+ unit_decl_t the_same_automaton_unit;
+ /* The following field is TRUE if we already reported that the unit
+ is not in the same automaton. */
+ int the_same_automaton_message_reported_p;
+
/* The following field value is order number (0, 1, ...) of given
unit. */
int unit_num;
enters. */
int state_alts;
/* The following member value is the list to automata which can be
- changed by the insn issue. */
+ changed by the insn issue. */
automata_list_el_t important_automata_list;
/* The following member is used to process insn once for output. */
int processed_p;
struct unit_regexp
{
char *name;
- struct unit_decl *unit_decl;
+ unit_decl_t unit_decl;
};
/* Define_reservation in a reservation. */
presence_list, absence_list. */
struct unit_set_el
{
- struct unit_decl *unit_decl;
+ unit_decl_t unit_decl;
unit_set_el_t next_unit_set_el;
};
};
/* The following macro is an initial value of member
- `longest_path_length' of a state. */
+ `longest_path_length' of a state. */
#define UNDEFINED_LONGEST_PATH_LENGTH -1
/* Automaton arc. */
description->max_insn_reserv_cycles = max_insn_cycles_num;
}
}
+ description->max_insn_reserv_cycles++;
}
/* The following function calls functions for checking all
/* This page contains abstract data `state'. */
-/* Maximal length of reservations in cycles (> 1). */
+/* Maximal length of reservations in cycles (>= 1). */
static int max_cycles_num;
/* Number of set elements (see type set_el_t) needed for
static vla_ptr_t units_container;
/* The start address of the array. */
-static struct unit_decl **units_array;
+static unit_decl_t *units_array;
/* Empty reservation of maximal length. */
static reserv_sets_t empty_reserv;
reserv_sets_hash_value (reservs)
reserv_sets_t reservs;
{
- unsigned int hash_value;
- int reservs_num;
+ set_el_t hash_value;
+ unsigned result;
+ int reservs_num, i;
set_el_t *reserv_ptr;
hash_value = 0;
reservs_num = els_in_reservs;
reserv_ptr = reservs;
+ i = 0;
while (reservs_num != 0)
{
reservs_num--;
- hash_value = ((hash_value >> (sizeof (unsigned) - 1) * CHAR_BIT)
- | (hash_value << CHAR_BIT)) + *reserv_ptr;
+ hash_value += ((*reserv_ptr >> i)
+ | (*reserv_ptr << (sizeof (set_el_t) * CHAR_BIT - i)));
+ i++;
+ if (i == sizeof (set_el_t) * CHAR_BIT)
+ i = 0;
reserv_ptr++;
}
- return hash_value;
+ if (sizeof (set_el_t) <= sizeof (unsigned))
+ return hash_value;
+ result = 0;
+ for (i = sizeof (set_el_t); i > 0; i -= sizeof (unsigned) - 1)
+ {
+ result += (unsigned) hash_value;
+ hash_value >>= (sizeof (unsigned) - 1) * CHAR_BIT;
+ }
+ return result;
}
/* Comparison of given reservation sets. */
fprintf (f, NOTHING_NAME);
if (repetition_num <= 0)
abort ();
- if (reserved_units_num != 0 && repetition_num != 1)
- {
- if (reserved_units_num > 1)
- fprintf (f, ")");
- fprintf (f, "*%d", repetition_num);
- }
+ if (reserved_units_num > 1)
+ fprintf (f, ")");
+ if (repetition_num != 1)
+ fprintf (f, "*%d", repetition_num);
}
/* The function outputs string representation of units reservation in
VLA_PTR_CREATE (units_container, description->units_num, "units_container");
units_array
- = (description->decls_num ? VLA_PTR_BEGIN (units_container) : NULL);
+ = (description->decls_num && description->units_num
+ ? VLA_PTR_BEGIN (units_container) : NULL);
for (i = 0; i < description->decls_num; i++)
{
decl = description->decls [i];
units_array [decl->decl.unit.unit_num] = &decl->decl.unit;
}
max_cycles_num = description->max_insn_reserv_cycles;
- if (max_cycles_num == 0)
- max_cycles_num++;
els_in_cycle_reserv
= ((description->units_num + sizeof (set_el_t) * CHAR_BIT - 1)
/ (sizeof (set_el_t) * CHAR_BIT));
/* The function makes transformations
...,A|B|...,C,... -> (...,A,C,...)|(...,B,C,...)|...
- ...+(A|B|...)+C+... -> (...+A+C+...)|(...+B+C+...)|... */
+ ...+(A|B|...)+C+... -> (...+A+C+...)|(...+B+C+...)|...
+ ...+(A,B,...)+C+... -> (...+A+C+...),B,...
+ ...+(A,B,...)+(C,D,...) -> (A+C),(B+D),... */
static regexp_t
transform_3 (regexp)
regexp_t regexp;
}
else if (regexp->mode == rm_allof)
{
- regexp_t oneof;
- int oneof_index;
+ regexp_t oneof, seq;
+ int oneof_index, max_seq_length, allof_length;
regexp_t result;
- regexp_t allof;
+ regexp_t allof, allof_op;
int i, j;
for (i = 0; i < regexp->regexp.allof.regexps_num; i++)
regexp_transformed_p = 1;
regexp = result;
}
+ max_seq_length = 0;
+ for (i = 0; i < regexp->regexp.allof.regexps_num; i++)
+ if (regexp->regexp.allof.regexps [i]->mode == rm_sequence)
+ {
+ seq = regexp->regexp.allof.regexps [i];
+ if (max_seq_length < seq->regexp.sequence.regexps_num)
+ max_seq_length = seq->regexp.sequence.regexps_num;
+ }
+ else if (regexp->regexp.allof.regexps [i]->mode != rm_unit)
+ {
+ max_seq_length = 0;
+ break;
+ }
+ if (max_seq_length != 0)
+ {
+ if (max_seq_length == 1 || regexp->regexp.allof.regexps_num <= 1)
+ abort ();
+ result = create_node (sizeof (struct regexp)
+ + sizeof (regexp_t) * (max_seq_length - 1));
+ result->mode = rm_sequence;
+ result->pos = regexp->pos;
+ result->regexp.sequence.regexps_num = max_seq_length;
+ for (i = 0; i < max_seq_length; i++)
+ {
+ allof_length = 0;
+ for (j = 0; j < regexp->regexp.allof.regexps_num; j++)
+ if (regexp->regexp.allof.regexps [j]->mode == rm_sequence
+ && (i < (regexp->regexp.allof.regexps [j]
+ ->regexp.sequence.regexps_num)))
+ {
+ allof_op = (regexp->regexp.allof.regexps [j]
+ ->regexp.sequence.regexps [i]);
+ allof_length++;
+ }
+ else if (i == 0
+ && regexp->regexp.allof.regexps [j]->mode == rm_unit)
+ {
+ allof_op = regexp->regexp.allof.regexps [j];
+ allof_length++;
+ }
+ if (allof_length == 1)
+ result->regexp.sequence.regexps [i] = allof_op;
+ else
+ {
+ allof = create_node (sizeof (struct regexp)
+ + sizeof (regexp_t)
+ * (allof_length - 1));
+ allof->mode = rm_allof;
+ allof->pos = regexp->pos;
+ allof->regexp.allof.regexps_num = allof_length;
+ result->regexp.sequence.regexps [i] = allof;
+ allof_length = 0;
+ for (j = 0; j < regexp->regexp.allof.regexps_num; j++)
+ if (regexp->regexp.allof.regexps [j]->mode == rm_sequence
+ && (i < (regexp->regexp.allof.regexps [j]
+ ->regexp.sequence.regexps_num)))
+ {
+ allof_op = (regexp->regexp.allof.regexps [j]
+ ->regexp.sequence.regexps [i]);
+ allof->regexp.allof.regexps [allof_length] = allof_op;
+
+ allof_length++;
+ }
+ else if (i == 0
+ && (regexp->regexp.allof.regexps [j]->mode
+ == rm_unit))
+ {
+ allof_op = regexp->regexp.allof.regexps [j];
+ allof->regexp.allof.regexps [allof_length] = allof_op;
+ allof_length++;
+ }
+ }
+ }
+ regexp_transformed_p = 1;
+ regexp = result;
+ }
}
return regexp;
}
decl_t decl;
int i;
+ transform_time = create_ticker ();
+ add_advance_cycle_insn_decl ();
+ fprintf (stderr, "Reservation transformation...");
+ fflush (stderr);
for (i = 0; i < description->decls_num; i++)
{
decl = description->decls [i];
= transform_regexp (copy_insn_regexp
(decl->decl.insn_reserv.regexp));
}
+ fprintf (stderr, "done\n");
+ ticker_off (&transform_time);
+ fflush (stderr);
+}
+
+\f
+
+/* The following variable is an array indexed by cycle. Each element
+ contains cyclic list of units which should be in the same cycle. */
+static unit_decl_t *the_same_automaton_lists;
+
+/* The function processes all alternative reservations on CYCLE in
+ given REGEXP to check the UNIT is not reserved on the all
+ alternatives. If it is true, the unit should be in the same
+ automaton with other analogous units reserved on CYCLE in given
+ REGEXP. */
+static void
+process_unit_to_form_the_same_automaton_unit_lists (unit, regexp, cycle)
+ regexp_t unit;
+ regexp_t regexp;
+ int cycle;
+{
+ int i, k;
+ regexp_t seq, allof;
+ unit_decl_t unit_decl, last;
+
+ if (regexp == NULL || regexp->mode != rm_oneof)
+ abort ();
+ unit_decl = unit->regexp.unit.unit_decl;
+ for (i = regexp->regexp.oneof.regexps_num - 1; i >= 0; i--)
+ {
+ seq = regexp->regexp.oneof.regexps [i];
+ if (seq->mode == rm_sequence)
+ {
+ if (cycle >= seq->regexp.sequence.regexps_num)
+ break;
+ allof = seq->regexp.sequence.regexps [cycle];
+ if (allof->mode == rm_allof)
+ {
+ for (k = 0; k < allof->regexp.allof.regexps_num; k++)
+ if (allof->regexp.allof.regexps [k]->mode == rm_unit
+ && (allof->regexp.allof.regexps [k]->regexp.unit.unit_decl
+ == unit_decl))
+ break;
+ if (k >= allof->regexp.allof.regexps_num)
+ break;
+ }
+ else if (allof->mode == rm_unit
+ && allof->regexp.unit.unit_decl != unit_decl)
+ break;
+ }
+ else if (cycle != 0)
+ break;
+ else if (seq->mode == rm_allof)
+ {
+ for (k = 0; k < seq->regexp.allof.regexps_num; k++)
+ if (seq->regexp.allof.regexps [k]->mode == rm_unit
+ && (seq->regexp.allof.regexps [k]->regexp.unit.unit_decl
+ == unit_decl))
+ break;
+ if (k >= seq->regexp.allof.regexps_num)
+ break;
+ }
+ else if (seq->mode == rm_unit && seq->regexp.unit.unit_decl != unit_decl)
+ break;
+ }
+ if (i >= 0)
+ {
+ if (the_same_automaton_lists [cycle] == NULL)
+ the_same_automaton_lists [cycle] = unit_decl;
+ else
+ {
+ for (last = the_same_automaton_lists [cycle];;)
+ {
+ if (last == unit_decl)
+ return;
+ if (last->the_same_automaton_unit
+ == the_same_automaton_lists [cycle])
+ break;
+ last = last->the_same_automaton_unit;
+ }
+ last->the_same_automaton_unit = unit_decl->the_same_automaton_unit;
+ unit_decl->the_same_automaton_unit
+ = the_same_automaton_lists [cycle];
+ }
+ }
+}
+
+/* The function processes given REGEXP to find units which should be
+ in the same automaton. */
+static void
+form_the_same_automaton_unit_lists_from_regexp (regexp)
+ regexp_t regexp;
+{
+ int i, j, k;
+ regexp_t seq, allof, unit;
+
+ if (regexp == NULL || regexp->mode != rm_oneof)
+ return;
+ for (i = 0; i < description->max_insn_reserv_cycles; i++)
+ the_same_automaton_lists [i] = NULL;
+ for (i = regexp->regexp.oneof.regexps_num - 1; i >= 0; i--)
+ {
+ seq = regexp->regexp.oneof.regexps [i];
+ if (seq->mode == rm_sequence)
+ for (j = 0; j < seq->regexp.sequence.regexps_num; j++)
+ {
+ allof = seq->regexp.sequence.regexps [j];
+ if (allof->mode == rm_allof)
+ for (k = 0; k < allof->regexp.allof.regexps_num; k++)
+ {
+ unit = allof->regexp.allof.regexps [k];
+ if (unit->mode == rm_unit)
+ process_unit_to_form_the_same_automaton_unit_lists
+ (unit, regexp, j);
+ else if (unit->mode != rm_nothing)
+ abort ();
+ }
+ else if (allof->mode == rm_unit)
+ process_unit_to_form_the_same_automaton_unit_lists
+ (allof, regexp, j);
+ else if (allof->mode != rm_nothing)
+ abort ();
+ }
+ else if (seq->mode == rm_allof)
+ for (k = 0; k < seq->regexp.allof.regexps_num; k++)
+ {
+ unit = seq->regexp.allof.regexps [k];
+ if (unit->mode == rm_unit)
+ process_unit_to_form_the_same_automaton_unit_lists
+ (unit, regexp, 0);
+ else if (unit->mode != rm_nothing)
+ abort ();
+ }
+ else if (seq->mode == rm_unit)
+ process_unit_to_form_the_same_automaton_unit_lists (seq, regexp, 0);
+ else if (seq->mode != rm_nothing)
+ abort ();
+ }
+}
+
+/* The function initializes data to search for units which should be
+ in the same automaton and call function
+ `form_the_same_automaton_unit_lists_from_regexp' for each insn
+ reservation regexp. */
+static void
+form_the_same_automaton_unit_lists ()
+{
+ decl_t decl;
+ int i;
+
+ the_same_automaton_lists
+ = (unit_decl_t *) xmalloc (description->max_insn_reserv_cycles
+ * sizeof (unit_decl_t));
+ for (i = 0; i < description->decls_num; i++)
+ {
+ decl = description->decls [i];
+ if (decl->mode == dm_unit)
+ {
+ decl->decl.unit.the_same_automaton_message_reported_p = FALSE;
+ decl->decl.unit.the_same_automaton_unit = &decl->decl.unit;
+ }
+ }
+ for (i = 0; i < description->decls_num; i++)
+ {
+ decl = description->decls [i];
+ if (decl->mode == dm_insn_reserv)
+ form_the_same_automaton_unit_lists_from_regexp
+ (decl->decl.insn_reserv.transformed_regexp);
+ }
+ free (the_same_automaton_lists);
+}
+
+/* The function finds units which should be in the same automaton and,
+ if they are not, reports about it. */
+static void
+check_unit_distributions_to_automata ()
+{
+ decl_t decl;
+ unit_decl_t start_unit_decl, unit_decl;
+ int i;
+
+ form_the_same_automaton_unit_lists ();
+ for (i = 0; i < description->decls_num; i++)
+ {
+ decl = description->decls [i];
+ if (decl->mode == dm_unit)
+ {
+ start_unit_decl = &decl->decl.unit;
+ if (!start_unit_decl->the_same_automaton_message_reported_p)
+ for (unit_decl = start_unit_decl->the_same_automaton_unit;
+ unit_decl != start_unit_decl;
+ unit_decl = unit_decl->the_same_automaton_unit)
+ if (start_unit_decl->automaton_decl != unit_decl->automaton_decl)
+ {
+ error ("Units `%s' and `%s' should be in the same automaton",
+ start_unit_decl->name, unit_decl->name);
+ unit_decl->the_same_automaton_message_reported_p = TRUE;
+ }
+ }
+ }
}
\f
removing nonequivalent states and placing them in
*NEXT_ITERATION_CLASSES, increments *NEW_EQUIV_CLASS_NUM_PTR ans
assigns it to the state equivalence number. If the class has been
- partitioned, the function returns nonzero value. */
+ partitioned, the function returns nonzero value. */
static int
partition_equiv_class (equiv_class_ptr, odd_iteration_flag,
next_iteration_classes, new_equiv_class_num_ptr)
result = 0;
for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
- /* Ignore cycles containing one state and `cycle advance' arcs. */
+ /* Ignore cycles containing one state and `cycle advance' arcs. */
if (arc->to_state != state
&& (arc->insn->insn_reserv_decl
!= &advance_cycle_insn_decl->decl.insn_reserv))
static int max_dfa_issue_rate;
/* The following function processes the longest path length staring
- from STATE to find MAX_DFA_ISSUE_RATE. */
+ from STATE to find MAX_DFA_ISSUE_RATE. */
static void
process_state_longest_path_length (state)
/* Name of cache of insn dfa codes. */
#define DFA_INSN_CODES_VARIABLE_NAME "dfa_insn_codes"
-/* Name of length of cache of insn dfa codes. */
+/* Name of length of cache of insn dfa codes. */
#define DFA_INSN_CODES_LENGTH_VARIABLE_NAME "dfa_insn_codes_length"
/* Names of the PHR interface functions: */
/* This recursive function passes states to find minimal issue delay
- value for AINSN. The state being visited is STATE. */
-static void
+ value for AINSN. The state being visited is STATE. The function
+ returns minimal issue delay value for AINSN in STATE or -1 if we
+ enter into a loop. */
+static int
min_issue_delay_pass_states (state, ainsn)
state_t state;
ainsn_t ainsn;
arc_t arc;
int min_insn_issue_delay, insn_issue_delay;
- if (state->state_pass_num == curr_state_pass_num)
- return;
+ if (state->state_pass_num == curr_state_pass_num
+ || state->min_insn_issue_delay != -1)
+ /* We've entered into a loop or already have the correct value for
+ given state and ainsn. */
+ return state->min_insn_issue_delay;
state->state_pass_num = curr_state_pass_num;
- min_insn_issue_delay = state->min_insn_issue_delay = -1;
+ min_insn_issue_delay = -1;
for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
if (arc->insn == ainsn)
{
}
else
{
- min_issue_delay_pass_states (arc->to_state, ainsn);
- if (arc->to_state->min_insn_issue_delay != -1)
+ insn_issue_delay = min_issue_delay_pass_states (arc->to_state, ainsn);
+ if (insn_issue_delay != -1)
{
- insn_issue_delay
- = (arc->to_state->min_insn_issue_delay
- + (arc->insn->insn_reserv_decl
- == &advance_cycle_insn_decl->decl.insn_reserv ? 1 : 0));
+ if (arc->insn->insn_reserv_decl
+ == &advance_cycle_insn_decl->decl.insn_reserv)
+ insn_issue_delay++;
if (min_insn_issue_delay == -1
|| min_insn_issue_delay > insn_issue_delay)
- min_insn_issue_delay = insn_issue_delay;
+ {
+ min_insn_issue_delay = insn_issue_delay;
+ if (insn_issue_delay == 0)
+ break;
+ }
}
}
- state->min_insn_issue_delay = min_insn_issue_delay;
+ return min_insn_issue_delay;
}
/* The function searches minimal issue delay value for AINSN in STATE.
- The function can return negative can not issue AINSN. We will
- report about it later. */
+ The function can return negative value if we can not issue AINSN. We
+ will report about it later. */
static int
min_issue_delay (state, ainsn)
state_t state;
ainsn_t ainsn;
{
curr_state_pass_num++;
- min_issue_delay_pass_states (state, ainsn);
+ state->min_insn_issue_delay = min_issue_delay_pass_states (state, ainsn);
return state->min_insn_issue_delay;
}
i++)
VLA_HWINT (min_issue_delay_vect, i) = 0;
automaton->max_min_delay = 0;
- for (state_ptr = VLA_PTR_BEGIN (output_states_vect);
- state_ptr <= (state_t *) VLA_PTR_LAST (output_states_vect);
- state_ptr++)
- {
- for (ainsn = automaton->ainsn_list;
- ainsn != NULL;
- ainsn = ainsn->next_ainsn)
- if (ainsn->first_ainsn_with_given_equialence_num)
- {
+ for (ainsn = automaton->ainsn_list; ainsn != NULL; ainsn = ainsn->next_ainsn)
+ if (ainsn->first_ainsn_with_given_equialence_num)
+ {
+ for (state_ptr = VLA_PTR_BEGIN (output_states_vect);
+ state_ptr <= (state_t *) VLA_PTR_LAST (output_states_vect);
+ state_ptr++)
+ (*state_ptr)->min_insn_issue_delay = -1;
+ for (state_ptr = VLA_PTR_BEGIN (output_states_vect);
+ state_ptr <= (state_t *) VLA_PTR_LAST (output_states_vect);
+ state_ptr++)
+ {
min_delay = min_issue_delay (*state_ptr, ainsn);
if (automaton->max_min_delay < min_delay)
automaton->max_min_delay = min_delay;
* automaton->insn_equiv_classes_num
+ ainsn->insn_equiv_class_num) = min_delay;
}
- }
+ }
fprintf (output_file, "/* Vector of min issue delay of insns.*/\n");
fprintf (output_file, "static const ");
output_range_type (output_file, 0, automaton->max_min_delay);
fprintf (output_file, "static int %s PARAMS ((int, struct %s *));\n",
INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME, CHIP_NAME);
fprintf (output_file,
- "static int\n%s (%s, %s)\n\tint %s;\n\tstruct %s *%s;\n",
+ "static int\n%s (%s, %s)\n\tint %s;\n\tstruct %s *%s ATTRIBUTE_UNUSED;\n",
INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME, INTERNAL_INSN_CODE_NAME,
CHIP_PARAMETER_NAME, INTERNAL_INSN_CODE_NAME, CHIP_NAME,
CHIP_PARAMETER_NAME);
- fprintf (output_file, "{\n int %s;\n int %s;\n",
+ fprintf (output_file, "{\n int %s ATTRIBUTE_UNUSED;\n int %s;\n",
TEMPORARY_VARIABLE_NAME, RESULT_VARIABLE_NAME);
fprintf (output_file, "\n switch (%s)\n {\n", INTERNAL_INSN_CODE_NAME);
output_insn_code_cases (output_automata_list_min_issue_delay_code);
fprintf (output_file, "static int %s PARAMS ((int, struct %s *));\n",
INTERNAL_TRANSITION_FUNC_NAME, CHIP_NAME);
fprintf (output_file,
- "static int\n%s (%s, %s)\n\tint %s;\n\tstruct %s *%s;\n",
+ "static int\n%s (%s, %s)\n\tint %s;\n\tstruct %s *%s ATTRIBUTE_UNUSED;\n",
INTERNAL_TRANSITION_FUNC_NAME, INTERNAL_INSN_CODE_NAME,
CHIP_PARAMETER_NAME, INTERNAL_INSN_CODE_NAME,
CHIP_NAME, CHIP_PARAMETER_NAME);
- fprintf (output_file, "{\n int %s;\n", TEMPORARY_VARIABLE_NAME);
+ fprintf (output_file, "{\n int %s ATTRIBUTE_UNUSED;\n", TEMPORARY_VARIABLE_NAME);
fprintf (output_file, "\n switch (%s)\n {\n", INTERNAL_INSN_CODE_NAME);
output_insn_code_cases (output_automata_list_transition_code);
fprintf (output_file, "\n default:\n return -1;\n }\n");
units_cmp (unit1, unit2)
const void *unit1, *unit2;
{
- const struct unit_decl *u1 = *(struct unit_decl **) unit1;
- const struct unit_decl *u2 = *(struct unit_decl **) unit2;
+ const unit_decl_t u1 = *(unit_decl_t *) unit1;
+ const unit_decl_t u2 = *(unit_decl_t *) unit2;
return strcmp (u1->name, u2->name);
}
output_get_cpu_unit_code_func ()
{
int i;
- struct unit_decl **units;
+ unit_decl_t *units;
fprintf (output_file, "int\n%s (%s)\n\tconst char *%s;\n",
GET_CPU_UNIT_CODE_FUNC_NAME, CPU_UNIT_NAME_PARAMETER_NAME,
LOW_VARIABLE_NAME, MIDDLE_VARIABLE_NAME, HIGH_VARIABLE_NAME);
fprintf (output_file, " static struct %s %s [] =\n {\n",
NAME_CODE_STRUCT_NAME, NAME_CODE_TABLE_NAME);
- units = (struct unit_decl **) xmalloc (sizeof (struct unit_decl *)
- * description->units_num);
- memcpy (units, units_array,
- sizeof (struct unit_decl *) * description->units_num);
- qsort (units, description->units_num,
- sizeof (struct unit_decl *), units_cmp);
+ units = (unit_decl_t *) xmalloc (sizeof (unit_decl_t)
+ * description->units_num);
+ memcpy (units, units_array, sizeof (unit_decl_t) * description->units_num);
+ qsort (units, description->units_num, sizeof (unit_decl_t), units_cmp);
for (i = 0; i < description->units_num; i++)
if (units [i]->query_p)
fprintf (output_file, " {\"%s\", %d},\n",
initiate_excl_sets ();
initiate_presence_absence_sets ();
automaton_generation_time = create_ticker ();
- transform_time = create_ticker ();
- add_advance_cycle_insn_decl ();
- fprintf (stderr, "Reservation transformation...");
- fflush (stderr);
- transform_insn_regexps ();
- fprintf (stderr, "done\n");
- ticker_off (&transform_time);
- fflush (stderr);
create_automata ();
ticker_off (&automaton_generation_time);
}
/* The following function checks existence at least one arc marked by
each insn. */
static void
-check_automata ()
+check_automata_insn_issues ()
{
automaton_t automaton;
ainsn_t ainsn, reserv_ainsn;
VLA_PTR_CREATE (automaton_states, 1500,
"automaton states for forming important insn automata sets");
- /* Mark important ainsns. */
+ /* Mark important ainsns. */
for (automaton = description->first_automaton;
automaton != NULL;
automaton = automaton->next_automaton)
}
}
VLA_PTR_DELETE (automaton_states);
- /* Create automata sets for the insns. */
+ /* Create automata sets for the insns. */
for (i = 0; i < description->decls_num; i++)
{
decl = description->decls [i];
generation_time = create_ticker ();
if (!have_error)
{
+ transform_insn_regexps ();
+ check_unit_distributions_to_automata ();
+ }
+ if (!have_error)
+ {
generate ();
- check_automata ();
- if (!have_error)
- {
- form_important_insn_automata_lists ();
- fprintf (stderr, "Generation of attributes...");
- fflush (stderr);
- make_internal_dfa_insn_code_attr ();
- make_insn_alts_attr ();
- make_default_insn_latency_attr ();
- make_bypass_attr ();
- fprintf (stderr, "done\n");
- }
+ check_automata_insn_issues ();
+ }
+ if (!have_error)
+ {
+ form_important_insn_automata_lists ();
+ fprintf (stderr, "Generation of attributes...");
+ fflush (stderr);
+ make_internal_dfa_insn_code_attr ();
+ make_insn_alts_attr ();
+ make_default_insn_latency_attr ();
+ make_bypass_attr ();
+ fprintf (stderr, "done\n");
}
ticker_off (&generation_time);
ticker_off (&all_time);