12. genflags Tool
This tool outputs insn-flags, functions generated by genemit, and a series of have _ * Macros containing conditions templates in the define_insn and define_expand modes.
233Int
234Main (INT argc, char ** argv) inGenflags. c
235{
236Rtx desc;
237RTX dummy;
238RTX * insns;
239RTX * insn_ptr;
240
241 progname= "Genflags ";
242Obstack_init (&Obstack);
243
244/* We need to see all the possibilities. elided insns may have
245Direct callto their generators in cCode .*/
246 insn_elision= 0;
247
248If (argc <= 1)
249Fatal ("no input file name ");
250
251If (init_md_reader_args (argc, argv )! = Success_exit_code)
252Return (fatal_exit_code );
253
254Puts ("/* generated automatically by the program 'genflags '");
255Puts ("from the machine descriptionfile 'md'. */\ n ");
256Puts ("# ifndef gcc_insn_flags_h ");
257Puts ("# define gcc_insn_flags_h \ n ");
258
259/* Read the machine description .*/
260
261While (1)
262{
263Int line_no, insn_code_number = 0;
264
265Desc = read_md_rtx (& line_no, & insn_code_number );
266If (DESC = NULL)
267Break;
268If (get_code (DESC) = define_insn | get_code (DESC) = define_expand)
269Gen_insn (DESC );
270}
271
272/* Print out the prototypes now .*/
273Dummy = (RTx) 0;
274Obstack_grow (&Obstack, & Dummy, sizeof (RTx ));
275Insns = (RTX *) obstack_finish (&Obstack);
276
277For (insn_ptr = insns; * insn_ptr; insn_ptr ++)
278Gen_proto (* insn_ptr );
279
280Puts ("\ n # endif/* gcc_insn_flags_h */");
281
282If (ferror (stdout) | fflush (stdout) | fclose (stdout ))
283Return fatal_exit_code;
284
285Return success_exit_code;
286}
As we can see from other chapters,Init_md_reader_argsAndRead_md_rtxRead the pattern from the machine description file, and build the correspondingDescThe RTX object. This object consistsGen_insn.
192Static void
193Gen_insn (RTX insn) inGenflags. c
194{
195Const char * name = xstr (insn, 0 );
196Const char * P;
197Int Len;
198Int truth = maybe_eval_c_test (xstr (insn, 2 ));
199
200/* Don't mention instructions whose names arethe Null String
201Or begin with '*'. They are in the machinedescription just
202To be recognized .*/
203If (name [0] = 0 | Name [0] = '*')
204Return;
205
206Len = strlen (name );
207
208If (LEN>Max_id_len)
209 max_id_len= Len;
210
211If (truth = 0)
212/* Emit nothing .*/;
213Else if (truth = 1)
214Printf ("# define have _ % S 1 \ n", name );
215Else
216{
217/* Write the macro definition, putting \'s atthe end of each line,
218If more than one .*/
219Printf ("# define have _ % s (", name );
220For (P = xstr (insn, 2); * P; P ++)
221{
222If (is_vspace (* p ))
223Fputs ("\\\ N", stdout );
224Else
225Putchar (* P );
226}
227Fputs (") \ n", stdout );
228}
229
230Obstack_grow (&Obstack, & Insn, sizeof (RTx ));
231}
We already know that for expressions that are known to be true at the time of compilation,Maybe_eval_c_test1 is returned. If it is a false expression, 0 is returned. If it is other expressions,-1 is returned. Note that in row 203, the anonymous mode or the mode whose name starts with '*' will be ignored. In row 3, the address of the qualified RTX object will be savedObstack.
BackMainIn row 275, an empty RTX object is addedObstackTo ensure that 277 rowsForThe loop can exit correctly. For each meaningful define_insn or define_expand mode (pattern ),Gen_protoPerform the following operations.
129Static void
130Gen_proto (RTX insn) inGenflags. c
131{
132Int num = num_operands (insn );
133Int I;
134Const char * name = xstr (insn, 0 );
135Int truth = maybe_eval_c_test (xstr (insn, 2 ));
136
137/* Specify MD files don't refer to the last twooperands passed to
138Call patterns. This means their generatorfunctions will be two
139Arguments too short. Instead of changingevery MD file to touch
140Those operands, we wrap the prototypes inmacros that take
141Correct number of arguments .*/
142If (name [0] = 'C' | Name [0] ='s ')
143{
144If (! Strcmp (name, "call ")
145|! Strcmp (name, "call_pop ")
146|! Strcmp (name, "sibcall ")
147|! Strcmp (name, "sibcall_pop "))
148Gen_macro (name, num, 4 );
149Else if (! Strcmp (name, "call_value ")
150|! Strcmp (name, "call_value_pop ")
151|! Strcmp (name, "sibcall_value ")
152|! Strcmp (name, "sibcall_value_pop "))
153Gen_macro (name, num, 5 );
154}
155
156If (truth! = 0)
157Printf ("extern RTX Gen _ %-* s (",Max_id_len, Name );
158Else
159Printf ("static inline RTX Gen _ %-* s (",Max_id_len, Name );
160
161If (num = 0)
162Fputs ("Void", stdout );
163Else
164{
165For (I = 1; I <num; I ++)
166Fputs ("RTX,", stdout );
167
168Fputs ("RTX", stdout );
169}
170
171Puts (");");
172
173/* Some back ends want to take the address ofgenerator functions,
174So we cannot simply use # define for thesedummy definitions .*/
175If (truth = 0)
176{
177Printf ("static inline RTX \ ngen _ % s", name );
178If (Num> 0)
179{
180Putchar ('(');
181For (I = 0; I <num-1; I ++)
182Printf ("RTX % cattribute_unused,", 'A' + I );
183Printf ("RTX % C attribute_unused) \ n", 'A' + I );
184}
185Else
186Puts ("(void )");
187Puts ("{\ n return0; \ n }");
188}
189
190}
We can see the pattern with the name "call", "call_pop", "sibcall", "sbicall_pop", "call_value_pop", "call_value", "sibcall_value", and "sibcall_value_pop) furtherGen_macroPerform the following operations.
100Static void
101Gen_macro (const char * Name, int real, intexpect) in
Genflags. c
102{
103Int I;
104
105If (real> exact CT)
106Abort ();
107If (real = 0)
108Abort ();
109
110/* # Define gen_call (A, B, C, D) gen_call (a), (B ))*/
111Fputs ("# define Gen _", stdout );
112For (I = 0; name [I]; I ++)
113Putchar (toupper (name [I]);
114
115Putchar ('(');
116For (I = 0; I <CT-1; I ++)
117Printf ("% C,", I + 'A ');
118Printf ("% C) Gen _ % s (", I + 'A', name );
119
120For (I = 0; I <real-1; I ++)
121Printf ("(% C),", I + 'A ');
122Printf ("(% C) \ n", I + 'A ');
123}
This function generates a macro for the corresponding function used in the pattern mentioned above. BackGen_proto, Output the prototype of these functions from rows 156 to 169. Note that for the pattern condition template that is known as false at the time of compilation, its definition will also appear in insn-Flags -- 175 to 188 rows to generate the functions that return 0.