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