OSDN Git Service

* opt-functions.awk (static_var): Update comment.
[pf3gnuchains/gcc-fork.git] / gcc / opth-gen.awk
1 #  Copyright (C) 2003,2004,2005,2006,2007,2008, 2010
2 #  Free Software Foundation, Inc.
3 #  Contributed by Kelley Cook, June 2004.
4 #  Original code from Neil Booth, May 2003.
5 #
6 # This program is free software; you can redistribute it and/or modify it
7 # under the terms of the GNU General Public License as published by the
8 # Free Software Foundation; either version 3, or (at your option) any
9 # later version.
10
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 # GNU General Public License for more details.
15
16 # You should have received a copy of the GNU General Public License
17 # along with this program; see the file COPYING3.  If not see
18 # <http://www.gnu.org/licenses/>.
19
20 # This Awk script reads in the option records generated from 
21 # opt-gather.awk, combines the flags of duplicate options and generates a
22 # C header file.
23 #
24 # This program uses functions from opt-functions.awk
25 # Usage: awk -f opt-functions.awk -f opth-gen.awk < inputfile > options.h
26
27 BEGIN {
28         n_opts = 0
29         n_langs = 0
30         n_target_save = 0
31         n_extra_vars = 0
32         n_extra_masks = 0
33         FS=SUBSEP
34 }
35
36 # Collect the text and flags of each option into an array
37         {
38                 if ($1 == "Language") {
39                         langs[n_langs] = $2
40                         n_langs++;
41                 }
42                 else if ($1 == "TargetSave") {
43                         # Make sure the declarations are put in source order
44                         target_save_decl[n_target_save] = $2
45                         n_target_save++
46                 }
47                 else if ($1 == "Variable") {
48                         extra_vars[n_extra_vars] = $2
49                         n_extra_vars++
50                 }
51                 else {
52                         name = opt_args("Mask", $1)
53                         if (name == "") {
54                                 opts[n_opts]  = $1
55                                 flags[n_opts] = $2
56                                 help[n_opts]  = $3
57                                 n_opts++;
58                         }
59                         else {
60                                 extra_masks[n_extra_masks++] = name
61                         }
62                 }
63         }
64
65 # Dump out an enumeration into a .h file.
66 # Combine the flags of duplicate options.
67 END {
68 print "/* This file is auto-generated by opth-gen.awk.  */"
69 print ""
70 print "#ifndef OPTIONS_H"
71 print "#define OPTIONS_H"
72 print ""
73 print "extern int target_flags_explicit;"
74 print ""
75
76 have_save = 0;
77
78 print "#ifndef GENERATOR_FILE"
79 print "struct gcc_options\n{"
80 print "#endif"
81
82 for (i = 0; i < n_extra_vars; i++) {
83         var = extra_vars[i]
84         sub(" *=.*", "", var)
85         orig_var = var
86         name = var
87         type = var
88         sub("^.*[ *]", "", name)
89         sub(" *" name "$", "", type)
90         var_seen[name] = 1
91         print "#ifdef GENERATOR_FILE"
92         print "extern " orig_var ";"
93         print "#else"
94         print "  " type " x_" name ";"
95         print "#define " name " global_options.x_" name
96         print "#endif"
97 }
98
99 for (i = 0; i < n_opts; i++) {
100         if (flag_set_p("Save", flags[i]))
101                 have_save = 1;
102
103         name = var_name(flags[i]);
104         if (name == "")
105                 continue;
106
107         if (name in var_seen)
108                 continue;
109
110         var_seen[name] = 1;
111         print "#ifdef GENERATOR_FILE"
112         print "extern " var_type(flags[i]) name ";"
113         print "#else"
114         print "  " var_type(flags[i]) "x_" name ";"
115         print "#define " name " global_options.x_" name
116         print "#endif"
117 }
118 for (i = 0; i < n_opts; i++) {
119         name = static_var(opts[i], flags[i]);
120         if (name != "") {
121                 print "#ifndef GENERATOR_FILE"
122                 print "  " var_type(flags[i]) "x_" name ";"
123                 print "#define x_" name " do_not_use"
124                 print "#endif"
125         }
126 }
127 print "#ifndef GENERATOR_FILE"
128 print "};"
129 print "extern struct gcc_options global_options;"
130 print "#endif"
131 print ""
132
133 # All of the optimization switches gathered together so they can be saved and restored.
134 # This will allow attribute((cold)) to turn on space optimization.
135
136 # Change the type of normal switches from int to unsigned char to save space.
137 # Also, order the structure so that pointer fields occur first, then int
138 # fields, and then char fields to provide the best packing.
139
140 print "#if !defined(GCC_DRIVER) && !defined(IN_LIBGCC2) && !defined(IN_TARGET_LIBS)"
141 print ""
142 print "/* Structure to save/restore optimization and target specific options.  */";
143 print "struct GTY(()) cl_optimization";
144 print "{";
145
146 n_opt_char = 2;
147 n_opt_short = 0;
148 n_opt_int = 0;
149 n_opt_other = 0;
150 var_opt_char[0] = "unsigned char x_optimize";
151 var_opt_char[1] = "unsigned char x_optimize_size";
152
153 for (i = 0; i < n_opts; i++) {
154         if (flag_set_p("Optimization", flags[i])) {
155                 name = var_name(flags[i])
156                 if(name == "")
157                         continue;
158
159                 if(name in var_opt_seen)
160                         continue;
161
162                 var_opt_seen[name]++;
163                 otype = var_type_struct(flags[i]);
164                 if (otype ~ "^((un)?signed +)?int *$")
165                         var_opt_int[n_opt_int++] = otype "x_" name;
166
167                 else if (otype ~ "^((un)?signed +)?short *$")
168                         var_opt_short[n_opt_short++] = otype "x_" name;
169
170                 else if (otype ~ "^((un)?signed +)?char *$")
171                         var_opt_char[n_opt_char++] = otype "x_" name;
172
173                 else
174                         var_opt_other[n_opt_other++] = otype "x_" name;
175         }
176 }
177
178 for (i = 0; i < n_opt_other; i++) {
179         print "  " var_opt_other[i] ";";
180 }
181
182 for (i = 0; i < n_opt_int; i++) {
183         print "  " var_opt_int[i] ";";
184 }
185
186 for (i = 0; i < n_opt_short; i++) {
187         print "  " var_opt_short[i] ";";
188 }
189
190 for (i = 0; i < n_opt_char; i++) {
191         print "  " var_opt_char[i] ";";
192 }
193
194 print "};";
195 print "";
196
197 # Target and optimization save/restore/print functions.
198 print "/* Structure to save/restore selected target specific options.  */";
199 print "struct GTY(()) cl_target_option";
200 print "{";
201
202 n_target_char = 0;
203 n_target_short = 0;
204 n_target_int = 0;
205 n_target_other = 0;
206
207 for (i = 0; i < n_target_save; i++) {
208         if (target_save_decl[i] ~ "^((un)?signed +)?int +[_a-zA-Z0-9]+$")
209                 var_target_int[n_target_int++] = target_save_decl[i];
210
211         else if (target_save_decl[i] ~ "^((un)?signed +)?short +[_a-zA-Z0-9]+$")
212                 var_target_short[n_target_short++] = target_save_decl[i];
213
214         else if (target_save_decl[i] ~ "^((un)?signed +)?char +[_a-zA-Z0-9]+$")
215                 var_target_char[n_target_char++] = target_save_decl[i];
216
217         else
218                 var_target_other[n_target_other++] = target_save_decl[i];
219 }
220
221 if (have_save) {
222         for (i = 0; i < n_opts; i++) {
223                 if (flag_set_p("Save", flags[i])) {
224                         name = var_name(flags[i])
225                         if(name == "")
226                                 name = "target_flags";
227
228                         if(name in var_save_seen)
229                                 continue;
230
231                         var_save_seen[name]++;
232                         otype = var_type_struct(flags[i])
233                         if (otype ~ "^((un)?signed +)?int *$")
234                                 var_target_int[n_target_int++] = otype "x_" name;
235
236                         else if (otype ~ "^((un)?signed +)?short *$")
237                                 var_target_short[n_target_short++] = otype "x_" name;
238
239                         else if (otype ~ "^((un)?signed +)?char *$")
240                                 var_target_char[n_target_char++] = otype "x_" name;
241
242                         else
243                                 var_target_other[n_target_other++] = otype "x_" name;
244                 }
245         }
246 } else {
247         var_target_int[n_target_int++] = "int x_target_flags";
248 }
249
250 for (i = 0; i < n_target_other; i++) {
251         print "  " var_target_other[i] ";";
252 }
253
254 for (i = 0; i < n_target_int; i++) {
255         print "  " var_target_int[i] ";";
256 }
257
258 for (i = 0; i < n_target_short; i++) {
259         print "  " var_target_short[i] ";";
260 }
261
262 for (i = 0; i < n_target_char; i++) {
263         print "  " var_target_char[i] ";";
264 }
265
266 print "};";
267 print "";
268 print "";
269 print "/* Save optimization variables into a structure.  */"
270 print "extern void cl_optimization_save (struct cl_optimization *, struct gcc_options *);";
271 print "";
272 print "/* Restore optimization variables from a structure.  */";
273 print "extern void cl_optimization_restore (struct gcc_options *, struct cl_optimization *);";
274 print "";
275 print "/* Print optimization variables from a structure.  */";
276 print "extern void cl_optimization_print (FILE *, int, struct cl_optimization *);";
277 print "";
278 print "/* Save selected option variables into a structure.  */"
279 print "extern void cl_target_option_save (struct cl_target_option *, struct gcc_options *);";
280 print "";
281 print "/* Restore selected option variables from a structure.  */"
282 print "extern void cl_target_option_restore (struct gcc_options *, struct cl_target_option *);";
283 print "";
284 print "/* Print target option variables from a structure.  */";
285 print "extern void cl_target_option_print (FILE *, int, struct cl_target_option *);";
286 print "#endif";
287 print "";
288
289 for (i = 0; i < n_opts; i++) {
290         name = opt_args("Mask", flags[i])
291         vname = var_name(flags[i])
292         mask = "MASK_"
293         if (vname != "") {
294                 mask = "OPTION_MASK_"
295         }
296         if (name != "" && !flag_set_p("MaskExists", flags[i]))
297                 print "#define " mask name " (1 << " masknum[vname]++ ")"
298 }
299 for (i = 0; i < n_extra_masks; i++) {
300         print "#define MASK_" extra_masks[i] " (1 << " masknum[""]++ ")"
301 }
302
303 for (var in masknum) {
304         if (masknum[var] > 31) {
305                 if (var == "")
306                         print "#error too many target masks"
307                 else
308                         print "#error too many masks for " var
309         }
310 }
311 print ""
312
313 for (i = 0; i < n_opts; i++) {
314         name = opt_args("Mask", flags[i])
315         vname = var_name(flags[i])
316         macro = "OPTION_"
317         mask = "OPTION_MASK_"
318         if (vname == "") {
319                 vname = "target_flags"
320                 macro = "TARGET_"
321                 mask = "MASK_"
322         }
323         if (name != "" && !flag_set_p("MaskExists", flags[i]))
324                 print "#define " macro name \
325                       " ((" vname " & " mask name ") != 0)"
326 }
327 for (i = 0; i < n_extra_masks; i++) {
328         print "#define TARGET_" extra_masks[i] \
329               " ((target_flags & MASK_" extra_masks[i] ") != 0)"
330 }
331 print ""
332
333 for (i = 0; i < n_opts; i++) {
334         opt = opt_args("InverseMask", flags[i])
335         if (opt ~ ",") {
336                 vname = var_name(flags[i])
337                 macro = "OPTION_"
338                 mask = "OPTION_MASK_"
339                 if (vname == "") {
340                         vname = "target_flags"
341                         macro = "TARGET_"
342                         mask = "MASK_"
343                 }
344                 print "#define " macro nth_arg(1, opt) \
345                       " ((" vname " & " mask nth_arg(0, opt) ") == 0)"
346         }
347 }
348 print ""
349
350 for (i = 0; i < n_langs; i++) {
351         macros[i] = "CL_" langs[i]
352         gsub( "[^A-Za-z0-9_]", "X", macros[i] )
353         s = substr("            ", length (macros[i]))
354         print "#define " macros[i] s " (1 << " i ")"
355     }
356 print "#define CL_LANG_ALL   ((1 << " n_langs ") - 1)"
357
358 print ""
359 print "enum opt_code"
360 print "{"
361         
362 for (i = 0; i < n_opts; i++)
363         back_chain[i] = "N_OPTS";
364
365 enum_value = 0
366 for (i = 0; i < n_opts; i++) {
367         # Combine the flags of identical switches.  Switches
368         # appear many times if they are handled by many front
369         # ends, for example.
370         while( i + 1 != n_opts && opts[i] == opts[i + 1] ) {
371                 flags[i + 1] = flags[i] " " flags[i + 1];
372                 i++;
373         }
374
375         len = length (opts[i]);
376         enum = opt_enum(opts[i])
377         enum_string = enum " = " enum_value ","
378
379         # Aliases do not get enumeration names.
380         if ((flag_set_p("Alias.*", flags[i]) \
381              && !flag_set_p("SeparateAlias", flags[i])) \
382             || flag_set_p("Ignore", flags[i])) {
383                 enum_string = "/* " enum_string " */"
384         }
385
386         # If this switch takes joined arguments, back-chain all
387         # subsequent switches to it for which it is a prefix.  If
388         # a later switch S is a longer prefix of a switch T, T
389         # will be back-chained to S in a later iteration of this
390         # for() loop, which is what we want.
391         if (flag_set_p("Joined.*", flags[i])) {
392                 for (j = i + 1; j < n_opts; j++) {
393                         if (substr (opts[j], 1, len) != opts[i])
394                                 break;
395                         back_chain[j] = enum;
396                 }
397         }
398
399         s = substr("                                          ",
400                    length (enum_string))
401
402         if (help[i] == "")
403                 hlp = "0"
404         else
405                 hlp = "N_(\"" help[i] "\")";
406
407         print "  " enum_string s "/* -" opts[i] " */"
408         enum_value++
409 }
410
411 print "  N_OPTS,"
412 print "  OPT_SPECIAL_unknown,"
413 print "  OPT_SPECIAL_ignore,"
414 print "  OPT_SPECIAL_program_name,"
415 print "  OPT_SPECIAL_input_file"
416 print "};"
417 print ""
418 print "#endif /* OPTIONS_H */"
419 }