1#  Copyright (C) 2003, 2004, 2007, 2008, 2009, 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 file.
23#
24
25# This program uses functions from opt-functions.awk and code from
26# opt-read.awk.
27#
28# Usage: awk -f opt-functions.awk -f opt-read.awk -f optc-save-gen.awk \
29#            [-v header_name=header.h] < inputfile > options-save.c
30
31# Dump that array of options into a C file.
32END {
33print "/* This file is auto-generated by optc-save-gen.awk.  */"
34print ""
35n_headers = split(header_name, headers, " ")
36for (i = 1; i <= n_headers; i++)
37	print "#include " quote headers[i] quote
38print "#include " quote "opts.h" quote
39print "#include " quote "intl.h" quote
40print ""
41print "#include " quote "flags.h" quote
42print "#include " quote "target.h" quote
43print ""
44
45if (n_extra_c_includes > 0) {
46	for (i = 0; i < n_extra_c_includes; i++) {
47		print "#include " quote extra_c_includes[i] quote
48	}
49	print ""
50}
51
52have_save = 0;
53if (n_extra_target_vars)
54	have_save = 1
55
56for (i = 0; i < n_opts; i++) {
57	if (flag_set_p("Save", flags[i]))
58		have_save = 1;
59}
60
61print "/* Save optimization variables into a structure.  */"
62print "void";
63print "cl_optimization_save (struct cl_optimization *ptr, struct gcc_options *opts)";
64print "{";
65
66n_opt_char = 2;
67n_opt_short = 0;
68n_opt_int = 0;
69n_opt_enum = 1;
70n_opt_other = 0;
71var_opt_char[0] = "optimize";
72var_opt_char[1] = "optimize_size";
73var_opt_range["optimize"] = "0, 255";
74var_opt_range["optimize_size"] = "0, 255";
75var_opt_enum[0] = "flag_fp_contract_mode";
76
77# Sort by size to mimic how the structure is laid out to be friendlier to the
78# cache.
79
80for (i = 0; i < n_opts; i++) {
81	if (flag_set_p("Optimization", flags[i])) {
82		name = var_name(flags[i])
83		if(name == "")
84			continue;
85
86		if(name in var_opt_seen)
87			continue;
88
89		var_opt_seen[name]++;
90		otype = var_type_struct(flags[i]);
91		if (otype ~ "^((un)?signed +)?int *$")
92			var_opt_int[n_opt_int++] = name;
93
94		else if (otype ~ "^((un)?signed +)?short *$")
95			var_opt_short[n_opt_short++] = name;
96
97		else if (otype ~ ("^enum +[_" alnum "]+ *"))
98			var_opt_enum[n_opt_enum++] = name;
99
100		else if (otype ~ "^((un)?signed +)?char *$") {
101			var_opt_char[n_opt_char++] = name;
102			if (otype ~ "^unsigned +char *$")
103				var_opt_range[name] = "0, 255"
104			else if (otype ~ "^signed +char *$")
105				var_opt_range[name] = "-128, 127"
106		}
107		else
108			var_opt_other[n_opt_other++] = name;
109	}
110}
111
112for (i = 0; i < n_opt_char; i++) {
113	name = var_opt_char[i];
114	if (var_opt_range[name] != "")
115		print "  gcc_assert (IN_RANGE (opts->x_" name ", " var_opt_range[name] "));";
116}
117
118print "";
119for (i = 0; i < n_opt_other; i++) {
120	print "  ptr->x_" var_opt_other[i] " = opts->x_" var_opt_other[i] ";";
121}
122
123for (i = 0; i < n_opt_int; i++) {
124	print "  ptr->x_" var_opt_int[i] " = opts->x_" var_opt_int[i] ";";
125}
126
127for (i = 0; i < n_opt_enum; i++) {
128	print "  ptr->x_" var_opt_enum[i] " = opts->x_" var_opt_enum[i] ";";
129}
130
131for (i = 0; i < n_opt_short; i++) {
132	print "  ptr->x_" var_opt_short[i] " = opts->x_" var_opt_short[i] ";";
133}
134
135for (i = 0; i < n_opt_char; i++) {
136	print "  ptr->x_" var_opt_char[i] " = opts->x_" var_opt_char[i] ";";
137}
138
139print "}";
140
141print "";
142print "/* Restore optimization options from a structure.  */";
143print "void";
144print "cl_optimization_restore (struct gcc_options *opts, struct cl_optimization *ptr)";
145print "{";
146
147for (i = 0; i < n_opt_other; i++) {
148	print "  opts->x_" var_opt_other[i] " = ptr->x_" var_opt_other[i] ";";
149}
150
151for (i = 0; i < n_opt_int; i++) {
152	print "  opts->x_" var_opt_int[i] " = ptr->x_" var_opt_int[i] ";";
153}
154
155for (i = 0; i < n_opt_enum; i++) {
156	print "  opts->x_" var_opt_enum[i] " = ptr->x_" var_opt_enum[i] ";";
157}
158
159for (i = 0; i < n_opt_short; i++) {
160	print "  opts->x_" var_opt_short[i] " = ptr->x_" var_opt_short[i] ";";
161}
162
163for (i = 0; i < n_opt_char; i++) {
164	print "  opts->x_" var_opt_char[i] " = ptr->x_" var_opt_char[i] ";";
165}
166
167print "  targetm.override_options_after_change ();";
168print "}";
169
170print "";
171print "/* Print optimization options from a structure.  */";
172print "void";
173print "cl_optimization_print (FILE *file,";
174print "                       int indent_to,";
175print "                       struct cl_optimization *ptr)";
176print "{";
177
178print "  fputs (\"\\n\", file);";
179for (i = 0; i < n_opt_other; i++) {
180	print "  if (ptr->x_" var_opt_other[i] ")";
181	print "    fprintf (file, \"%*s%s (%#lx)\\n\",";
182	print "             indent_to, \"\",";
183	print "             \"" var_opt_other[i] "\",";
184	print "             (unsigned long)ptr->x_" var_opt_other[i] ");";
185	print "";
186}
187
188for (i = 0; i < n_opt_int; i++) {
189	print "  if (ptr->x_" var_opt_int[i] ")";
190	print "    fprintf (file, \"%*s%s (%#x)\\n\",";
191	print "             indent_to, \"\",";
192	print "             \"" var_opt_int[i] "\",";
193	print "             ptr->x_" var_opt_int[i] ");";
194	print "";
195}
196
197for (i = 0; i < n_opt_enum; i++) {
198	print "  fprintf (file, \"%*s%s (%#x)\\n\",";
199	print "           indent_to, \"\",";
200	print "           \"" var_opt_enum[i] "\",";
201	print "           (int) ptr->x_" var_opt_enum[i] ");";
202	print "";
203}
204
205for (i = 0; i < n_opt_short; i++) {
206	print "  if (ptr->x_" var_opt_short[i] ")";
207	print "    fprintf (file, \"%*s%s (%#x)\\n\",";
208	print "             indent_to, \"\",";
209	print "             \"" var_opt_short[i] "\",";
210	print "             ptr->x_" var_opt_short[i] ");";
211	print "";
212}
213
214for (i = 0; i < n_opt_char; i++) {
215	print "  if (ptr->x_" var_opt_char[i] ")";
216	print "    fprintf (file, \"%*s%s (%#x)\\n\",";
217	print "             indent_to, \"\",";
218	print "             \"" var_opt_char[i] "\",";
219	print "             ptr->x_" var_opt_char[i] ");";
220	print "";
221}
222
223print "}";
224
225print "";
226print "/* Save selected option variables into a structure.  */"
227print "void";
228print "cl_target_option_save (struct cl_target_option *ptr, struct gcc_options *opts)";
229print "{";
230
231n_target_char = 0;
232n_target_short = 0;
233n_target_int = 0;
234n_target_enum = 0;
235n_target_other = 0;
236
237if (have_save) {
238	for (i = 0; i < n_opts; i++) {
239		if (flag_set_p("Save", flags[i])) {
240			name = var_name(flags[i])
241			if(name == "")
242				name = "target_flags";
243
244			if(name in var_save_seen)
245				continue;
246
247			var_save_seen[name]++;
248			otype = var_type_struct(flags[i])
249			if (otype ~ "^((un)?signed +)?int *$")
250				var_target_int[n_target_int++] = name;
251
252			else if (otype ~ "^((un)?signed +)?short *$")
253				var_target_short[n_target_short++] = name;
254
255			else if (otype ~ ("^enum +[_" alnum "]+ *$"))
256				var_target_enum[n_target_enum++] = name;
257
258			else if (otype ~ "^((un)?signed +)?char *$") {
259				var_target_char[n_target_char++] = name;
260				if (otype ~ "^unsigned +char *$")
261					var_target_range[name] = "0, 255"
262				else if (otype ~ "^signed +char *$")
263					var_target_range[name] = "-128, 127"
264				if (otype == var_type(flags[i]))
265					var_target_range[name] = ""
266			}
267			else
268				var_target_other[n_target_other++] = name;
269		}
270	}
271} else {
272	var_target_int[n_target_int++] = "target_flags";
273}
274
275have_assert = 0;
276for (i = 0; i < n_target_char; i++) {
277	name = var_target_char[i];
278	if (var_target_range[name] != "") {
279		have_assert = 1;
280		print "  gcc_assert (IN_RANGE (opts->x_" name ", " var_target_range[name] "));";
281	}
282}
283
284if (have_assert)
285	print "";
286
287print "  if (targetm.target_option.save)";
288print "    targetm.target_option.save (ptr);";
289print "";
290
291for (i = 0; i < n_extra_target_vars; i++) {
292	print "  ptr->x_" extra_target_vars[i] " = opts->x_" extra_target_vars[i] ";";
293}
294
295for (i = 0; i < n_target_other; i++) {
296	print "  ptr->x_" var_target_other[i] " = opts->x_" var_target_other[i] ";";
297}
298
299for (i = 0; i < n_target_enum; i++) {
300	print "  ptr->x_" var_target_enum[i] " = opts->x_" var_target_enum[i] ";";
301}
302
303for (i = 0; i < n_target_int; i++) {
304	print "  ptr->x_" var_target_int[i] " = opts->x_" var_target_int[i] ";";
305}
306
307for (i = 0; i < n_target_short; i++) {
308	print "  ptr->x_" var_target_short[i] " = opts->x_" var_target_short[i] ";";
309}
310
311for (i = 0; i < n_target_char; i++) {
312	print "  ptr->x_" var_target_char[i] " = opts->x_" var_target_char[i] ";";
313}
314
315print "}";
316
317print "";
318print "/* Restore selected current options from a structure.  */";
319print "void";
320print "cl_target_option_restore (struct gcc_options *opts, struct cl_target_option *ptr)";
321print "{";
322
323for (i = 0; i < n_extra_target_vars; i++) {
324	print "  opts->x_" extra_target_vars[i] " = ptr->x_" extra_target_vars[i] ";";
325}
326
327for (i = 0; i < n_target_other; i++) {
328	print "  opts->x_" var_target_other[i] " = ptr->x_" var_target_other[i] ";";
329}
330
331for (i = 0; i < n_target_enum; i++) {
332	print "  opts->x_" var_target_enum[i] " = ptr->x_" var_target_enum[i] ";";
333}
334
335for (i = 0; i < n_target_int; i++) {
336	print "  opts->x_" var_target_int[i] " = ptr->x_" var_target_int[i] ";";
337}
338
339for (i = 0; i < n_target_short; i++) {
340	print "  opts->x_" var_target_short[i] " = ptr->x_" var_target_short[i] ";";
341}
342
343for (i = 0; i < n_target_char; i++) {
344	print "  opts->x_" var_target_char[i] " = ptr->x_" var_target_char[i] ";";
345}
346
347# This must occur after the normal variables in case the code depends on those
348# variables.
349print "";
350print "  if (targetm.target_option.restore)";
351print "    targetm.target_option.restore (ptr);";
352
353print "}";
354
355print "";
356print "/* Print optimization options from a structure.  */";
357print "void";
358print "cl_target_option_print (FILE *file,";
359print "                        int indent,";
360print "                        struct cl_target_option *ptr)";
361print "{";
362
363print "  fputs (\"\\n\", file);";
364for (i = 0; i < n_target_other; i++) {
365	print "  if (ptr->x_" var_target_other[i] ")";
366	if (host_wide_int[var_target_other[i]] == "yes")
367		print "    fprintf (file, \"%*s%s (%#\" HOST_WIDE_INT_PRINT \"x)\\n\",";
368	else
369		print "    fprintf (file, \"%*s%s (%#x)\\n\",";
370	print "             indent, \"\",";
371	print "             \"" var_target_other[i] "\",";
372	if (host_wide_int[var_target_other[i]] == "yes")
373		print "             ptr->x_" var_target_other[i] ");";
374	else
375		print "             (unsigned long)ptr->x_" var_target_other[i] ");";
376	print "";
377}
378
379for (i = 0; i < n_target_enum; i++) {
380	print "  if (ptr->x_" var_target_enum[i] ")";
381	print "    fprintf (file, \"%*s%s (%#x)\\n\",";
382	print "             indent, \"\",";
383	print "             \"" var_target_enum[i] "\",";
384	print "             ptr->x_" var_target_enum[i] ");";
385	print "";
386}
387
388for (i = 0; i < n_target_int; i++) {
389	print "  if (ptr->x_" var_target_int[i] ")";
390	print "    fprintf (file, \"%*s%s (%#x)\\n\",";
391	print "             indent, \"\",";
392	print "             \"" var_target_int[i] "\",";
393	print "             ptr->x_" var_target_int[i] ");";
394	print "";
395}
396
397for (i = 0; i < n_target_short; i++) {
398	print "  if (ptr->x_" var_target_short[i] ")";
399	print "    fprintf (file, \"%*s%s (%#x)\\n\",";
400	print "             indent, \"\",";
401	print "             \"" var_target_short[i] "\",";
402	print "             ptr->x_" var_target_short[i] ");";
403	print "";
404}
405
406for (i = 0; i < n_target_char; i++) {
407	print "  if (ptr->x_" var_target_char[i] ")";
408	print "    fprintf (file, \"%*s%s (%#x)\\n\",";
409	print "             indent, \"\",";
410	print "             \"" var_target_char[i] "\",";
411	print "             ptr->x_" var_target_char[i] ");";
412	print "";
413}
414
415print "";
416print "  if (targetm.target_option.print)";
417print "    targetm.target_option.print (file, indent, ptr);";
418
419print "}";
420
421}
422