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 }