GCC's bacl-end & assemble emission (35)

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   }

7767   output_state_ainsn_table

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

}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值