]>
Commit | Line | Data |
---|---|---|
9dcd6f09 | 1 | # Copyright (C) 2003,2004,2005,2006,2007 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 | |
20 | # opt-gather.awk, combines the flags of duplicate options and generates a | |
21 | # C header file. | |
22 | # | |
23 | # This program uses functions from opt-functions.awk | |
24 | # Usage: awk -f opt-functions.awk -f opth-gen.awk < inputfile > options.h | |
25 | ||
26 | BEGIN { | |
27 | n_opts = 0 | |
28 | n_langs = 0 | |
ab442df7 | 29 | n_target_save = 0 |
fe609b0f EB |
30 | n_extra_masks = 0 |
31 | quote = "\042" | |
776dc15d KC |
32 | comma = "," |
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 | } | |
776dc15d | 47 | else { |
fe609b0f EB |
48 | name = opt_args("Mask", $1) |
49 | if (name == "") { | |
50 | opts[n_opts] = $1 | |
51 | flags[n_opts] = $2 | |
52 | help[n_opts] = $3 | |
53 | n_opts++; | |
54 | } | |
55 | else { | |
56 | extra_masks[n_extra_masks++] = name | |
57 | } | |
776dc15d KC |
58 | } |
59 | } | |
60 | ||
61 | # Dump out an enumeration into a .h file. | |
62 | # Combine the flags of duplicate options. | |
63 | END { | |
14078ff6 | 64 | print "/* This file is auto-generated by opth-gen.awk. */" |
776dc15d KC |
65 | print "" |
66 | print "#ifndef OPTIONS_H" | |
67 | print "#define OPTIONS_H" | |
68 | print "" | |
75685792 | 69 | print "extern int target_flags;" |
e9276c30 | 70 | print "extern int target_flags_explicit;" |
fe609b0f | 71 | print "" |
776dc15d | 72 | |
ab442df7 MM |
73 | have_save = 0; |
74 | ||
776dc15d | 75 | for (i = 0; i < n_opts; i++) { |
ab442df7 MM |
76 | if (flag_set_p("Save", flags[i])) |
77 | have_save = 1; | |
78 | ||
776dc15d KC |
79 | name = var_name(flags[i]); |
80 | if (name == "") | |
81 | continue; | |
82 | ||
ab442df7 MM |
83 | if (name in var_seen) |
84 | continue; | |
85 | ||
86 | var_seen[name] = 1; | |
55bea00a RS |
87 | print "extern " var_type(flags[i]) name ";" |
88 | } | |
89 | print "" | |
776dc15d | 90 | |
ab442df7 MM |
91 | # All of the optimization switches gathered together so they can be saved and restored. |
92 | # This will allow attribute((cold)) to turn on space optimization. | |
93 | ||
94 | # Change the type of normal switches from int to unsigned char to save space. | |
95 | # Also, order the structure so that pointer fields occur first, then int | |
96 | # fields, and then char fields to provide the best packing. | |
97 | ||
98 | print "#if !defined(GCC_DRIVER) && !defined(IN_LIBGCC2)" | |
99 | print "" | |
100 | print "/* Structure to save/restore optimization and target specific options. */"; | |
101 | print "struct cl_optimization GTY(())"; | |
102 | print "{"; | |
103 | ||
104 | n_opt_char = 2; | |
105 | n_opt_short = 0; | |
106 | n_opt_int = 0; | |
107 | n_opt_other = 0; | |
108 | var_opt_char[0] = "unsigned char optimize"; | |
109 | var_opt_char[1] = "unsigned char optimize_size"; | |
110 | ||
111 | for (i = 0; i < n_opts; i++) { | |
112 | if (flag_set_p("Optimization", flags[i])) { | |
113 | name = var_name(flags[i]) | |
114 | if(name == "") | |
115 | continue; | |
116 | ||
117 | if(name in var_opt_seen) | |
118 | continue; | |
119 | ||
120 | var_opt_seen[name]++; | |
121 | otype = var_type_struct(flags[i]); | |
122 | if (otype ~ "^((un)?signed +)?int *$") | |
123 | var_opt_int[n_opt_int++] = otype name; | |
124 | ||
125 | else if (otype ~ "^((un)?signed +)?short *$") | |
126 | var_opt_short[n_opt_short++] = otype name; | |
127 | ||
128 | else if (otype ~ "^((un)?signed +)?char *$") | |
129 | var_opt_char[n_opt_char++] = otype name; | |
130 | ||
131 | else | |
132 | var_opt_other[n_opt_other++] = otype name; | |
133 | } | |
134 | } | |
135 | ||
136 | for (i = 0; i < n_opt_other; i++) { | |
137 | print " " var_opt_other[i] ";"; | |
138 | } | |
139 | ||
140 | for (i = 0; i < n_opt_int; i++) { | |
141 | print " " var_opt_int[i] ";"; | |
142 | } | |
143 | ||
144 | for (i = 0; i < n_opt_short; i++) { | |
145 | print " " var_opt_short[i] ";"; | |
146 | } | |
147 | ||
148 | for (i = 0; i < n_opt_char; i++) { | |
149 | print " " var_opt_char[i] ";"; | |
150 | } | |
151 | ||
152 | print "};"; | |
153 | print ""; | |
154 | ||
155 | # Target and optimization save/restore/print functions. | |
156 | print "/* Structure to save/restore selected target specific options. */"; | |
157 | print "struct cl_target_option GTY(())"; | |
158 | print "{"; | |
159 | ||
160 | n_target_char = 0; | |
161 | n_target_short = 0; | |
162 | n_target_int = 0; | |
163 | n_target_other = 0; | |
164 | ||
165 | for (i = 0; i < n_target_save; i++) { | |
166 | if (target_save_decl[i] ~ "^((un)?signed +)?int +[_a-zA-Z0-9]+$") | |
167 | var_target_int[n_target_int++] = target_save_decl[i]; | |
168 | ||
169 | else if (target_save_decl[i] ~ "^((un)?signed +)?short +[_a-zA-Z0-9]+$") | |
170 | var_target_short[n_target_short++] = target_save_decl[i]; | |
171 | ||
172 | else if (target_save_decl[i] ~ "^((un)?signed +)?char +[_a-zA-Z0-9]+$") | |
173 | var_target_char[n_target_char++] = target_save_decl[i]; | |
174 | ||
175 | else | |
176 | var_target_other[n_target_other++] = target_save_decl[i]; | |
177 | } | |
178 | ||
179 | if (have_save) { | |
180 | for (i = 0; i < n_opts; i++) { | |
181 | if (flag_set_p("Save", flags[i])) { | |
182 | name = var_name(flags[i]) | |
183 | if(name == "") | |
184 | name = "target_flags"; | |
185 | ||
186 | if(name in var_save_seen) | |
187 | continue; | |
188 | ||
189 | var_save_seen[name]++; | |
190 | otype = var_type_struct(flags[i]) | |
191 | if (otype ~ "^((un)?signed +)?int *$") | |
192 | var_target_int[n_target_int++] = otype name; | |
193 | ||
194 | else if (otype ~ "^((un)?signed +)?short *$") | |
195 | var_target_short[n_target_short++] = otype name; | |
196 | ||
197 | else if (otype ~ "^((un)?signed +)?char *$") | |
198 | var_target_char[n_target_char++] = otype name; | |
199 | ||
200 | else | |
201 | var_target_other[n_target_other++] = otype name; | |
202 | } | |
203 | } | |
204 | } else { | |
205 | var_target_int[n_target_int++] = "int target_flags"; | |
206 | } | |
207 | ||
208 | for (i = 0; i < n_target_other; i++) { | |
209 | print " " var_target_other[i] ";"; | |
210 | } | |
211 | ||
212 | for (i = 0; i < n_target_int; i++) { | |
213 | print " " var_target_int[i] ";"; | |
214 | } | |
215 | ||
216 | for (i = 0; i < n_target_short; i++) { | |
217 | print " " var_target_short[i] ";"; | |
218 | } | |
219 | ||
220 | for (i = 0; i < n_target_char; i++) { | |
221 | print " " var_target_char[i] ";"; | |
222 | } | |
223 | ||
224 | print "};"; | |
225 | print ""; | |
226 | print ""; | |
227 | print "/* Save optimization variables into a structure. */" | |
228 | print "extern void cl_optimization_save (struct cl_optimization *);"; | |
229 | print ""; | |
230 | print "/* Restore optimization variables from a structure. */"; | |
231 | print "extern void cl_optimization_restore (struct cl_optimization *);"; | |
232 | print ""; | |
233 | print "/* Print optimization variables from a structure. */"; | |
234 | print "extern void cl_optimization_print (FILE *, int, struct cl_optimization *);"; | |
235 | print ""; | |
236 | print "/* Save selected option variables into a structure. */" | |
237 | print "extern void cl_target_option_save (struct cl_target_option *);"; | |
238 | print ""; | |
239 | print "/* Restore selected option variables from a structure. */" | |
240 | print "extern void cl_target_option_restore (struct cl_target_option *);"; | |
241 | print ""; | |
242 | print "/* Print target option variables from a structure. */"; | |
243 | print "extern void cl_target_option_print (FILE *, int, struct cl_target_option *);"; | |
244 | print "#endif"; | |
245 | print ""; | |
246 | ||
75685792 RS |
247 | for (i = 0; i < n_opts; i++) { |
248 | name = opt_args("Mask", flags[i]) | |
f7f655c7 DD |
249 | vname = var_name(flags[i]) |
250 | mask = "MASK_" | |
251 | if (vname != "") { | |
252 | mask = "OPTION_MASK_" | |
253 | } | |
f9b4c1db | 254 | if (name != "" && !flag_set_p("MaskExists", flags[i])) |
f7f655c7 | 255 | print "#define " mask name " (1 << " masknum[vname]++ ")" |
75685792 | 256 | } |
fe609b0f | 257 | for (i = 0; i < n_extra_masks; i++) { |
f7f655c7 DD |
258 | print "#define MASK_" extra_masks[i] " (1 << " masknum[""]++ ")" |
259 | } | |
260 | ||
261 | for (var in masknum) { | |
262 | if (masknum[var] > 31) { | |
263 | if (var == "") | |
264 | print "#error too many target masks" | |
265 | else | |
266 | print "#error too many masks for " var | |
267 | } | |
fe609b0f | 268 | } |
75685792 RS |
269 | print "" |
270 | ||
271 | for (i = 0; i < n_opts; i++) { | |
272 | name = opt_args("Mask", flags[i]) | |
f7f655c7 DD |
273 | vname = var_name(flags[i]) |
274 | macro = "OPTION_" | |
275 | mask = "OPTION_MASK_" | |
276 | if (vname == "") { | |
277 | vname = "target_flags" | |
278 | macro = "TARGET_" | |
279 | mask = "MASK_" | |
280 | } | |
f9b4c1db | 281 | if (name != "" && !flag_set_p("MaskExists", flags[i])) |
f7f655c7 DD |
282 | print "#define " macro name \ |
283 | " ((" vname " & " mask name ") != 0)" | |
75685792 | 284 | } |
fe609b0f EB |
285 | for (i = 0; i < n_extra_masks; i++) { |
286 | print "#define TARGET_" extra_masks[i] \ | |
287 | " ((target_flags & MASK_" extra_masks[i] ") != 0)" | |
288 | } | |
75685792 RS |
289 | print "" |
290 | ||
291 | for (i = 0; i < n_opts; i++) { | |
292 | opt = opt_args("InverseMask", flags[i]) | |
7bd85ce0 JM |
293 | if (opt ~ ",") { |
294 | vname = var_name(flags[i]) | |
295 | macro = "OPTION_" | |
296 | mask = "OPTION_MASK_" | |
297 | if (vname == "") { | |
298 | vname = "target_flags" | |
299 | macro = "TARGET_" | |
300 | mask = "MASK_" | |
301 | } | |
302 | print "#define " macro nth_arg(1, opt) \ | |
303 | " ((" vname " & " mask nth_arg(0, opt) ") == 0)" | |
304 | } | |
75685792 RS |
305 | } |
306 | print "" | |
776dc15d KC |
307 | |
308 | for (i = 0; i < n_langs; i++) { | |
309 | macros[i] = "CL_" langs[i] | |
310 | gsub( "[^A-Za-z0-9_]", "X", macros[i] ) | |
311 | s = substr(" ", length (macros[i])) | |
312 | print "#define " macros[i] s " (1 << " i ")" | |
313 | } | |
1f1d5130 | 314 | print "#define CL_LANG_ALL ((1 << " n_langs ") - 1)" |
776dc15d KC |
315 | |
316 | print "" | |
317 | print "enum opt_code" | |
318 | print "{" | |
319 | ||
320 | for (i = 0; i < n_opts; i++) | |
321 | back_chain[i] = "N_OPTS"; | |
322 | ||
64fbae21 RS |
323 | for (i = 0; i < n_opts; i++) { |
324 | # Combine the flags of identical switches. Switches | |
325 | # appear many times if they are handled by many front | |
326 | # ends, for example. | |
327 | while( i + 1 != n_opts && opts[i] == opts[i + 1] ) { | |
328 | flags[i + 1] = flags[i] " " flags[i + 1]; | |
329 | i++; | |
330 | } | |
776dc15d KC |
331 | |
332 | len = length (opts[i]); | |
333 | enum = "OPT_" opts[i] | |
e8fc888d | 334 | if (opts[i] == "finline-limit=" || opts[i] == "Wlarger-than=") |
776dc15d KC |
335 | enum = enum "eq" |
336 | gsub ("[^A-Za-z0-9]", "_", enum) | |
337 | ||
338 | # If this switch takes joined arguments, back-chain all | |
339 | # subsequent switches to it for which it is a prefix. If | |
340 | # a later switch S is a longer prefix of a switch T, T | |
341 | # will be back-chained to S in a later iteration of this | |
342 | # for() loop, which is what we want. | |
a56a0779 | 343 | if (flag_set_p("Joined.*", flags[i])) { |
776dc15d KC |
344 | for (j = i + 1; j < n_opts; j++) { |
345 | if (substr (opts[j], 1, len) != opts[i]) | |
346 | break; | |
347 | back_chain[j] = enum; | |
348 | } | |
349 | } | |
350 | ||
351 | s = substr(" ", length (opts[i])) | |
352 | if (i + 1 == n_opts) | |
353 | comma = "" | |
354 | ||
355 | if (help[i] == "") | |
356 | hlp = "0" | |
357 | else | |
358 | hlp = "N_(\"" help[i] "\")"; | |
359 | ||
360 | print " " enum "," s "/* -" opts[i] " */" | |
361 | } | |
362 | ||
363 | print " N_OPTS" | |
364 | print "};" | |
365 | print "" | |
366 | print "#endif /* OPTIONS_H */" | |
367 | } |