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

9.6.4.2.    Outputfunctions for interface

Now all tablesare ready. In fact, we can see that the relation of states and the instructionsto trigger the transition, and the relation of resource competition amonginstructions (via issue delay) are all embodied into these talbes. At the sametime the potential dependency (via blockage cost or ready cost) amonginstructions and detail about delayslots for certain branch/jump instructions are already output in form of attributefetching function tegother with other normal tool generated attribute accessor.

It now canproduce interface for pipeline hazards recognizer.

 

write_automata (continued)

 

9885   output_chip_definitions();

9886   output_max_insn_queue_index_def();

9887   output_internal_min_issue_delay_func();

9888   output_internal_trans_func();

9889   /* Cache of insndfa codes: */

9890   fprintf (output_file, "\nstatic int *%s;\n",DFA_INSN_CODES_VARIABLE_NAME);

9891   fprintf (output_file, "\nstatic int %s;\n\n",

9892          DFA_INSN_CODES_LENGTH_VARIABLE_NAME);

9893   output_dfa_insn_code_func();

9894   output_trans_func();

9895   fprintf (output_file, "\n#if %s\n\n",AUTOMATON_STATE_ALTS_MACRO_NAME);

9896   output_internal_state_alts_func();

9897   output_state_alts_func();

9898   fprintf (output_file, "\n#endif /* #if %s*/\n\n",

9899         AUTOMATON_STATE_ALTS_MACRO_NAME);

9900  output_min_issue_delay_func();

9901   output_internal_dead_lock_func();

9902   output_dead_lock_func();

9903   output_size_func();

9904   output_internal_reset_func();

9905   output_reset_func();

9906   output_min_insn_conflict_delay_func();

9907   output_internal_insn_latency_func();

9908   output_insn_latency_func();

9909   output_print_reservation_func();

9910   /* Output functionget_cpu_unit_code.  */

9911   fprintf (output_file, "\n#if %s\n\n",CPU_UNITS_QUERY_MACRO_NAME);

9912   output_get_cpu_unit_code_func();

9913   output_cpu_unit_reservation_p();

9914   fprintf (output_file, "\n#endif /* #if %s*/\n\n",

9915          CPU_UNITS_QUERY_MACRO_NAME);

9916   output_dfa_clean_insn_cache_func();

9917   output_dfa_start_func();

9918   output_dfa_finish_func();

9.6.4.2.1.           Pseudochip definition

To find out the right candidate instruction to run next, pipelinehazard recognizer maintains an pseudo CPU to simulate the instructions’ issuewhich is defined by output_chip_definitions.

 

7413 static void

7414 output_chip_definitions (void)                                                             in genautomata.c

7415 {

7416   automaton_tautomaton;

7417

7418   fprintf (output_file, "struct %s\n{\n",CHIP_NAME);

7419   for(automaton = description->first_automaton;

7420       automaton != NULL;

7421       automaton = automaton->next_automaton)

7422   {

7423     fprintf (output_file, "  ");

7424     output_state_member_type (output_file,automaton);

7425     fprintf (output_file, " ");

7426     output_chip_member_name (output_file,automaton);

7427     fprintf (output_file, ";\n");

7428   }

7429   fprintf (output_file, "};\n\n");

7430 #if 0

7431   fprintf (output_file, "static struct %s%s;\n\n", CHIP_NAME, CHIP_NAME);

7432 #endif

7433 }

 

Here it outputs following (content in greenis not output by tool), assuming states number of the automaton doesn’t exceed65536, automata are nameless.

 

       struct DFA_chip

       {

         unsigned short automaton_state_0;

      …                             // variables for other automatons

       }

 

The definition of this pseudo CPU is very simple, it just containsvariables holding the state of automatons. The complicate of recoganizer ishidden behind states and arcs connecting them (refer to 9.5.8 Automata generation).

9.6.4.2.2.           Outputfunction internal_min_issue_delay

Like define_function_unit, though from different view-point,deciding issue delay for given instruction is also important part of theautomaton. Here, first finds out the maximum of latency time in the system. Itis very simple.

 

8110 static void

8111 output_max_insn_queue_index_def (void)                                             in genautomata.c

8112 {

8113   int i, max, latency;

8114   decl_t decl;

8115

8116  max = description->max_insn_reserv_cycles;

8117   for (i = 0; i < description->decls_num; i++)

8118   {

8119     decl = description->decls [i];

8120     if (decl->mode == dm_insn_reserv&& decl != advance_cycle_insn_decl)

8121     {

8122       latency = DECL_INSN_RESERV(decl)->default_latency;

8123       if (latency > max)

8124         max = latency;

8125    }

8126    else if (decl->mode == dm_bypass)

8127     {

8128       latency = DECL_BYPASS (decl)->latency;

8129       if (latency > max)

8130         max = latency;

8131    }

8132   }

8133   for (i = 0; (1 << i) <= max; i++)

8134    ;

8135   if(i < 0)

8136     abort ();

8137   fprintf (output_file, "\nint max_insn_queue_index =%d;\n\n", (1 << i) - 1);

8138 }

 

At line 8122, default_latency is defined indefine_insn_reservation pattern, to describe latency time of the instruction.Besides, we have seen that define_bypass is used to is used to describeexceptions in the latency time for given instruction pair. output_max_insn_queue_index_deffinds out the max latency time has been met and outputs the value.

 

8235 static void

8236 output_internal_min_issue_delay_func (void)                                        ingenautomata.c

8237 {

8238   fprintf (output_file,

8239          "static int\n%s (int %s, struct %s *%s ATTRIBUTE_UNUSED)\n",

8240          INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME, INTERNAL_INSN_CODE_NAME,

8241          CHIP_NAME, CHIP_PARAMETER_NAME);

8242   fprintf (output_file, "{\n  int %s ATTRIBUTE_UNUSED;\n  int %s = -1;\n",

8243          TEMPORARY_VARIABLE_NAME, RESULT_VARIABLE_NAME);

8244   fprintf (output_file, "\n  switch (%s)\n    {\n", INTERNAL_INSN_CODE_NAME);

8245  output_insn_code_cases(output_automata_list_min_issue_delay_code);

8246   fprintf (output_file,

8247         "\n    default:\n      %s = -1;\n      break;\n    }\n",

8248         RESULT_VARIABLE_NAME);

8249   fprintf (output_file, "  return %s;\n", RESULT_VARIABLE_NAME);

8250   fprintf (output_file, "}\n\n");

8251 }

 

We have output the table for min issue delay in 9.6.4.1.4 Output table for issue delay. Forsome modern CPUs, they contain several function units that can be executedparallelly or in other words several instructions may be issued synchronously.In machine description file, such function units will be defined as automatons.Then in 9.5.8 Automata generation,states and arcs presenting the state transition are created for theseautomatons. As these automatons may be executed at the same time, the minmum issuedelay of given instructions should be largest one among those automatons.

 

8134 static void

8135 output_insn_code_cases (void(*output_automata_list_code)                    in genautomata.c

8136                     (automata_list_el_t))

8137 {

8138   decl_t decl, decl2;

8139  int i, j;

8140

8141   for (i = 0; i < description->decls_num; i++)

8142   {

8143     decl = description->decls [i];

8144     if (decl->mode == dm_insn_reserv)

8145       DECL_INSN_RESERV (decl)->processed_p =FALSE;

8146   }

8147   for (i = 0; i< description->decls_num;i++)

8148   {

8149     decl = description->decls [i];

8150     if (decl->mode == dm_insn_reserv

8151        && !DECL_INSN_RESERV(decl)->processed_p)

8152     {

8153       for (j =i; j < description->decls_num;j++)

8154       {

8155         decl2 = description->decls [j];

8156         if (decl2->mode == dm_insn_reserv

8157           && (DECL_INSN_RESERV(decl2)->important_automata_list

8158                == DECL_INSN_RESERV(decl)->important_automata_list))

8159         {

8160           DECL_INSN_RESERV(decl2)->processed_p = TRUE;

8161           fprintf (output_file, "    case %d: /* %s */\n",

8162                 DECL_INSN_RESERV(decl2)->insn_num,

8163                 DECL_INSN_RESERV (decl2)->name);

8164         }

8165       }

8166       (*output_automata_list_code)

8167           (DECL_INSN_RESERV (decl)->important_automata_list);

8168     }

8169   }

8170 }

 

At line 8157, important_automata_list records the validautomatons generated so far in which the instruction is involved. So FOR loops at line 8147 and 8153 findout all instructions in the same automaton list to be used as operand of casestatement.

 

8184 static void

8185 output_automata_list_min_issue_delay_code (automata_list_el_t automata_list) in genautomata.c

8186 {

8187   automata_list_el_t el;

8188   automaton_t automaton;

8189

8190   for (el = automata_list; el != NULL; el =el->next_automata_list_el)

8191   {

8192     automaton = el->automaton;

8193     fprintf (output_file, "\n      %s = ", TEMPORARY_VARIABLE_NAME);

8194     output_min_issue_delay_vect_name (output_file,automaton);

8195     fprintf (output_file,

8196              (automaton->min_issue_delay_table_compression_factor != 1

8197           ? " [(" : " ["));

8198     output_translate_vect_name (output_file,automaton);

8199     fprintf (output_file, " [%s] + ",INTERNAL_INSN_CODE_NAME);

8200     fprintf (output_file, "%s->",CHIP_PARAMETER_NAME);

8201     output_chip_member_name (output_file,automaton);

8202     fprintf (output_file, " * %d",automaton->insn_equiv_classes_num);

8203     if(automaton->min_issue_delay_table_compression_factor == 1)

8204       fprintf (output_file, "];\n");

8205     else

8206     {

8207       fprintf (output_file, ") /%d];\n",

8208            automaton->min_issue_delay_table_compression_factor);

8209       fprintf (output_file, "      %s = (%s >> (8 - (",

8210             TEMPORARY_VARIABLE_NAME,TEMPORARY_VARIABLE_NAME);

8211       output_translate_vect_name (output_file,automaton);

8212       fprintf

8213           (output_file, " [%s] %% %d + 1) * %d)) &%d;\n",

8214           INTERNAL_INSN_CODE_NAME,

8215          automaton->min_issue_delay_table_compression_factor,

8216           8 / automaton->min_issue_delay_table_compression_factor,

8217           (1 << (8 /automaton->min_issue_delay_table_compression_factor))

8218             - 1);

8219     }

8220     if (el == automata_list)

8221       fprintf (output_file, "      %s = %s;\n",

8222             RESULT_VARIABLE_NAME,TEMPORARY_VARIABLE_NAME);

8223     else

8224     {

8225       fprintf (output_file, "      if (%s > %s)\n",

8226             TEMPORARY_VARIABLE_NAME,RESULT_VARIABLE_NAME);

8227       fprintf (output_file, "        %s = %s;\n",

8228             RESULT_VARIABLE_NAME,TEMPORARY_VARIABLE_NAME);

8229     }

8230   }

8231   fprintf (output_file, "      break;\n\n");

8232 }

 

For instructions present in same autonamton set, output_automata_list_min_issue_delay_codewill output following code (assuming min_issue_delay_table_compression_factor is notequal to 1). Now we get the definition of internal_min_issue_delay as following(content in red is not output by the tool).

 

1     static int

2     internal_min_issue_delay (int insn_code,struct DFA_chip * chip ATTRIBUTE_UNUSED)

3     {

4       int temp ATTRIBUTE_UNUSED;

5       int res =-1;

6    

7       switch (insn_code)

8       {

9        case insn-x:             // for instructions reserve same automaton list.

10        …

11       case insn-y:

12        // forfirst automaton

13         temp = min_issue_delay_0[(translate_0[insn_code] +

14            chip->automaton_state_0 * `insn_equiv_classes_num0`)/

15            `min_issue_delay_table_compression_factor0`];

16         temp =(temp >> (8–(translate_0[insn_code]%%`min_issue_delay_table_compression_factor0`

17               + 1) * 8 / `min_issue_delay_table_compression_factor0`))& -1;

18         res = temp;

19          

20         // for other automaton n, not appear in ourassuming example

21         temp =min_issue_delay_n [(translate_n[insn_code] +

22            chip->automaton_state_n * `insn_equiv_classes_numn`)/

23            `min_issue_delay_table_compression_factorn`];

24         temp =(temp >> (8–(translate_n[insn_code]%%`min_issue_delay_table_compression_factorn`

25             + 1) * 8 / `min_issue_delay_table_compression_factorn`))& -1;

26         if (temp > res)

27          res= temp;

28         …

29         break;

30         …  //instructions reserve other automaton list, not appear in our assuming example

31       default:

32        res = -1;

33        break;

34    }

35      return res;

36    }

 

Above vector translate_`x` maps insn num (code) to instructionequivalent class number of the automaton. Here, we assume min_issue_delay_table_compression_factor`x` islarger than 1, then in one byte more than one min issue delay can be saved.Line 24 fetches the corresponding data out, see that the position caculatedmust be same as that gotten in filling (refer to 9.6.4.1.4 Output table for issue delay).See that the function, given an instruction, finds out the maximum min issuedelay incurred among the automatons the instruction employing.

9.6.4.2.3.           Outputfunction internal_state_transition

Following, we need output function for state transition – the engineof automaton!

 

8348 static void

8349 output_internal_trans_func (void)                                                         ingenautomata.c

8350 {

8351   fprintf (output_file,

8352         "static int\n%s (int %s, struct %s*%s ATTRIBUTE_UNUSED)\n",

8353         INTERNAL_TRANSITION_FUNC_NAME,INTERNAL_INSN_CODE_NAME,

8354         CHIP_NAME, CHIP_PARAMETER_NAME);

8355   fprintf (output_file, "{\n  int %s ATTRIBUTE_UNUSED;\n",TEMPORARY_VARIABLE_NAME);

8356   fprintf (output_file, "\n  switch (%s)\n    {\n", INTERNAL_INSN_CODE_NAME);

8357   output_insn_code_cases(output_automata_list_transition_code);

8358   fprintf (output_file, "\n    default:\n      return -1;\n    }\n");

8359   fprintf (output_file, "}\n\n");

8360 }

 

For output_insn_code_cases, we haveseen that it will filter out the instructions possessing the same automatonlist, and output_automata_list_transition_codeis invoked for every qualified instructions group.

 

8255 static void

8256 output_automata_list_transition_code (automata_list_el_t automata_list) ingenautomata.c

8257 {

8258   automata_list_el_t el, next_el;

8259

8260   fprintf (output_file, "      {\n");

8261   if (automata_list != NULL && automata_list->next_automata_list_el!= NULL)

8262     for (el = automata_list;; el = next_el)

8263     {

8264      next_el = el->next_automata_list_el;

8265       if (next_el == NULL)

8266         break;

8267       fprintf (output_file, "        ");

8268      output_state_member_type (output_file,el->automaton);

8269       fprintf (output_file, " ");

8270       output_temp_chip_member_name (output_file,el->automaton);

8271      fprintf (output_file,";\n");

8272    }

8273   for (el = automata_list; el != NULL; el =el->next_automata_list_el)

8274     if (comb_vect_p(el->automaton->trans_table))

8275     {

8276       fprintf (output_file, "\n        %s = ", TEMPORARY_VARIABLE_NAME);

8277       output_trans_base_vect_name(output_file,el->automaton);

8278       fprintf (output_file, " [%s->",CHIP_PARAMETER_NAME);

8279       output_chip_member_name (output_file,el->automaton);

8280       fprintf (output_file, "] + ");

8281       output_translate_vect_name(output_file,el->automaton);

8282       fprintf (output_file, " [%s];\n",INTERNAL_INSN_CODE_NAME);

8283       fprintf (output_file, "        if (");

8284       output_trans_check_vect_name(output_file,el->automaton);

8285       fprintf (output_file, " [%s] !=%s->",

8286             TEMPORARY_VARIABLE_NAME, CHIP_PARAMETER_NAME);

8287       output_chip_member_name (output_file,el->automaton);

8288       fprintf (output_file, ")\n");

8289       fprintf (output_file, "          return %s (%s, %s);\n",

8290          INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME,INTERNAL_INSN_CODE_NAME,

8291          CHIP_PARAMETER_NAME);

8292       fprintf (output_file, "        else\n");

8293       fprintf (output_file, "          ");

8294       if (el->next_automata_list_el != NULL)

8295         output_temp_chip_member_name (output_file,el->automaton);

8296       else

8297       {

8298         fprintf (output_file, "%s->",CHIP_PARAMETER_NAME);

8299         output_chip_member_name (output_file,el->automaton);

8300       }

8301       fprintf (output_file, " = ");

8302       output_trans_comb_vect_name(output_file,el->automaton);

8303      fprintf (output_file, " [%s];\n",TEMPORARY_VARIABLE_NAME);

8304     }

8305     else

8306     {

8307       fprintf (output_file, "\n        %s = ", TEMPORARY_VARIABLE_NAME);

8308       output_trans_full_vect_name(output_file,el->automaton);

8309       fprintf (output_file, " [");

8310       output_translate_vect_name(output_file,el->automaton);

8311       fprintf (output_file, " [%s] + ",INTERNAL_INSN_CODE_NAME);

8312       fprintf (output_file, "%s->",CHIP_PARAMETER_NAME);

8313       output_chip_member_name (output_file,el->automaton);

8314       fprintf (output_file, " * %d];\n",

8315            el->automaton->insn_equiv_classes_num);

8316       fprintf (output_file, "        if (%s >= %d)\n",

8317           TEMPORARY_VARIABLE_NAME,el->automaton->achieved_states_num);

8318       fprintf (output_file, "          return %s (%s, %s);\n",

8319            INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME,INTERNAL_INSN_CODE_NAME,

8320            CHIP_PARAMETER_NAME);

8321       fprintf (output_file, "        else\n          ");

8322      if (el->next_automata_list_el != NULL)

8323         output_temp_chip_member_name (output_file,el->automaton);

8324       else

8325       {

8326         fprintf (output_file, "%s->",CHIP_PARAMETER_NAME);

8327         output_chip_member_name (output_file,el->automaton);

8328       }

8329       fprintf (output_file, " = %s;\n",TEMPORARY_VARIABLE_NAME);

8330    }

8331   if(automata_list != NULL && automata_list->next_automata_list_el !=NULL)

8332     for (el = automata_list;; el = next_el)

8333     {

8334      next_el = el->next_automata_list_el;

8335       if (next_el == NULL)

8336         break;

8337       fprintf (output_file, "        %s->", CHIP_PARAMETER_NAME);

8338       output_chip_member_name (output_file,el->automaton);

8339       fprintf (output_file, " = ");

8340       output_temp_chip_member_name (output_file,el->automaton);

8341       fprintf (output_file, ";\n");

8342     }

8343   fprintf (output_file, "        return -1;\n");

8344   fprintf (output_file, "      }\n");

8345 }

 

We get the definition of internal_state_transition as following(content in red is not putput by the tool),assuming vector transition_xis not combined (transition_xrefer to 9.6.4.1.2 Output table(s) forstate transition).

 

1     static int

2     internal_state_transition (intinsn_code, struct DFA_chip *chip ATTRIBUTE_UNUSED)

3     {

4       int temp ATTRIBUTE_UNUSED;

5       switch(insn_code)

6       {

7         caseinsn-x:           // for instructions reserve same automaton list.

8         …

9         caseinsn-y:

10           {

11             unsigned short _automaton_state_0;

12             …                                                              // declaration for other automatons

13             temp= transitions_0 [translate_0 [insn_code] + chip->automaton_state_0 *

14                  ` insn_equiv_classes_num0`];

15             if (temp >= ` achieved_states_num0` )

16               return internal_min_issue_delay(insn_code, chip);

17              else

18               _automaton_state_0 = transitions_0 [temp];

19               …                                                          // statement for other automatons

20              //statement for last automatons

21             temp= transitions_n [translate_n [insn_code] + chip->automaton_state_n *

22                       ` insn_equiv_classes_numn`];

23             if (temp >= ` achieved_states_numn` )

24               return internal_min_issue_delay(insn_code, chip);

25             else

26               chip->automaton_state_n = transitions_n [temp];

27   

28             chip->automaton_state_0 = _automaton_state_0;

29             …                                                              // statement for other automatons

30             return-1;

31           }

32           … // instructions reserve other automaton list, not appear inour assuming example

33       default:

34        return -1;

35      }

36    }

 

Vector translate_x is per automaton. It maps instruction num (code)to instruction equivalent class number. And vector transition_x records the targetstate indexed by instruction equivalent class number (remember that instuctionsof same equivalence class have same state transition). Notice that unfilledelements of transition_xare occupied by undefined_vect_el_valuewhich is defined as achieved_states_num in output_trans_table. In this case,it means the instruction can’t be issued, and as line 23 above indicates, internal_min_issue_delay isinvoked to find out the min issue delay for the instruction.

9.6.4.2.4.           Output functions dfa_insn_code_enlarge &dfa_insn_code

Given an instruction, it is not convient to use it through out thesystem, as it will change form as the result of optimization, handled bycompilation passes etc. So the system assigns unique number for everyinstruction. It is the identifier for instruction throughout the system duringthe compilation. dfa_insn_code, given instruction, returns itsinsn number (code).

 

8392 static void

8393 output_dfa_insn_code_func (void)                                                        ingenautomata.c

8394 {

8395   /* Emacs c-modegets really confused if there's a { or } in column 0

8396     inside a string, so don't do that.  */

8397   fprintf (output_file, "\

8398 static void\n\

8399 dfa_insn_code_enlarge (int uid)\n\

8400 {\n\

8401   int i = %s;\n\

8402   %s = 2 * uid;\n\

8403   %s = xrealloc (%s,\n\

8404                  %s * sizeof(int));\n\

8405   for (; i <%s; i++)\n\

8406     %s[i] = -1;\n}\n\n",

8407          DFA_INSN_CODES_LENGTH_VARIABLE_NAME,

8408          DFA_INSN_CODES_LENGTH_VARIABLE_NAME,

8409          DFA_INSN_CODES_VARIABLE_NAME, DFA_INSN_CODES_VARIABLE_NAME,

8410          DFA_INSN_CODES_LENGTH_VARIABLE_NAME,

8411          DFA_INSN_CODES_LENGTH_VARIABLE_NAME,

8412          DFA_INSN_CODES_VARIABLE_NAME);

8413   fprintf (output_file, "\

8414 static inlineint\n%s (rtx %s)\n\

8415 {\n\

8416   int uid = INSN_UID (%s);\n\

8417   int %s;\n\n",

8418          DFA_INSN_CODE_FUNC_NAME, INSN_PARAMETER_NAME,

8419          INSN_PARAMETER_NAME, INTERNAL_INSN_CODE_NAME);

8420

8421   fprintf (output_file,

8422          "  if (uid >= %s)\n    dfa_insn_code_enlarge (uid);\n\n",

8423          DFA_INSN_CODES_LENGTH_VARIABLE_NAME);

8424   fprintf (output_file, "  %s = %s[uid];\n",

8425          INTERNAL_INSN_CODE_NAME, DFA_INSN_CODES_VARIABLE_NAME);

8426   fprintf (output_file, "\

8427   if (%s < 0)\n\

8428     {\n\

8429       %s = %s (%s);\n\

8430       %s[uid] = %s;\n\

8431     }\n",

8432           INTERNAL_INSN_CODE_NAME,

8433          INTERNAL_INSN_CODE_NAME,

8434          INTERNAL_DFA_INSN_CODE_FUNC_NAME, INSN_PARAMETER_NAME,

8435          DFA_INSN_CODES_VARIABLE_NAME, INTERNAL_INSN_CODE_NAME);

8436   fprintf (output_file, "  return %s;\n}\n\n", INTERNAL_INSN_CODE_NAME);

8437 }

 

The output functions look alike following.

 

1     static void

2     dfa_insn_code_enlarge (intuid)

3     {

4       int i = dfa_insn_codes_length;

5       dfa_insn_codes_length= 2 * uid;

6      dfa_insn_codes = xrealloc (dfa_insn_codes,

7                             dfa_insn_codes_length * sizeof(int));

8       for (; i< dfa_insn_codes_length; i++)

9        dfa_insn_codes[i]= -1;

10    }

11   

12   staticinline int

13   dfa_insn_code (rtx insn)

14   {

15     int uid = INSN_UID (insn);

16     int insn_code;

17  

18     if (uid >= dfa_insn_codes_length)

19       dfa_insn_code_enlarge (uid);

20     insn_code = dfa_insn_codes [uid];

21     if (insn_code < 0)

22     {

23       insn_code = internal_dfa_insn_code (insn);

24       dfa_insn_codes [uid] = insn_code;

25     }

26     return insn_code;

27   }

 

Above at line 23, internal_dfa_insn_codeis produced by attribute “*internal_dfa_insn_code”. The content of theattribute is a COND containing all reserving instructions, in which each branchhas its test from the test part of the reservation pattern definition, andcontent is insn code.

9.6.4.2.5.           Outputfunction state_transition

In 9.6.4.2.3 Output functioninternal_state_transition, it generated internal_state_transition which acceptsinsn_code and state as its parameters. But it is not the ideal interface whichshould accept instruction itself, here further packaging it.

 

8440 static void

8441 output_trans_func (void)                                                                     in genautomata.c

8442 {

8443   fprintf (output_file, "int\n%s (%s %s, rtx%s)\n",

8444          TRANSITION_FUNC_NAME, STATE_TYPE_NAME, STATE_NAME,

8445          INSN_PARAMETER_NAME);

8446   fprintf (output_file, "{\n  int %s;\n", INTERNAL_INSN_CODE_NAME);

8447   output_internal_insn_code_evaluation(INSN_PARAMETER_NAME,

8448                                    INTERNAL_INSN_CODE_NAME,-1);

8449   fprintf (output_file, "  return %s (%s, %s);\n}\n\n",

8450        INTERNAL_TRANSITION_FUNC_NAME,INTERNAL_INSN_CODE_NAME, STATE_NAME);

8451 }

 

Following is the output function.

 

1     int

2     state_transition(state_t state, rtx insn)

3     {

4       intinsn_code;

5       if (insn!= 0)

6       {

7         insn_code = dfa_insn_code (insn);

8         if(insn_code > DFA__ADVANCE_CYCLE)

9          return -1;

10      }

11      else

12        insn_code = DFA__ADVANCE_CYCLE;

13      return internal_state_transition(insn_code, state);

14    }

9.6.4.2.6.           Outputfunctions internal_state_alts & state_alts

We have seen that state_alts field records the degree ofnondeterministic of certain instruction upon certain state, the function outputhere is for debug purpose.

 

8515 static void

8516 output_internal_state_alts_func (void)                                                   ngenautomata.c

8517 {

8518   fprintf (output_file,

8519          "static int\n%s (int %s, struct %s *%s)\n",

8520          INTERNAL_STATE_ALTS_FUNC_NAME, INTERNAL_INSN_CODE_NAME,

8521          CHIP_NAME, CHIP_PARAMETER_NAME);

8522   fprintf (output_file, "{\n  int %s;\n", RESULT_VARIABLE_NAME);

8523   fprintf (output_file, "\n  switch (%s)\n    {\n", INTERNAL_INSN_CODE_NAME);

8524   output_insn_code_cases(output_automata_list_state_alts_code);

8525   fprintf (output_file,

8526          "\n    default:\n      %s = 0;\n      break;\n    }\n",

8527          RESULT_VARIABLE_NAME);

8528   fprintf (output_file, "  return %s;\n", RESULT_VARIABLE_NAME);

8529   fprintf (output_file, "}\n\n");

8530 }

 

Again instructions are grouped according to the reserving automatonslist.

 

8455 static void

8456 output_automata_list_state_alts_code (automata_list_el_t automata_list) in genautomata.c

8457 {

8458   automata_list_el_t el;

8459   automaton_t automaton;

8460

8461  fprintf (output_file,"      {\n");

8462   for (el = automata_list; el != NULL; el =el->next_automata_list_el)

8463     if (comb_vect_p(el->automaton->state_alts_table))

8464     {

8465       fprintf (output_file, "        int %s;\n", TEMPORARY_VARIABLE_NAME);

8466      break;

8467    }

8468   for (el = automata_list; el != NULL; el =el->next_automata_list_el)

8469   {

8470     automaton = el->automaton;

8471     if (comb_vect_p(automaton->state_alts_table))

8472     {

8473       fprintf (output_file, "\n        %s = ", TEMPORARY_VARIABLE_NAME);

8474       output_state_alts_base_vect_name (output_file,automaton);

8475       fprintf (output_file, " [%s->",CHIP_PARAMETER_NAME);

8476       output_chip_member_name (output_file,automaton);

8477       fprintf (output_file, "] + ");

8478       output_translate_vect_name(output_file,automaton);

8479       fprintf (output_file, " [%s];\n",INTERNAL_INSN_CODE_NAME);

8480       fprintf (output_file, "        if (");

8481       output_state_alts_check_vect_name(output_file,automaton);

8482       fprintf (output_file, " [%s] !=%s->",

8483                 TEMPORARY_VARIABLE_NAME, CHIP_PARAMETER_NAME);

8484       output_chip_member_name (output_file,automaton);

8485       fprintf (output_file, ")\n");

8486       fprintf (output_file, "          return 0;\n");

8487       fprintf (output_file, "        else\n");

8488       fprintf (output_file,

8489             (el == automata_list

8490              ? "          %s = " : "          %s += "),

8491             RESULT_VARIABLE_NAME);

8492       output_state_alts_comb_vect_name (output_file,automaton);

8493       fprintf (output_file, " [%s];\n",TEMPORARY_VARIABLE_NAME);

8494     }

8495     else

8496     {

8497       fprintf (output_file,

8498             (el == automata_list

8499              ? "\n        %s = " : "        %s += "),

8500              RESULT_VARIABLE_NAME);

8501       output_state_alts_full_vect_name (output_file,automaton);

8502       fprintf (output_file, " [");

8503       output_translate_vect_name(output_file,automaton);

8504       fprintf (output_file, " [%s] + ",INTERNAL_INSN_CODE_NAME);

8505       fprintf (output_file, "%s->",CHIP_PARAMETER_NAME);

8506       output_chip_member_name (output_file,automaton);

8507       fprintf (output_file, " * %d];\n",

8508            automaton->insn_equiv_classes_num);

8509     }

8510   }

8511   fprintf (output_file, "        break;\n      }\n\n");

8512 }

 

The output function looks alike following (content in red is not output by the tool).

 

1     static int

2     internal_state_alts (intinsn_code, struct DFA_chip *chip)

3     {

4       int res;

5       switch(insn_code)

6       {

7         caseinsn-x:    // for instructions reserve same automaton list.

8         …

9         caseinsn-y:

10         temp = base_state_alts_0[chip->automaton_state_0]+ translate_0[insn_code];

11         if (check_state_alts_0[temp] != chip->automaton_state_0)

12           return 0;

13         else

14           res = state_alts_0[temp];

15         …         // for other automaton in list, notpresent in our example

16         //last automaton in list, not present in our example

17         temp = base_state_alts_n[chip->automaton_state_n]+ translate_n[insn_code];

18         if (check_state_alts_n[temp] != chip->automaton_state_n)

19           return 0;

20         else

21           res += state_alts_n[temp];

22         break;

23         …  // instructions reserve other automaton list, notappear in our assuming example

24        default:

25         res = 0;

26         break;

27      }

28      return res;

29    }

 

Vector state_alts_`n` records the number of alternative reservationswhich can be used for transition from given state by given instruction. internal_state_altscalculates out total number of alternative reservations of the automaton lists ofcertain instruction. We have seen that in the output function internal_state_transition(9.6.4.2.3 Output functioninternal_state_transition), automaton_state_`x` of chip saves the instructionequivalent class number, which is also recorded in check_state_alts_`x` if number ofalternative reservations present in the state_alts_`n`. See we assume combined vectorhere.

And following, it needs output a wrapper for internal_state_alts.

 

8533 static void

8534 output_state_alts_func (void)                                                                      in genautomata.c

8535 {

8536   fprintf (output_file, "int\n%s (%s, %s)\n\t%s%s;\n\trtx %s;\n",

8537          STATE_ALTS_FUNC_NAME, STATE_NAME, INSN_PARAMETER_NAME,

8538          STATE_TYPE_NAME, STATE_NAME, INSN_PARAMETER_NAME);

8539   fprintf (output_file, "{\n  int %s;\n", INTERNAL_INSN_CODE_NAME);

8540   output_internal_insn_code_evaluation(INSN_PARAMETER_NAME,

8541                                    INTERNAL_INSN_CODE_NAME,0);

8542   fprintf (output_file, "  return %s (%s, %s);\n}\n\n",

8543        INTERNAL_STATE_ALTS_FUNC_NAME,INTERNAL_INSN_CODE_NAME, STATE_NAME);

8544 }

 

8375 static void

8376 output_internal_insn_code_evaluation (const char *insn_name,                ingenautomata.c

8377                                 const char*insn_code_name,

8378                                 int code)

8379 {

8380   fprintf (output_file, "\n  if (%s != 0)\n    {\n", insn_name);

8381   fprintf (output_file, "      %s = %s (%s);\n", insn_code_name,

8382          DFA_INSN_CODE_FUNC_NAME, insn_name);

8383   fprintf (output_file, "      if (%s > %s)\n        return %d;\n",

8384          insn_code_name, ADVANCE_CYCLE_VALUE_NAME, code);

8385   fprintf (output_file, "    }\n else\n    %s = %s;\n\n",

8386          insn_code_name, ADVANCE_CYCLE_VALUE_NAME);

8387 }

 

For this output function, its definition is as following.

 

1     int

2     state_alts (state,insn)

3       state_tstate;

4       rtx insn;

5     {

6       intinsn_code;

7       if (insn!= 0)

8       {

9         insn_code = dfa_insn_code (insn);

10        if (insn_code > DFA__ADVANCE_CYCLE)

11         return 0;

12      }

13      else

14        insn_code = DFA__ADVANCE_CYCLE;

15      return internal_state_alts(insn_code, state);

16    }

 

DFA__ADVANCE_CYCLE has been defined as the number of instruction (insn number of advance_cycle_insn_decl).Notice that insn_code is also sequence number from 0 to number of instruction –1.

9.6.4.2.7.           Outputfunction min_issue_delay

This function is the wrapper for internal_min_issue_delay (refer to 9.6.4.2.2 Output functioninternal_min_issue_delay).

 

8547 static void

8548 output_min_issue_delay_func (void)                                                    ingenautomata.c

8549 {

8550   fprintf (output_file, "int\n%s (%s %s, rtx%s)\n",

8551           MIN_ISSUE_DELAY_FUNC_NAME, STATE_TYPE_NAME,STATE_NAME,

8552          INSN_PARAMETER_NAME);

8553   fprintf (output_file, "{\n  int %s;\n", INTERNAL_INSN_CODE_NAME);

8554   fprintf (output_file, "\n  if (%s != 0)\n    {\n", INSN_PARAMETER_NAME);

8555   fprintf (output_file, "      %s = %s (%s);\n",INTERNAL_INSN_CODE_NAME,

8556          DFA_INSN_CODE_FUNC_NAME, INSN_PARAMETER_NAME);

8557   fprintf (output_file, "      if (%s > %s)\n        return 0;\n",

8558          INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME);

8559   fprintf (output_file, "    }\n else\n    %s = %s;\n",

8560          INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME);

8561   fprintf (output_file, "\n  return %s (%s, %s);\n",

8562        INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME,INTERNAL_INSN_CODE_NAME,

8563          STATE_NAME);

8564   fprintf (output_file, "}\n\n");

8565 }

 

1            int

2            min_issue_delay(state_t state, rtx insn)

3            {

4              int insn_code;

5              if (insn != 0)

6              {

7                insn_code = dfa_insn_code (insn);

8                if (insn_code >DFA__ADVANCE_CYCLE)

9                  return 0;

10             }

11             else

12               insn_code = DFA__ADVANCE_CYCLE;

13          

14             return internal_min_issue_delay (insn_code,state);

15           }

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值