]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/optc-gen.awk
* gcc.dg/stack-usage-1.c: Adjust on i386/Darwin.
[thirdparty/gcc.git] / gcc / optc-gen.awk
CommitLineData
7cf0dbf3 1# Copyright (C) 2003, 2004, 2007, 2008, 2009, 2010
2# Free Software Foundation, Inc.
e8b212b8 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
8c4c00c1 8# Free Software Foundation; either version 3, or (at your option) any
e8b212b8 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
8c4c00c1 17# along with this program; see the file COPYING3. If not see
18# <http://www.gnu.org/licenses/>.
e8b212b8 19
20# This Awk script reads in the option records generated from
63433b97 21# opt-gather.awk, combines the flags of duplicate options and generates a
e8b212b8 22# C file.
23#
24# This program uses functions from opt-functions.awk
25#
26# Usage: awk -f opt-functions.awk -f optc-gen.awk \
27# [-v header_name=header.h] < inputfile > options.c
28
29BEGIN {
30 n_opts = 0
31 n_langs = 0
46f8e3b0 32 n_target_save = 0
e8b212b8 33 quote = "\042"
34 comma = ","
35 FS=SUBSEP
36 # Default the name of header created from opth-gen.awk to options.h
37 if (header_name == "") header_name="options.h"
38}
39
40# Collect the text and flags of each option into an array
41 {
42 if ($1 == "Language") {
43 langs[n_langs] = $2
44 n_langs++;
45 }
46f8e3b0 46 else if ($1 == "TargetSave") {
47 # Make sure the declarations are put in source order
48 target_save_decl[n_target_save] = $2
49 n_target_save++
50 }
e8b212b8 51 else {
a9341855 52 name = opt_args("Mask", $1)
53 if (name == "") {
54 opts[n_opts] = $1
55 flags[n_opts] = $2
56 help[n_opts] = $3
1df76a79 57 for (i = 4; i <= NF; i++)
58 help[n_opts] = help[n_opts] " " $i
a9341855 59 n_opts++;
60 }
e8b212b8 61 }
62 }
63
64# Dump that array of options into a C file.
65END {
30b0f428 66print "/* This file is auto-generated by optc-gen.awk. */"
e8b212b8 67print ""
5c5ccba2 68n_headers = split(header_name, headers, " ")
69for (i = 1; i <= n_headers; i++)
70 print "#include " quote headers[i] quote
e8b212b8 71print "#include " quote "opts.h" quote
6ce616df 72print "#include " quote "intl.h" quote
e8b212b8 73print ""
486ae7e7 74print "#ifdef GCC_DRIVER"
a1baa5f1 75print "int target_flags;"
b78351e5 76print "int target_flags_explicit;"
46f8e3b0 77print "#else"
78print "#include " quote "flags.h" quote
79print "#include " quote "target.h" quote
486ae7e7 80print "#endif /* GCC_DRIVER */"
a1baa5f1 81print ""
e8b212b8 82
46f8e3b0 83have_save = 0;
e8b212b8 84for (i = 0; i < n_opts; i++) {
46f8e3b0 85 if (flag_set_p("Save", flags[i]))
86 have_save = 1;
87
e8b212b8 88 name = var_name(flags[i]);
89 if (name == "")
90 continue;
91
a1baa5f1 92 if (flag_set_p("VarExists", flags[i])) {
93 # Need it for the gcc driver.
94 if (name in var_seen)
95 continue;
96 init = ""
486ae7e7 97 gcc_driver = 1
a1baa5f1 98 }
99 else {
100 init = opt_args("Init", flags[i])
101 if (init != "")
102 init = " = " init;
103 else if (name in var_seen)
104 continue;
486ae7e7 105 gcc_driver = 0
a1baa5f1 106 }
a150399d 107
486ae7e7 108 if (gcc_driver == 1)
109 print "#ifdef GCC_DRIVER"
0fe44c73 110 print "/* Set by -" opts[i] "."
111 print " " help[i] " */"
112 print var_type(flags[i]) name init ";"
486ae7e7 113 if (gcc_driver == 1)
114 print "#endif /* GCC_DRIVER */"
0fe44c73 115 print ""
c5e839cb 116
117 var_seen[name] = 1;
a150399d 118}
e8b212b8 119
d6907cfa 120print ""
121print "/* Local state variables. */"
122for (i = 0; i < n_opts; i++) {
123 name = static_var(opts[i], flags[i]);
124 if (name != "")
125 print "static " var_type(flags[i]) name ";"
126}
127print ""
e8b212b8 128
129print "const char * const lang_names[] =\n{"
130for (i = 0; i < n_langs; i++) {
131 macros[i] = "CL_" langs[i]
132 gsub( "[^A-Za-z0-9_]", "X", macros[i] )
133 s = substr(" ", length (macros[i]))
134 print " " quote langs[i] quote ","
135 }
136
137print " 0\n};\n"
138print "const unsigned int cl_options_count = N_OPTS;\n"
87c75316 139print "const unsigned int cl_lang_count = " n_langs ";\n"
e8b212b8 140
141print "const struct cl_option cl_options[] =\n{"
142
a1baa5f1 143j = 0
144for (i = 0; i < n_opts; i++) {
e8b212b8 145 back_chain[i] = "N_OPTS";
a1baa5f1 146 indices[opts[i]] = j;
147 # Combine the flags of identical switches. Switches
148 # appear many times if they are handled by many front
149 # ends, for example.
150 while( i + 1 != n_opts && opts[i] == opts[i + 1] ) {
151 flags[i + 1] = flags[i] " " flags[i + 1];
e6a03973 152 if (help[i + 1] == "")
153 help[i + 1] = help[i]
0863a8f4 154 else if (help[i] != "" && help[i + 1] != help[i])
155 print "warning: multiple different help strings for " \
156 opts[i] ":\n\t" help[i] "\n\t" help[i + 1] \
157 | "cat 1>&2"
a1baa5f1 158 i++;
159 back_chain[i] = "N_OPTS";
160 indices[opts[i]] = j;
161 }
162 j++;
163}
e8b212b8 164
d39ef3aa 165for (i = 0; i < n_opts; i++) {
e6a03973 166 # With identical flags, pick only the last one. The
167 # earlier loop ensured that it has all flags merged,
168 # and a nonempty help text if one of the texts was nonempty.
d39ef3aa 169 while( i + 1 != n_opts && opts[i] == opts[i + 1] ) {
d39ef3aa 170 i++;
171 }
e8b212b8 172
d39ef3aa 173 len = length (opts[i]);
d4c7816a 174 enum = opt_enum(opts[i])
d39ef3aa 175
176 # If this switch takes joined arguments, back-chain all
177 # subsequent switches to it for which it is a prefix. If
178 # a later switch S is a longer prefix of a switch T, T
179 # will be back-chained to S in a later iteration of this
180 # for() loop, which is what we want.
181 if (flag_set_p("Joined.*", flags[i])) {
182 for (j = i + 1; j < n_opts; j++) {
183 if (substr (opts[j], 1, len) != opts[i])
184 break;
185 back_chain[j] = enum;
e8b212b8 186 }
d39ef3aa 187 }
e8b212b8 188
d39ef3aa 189 s = substr(" ", length (opts[i]))
190 if (i + 1 == n_opts)
191 comma = ""
e8b212b8 192
d39ef3aa 193 if (help[i] == "")
194 hlp = "0"
195 else
196 hlp = quote help[i] quote;
e8b212b8 197
fecf9011 198 missing_arg_error = opt_args("MissingArgError", flags[i])
199 if (missing_arg_error == "")
200 missing_arg_error = "0"
201 else
202 missing_arg_error = quote missing_arg_error quote
203
a1baa5f1 204 neg = opt_args("Negative", flags[i]);
205 if (neg != "")
206 idx = indices[neg]
207 else {
208 if (flag_set_p("RejectNegative", flags[i]))
209 idx = -1;
210 else {
211 if (opts[i] ~ "^[Wfm]")
212 idx = indices[opts[i]];
213 else
214 idx = -1;
215 }
216 }
13c2c394 217 # Split the printf after %u to work around an ia64-hp-hpux11.23
218 # awk bug.
fecf9011 219 printf(" { %c-%s%c,\n %s,\n %s,\n %s, %u,",
220 quote, opts[i], quote, hlp, missing_arg_error,
221 back_chain[i], len)
13c2c394 222 printf(" %d,\n", idx)
5c5ccba2 223 condition = opt_args("Condition", flags[i])
224 cl_flags = switch_flags(flags[i])
225 if (condition != "")
226 printf("#if %s\n" \
227 " %s,\n" \
228 "#else\n" \
229 " CL_DISABLED,\n" \
230 "#endif\n",
231 condition, cl_flags, cl_flags)
232 else
233 printf(" %s,\n", cl_flags)
d6907cfa 234 printf(" %s, %s }%s\n", var_ref(opts[i], flags[i]),
235 var_set(flags[i]), comma)
e8b212b8 236}
237
238print "};"
46f8e3b0 239
240print "";
5cd72fe5 241print "#if !defined(GCC_DRIVER) && !defined(IN_LIBGCC2) && !defined(IN_TARGET_LIBS)"
46f8e3b0 242print "";
243print "/* Save optimization variables into a structure. */"
244print "void";
245print "cl_optimization_save (struct cl_optimization *ptr)";
246print "{";
247
248n_opt_char = 2;
249n_opt_short = 0;
250n_opt_int = 0;
251n_opt_other = 0;
252var_opt_char[0] = "optimize";
253var_opt_char[1] = "optimize_size";
254var_opt_range["optimize"] = "0, 255";
255var_opt_range["optimize_size"] = "0, 255";
256
257# Sort by size to mimic how the structure is laid out to be friendlier to the
258# cache.
259
260for (i = 0; i < n_opts; i++) {
261 if (flag_set_p("Optimization", flags[i])) {
262 name = var_name(flags[i])
263 if(name == "")
264 continue;
265
266 if(name in var_opt_seen)
267 continue;
268
269 var_opt_seen[name]++;
270 otype = var_type_struct(flags[i]);
271 if (otype ~ "^((un)?signed +)?int *$")
272 var_opt_int[n_opt_int++] = name;
273
274 else if (otype ~ "^((un)?signed +)?short *$")
275 var_opt_short[n_opt_short++] = name;
276
277 else if (otype ~ "^((un)?signed +)?char *$") {
278 var_opt_char[n_opt_char++] = name;
279 if (otype ~ "^unsigned +char *$")
280 var_opt_range[name] = "0, 255"
281 else if (otype ~ "^signed +char *$")
282 var_opt_range[name] = "-128, 127"
283 }
284 else
285 var_opt_other[n_opt_other++] = name;
286 }
287}
288
289for (i = 0; i < n_opt_char; i++) {
290 name = var_opt_char[i];
291 if (var_opt_range[name] != "")
292 print " gcc_assert (IN_RANGE (" name ", " var_opt_range[name] "));";
293}
294
295print "";
296for (i = 0; i < n_opt_other; i++) {
297 print " ptr->" var_opt_other[i] " = " var_opt_other[i] ";";
298}
299
300for (i = 0; i < n_opt_int; i++) {
301 print " ptr->" var_opt_int[i] " = " var_opt_int[i] ";";
302}
303
304for (i = 0; i < n_opt_short; i++) {
305 print " ptr->" var_opt_short[i] " = " var_opt_short[i] ";";
306}
307
308for (i = 0; i < n_opt_char; i++) {
309 print " ptr->" var_opt_char[i] " = " var_opt_char[i] ";";
310}
311
312print "}";
313
314print "";
315print "/* Restore optimization options from a structure. */";
316print "void";
317print "cl_optimization_restore (struct cl_optimization *ptr)";
318print "{";
319
320for (i = 0; i < n_opt_other; i++) {
321 print " " var_opt_other[i] " = ptr->" var_opt_other[i] ";";
322}
323
324for (i = 0; i < n_opt_int; i++) {
325 print " " var_opt_int[i] " = ptr->" var_opt_int[i] ";";
326}
327
328for (i = 0; i < n_opt_short; i++) {
329 print " " var_opt_short[i] " = ptr->" var_opt_short[i] ";";
330}
331
332for (i = 0; i < n_opt_char; i++) {
333 print " " var_opt_char[i] " = ptr->" var_opt_char[i] ";";
334}
335
4bec06b3 336print " targetm.override_options_after_change ();";
46f8e3b0 337print "}";
338
339print "";
340print "/* Print optimization options from a structure. */";
341print "void";
342print "cl_optimization_print (FILE *file,";
343print " int indent_to,";
344print " struct cl_optimization *ptr)";
345print "{";
346
347print " fputs (\"\\n\", file);";
348for (i = 0; i < n_opt_other; i++) {
349 print " if (ptr->" var_opt_other[i] ")";
95dcf70a 350 print " fprintf (file, \"%*s%s (%#lx)\\n\",";
46f8e3b0 351 print " indent_to, \"\",";
352 print " \"" var_opt_other[i] "\",";
353 print " (unsigned long)ptr->" var_opt_other[i] ");";
354 print "";
355}
356
357for (i = 0; i < n_opt_int; i++) {
358 print " if (ptr->" var_opt_int[i] ")";
95dcf70a 359 print " fprintf (file, \"%*s%s (%#x)\\n\",";
46f8e3b0 360 print " indent_to, \"\",";
361 print " \"" var_opt_int[i] "\",";
362 print " ptr->" var_opt_int[i] ");";
363 print "";
364}
365
366for (i = 0; i < n_opt_short; i++) {
367 print " if (ptr->" var_opt_short[i] ")";
95dcf70a 368 print " fprintf (file, \"%*s%s (%#x)\\n\",";
46f8e3b0 369 print " indent_to, \"\",";
370 print " \"" var_opt_short[i] "\",";
371 print " ptr->" var_opt_short[i] ");";
372 print "";
373}
374
375for (i = 0; i < n_opt_char; i++) {
376 print " if (ptr->" var_opt_char[i] ")";
95dcf70a 377 print " fprintf (file, \"%*s%s (%#x)\\n\",";
46f8e3b0 378 print " indent_to, \"\",";
379 print " \"" var_opt_char[i] "\",";
380 print " ptr->" var_opt_char[i] ");";
381 print "";
382}
383
384print "}";
385
386print "";
387print "/* Save selected option variables into a structure. */"
388print "void";
389print "cl_target_option_save (struct cl_target_option *ptr)";
390print "{";
391
392n_target_char = 0;
393n_target_short = 0;
394n_target_int = 0;
395n_target_other = 0;
396
397if (have_save) {
398 for (i = 0; i < n_opts; i++) {
399 if (flag_set_p("Save", flags[i])) {
400 name = var_name(flags[i])
401 if(name == "")
402 name = "target_flags";
403
404 if(name in var_save_seen)
405 continue;
406
407 var_save_seen[name]++;
408 otype = var_type_struct(flags[i])
409 if (otype ~ "^((un)?signed +)?int *$")
410 var_target_int[n_target_int++] = name;
411
412 else if (otype ~ "^((un)?signed +)?short *$")
413 var_target_short[n_target_short++] = name;
414
415 else if (otype ~ "^((un)?signed +)?char *$") {
416 var_target_char[n_target_char++] = name;
417 if (otype ~ "^unsigned +char *$")
418 var_target_range[name] = "0, 255"
419 else if (otype ~ "^signed +char *$")
420 var_target_range[name] = "-128, 127"
421 }
422 else
423 var_target_other[n_target_other++] = name;
424 }
425 }
426} else {
427 var_target_int[n_target_int++] = "target_flags";
428}
429
430have_assert = 0;
431for (i = 0; i < n_target_char; i++) {
432 name = var_target_char[i];
433 if (var_target_range[name] != "") {
434 have_assert = 1;
435 print " gcc_assert (IN_RANGE (" name ", " var_target_range[name] "));";
436 }
437}
438
439if (have_assert)
440 print "";
441
442print " if (targetm.target_option.save)";
443print " targetm.target_option.save (ptr);";
444print "";
445
446for (i = 0; i < n_target_other; i++) {
447 print " ptr->" var_target_other[i] " = " var_target_other[i] ";";
448}
449
450for (i = 0; i < n_target_int; i++) {
451 print " ptr->" var_target_int[i] " = " var_target_int[i] ";";
452}
453
454for (i = 0; i < n_target_short; i++) {
455 print " ptr->" var_target_short[i] " = " var_target_short[i] ";";
456}
457
458for (i = 0; i < n_target_char; i++) {
459 print " ptr->" var_target_char[i] " = " var_target_char[i] ";";
460}
461
462print "}";
463
464print "";
465print "/* Restore selected current options from a structure. */";
466print "void";
467print "cl_target_option_restore (struct cl_target_option *ptr)";
468print "{";
469
470for (i = 0; i < n_target_other; i++) {
471 print " " var_target_other[i] " = ptr->" var_target_other[i] ";";
472}
473
474for (i = 0; i < n_target_int; i++) {
475 print " " var_target_int[i] " = ptr->" var_target_int[i] ";";
476}
477
478for (i = 0; i < n_target_short; i++) {
479 print " " var_target_short[i] " = ptr->" var_target_short[i] ";";
480}
481
482for (i = 0; i < n_target_char; i++) {
483 print " " var_target_char[i] " = ptr->" var_target_char[i] ";";
484}
485
486# This must occur after the normal variables in case the code depends on those
487# variables.
488print "";
489print " if (targetm.target_option.restore)";
490print " targetm.target_option.restore (ptr);";
491
492print "}";
493
494print "";
495print "/* Print optimization options from a structure. */";
496print "void";
497print "cl_target_option_print (FILE *file,";
498print " int indent,";
499print " struct cl_target_option *ptr)";
500print "{";
501
502print " fputs (\"\\n\", file);";
503for (i = 0; i < n_target_other; i++) {
504 print " if (ptr->" var_target_other[i] ")";
95dcf70a 505 print " fprintf (file, \"%*s%s (%#lx)\\n\",";
46f8e3b0 506 print " indent, \"\",";
507 print " \"" var_target_other[i] "\",";
508 print " (unsigned long)ptr->" var_target_other[i] ");";
509 print "";
510}
511
512for (i = 0; i < n_target_int; i++) {
513 print " if (ptr->" var_target_int[i] ")";
95dcf70a 514 print " fprintf (file, \"%*s%s (%#x)\\n\",";
46f8e3b0 515 print " indent, \"\",";
516 print " \"" var_target_int[i] "\",";
517 print " ptr->" var_target_int[i] ");";
518 print "";
519}
520
521for (i = 0; i < n_target_short; i++) {
522 print " if (ptr->" var_target_short[i] ")";
95dcf70a 523 print " fprintf (file, \"%*s%s (%#x)\\n\",";
46f8e3b0 524 print " indent, \"\",";
525 print " \"" var_target_short[i] "\",";
526 print " ptr->" var_target_short[i] ");";
527 print "";
528}
529
530for (i = 0; i < n_target_char; i++) {
531 print " if (ptr->" var_target_char[i] ")";
95dcf70a 532 print " fprintf (file, \"%*s%s (%#x)\\n\",";
46f8e3b0 533 print " indent, \"\",";
534 print " \"" var_target_char[i] "\",";
535 print " ptr->" var_target_char[i] ");";
536 print "";
537}
538
539print "";
540print " if (targetm.target_option.print)";
541print " targetm.target_option.print (file, indent, ptr);";
542
543print "}";
544print "#endif";
545
e8b212b8 546}