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