]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/optc-gen.awk
PR driver/44076
[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
67089c6b 204 alias_arg = opt_args("Alias", flags[i])
205 if (alias_arg == "") {
206 alias_data = "NULL, NULL, N_OPTS"
207 } else {
208 alias_opt = nth_arg(0, alias_arg)
209 alias_posarg = nth_arg(1, alias_arg)
210 alias_negarg = nth_arg(2, alias_arg)
211
212 if (var_ref(opts[i], flags[i]) != "0")
213 print "#error Alias setting variable"
214
215 if (alias_posarg != "" && alias_negarg == "") {
216 if (!flag_set_p("RejectNegative", flags[i]) \
217 && opts[i] ~ "^[Wfm]")
218 print "#error Alias with single argument " \
219 "allowing negative form"
220 }
221
222 alias_opt = opt_enum(alias_opt)
223 if (alias_posarg == "")
224 alias_posarg = "NULL"
225 else
226 alias_posarg = quote alias_posarg quote
227 if (alias_negarg == "")
228 alias_negarg = "NULL"
229 else
230 alias_negarg = quote alias_negarg quote
231 alias_data = alias_posarg ", " alias_negarg ", " alias_opt
232 }
233
a1baa5f1 234 neg = opt_args("Negative", flags[i]);
235 if (neg != "")
236 idx = indices[neg]
237 else {
238 if (flag_set_p("RejectNegative", flags[i]))
239 idx = -1;
240 else {
241 if (opts[i] ~ "^[Wfm]")
242 idx = indices[opts[i]];
243 else
244 idx = -1;
245 }
246 }
13c2c394 247 # Split the printf after %u to work around an ia64-hp-hpux11.23
248 # awk bug.
67089c6b 249 printf(" { %c-%s%c,\n %s,\n %s,\n %s, %s, %u,",
fecf9011 250 quote, opts[i], quote, hlp, missing_arg_error,
67089c6b 251 alias_data, back_chain[i], len)
13c2c394 252 printf(" %d,\n", idx)
5c5ccba2 253 condition = opt_args("Condition", flags[i])
254 cl_flags = switch_flags(flags[i])
255 if (condition != "")
256 printf("#if %s\n" \
257 " %s,\n" \
258 "#else\n" \
259 " CL_DISABLED,\n" \
260 "#endif\n",
261 condition, cl_flags, cl_flags)
262 else
263 printf(" %s,\n", cl_flags)
d6907cfa 264 printf(" %s, %s }%s\n", var_ref(opts[i], flags[i]),
265 var_set(flags[i]), comma)
e8b212b8 266}
267
268print "};"
46f8e3b0 269
270print "";
5cd72fe5 271print "#if !defined(GCC_DRIVER) && !defined(IN_LIBGCC2) && !defined(IN_TARGET_LIBS)"
46f8e3b0 272print "";
273print "/* Save optimization variables into a structure. */"
274print "void";
275print "cl_optimization_save (struct cl_optimization *ptr)";
276print "{";
277
278n_opt_char = 2;
279n_opt_short = 0;
280n_opt_int = 0;
281n_opt_other = 0;
282var_opt_char[0] = "optimize";
283var_opt_char[1] = "optimize_size";
284var_opt_range["optimize"] = "0, 255";
285var_opt_range["optimize_size"] = "0, 255";
286
287# Sort by size to mimic how the structure is laid out to be friendlier to the
288# cache.
289
290for (i = 0; i < n_opts; i++) {
291 if (flag_set_p("Optimization", flags[i])) {
292 name = var_name(flags[i])
293 if(name == "")
294 continue;
295
296 if(name in var_opt_seen)
297 continue;
298
299 var_opt_seen[name]++;
300 otype = var_type_struct(flags[i]);
301 if (otype ~ "^((un)?signed +)?int *$")
302 var_opt_int[n_opt_int++] = name;
303
304 else if (otype ~ "^((un)?signed +)?short *$")
305 var_opt_short[n_opt_short++] = name;
306
307 else if (otype ~ "^((un)?signed +)?char *$") {
308 var_opt_char[n_opt_char++] = name;
309 if (otype ~ "^unsigned +char *$")
310 var_opt_range[name] = "0, 255"
311 else if (otype ~ "^signed +char *$")
312 var_opt_range[name] = "-128, 127"
313 }
314 else
315 var_opt_other[n_opt_other++] = name;
316 }
317}
318
319for (i = 0; i < n_opt_char; i++) {
320 name = var_opt_char[i];
321 if (var_opt_range[name] != "")
322 print " gcc_assert (IN_RANGE (" name ", " var_opt_range[name] "));";
323}
324
325print "";
326for (i = 0; i < n_opt_other; i++) {
327 print " ptr->" var_opt_other[i] " = " var_opt_other[i] ";";
328}
329
330for (i = 0; i < n_opt_int; i++) {
331 print " ptr->" var_opt_int[i] " = " var_opt_int[i] ";";
332}
333
334for (i = 0; i < n_opt_short; i++) {
335 print " ptr->" var_opt_short[i] " = " var_opt_short[i] ";";
336}
337
338for (i = 0; i < n_opt_char; i++) {
339 print " ptr->" var_opt_char[i] " = " var_opt_char[i] ";";
340}
341
342print "}";
343
344print "";
345print "/* Restore optimization options from a structure. */";
346print "void";
347print "cl_optimization_restore (struct cl_optimization *ptr)";
348print "{";
349
350for (i = 0; i < n_opt_other; i++) {
351 print " " var_opt_other[i] " = ptr->" var_opt_other[i] ";";
352}
353
354for (i = 0; i < n_opt_int; i++) {
355 print " " var_opt_int[i] " = ptr->" var_opt_int[i] ";";
356}
357
358for (i = 0; i < n_opt_short; i++) {
359 print " " var_opt_short[i] " = ptr->" var_opt_short[i] ";";
360}
361
362for (i = 0; i < n_opt_char; i++) {
363 print " " var_opt_char[i] " = ptr->" var_opt_char[i] ";";
364}
365
4bec06b3 366print " targetm.override_options_after_change ();";
46f8e3b0 367print "}";
368
369print "";
370print "/* Print optimization options from a structure. */";
371print "void";
372print "cl_optimization_print (FILE *file,";
373print " int indent_to,";
374print " struct cl_optimization *ptr)";
375print "{";
376
377print " fputs (\"\\n\", file);";
378for (i = 0; i < n_opt_other; i++) {
379 print " if (ptr->" var_opt_other[i] ")";
95dcf70a 380 print " fprintf (file, \"%*s%s (%#lx)\\n\",";
46f8e3b0 381 print " indent_to, \"\",";
382 print " \"" var_opt_other[i] "\",";
383 print " (unsigned long)ptr->" var_opt_other[i] ");";
384 print "";
385}
386
387for (i = 0; i < n_opt_int; i++) {
388 print " if (ptr->" var_opt_int[i] ")";
95dcf70a 389 print " fprintf (file, \"%*s%s (%#x)\\n\",";
46f8e3b0 390 print " indent_to, \"\",";
391 print " \"" var_opt_int[i] "\",";
392 print " ptr->" var_opt_int[i] ");";
393 print "";
394}
395
396for (i = 0; i < n_opt_short; i++) {
397 print " if (ptr->" var_opt_short[i] ")";
95dcf70a 398 print " fprintf (file, \"%*s%s (%#x)\\n\",";
46f8e3b0 399 print " indent_to, \"\",";
400 print " \"" var_opt_short[i] "\",";
401 print " ptr->" var_opt_short[i] ");";
402 print "";
403}
404
405for (i = 0; i < n_opt_char; i++) {
406 print " if (ptr->" var_opt_char[i] ")";
95dcf70a 407 print " fprintf (file, \"%*s%s (%#x)\\n\",";
46f8e3b0 408 print " indent_to, \"\",";
409 print " \"" var_opt_char[i] "\",";
410 print " ptr->" var_opt_char[i] ");";
411 print "";
412}
413
414print "}";
415
416print "";
417print "/* Save selected option variables into a structure. */"
418print "void";
419print "cl_target_option_save (struct cl_target_option *ptr)";
420print "{";
421
422n_target_char = 0;
423n_target_short = 0;
424n_target_int = 0;
425n_target_other = 0;
426
427if (have_save) {
428 for (i = 0; i < n_opts; i++) {
429 if (flag_set_p("Save", flags[i])) {
430 name = var_name(flags[i])
431 if(name == "")
432 name = "target_flags";
433
434 if(name in var_save_seen)
435 continue;
436
437 var_save_seen[name]++;
438 otype = var_type_struct(flags[i])
439 if (otype ~ "^((un)?signed +)?int *$")
440 var_target_int[n_target_int++] = name;
441
442 else if (otype ~ "^((un)?signed +)?short *$")
443 var_target_short[n_target_short++] = name;
444
445 else if (otype ~ "^((un)?signed +)?char *$") {
446 var_target_char[n_target_char++] = name;
447 if (otype ~ "^unsigned +char *$")
448 var_target_range[name] = "0, 255"
449 else if (otype ~ "^signed +char *$")
450 var_target_range[name] = "-128, 127"
451 }
452 else
453 var_target_other[n_target_other++] = name;
454 }
455 }
456} else {
457 var_target_int[n_target_int++] = "target_flags";
458}
459
460have_assert = 0;
461for (i = 0; i < n_target_char; i++) {
462 name = var_target_char[i];
463 if (var_target_range[name] != "") {
464 have_assert = 1;
465 print " gcc_assert (IN_RANGE (" name ", " var_target_range[name] "));";
466 }
467}
468
469if (have_assert)
470 print "";
471
472print " if (targetm.target_option.save)";
473print " targetm.target_option.save (ptr);";
474print "";
475
476for (i = 0; i < n_target_other; i++) {
477 print " ptr->" var_target_other[i] " = " var_target_other[i] ";";
478}
479
480for (i = 0; i < n_target_int; i++) {
481 print " ptr->" var_target_int[i] " = " var_target_int[i] ";";
482}
483
484for (i = 0; i < n_target_short; i++) {
485 print " ptr->" var_target_short[i] " = " var_target_short[i] ";";
486}
487
488for (i = 0; i < n_target_char; i++) {
489 print " ptr->" var_target_char[i] " = " var_target_char[i] ";";
490}
491
492print "}";
493
494print "";
495print "/* Restore selected current options from a structure. */";
496print "void";
497print "cl_target_option_restore (struct cl_target_option *ptr)";
498print "{";
499
500for (i = 0; i < n_target_other; i++) {
501 print " " var_target_other[i] " = ptr->" var_target_other[i] ";";
502}
503
504for (i = 0; i < n_target_int; i++) {
505 print " " var_target_int[i] " = ptr->" var_target_int[i] ";";
506}
507
508for (i = 0; i < n_target_short; i++) {
509 print " " var_target_short[i] " = ptr->" var_target_short[i] ";";
510}
511
512for (i = 0; i < n_target_char; i++) {
513 print " " var_target_char[i] " = ptr->" var_target_char[i] ";";
514}
515
516# This must occur after the normal variables in case the code depends on those
517# variables.
518print "";
519print " if (targetm.target_option.restore)";
520print " targetm.target_option.restore (ptr);";
521
522print "}";
523
524print "";
525print "/* Print optimization options from a structure. */";
526print "void";
527print "cl_target_option_print (FILE *file,";
528print " int indent,";
529print " struct cl_target_option *ptr)";
530print "{";
531
532print " fputs (\"\\n\", file);";
533for (i = 0; i < n_target_other; i++) {
534 print " if (ptr->" var_target_other[i] ")";
95dcf70a 535 print " fprintf (file, \"%*s%s (%#lx)\\n\",";
46f8e3b0 536 print " indent, \"\",";
537 print " \"" var_target_other[i] "\",";
538 print " (unsigned long)ptr->" var_target_other[i] ");";
539 print "";
540}
541
542for (i = 0; i < n_target_int; i++) {
543 print " if (ptr->" var_target_int[i] ")";
95dcf70a 544 print " fprintf (file, \"%*s%s (%#x)\\n\",";
46f8e3b0 545 print " indent, \"\",";
546 print " \"" var_target_int[i] "\",";
547 print " ptr->" var_target_int[i] ");";
548 print "";
549}
550
551for (i = 0; i < n_target_short; i++) {
552 print " if (ptr->" var_target_short[i] ")";
95dcf70a 553 print " fprintf (file, \"%*s%s (%#x)\\n\",";
46f8e3b0 554 print " indent, \"\",";
555 print " \"" var_target_short[i] "\",";
556 print " ptr->" var_target_short[i] ");";
557 print "";
558}
559
560for (i = 0; i < n_target_char; i++) {
561 print " if (ptr->" var_target_char[i] ")";
95dcf70a 562 print " fprintf (file, \"%*s%s (%#x)\\n\",";
46f8e3b0 563 print " indent, \"\",";
564 print " \"" var_target_char[i] "\",";
565 print " ptr->" var_target_char[i] ");";
566 print "";
567}
568
569print "";
570print " if (targetm.target_option.print)";
571print " targetm.target_option.print (file, indent, ptr);";
572
573print "}";
574print "#endif";
575
e8b212b8 576}