]>
Commit | Line | Data |
---|---|---|
c75c517d SB |
1 | # Copyright (C) 2003,2004,2005,2006,2007,2008, 2010 |
2 | # Free Software Foundation, Inc. | |
776dc15d KC |
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 | |
9dcd6f09 | 8 | # Free Software Foundation; either version 3, or (at your option) any |
776dc15d KC |
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 | |
9dcd6f09 NC |
17 | # along with this program; see the file COPYING3. If not see |
18 | # <http://www.gnu.org/licenses/>. | |
776dc15d KC |
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 | |
ab442df7 | 30 | n_target_save = 0 |
e90afde6 | 31 | n_extra_vars = 0 |
fe609b0f | 32 | n_extra_masks = 0 |
776dc15d KC |
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 | } | |
ab442df7 MM |
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 | } | |
e90afde6 JM |
47 | else if ($1 == "Variable") { |
48 | extra_vars[n_extra_vars] = $2 | |
49 | n_extra_vars++ | |
50 | } | |
776dc15d | 51 | else { |
fe609b0f EB |
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 | } | |
776dc15d KC |
62 | } |
63 | } | |
64 | ||
65 | # Dump out an enumeration into a .h file. | |
66 | # Combine the flags of duplicate options. | |
67 | END { | |
14078ff6 | 68 | print "/* This file is auto-generated by opth-gen.awk. */" |
776dc15d KC |
69 | print "" |
70 | print "#ifndef OPTIONS_H" | |
71 | print "#define OPTIONS_H" | |
72 | print "" | |
73 | ||
ab442df7 MM |
74 | have_save = 0; |
75 | ||
a75bfaa6 | 76 | print "#if !defined(IN_LIBGCC2) && !defined(IN_TARGET_LIBS) && !defined(IN_RTS)" |
e3339d0f JM |
77 | print "#ifndef GENERATOR_FILE" |
78 | print "struct gcc_options\n{" | |
79 | print "#endif" | |
80 | ||
e90afde6 JM |
81 | for (i = 0; i < n_extra_vars; i++) { |
82 | var = extra_vars[i] | |
83 | sub(" *=.*", "", var) | |
e3339d0f JM |
84 | orig_var = var |
85 | name = var | |
86 | type = var | |
87 | sub("^.*[ *]", "", name) | |
88 | sub(" *" name "$", "", type) | |
89 | var_seen[name] = 1 | |
90 | print "#ifdef GENERATOR_FILE" | |
91 | print "extern " orig_var ";" | |
92 | print "#else" | |
93 | print " " type " x_" name ";" | |
94 | print "#define " name " global_options.x_" name | |
95 | print "#endif" | |
e90afde6 JM |
96 | } |
97 | ||
776dc15d | 98 | for (i = 0; i < n_opts; i++) { |
ab442df7 MM |
99 | if (flag_set_p("Save", flags[i])) |
100 | have_save = 1; | |
101 | ||
776dc15d KC |
102 | name = var_name(flags[i]); |
103 | if (name == "") | |
104 | continue; | |
105 | ||
ab442df7 MM |
106 | if (name in var_seen) |
107 | continue; | |
108 | ||
109 | var_seen[name] = 1; | |
e3339d0f | 110 | print "#ifdef GENERATOR_FILE" |
55bea00a | 111 | print "extern " var_type(flags[i]) name ";" |
e3339d0f JM |
112 | print "#else" |
113 | print " " var_type(flags[i]) "x_" name ";" | |
114 | print "#define " name " global_options.x_" name | |
115 | print "#endif" | |
55bea00a | 116 | } |
46625112 JM |
117 | for (i = 0; i < n_opts; i++) { |
118 | name = static_var(opts[i], flags[i]); | |
119 | if (name != "") { | |
120 | print "#ifndef GENERATOR_FILE" | |
121 | print " " var_type(flags[i]) "x_" name ";" | |
122 | print "#define x_" name " do_not_use" | |
123 | print "#endif" | |
124 | } | |
125 | } | |
e3339d0f JM |
126 | print "#ifndef GENERATOR_FILE" |
127 | print "};" | |
128 | print "extern struct gcc_options global_options;" | |
a75bfaa6 | 129 | print "extern const struct gcc_options global_options_init;" |
d4d24ba4 JM |
130 | print "extern struct gcc_options global_options_set;" |
131 | print "#define target_flags_explicit global_options_set.x_target_flags" | |
e3339d0f | 132 | print "#endif" |
a75bfaa6 | 133 | print "#endif" |
55bea00a | 134 | print "" |
776dc15d | 135 | |
ab442df7 MM |
136 | # All of the optimization switches gathered together so they can be saved and restored. |
137 | # This will allow attribute((cold)) to turn on space optimization. | |
138 | ||
139 | # Change the type of normal switches from int to unsigned char to save space. | |
140 | # Also, order the structure so that pointer fields occur first, then int | |
141 | # fields, and then char fields to provide the best packing. | |
142 | ||
e62fe68a | 143 | print "#if !defined(GCC_DRIVER) && !defined(IN_LIBGCC2) && !defined(IN_TARGET_LIBS)" |
ab442df7 MM |
144 | print "" |
145 | print "/* Structure to save/restore optimization and target specific options. */"; | |
d1b38208 | 146 | print "struct GTY(()) cl_optimization"; |
ab442df7 MM |
147 | print "{"; |
148 | ||
149 | n_opt_char = 2; | |
150 | n_opt_short = 0; | |
151 | n_opt_int = 0; | |
152 | n_opt_other = 0; | |
e3339d0f JM |
153 | var_opt_char[0] = "unsigned char x_optimize"; |
154 | var_opt_char[1] = "unsigned char x_optimize_size"; | |
ab442df7 MM |
155 | |
156 | for (i = 0; i < n_opts; i++) { | |
157 | if (flag_set_p("Optimization", flags[i])) { | |
158 | name = var_name(flags[i]) | |
159 | if(name == "") | |
160 | continue; | |
161 | ||
162 | if(name in var_opt_seen) | |
163 | continue; | |
164 | ||
165 | var_opt_seen[name]++; | |
166 | otype = var_type_struct(flags[i]); | |
167 | if (otype ~ "^((un)?signed +)?int *$") | |
e3339d0f | 168 | var_opt_int[n_opt_int++] = otype "x_" name; |
ab442df7 MM |
169 | |
170 | else if (otype ~ "^((un)?signed +)?short *$") | |
e3339d0f | 171 | var_opt_short[n_opt_short++] = otype "x_" name; |
ab442df7 MM |
172 | |
173 | else if (otype ~ "^((un)?signed +)?char *$") | |
e3339d0f | 174 | var_opt_char[n_opt_char++] = otype "x_" name; |
ab442df7 MM |
175 | |
176 | else | |
e3339d0f | 177 | var_opt_other[n_opt_other++] = otype "x_" name; |
ab442df7 MM |
178 | } |
179 | } | |
180 | ||
181 | for (i = 0; i < n_opt_other; i++) { | |
182 | print " " var_opt_other[i] ";"; | |
183 | } | |
184 | ||
185 | for (i = 0; i < n_opt_int; i++) { | |
186 | print " " var_opt_int[i] ";"; | |
187 | } | |
188 | ||
189 | for (i = 0; i < n_opt_short; i++) { | |
190 | print " " var_opt_short[i] ";"; | |
191 | } | |
192 | ||
193 | for (i = 0; i < n_opt_char; i++) { | |
194 | print " " var_opt_char[i] ";"; | |
195 | } | |
196 | ||
197 | print "};"; | |
198 | print ""; | |
199 | ||
200 | # Target and optimization save/restore/print functions. | |
201 | print "/* Structure to save/restore selected target specific options. */"; | |
d1b38208 | 202 | print "struct GTY(()) cl_target_option"; |
ab442df7 MM |
203 | print "{"; |
204 | ||
205 | n_target_char = 0; | |
206 | n_target_short = 0; | |
207 | n_target_int = 0; | |
208 | n_target_other = 0; | |
209 | ||
210 | for (i = 0; i < n_target_save; i++) { | |
e4590d63 | 211 | if (target_save_decl[i] ~ "^((un)?signed +)?int +[_" alnum "]+$") |
ab442df7 MM |
212 | var_target_int[n_target_int++] = target_save_decl[i]; |
213 | ||
e4590d63 | 214 | else if (target_save_decl[i] ~ "^((un)?signed +)?short +[_" alnum "]+$") |
ab442df7 MM |
215 | var_target_short[n_target_short++] = target_save_decl[i]; |
216 | ||
e4590d63 | 217 | else if (target_save_decl[i] ~ "^((un)?signed +)?char +[_ " alnum "]+$") |
ab442df7 MM |
218 | var_target_char[n_target_char++] = target_save_decl[i]; |
219 | ||
220 | else | |
221 | var_target_other[n_target_other++] = target_save_decl[i]; | |
222 | } | |
223 | ||
224 | if (have_save) { | |
225 | for (i = 0; i < n_opts; i++) { | |
226 | if (flag_set_p("Save", flags[i])) { | |
227 | name = var_name(flags[i]) | |
228 | if(name == "") | |
229 | name = "target_flags"; | |
230 | ||
231 | if(name in var_save_seen) | |
232 | continue; | |
233 | ||
234 | var_save_seen[name]++; | |
235 | otype = var_type_struct(flags[i]) | |
236 | if (otype ~ "^((un)?signed +)?int *$") | |
e3339d0f | 237 | var_target_int[n_target_int++] = otype "x_" name; |
ab442df7 MM |
238 | |
239 | else if (otype ~ "^((un)?signed +)?short *$") | |
e3339d0f | 240 | var_target_short[n_target_short++] = otype "x_" name; |
ab442df7 MM |
241 | |
242 | else if (otype ~ "^((un)?signed +)?char *$") | |
e3339d0f | 243 | var_target_char[n_target_char++] = otype "x_" name; |
ab442df7 MM |
244 | |
245 | else | |
e3339d0f | 246 | var_target_other[n_target_other++] = otype "x_" name; |
ab442df7 MM |
247 | } |
248 | } | |
249 | } else { | |
e3339d0f | 250 | var_target_int[n_target_int++] = "int x_target_flags"; |
ab442df7 MM |
251 | } |
252 | ||
253 | for (i = 0; i < n_target_other; i++) { | |
254 | print " " var_target_other[i] ";"; | |
255 | } | |
256 | ||
257 | for (i = 0; i < n_target_int; i++) { | |
258 | print " " var_target_int[i] ";"; | |
259 | } | |
260 | ||
261 | for (i = 0; i < n_target_short; i++) { | |
262 | print " " var_target_short[i] ";"; | |
263 | } | |
264 | ||
265 | for (i = 0; i < n_target_char; i++) { | |
266 | print " " var_target_char[i] ";"; | |
267 | } | |
268 | ||
269 | print "};"; | |
270 | print ""; | |
271 | print ""; | |
272 | print "/* Save optimization variables into a structure. */" | |
46625112 | 273 | print "extern void cl_optimization_save (struct cl_optimization *, struct gcc_options *);"; |
ab442df7 MM |
274 | print ""; |
275 | print "/* Restore optimization variables from a structure. */"; | |
46625112 | 276 | print "extern void cl_optimization_restore (struct gcc_options *, struct cl_optimization *);"; |
ab442df7 MM |
277 | print ""; |
278 | print "/* Print optimization variables from a structure. */"; | |
279 | print "extern void cl_optimization_print (FILE *, int, struct cl_optimization *);"; | |
280 | print ""; | |
281 | print "/* Save selected option variables into a structure. */" | |
46625112 | 282 | print "extern void cl_target_option_save (struct cl_target_option *, struct gcc_options *);"; |
ab442df7 MM |
283 | print ""; |
284 | print "/* Restore selected option variables from a structure. */" | |
46625112 | 285 | print "extern void cl_target_option_restore (struct gcc_options *, struct cl_target_option *);"; |
ab442df7 MM |
286 | print ""; |
287 | print "/* Print target option variables from a structure. */"; | |
288 | print "extern void cl_target_option_print (FILE *, int, struct cl_target_option *);"; | |
289 | print "#endif"; | |
290 | print ""; | |
291 | ||
75685792 RS |
292 | for (i = 0; i < n_opts; i++) { |
293 | name = opt_args("Mask", flags[i]) | |
f7f655c7 DD |
294 | vname = var_name(flags[i]) |
295 | mask = "MASK_" | |
296 | if (vname != "") { | |
297 | mask = "OPTION_MASK_" | |
298 | } | |
f9b4c1db | 299 | if (name != "" && !flag_set_p("MaskExists", flags[i])) |
f7f655c7 | 300 | print "#define " mask name " (1 << " masknum[vname]++ ")" |
75685792 | 301 | } |
fe609b0f | 302 | for (i = 0; i < n_extra_masks; i++) { |
f7f655c7 DD |
303 | print "#define MASK_" extra_masks[i] " (1 << " masknum[""]++ ")" |
304 | } | |
305 | ||
306 | for (var in masknum) { | |
307 | if (masknum[var] > 31) { | |
308 | if (var == "") | |
309 | print "#error too many target masks" | |
310 | else | |
311 | print "#error too many masks for " var | |
312 | } | |
fe609b0f | 313 | } |
75685792 RS |
314 | print "" |
315 | ||
316 | for (i = 0; i < n_opts; i++) { | |
317 | name = opt_args("Mask", flags[i]) | |
f7f655c7 DD |
318 | vname = var_name(flags[i]) |
319 | macro = "OPTION_" | |
320 | mask = "OPTION_MASK_" | |
321 | if (vname == "") { | |
322 | vname = "target_flags" | |
323 | macro = "TARGET_" | |
324 | mask = "MASK_" | |
325 | } | |
f9b4c1db | 326 | if (name != "" && !flag_set_p("MaskExists", flags[i])) |
f7f655c7 DD |
327 | print "#define " macro name \ |
328 | " ((" vname " & " mask name ") != 0)" | |
75685792 | 329 | } |
fe609b0f EB |
330 | for (i = 0; i < n_extra_masks; i++) { |
331 | print "#define TARGET_" extra_masks[i] \ | |
332 | " ((target_flags & MASK_" extra_masks[i] ") != 0)" | |
333 | } | |
75685792 RS |
334 | print "" |
335 | ||
336 | for (i = 0; i < n_opts; i++) { | |
337 | opt = opt_args("InverseMask", flags[i]) | |
7bd85ce0 JM |
338 | if (opt ~ ",") { |
339 | vname = var_name(flags[i]) | |
340 | macro = "OPTION_" | |
341 | mask = "OPTION_MASK_" | |
342 | if (vname == "") { | |
343 | vname = "target_flags" | |
344 | macro = "TARGET_" | |
345 | mask = "MASK_" | |
346 | } | |
347 | print "#define " macro nth_arg(1, opt) \ | |
348 | " ((" vname " & " mask nth_arg(0, opt) ") == 0)" | |
349 | } | |
75685792 RS |
350 | } |
351 | print "" | |
776dc15d KC |
352 | |
353 | for (i = 0; i < n_langs; i++) { | |
354 | macros[i] = "CL_" langs[i] | |
e4590d63 | 355 | gsub( "[^" alnum "_]", "X", macros[i] ) |
776dc15d KC |
356 | s = substr(" ", length (macros[i])) |
357 | print "#define " macros[i] s " (1 << " i ")" | |
358 | } | |
1f1d5130 | 359 | print "#define CL_LANG_ALL ((1 << " n_langs ") - 1)" |
776dc15d KC |
360 | |
361 | print "" | |
362 | print "enum opt_code" | |
363 | print "{" | |
364 | ||
365 | for (i = 0; i < n_opts; i++) | |
366 | back_chain[i] = "N_OPTS"; | |
367 | ||
5de8299c | 368 | enum_value = 0 |
64fbae21 RS |
369 | for (i = 0; i < n_opts; i++) { |
370 | # Combine the flags of identical switches. Switches | |
371 | # appear many times if they are handled by many front | |
372 | # ends, for example. | |
373 | while( i + 1 != n_opts && opts[i] == opts[i + 1] ) { | |
374 | flags[i + 1] = flags[i] " " flags[i + 1]; | |
375 | i++; | |
376 | } | |
776dc15d KC |
377 | |
378 | len = length (opts[i]); | |
9db94baa | 379 | enum = opt_enum(opts[i]) |
5de8299c JM |
380 | enum_string = enum " = " enum_value "," |
381 | ||
382 | # Aliases do not get enumeration names. | |
d1583032 JM |
383 | if ((flag_set_p("Alias.*", flags[i]) \ |
384 | && !flag_set_p("SeparateAlias", flags[i])) \ | |
385 | || flag_set_p("Ignore", flags[i])) { | |
5de8299c JM |
386 | enum_string = "/* " enum_string " */" |
387 | } | |
776dc15d KC |
388 | |
389 | # If this switch takes joined arguments, back-chain all | |
390 | # subsequent switches to it for which it is a prefix. If | |
391 | # a later switch S is a longer prefix of a switch T, T | |
392 | # will be back-chained to S in a later iteration of this | |
393 | # for() loop, which is what we want. | |
a56a0779 | 394 | if (flag_set_p("Joined.*", flags[i])) { |
776dc15d KC |
395 | for (j = i + 1; j < n_opts; j++) { |
396 | if (substr (opts[j], 1, len) != opts[i]) | |
397 | break; | |
398 | back_chain[j] = enum; | |
399 | } | |
400 | } | |
401 | ||
5de8299c JM |
402 | s = substr(" ", |
403 | length (enum_string)) | |
776dc15d KC |
404 | |
405 | if (help[i] == "") | |
406 | hlp = "0" | |
407 | else | |
408 | hlp = "N_(\"" help[i] "\")"; | |
409 | ||
5de8299c JM |
410 | print " " enum_string s "/* -" opts[i] " */" |
411 | enum_value++ | |
776dc15d KC |
412 | } |
413 | ||
6e2f1956 JM |
414 | print " N_OPTS," |
415 | print " OPT_SPECIAL_unknown," | |
2d2bd949 | 416 | print " OPT_SPECIAL_ignore," |
6e2f1956 JM |
417 | print " OPT_SPECIAL_program_name," |
418 | print " OPT_SPECIAL_input_file" | |
776dc15d KC |
419 | print "};" |
420 | print "" | |
421 | print "#endif /* OPTIONS_H */" | |
422 | } |