9.6.4. Output data for automaton
In 9.5.8 Automata generation, we have seenthat during automaton generation, lot of data are created. Now it is time tooutput code for it.
9867 void
9868 write_automata (void) in genautomata.c
9869 {
9870 if (progress_flag)
9871 fprintf (stderr, "done\n");
9872 if (have_error)
9873 fatal ("Errors in DFAdescription");
9874 ticker_on (&all_time);
9875 output_time = create_ticker ();
9876 if (progress_flag)
9877 fprintf (stderr, "Forming andoutputting automata tables...");
9878 output_dfa_max_issue_rate();
9879 output_tables();
9880 if (progress_flag)
9881 {
9882 fprintf (stderr, "done\n");
9883 fprintf (stderr, "Output functions towork with automata...");
9884 }
At line 9878, output_dfa_max_issue_ratedetermines the value of max_dfa_issue_rate which is accessed by macro MAX_DFA_ISSUE_RATE.Its value is equal to maximal number of all instructons described inconstructions `define_insn_reservation' which can be issued on the sameprocessor cycle.
7090 static void
7091 output_dfa_max_issue_rate (void) in genautomata.c
7092 {
7093 automaton_tautomaton;
7094
7095 if (UNDEFINED_LONGEST_PATH_LENGTH ==ON_THE_PATH || ON_THE_PATH >= 0)
7096 abort ();
7097 max_dfa_issue_rate = 0;
7098 for(automaton = description->first_automaton;
7099 automaton != NULL;
7100 automaton = automaton->next_automaton)
7101 pass_states(automaton, process_state_longest_path_length);
7102 fprintf (output_file, "\nint %s = %d;\n",
7103 MAX_DFA_ISSUE_RATE_VAR_NAME, max_dfa_issue_rate);
7104 }
Above, UNDEFINED_LONGEST_PATH_LENGTH is defined as -1, ON_THE_PATHis defined as -2.
7072 static void
7073 process_state_longest_path_length (state_t state) in genautomata.c
7074 {
7075 int value;
7076
7077 value = longest_path_length(state);
7078 if (value > max_dfa_issue_rate)
7079 max_dfa_issue_rate = value;
7080 }
We have seen that instruction issue drives up the automaton here.And pseudo instruction advance_cycle_insn_decl advances the CPU onecycle. So longest_path_lengthfinds out the max number of instructions can be issued in one cycle. This valueis saved into max_dfa_issue_rateat line 7079 above.
7034 static int
7035 longest_path_length (state_tstate) in genautomata.c
7036 {
7037 arc_t arc;
7038 int length, result;
7039
7040 if (state->longest_path_length == ON_THE_PATH)
7041 /* We don'texpect the path cycle here. Our graph may contain
7042 only cycles with one state on the pathnot containing `cycle
7043 advance' arcs -- see comment below. */
7044 abort ();
7045 else if (state->longest_path_length !=UNDEFINED_LONGEST_PATH_LENGTH)
7046 /* We alreadyvisited the state. */
7047 returnstate->longest_path_length;
7048
7049 result = 0;
7050 for (arc =first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
7051 /* Ignore cyclescontaining one state and `cycle advance' arcs. */
7052 if (arc->to_state != state
7053 &&(arc->insn->insn_reserv_decl
7054 != DECL_INSN_RESERV (advance_cycle_insn_decl)))
7055 {
7056 length = longest_path_length(arc->to_state);
7057 if (length > result)
7058 result = length;
7059 }
7060 state->longest_path_length = result + 1;
7061 returnresult;
7062 }
9.6.4.1. Output tables
As in most automatons, table driven frequently gives the expectedperformance, the automaton generated here is also table driven. Function output_tablesproduces tables for the automaton.
8077 static void
8078 output_tables (void) in genautomata.c
8079 {
8080 automaton_tautomaton;
8081
8082 #ifndef NDEBUG
8083 locked_states_num = 0;
8084 #endif
8085 initiate_min_issue_delay_pass_states ();
8086 for(automaton = description->first_automaton;
8087 automaton != NULL;
8088 automaton = automaton->next_automaton)
8089 {
8090 output_translate_vect(automaton);
8091 output_trans_table(automaton);
8092 fprintf (output_file, "\n#if%s\n", AUTOMATON_STATE_ALTS_MACRO_NAME);
8093 output_state_alts_table(automaton);
8094 fprintf (output_file, "\n#endif /* #if%s */\n\n",
8095 AUTOMATON_STATE_ALTS_MACRO_NAME);
8096 output_min_issue_delay_table(automaton);
8097 output_dead_lock_vect(automaton);
8098 fprintf (output_file, "\n#if%s\n\n", CPU_UNITS_QUERY_MACRO_NAME);
8099 output_reserved_units_table(automaton);
8100 fprintf (output_file, "\n#endif /* #if%s */\n\n",
8101 CPU_UNITS_QUERY_MACRO_NAME);
8102 }
8103 fprintf (output_file, "\n#define %s %d\n\n",ADVANCE_CYCLE_VALUE_NAME,
8104 DECL_INSN_RESERV (advance_cycle_insn_decl)->insn_num);
8105 }
9.6.4.1.1. Outputtable for instruction equivalent set
At line 8085 above, initiate_min_issue_delay_pass_statesinitializes curr_state_pass_numto 0. As we have known automatons are driven by instructions set of equivalentclass instead of single instructions. Often, given certain insn code(identifier of instruction), it needs find out the equivalent class belongs to.We have found out the relation in 9.5.8Automata generation. It needs a table for mapping external instructionnumber to internal instruction number (equivalent class number indeed).
7439 static void
7440 output_translate_vect (automaton_t automaton) in genautomata.c
7441 {
7442 ainsn_t ainsn;
7443 int insn_value;
7444 vla_hwint_t translate_vect;
7445
7446 VLA_HWINT_CREATE (translate_vect, 250,"translate vector");
7447 VLA_HWINT_EXPAND (translate_vect, description->insns_num);
7448 for(insn_value = 0; insn_value < description->insns_num; insn_value++)
7449 /* Undefinedvalue */
7450 VLA_HWINT (translate_vect, insn_value) =automaton->insn_equiv_classes_num;
7451 for (ainsn = automaton->ainsn_list; ainsn != NULL;ainsn = ainsn->next_ainsn)
7452 VLA_HWINT (translate_vect, ainsn->insn_reserv_decl->insn_num)
7453 = ainsn->insn_equiv_class_num;
7454 fprintf (output_file,
7455 "/* Vector translating externalinsn codes to internal ones.*/\n");
7456 fprintf (output_file, "static const ");
7457 output_range_type(output_file,0, automaton->insn_equiv_classes_num);
7458 fprintf (output_file, " ");
7459 output_translate_vect_name(output_file,automaton);
7460 fprintf (output_file, "[] ATTRIBUTE_UNUSED ={\n");
7461 output_vect(VLA_HWINT_BEGIN (translate_vect),
7462 VLA_HWINT_LENGTH (translate_vect));
7463 fprintf (output_file, "};\n\n");
7464 VLA_HWINT_DELETE (translate_vect);
7465 }
We have known that insn_equiv_classes_num of automaton records thenumber of equivalent class in the automaton and the field insn_equiv_class_num of ainsnrecords the No. of equivalent class it belongs to (see set_insn_equiv_classes).
output_range_typedecides the type declared for the variable in output file.
7008 static void
7009 output_range_type (FILE *f, long intmin_range_value, ingenautomata.c
7010 long int max_range_value)
7011 {
7012 if (min_range_value >= 0 &&max_range_value <= 255)
7013 fprintf (f, "unsigned char");
7014 else if (min_range_value >= -127&& max_range_value <= 127)
7015 fprintf (f, "signed char");
7016 else if (min_range_value >= 0 &&max_range_value <= 65535)
7017 fprintf (f, "unsigned short");
7018 else if (min_range_value >= -32767&& max_range_value <= 32767)
7019 fprintf (f, "short");
7020 else
7021 fprintf (f, "int");
7022 }
Then output_translate_vect_nameoutputs name for the automaton, following at line 7027, automaton_order_num is assigned in create_automataas the sequential No.
7168 static void
7169 output_translate_vect_name (FILE *f, automaton_t automaton) ingenautomata.c
7170 {
7171 if (automaton->corresponding_automaton_decl== NULL)
7172 fprintf (f, "translate_%d",automaton->automaton_order_num);
7173 else
7174 fprintf (f, "%s_translate",automaton->corresponding_automaton_decl->name);
7175 }
In this step, we have output following code for automaton. Assumingthe number of equivalent class of the automaton is less than 255, and only oneautomaton is created (default case, however, for modern cpu architecture,commonly more than 1 automatons will be declared).
/* Vector translating external insn codes to internalones.*/
static const unsigned char translate_0 []ATTRIBUTE_UNUSED = {
Here vectis translate_vectin output_translate_vect, as all insnsare ensured can be issued when building automaton, every element (insn) in vectwill contain equivalent set number. Notice that vect is indexed by insn num – thesequential number of instruction.
7108 static void
7109 output_vect (vect_el_t *vect, intvect_length) ingenautomata.c
7110 {
7111 int els_on_line;
7112
7113 els_on_line = 1;
7114 if (vect_length == 0)
7115 fprintf (output_file,
7116 "0 /* This is dummy el becausethe vect is empty */");
7117 else
7118 {
7119 do
7120 {
7121 fprintf (output_file, "%5ld",(long) *vect);
7122 vect_length--;
7123 if (els_on_line == 10)
7124 {
7125 els_on_line = 0;
7126 fprintf (output_file, ",\n");
7127 }
7128 else if (vect_length != 0)
7129 fprintf (output_file, ", ");
7130 els_on_line++;
7131 vect++;
7132 }
7133 while(vect_length != 0);
7134 }
7135 }
So the output translate_0 is a map between external instructionnum and instruction unit reservation equivalent class number.
9.6.4.1.2. Outputtable(s) for state transition
State, according to the way it created, can tell the resourcesoccupied. State transition is driven by instruction issuing (in form ofequivalent class indeed), arc is created to record the detail of transition.See state and arc are indivisible data; the output tables should embody both ofthem.
7731 static void
7732 output_trans_table (automaton_t automaton) ingenautomata.c
7733 {
7734 state_t *state_ptr;
7735 arc_t arc;
7736 vla_hwint_t transition_vect;
7737
7738 undefined_vect_el_value =automaton->achieved_states_num;
7739 automaton->trans_table = create_state_ainsn_table (automaton);
7740 /* Create vect ofpointers to states ordered by num of transitions
7741 from the state (state with the maximum numis the first). */
7742 VLA_PTR_CREATE (output_states_vect, 1500,"output states vector");
7743 pass_states(automaton, add_states_vect_el);
7744 qsort (VLA_PTR_BEGIN (output_states_vect),
7745 VLA_PTR_LENGTH (output_states_vect),
7746 sizeof (state_t), compare_transition_els_num);
7747 VLA_HWINT_CREATE (transition_vect, 500,"transition vector");
7748 for(state_ptr = VLA_PTR_BEGIN (output_states_vect);
7749 state_ptr <= (state_t*) VLA_PTR_LAST (output_states_vect);
7750 state_ptr++)
7751 {
7752 VLA_HWINT_NULLIFY (transition_vect);
7753 for (arc =first_out_arc (*state_ptr);
7754 arc != NULL;
7755 arc = next_out_arc (arc))
7756 {
7757 if (arc->insn == NULL)
7758 abort ();
7759 if (arc->insn->first_ainsn_with_given_equialence_num)
7760 add_vect_el(&transition_vect, arc->insn,
7761 arc->to_state->order_state_num);
7762 }
7763 add_vect(automaton->trans_table, (*state_ptr)->order_state_num,
7764 VLA_HWINT_BEGIN (transition_vect),
7765 VLA_HWINT_LENGTH(transition_vect));
7766 }
7768 (automaton->trans_table, (char *)"state transitions",
7769 output_trans_full_vect_name, output_trans_comb_vect_name,
7770 output_trans_check_vect_name, output_trans_base_vect_name);
7771 VLA_PTR_DELETE (output_states_vect);
7772 VLA_HWINT_DELETE (transition_vect);
7773 }
achieved_states_num at line 7738 records the number of states of the automaton (see enumerate_states).create_state_ainsn_table atline 7739 creates an instance of state_ainsn_table.
7481 static state_ainsn_table_t
7482 create_state_ainsn_table (automaton_t automaton) ingenautomata.c
7483 {
7484 state_ainsn_table_ttab;
7485 int full_vect_length;
7486 int i;
7487
7488 tab = create_node (sizeof(struct state_ainsn_table));
7489 tab->automaton = automaton;
7490 VLA_HWINT_CREATE (tab->comb_vect, 10000,"comb vector");
7491 VLA_HWINT_CREATE (tab->check_vect, 10000,"check vector");
7492 VLA_HWINT_CREATE (tab->base_vect, 1000,"base vector");
7493 VLA_HWINT_EXPAND (tab->base_vect,automaton->achieved_states_num);
7494 VLA_HWINT_CREATE (tab->full_vect, 10000,"full vector");
7495 full_vect_length =(automaton->insn_equiv_classes_num
7496 *automaton->achieved_states_num);
7497 VLA_HWINT_EXPAND (tab->full_vect,full_vect_length);
7498 for (i = 0; i< full_vect_length; i++)
7499 VLA_HWINT (tab->full_vect, i) = undefined_vect_el_value;
7500 tab->min_base_vect_el_value= 0;
7501 tab->max_base_vect_el_value = 0;
7502 tab->min_comb_vect_el_value = 0;
7503 tab->max_comb_vect_el_value = 0;
7504 return tab;
7505 }
state_ainsn_table has following definition. It helps to collect datafor output table.
1280 struct state_ainsn_table in genautomata.c
1281 {
1282 /* Automaton towhich given table belongs. */
1283 automaton_tautomaton;
1284 /* The followingtree vectors for comb vector implementation of the
1285 table. */
1286 vla_hwint_t comb_vect;
1287 vla_hwint_tcheck_vect;
1288 vla_hwint_t base_vect;
1289 /* This is simpleimplementation of the table. */
1290 vla_hwint_t full_vect;
1291 /* Minimal andmaximal values of the previous vectors. */
1292 int min_comb_vect_el_value,max_comb_vect_el_value;
1293 int min_base_vect_el_value,max_base_vect_el_value;
1294 };
207 typedef struct state_ainsn_table*state_ainsn_table_t; ingenautomata.c
add_states_vect_eland pass_states,at line 7743 in create_state_ainsn_table, addsevery state of the automaton into output_states_vect which is of type vla_ptr_t.
7723 static void
7724 add_states_vect_el (state_tstate) in genautomata.c
7725 {
7726 VLA_PTR_ADD (output_states_vect, state);
7727 }
At line 7746 output_trans_table,compare_transition_els_numsorts states by the number of transitions in increasing order. Then output_trans_table traverses statesin output_states_vectwhich are now sorted by increasing order of transitions number. For everytransition from the state, as we have known, is triggered by certaininstruction, and all instructions are grouped by resource it reserves(equivalent class). And first_ainsn_with_given_equialence_num at line7759 is set for first found instruction in the class (see set_insn_equiv_classes). Forinstructions of this kind, the sequential No. of the destination state (see order_state_numat line 7761, passed via el_value below), and the instruction (see ainsnbelow) are passed to add_vect_el.
7702 static void
7703 add_vect_el (vla_hwint_t *vect, ainsn_tainsn, int el_value) ingenautomata.c
7704 {
7705 int equiv_class_num;
7706 int vect_index;
7707
7708 if (ainsn == NULL)
7709 abort ();
7710 equiv_class_num =ainsn->insn_equiv_class_num;
7711 for(vect_index = VLA_HWINT_LENGTH (*vect);
7712 vect_index <= equiv_class_num;
7713 vect_index++)
7714 VLA_HWINT_ADD (*vect, undefined_vect_el_value);
7715 VLA_HWINT (*vect, equiv_class_num) =el_value;
7716 }
See that add_vect_el resides in the FOR loop, as a result, transition_vectis input with following data. Notice that order_state_num is the sequential No. of thedestination state and its position is decided by equivalent class number of theinstruction triggering the transition. So this array binds all destinationstates with triggering instructions for given source state.
As the impactof VLA_HWINT_ADD is to enlarge vect by one element, then append undefined_vect_el_valueat its tail, so the size of vect is the max “equiv_class_num”.
figure 97 : output table of state_transition, step 1
Then this array is passed to add_vect by vectbelow. And tabrefers to trans_tablecreated in create_state_ainsn_table, which isempty now.
7566 static void
7567 add_vect (state_ainsn_table_ttab, int vect_num, ingenautomata.c
7568 vect_el_t *vect, int vect_length)
7569 {
7570 int real_vect_length;
7571 vect_el_t *comb_vect_start;
7572 vect_el_t *check_vect_start;
7573 int comb_vect_index;
7574 int comb_vect_els_num;
7575 int vect_index;
7576 int first_unempty_vect_index;
7577 int additional_els_num;
7578 int no_state_value;
7579 vect_el_t vect_el;
7580 int i;
7581
7582 if (vect_length == 0)
7583 abort ();
7584 real_vect_length =tab->automaton->insn_equiv_classes_num;
7585 if (vect [vect_length - 1] == undefined_vect_el_value)
7586 abort ();
7587 /* Form full vectorin the table: */
7588 for (i = 0; i< vect_length; i++)
7589 VLA_HWINT (tab->full_vect,
7590 i +tab->automaton->insn_equiv_classes_num * vect_num)
7591 = vect [i];
7592 /* Form comb vectorin the table: */
7593 if (VLA_HWINT_LENGTH (tab->comb_vect) !=VLA_HWINT_LENGTH (tab->check_vect))
7594 abort ();
7595 comb_vect_start = VLA_HWINT_BEGIN(tab->comb_vect);
7596 comb_vect_els_num = VLA_HWINT_LENGTH(tab->comb_vect);
7597 for(first_unempty_vect_index = 0;
7598 first_unempty_vect_index <vect_length;
7599 first_unempty_vect_index++)
7600 if (vect [first_unempty_vect_index] != undefined_vect_el_value)
7601 break;
7602 /* Search for theplace in comb vect for the inserted vect. */
7603 for(comb_vect_index = 0;
7604 comb_vect_index < comb_vect_els_num;
7605 comb_vect_index++)
7606 {
7607 for(vect_index = first_unempty_vect_index;
7608 vect_index < vect_length
7609 && vect_index +comb_vect_index < comb_vect_els_num;
7610 vect_index++)
7611 if (vect [vect_index] != undefined_vect_el_value
7612 && (comb_vect_start[vect_index + comb_vect_index]
7613 != undefined_vect_el_value))
7614 break;
7615 if (vect_index >= vect_length
7616 || vect_index + comb_vect_index >=comb_vect_els_num)
7617 break;
7618 }
7619 /* Slot wasfound. */
7620 additional_els_num = comb_vect_index +real_vect_length - comb_vect_els_num;
7621 if (additional_els_num < 0)
7622 additional_els_num = 0;
7623 /* Expand comb andcheck vectors. */
7624 vect_el = undefined_vect_el_value;
7625 no_state_value =tab->automaton->achieved_states_num;
7626 while(additional_els_num > 0)
7627 {
7628 VLA_HWINT_ADD (tab->comb_vect, vect_el);
7629 VLA_HWINT_ADD (tab->check_vect,no_state_value);
7630 additional_els_num--;
7631 }
7632 comb_vect_start = VLA_HWINT_BEGIN(tab->comb_vect);
7633 check_vect_start = VLA_HWINT_BEGIN(tab->check_vect);
7634 if (VLA_HWINT_LENGTH (tab->comb_vect)
7635 < (size_t) (comb_vect_index +real_vect_length))
7636 abort ();
7637 /* Fill comb andcheck vectors. */
7638 for(vect_index = 0; vect_index < vect_length; vect_index++)
7639 if (vect [vect_index] != undefined_vect_el_value)
7640 {
7641 if (comb_vect_start [comb_vect_index +vect_index]
7642 != undefined_vect_el_value)
7643 abort ();
7644 comb_vect_start [comb_vect_index +vect_index] = vect [vect_index];
7645 if (vect [vect_index] < 0)
7646 abort ();
7647 if(tab->max_comb_vect_el_value < vect [vect_index])
7648 tab->max_comb_vect_el_value = vect[vect_index];
7649 if (tab->min_comb_vect_el_value >vect [vect_index])
7650 tab->min_comb_vect_el_value = vect[vect_index];
7651 check_vect_start [comb_vect_index +vect_index] = vect_num;
7652 }
7653 if (tab->max_comb_vect_el_value < undefined_vect_el_value)
7654 tab->max_comb_vect_el_value = undefined_vect_el_value;
7655 if (tab->min_comb_vect_el_value > undefined_vect_el_value)
7656 tab->min_comb_vect_el_value = undefined_vect_el_value;
7657 if (tab->max_base_vect_el_value <comb_vect_index)
7658 tab->max_base_vect_el_value =comb_vect_index;
7659 if (tab->min_base_vect_el_value >comb_vect_index)
7660 tab->min_base_vect_el_value =comb_vect_index;
7661 VLA_HWINT (tab->base_vect, vect_num) =comb_vect_index;
7662 }
In FOR loop at line 7588,full_vectof tab(of type state_ainsn_table) can be regarded asarray of two dimensions, which is shown in below figure.
figure 98 : output table of state_transition, step 2
See that this array may be sparse indeed. Toreduce the size of state related function output, we can create a much smaller vector;comb_vectof tabis such a vector. As now this vector is not per state, we need extra vectors tosave information of source state.
To better understand the filling procefure of comb_vect and check_vect, assuming that theautomaton has 8 effective states in all, in first state it can transit tostates of No. 3 and 5 (we needn’t care about the state No. here), and thesecond state has the destination states of No. 2 and 4 respectively, then forthird state, there are 3 and 6.
For loop at line 7597 first finds out the index of the firsteffective unit in the array in figure 97, which is the initial value of FOR loop at line 7607. And FOR loopat line 7603 scans comb_vect and vect, if satisfies condition at line 7611, itindicates that the unit in comb_vect has been filled.
For the firststate, at first comb_vectis empty, so additional_els_numat line 7620 will be all automaton->insn_equiv_classes_num. Then WHILE loopat line 7626 fills comb_vect all by undefined_vect_el_value and check_vectall by automaton->achieved_states_num (the number of state of theautomaton). Next in FOR loop at line 7638, fills comb_vect the same as the vectorfor the first state, and check_vect with the No. of this source state, asindicated by below figure.
figure 99 : output table of state_transition, step 3
Then for the secondstate, transition_vectis refilled (line 7752 in output_trans_table),FOR loop at line 7603 sees if comb_vecthas been filled at specified poistion, and exits the FOR loop at line 7614 if so, then increases comb_vect_index at line 7603 andretry, till finds out certain comb_vect_index which makes comb_vect capable for transition_vect.For the second state, obviously comb_vect_index of 0 is OK as below figureindicates.
figure 100 : output table of state_transition, step 4
For the thirdstate, comb_vect [2] has been occupied by state 1, so increases comb_vect_indexto 1, nevertheless comb_vect [3] is also used by state 2, further increases comb_vect_indexto 2, however comb_vect [4] is still used by state 1. Until increasing comb_vect_indexto 3, when comb_vect [5] is available, after filling in state 3, it gets belowfiugre.
figure 101 : output table of state_transition, step 4
In above figure, we omit the vector of base_vect, which is indexed bysource state numbe and its content is comb_vect_index. From this index, we can recoverthe original vector for the state.
Now it is time to output the vectors we see above by output_state_ainsn_table.
7509 static void
7510 output_state_ainsn_table (state_ainsn_table_t tab, char *table_name, in genautomata.c
7511 void (*output_full_vect_name_func) (FILE *, automaton_t),
7512 void (*output_comb_vect_name_func) (FILE *, automaton_t),
7513 void (*output_check_vect_name_func) (FILE *, automaton_t),
7514 void (*output_base_vect_name_func) (FILE *, automaton_t))
7515 {
7516 if (!comb_vect_p (tab))
7517 {
7518 fprintf (output_file, "/* Vector for%s. */\n", table_name);
7519 fprintf (output_file, "static const");
7520 output_range_type(output_file,tab->min_comb_vect_el_value,
7521 tab->max_comb_vect_el_value);
7522 fprintf (output_file, " ");
7523 (*output_full_vect_name_func) (output_file,tab->automaton);
7524 fprintf (output_file, "[]ATTRIBUTE_UNUSED = {\n");
7525 output_vect(VLA_HWINT_BEGIN (tab->full_vect),
7526 VLA_HWINT_LENGTH(tab->full_vect));
7527 fprintf (output_file, "};\n\n");
7528 }
7529 else
7530 {
7531 fprintf (output_file, "/* Comb vectorfor %s. */\n", table_name);
7532 fprintf (output_file, "static const");
7533 output_range_type(output_file,tab->min_comb_vect_el_value,
7534 tab->max_comb_vect_el_value);
7535 fprintf (output_file, " ");
7536 (*output_comb_vect_name_func) (output_file,tab->automaton);
7537 fprintf (output_file, "[]ATTRIBUTE_UNUSED = {\n");
7538 output_vect(VLA_HWINT_BEGIN (tab->comb_vect),
7539 VLA_HWINT_LENGTH(tab->comb_vect));
7540 fprintf (output_file, "};\n\n");
7541 fprintf (output_file, "/* Check vectorfor %s. */\n", table_name);
7542 fprintf (output_file, "static const");
7543 output_range_type(output_file,0, tab->automaton->achieved_states_num);
7544 fprintf (output_file, " ");
7545 (*output_check_vect_name_func) (output_file,tab->automaton);
7546 fprintf (output_file, "[] = {\n");
7547 output_vect(VLA_HWINT_BEGIN (tab->check_vect),
7548 VLA_HWINT_LENGTH (tab->check_vect));
7549 fprintf (output_file, "};\n\n");
7550 fprintf (output_file, "/* Base vectorfor %s. */\n", table_name);
7551 fprintf (output_file, "static const");
7552 output_range_type(output_file,tab->min_base_vect_el_value,
7553 tab->max_base_vect_el_value);
7554 fprintf (output_file, " ");
7555 (*output_base_vect_name_func) (output_file,tab->automaton);
7556 fprintf (output_file, "[] = {\n");
7557 output_vect(VLA_HWINT_BEGIN (tab->base_vect),
7558 VLA_HWINT_LENGTH(tab->base_vect));
7559 fprintf (output_file, "};\n\n");
7560 }
7561 }
Above at line 7516, comb_vect_p checks if comb_vect is larger than two fifthsof full_vect.If so, we usecomb_vect, else use full_vect instead. Assuming we use comb_vect,now we will get following in output file (insn-attrtab.c)
/*Vector translating external insn codes to internal ones.*/
static const unsigned char translate_0 []ATTRIBUTE_UNUSED = {
`equivalent class set` //in description order
};
/*Comb vector for state transitions */
staticconst unsigned char transitions_0 [] ATTRIBUTE_UNUSED = {
`content of comb_vect` // refer to add_vect
};
/*Check vector for state transitions */
staticconst unsigned char check_0 [] ATTRIBUTE_UNUSED = {
`content of check_vect` // refer to add_vect
};
/* Basevector for state transitions */
staticconst unsigned char base_0 [] ATTRIBUTE_UNUSED = {
`content of base_vect` // refer to add_vect
}