xref: /netbsd-src/external/gpl3/gcc.old/dist/gcc/config/arm/parsecpu.awk (revision cef8759bd76c1b621f8eab8faa6f208faabc2e15)
1# Manipulate the CPU, FPU and architecture descriptions for ARM.
2# Copyright (C) 2017-2018 Free Software Foundation, Inc.
3#
4# This file is part of GCC.
5#
6# GCC is free software; you can redistribute it and/or modify
7# it under the terms of the GNU General Public License as published by
8# the Free Software Foundation; either version 3, or (at your option)
9# any later version.
10#
11# GCC 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 GCC; see the file COPYING3.  If not see
18# <http://www.gnu.org/licenses/>.
19
20# Invoke this with '-v cmd=<cmd>"
21# where <cmd> is one of:
22#	data: Print the standard 'C' data tables for the CPUs
23#	common-data: Print the 'C' data for shared driver/compiler files
24#	headers: Print the standard 'C' headers for the CPUs
25#	isa: Generate the arm-isa.h header
26#	md: Print the machine description fragment
27#	opt: Print the option tables fragment
28#	chkcpu <name>: Checks that <name> is a valid CPU
29#	chktune <name>: Checks that <name> is a valid CPU
30#	chkfpu <name>: Checks that <name> is a valid FPU
31#	chkarch <name>: Checks that <arch> is a valid architecture
32
33function fatal (m) {
34    print "error ("lineno"): " m > "/dev/stderr"
35    fatal_err = 1
36    if (parse_done) exit 1
37}
38
39function toplevel () {
40    if (cpu_name != "") fatal("missing \"end cpu\"")
41    if (arch_name != "") fatal("missing \"end arch\"")
42    if (fpu_name != "") fatal("missing \"end fpu\"")
43}
44
45function boilerplate (style) {
46    ce = ""
47    if (style == "C" ) {
48	cs = "/* "
49	cc = "   "
50	ce = "  */"
51    } else if (style == "md") {
52	cc = "; "
53	cs = cc
54    } else if (style == "sh") {
55	cc = "# "
56	cs = cc
57    } else fatal("Unknown comment style: "style)
58
59    print cs "-*- buffer-read-only: t -*-"
60
61    print cc "Generated automatically by parsecpu.awk from arm-cpus.in."
62    print cc "Do not edit."
63    print ""
64    print cc "Copyright (C) 2011-2018 Free Software Foundation, Inc."
65    print ""
66    print cc "This file is part of GCC."
67    print ""
68    print cc "GCC is free software; you can redistribute it and/or modify"
69    print cc "it under the terms of the GNU General Public License as"
70    print cc "published by the Free Software Foundation; either version 3,"
71    print cc "or (at your option) any later version."
72    print ""
73    print cc "GCC is distributed in the hope that it will be useful,"
74    print cc "but WITHOUT ANY WARRANTY; without even the implied warranty of"
75    print cc "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the"
76    print cc "GNU General Public License for more details."
77    print ""
78    print cc "You should have received a copy of the GNU General Public"
79    print cc "License along with GCC; see the file COPYING3.  If not see"
80    print cc "<http://www.gnu.org/licenses/>." ce
81    print ""
82}
83
84function tune_flag_pfx (f) {
85    return "TF_" f
86}
87
88# Print out the bits for the features in FLIST, which may be a
89# mixture of fgroup and individual bits.  Print each feature needed
90# exactly once.  Terminate the list with isa_nobit.  Prefix each line by
91# INDENT.  Does not print a new line at the end.
92function print_isa_bits_for (flist, indent) {
93    nbits = split (flist, bits)
94
95    for (bit = 1; bit <= nbits; bit++) {
96	if (bits[bit] in features) {
97	    pbit[bits[bit]] = 1
98	} else if (bits[bit] in fgroup) {
99	    for (gbits in fgrp_bits) {
100		split (gbits, bitsep, SUBSEP)
101		if (bitsep[1] == bits[bit]) {
102		    pbit[bitsep[2]] = 1
103		}
104	    }
105	} else fatal("feature " bits[bit] " not declared")
106    }
107    zbit = ORS
108    ORS = ""
109    print indent "{\n" indent "  "
110    ORS = ", "
111    count = 0
112    for (bname in pbit) {
113	print "isa_bit_" bname
114	count++
115	if (count == 4) {
116	    count = 0
117	    ORS = ""
118	    print "\n" indent "  "
119	    ORS = ", "
120	}
121    }
122    ORS = ""
123    print "isa_nobit\n" indent "}"
124    ORS = zbit
125    delete pbit
126}
127
128function gen_headers () {
129    boilerplate("C")
130
131    print "enum processor_type"
132    print "{"
133
134    ncpus = split (cpu_list, cpus)
135
136    for (n = 1; n <= ncpus; n++) {
137	print "  TARGET_CPU_"cpu_cnames[cpus[n]]","
138    }
139    print "  TARGET_CPU_arm_none"
140    print "};\n"
141
142    print "enum arch_type"
143    print "{"
144
145    narchs = split (arch_list, archs)
146
147    for (n = 1; n <= narchs; n++) {
148	print "  TARGET_ARCH_"arch_cnames[archs[n]]","
149    }
150    print "  TARGET_ARCH_arm_none"
151    print "};\n"
152
153    print "enum fpu_type"
154    print "{"
155
156    nfpus = split (fpu_list, fpus)
157
158    for (n = 1; n <= nfpus; n++) {
159	print "  TARGET_FPU_"fpu_cnames[fpus[n]]","
160    }
161    print "  TARGET_FPU_auto"
162    print "};"
163}
164
165function gen_isa () {
166    boilerplate("C")
167    print "enum isa_feature {"
168    print "  isa_nobit = 0,"
169    for (fbit in features) {
170	print "  isa_bit_" fbit ","
171    }
172    print "  isa_num_bits"
173    print "};\n"
174
175    for (fgrp in fgroup) {
176	print "#define ISA_"fgrp " \\"
177	z = ORS
178	ORS = ""
179	first = 1
180	for (bitcomb in fgrp_bits) {
181	    split (bitcomb, bitsep, SUBSEP)
182	    if (bitsep[1] == fgrp) {
183		if (first) {
184		    first = 0
185		} else print ", \\\n"
186		print "  isa_bit_" bitsep[2]
187	    }
188	}
189	ORS = z
190	print "\n"
191    }
192}
193
194function gen_data () {
195    boilerplate("C")
196
197    print "static const cpu_tune all_tunes[] ="
198    print "{"
199
200    ncpus = split (cpu_list, cpus)
201
202    for (n = 1; n <= ncpus; n++) {
203	print "  { /* " cpus[n] ".  */"
204	# scheduler
205	if (cpus[n] in cpu_tune_for) {
206	    if (! (cpu_tune_for[cpus[n]] in cpu_cnames)) {
207		fatal("unknown \"tune for\" target " cpu_tune_for[cpus[n]] \
208		      " for CPU " cpus[n])
209	    }
210	    print "    TARGET_CPU_" cpu_cnames[cpu_tune_for[cpus[n]]] ","
211	} else {
212	    print "    TARGET_CPU_" cpu_cnames[cpus[n]] ","
213	}
214	# tune_flags
215	if (cpus[n] in cpu_tune_flags) {
216	    print "    (" cpu_tune_flags[cpus[n]] "),"
217	} else print "    0,"
218	# tune
219	print "    &arm_" cpu_cost[cpus[n]] "_tune"
220	print "  },"
221    }
222    print "  {TARGET_CPU_arm_none, 0, NULL}"
223    print "};"
224}
225
226function gen_comm_data () {
227    boilerplate("C")
228
229    ncpus = split (cpu_list, cpus)
230
231    for (n = 1; n <= ncpus; n++) {
232	if (cpus[n] in cpu_opts) {
233	    print "static const cpu_arch_extension cpu_opttab_" \
234		cpu_cnames[cpus[n]] "[] = {"
235	    nopts = split (cpu_opts[cpus[n]], opts)
236	    for (opt = 1; opt <= nopts; opt++) {
237		print "  {"
238		print "    \"" opts[opt] "\", " \
239		    cpu_opt_remove[cpus[n],opts[opt]] ", false,"
240		print_isa_bits_for(cpu_opt_isa[cpus[n],opts[opt]], "    ")
241		print "\n  },"
242	    }
243	    if (cpus[n] in cpu_optaliases) {
244		naliases = split (cpu_optaliases[cpus[n]], aliases)
245		for (alias = 1; alias <= naliases; alias++) {
246		    if (! ((cpus[n], \
247			    cpu_opt_alias[cpus[n],aliases[alias]]) in \
248			   cpu_opt_isa)) {
249			fatal("Alias " aliases[alias] " target not defined " \
250			      "for CPU " cpus[n])
251		    }
252		    equiv=cpu_opt_alias[cpus[n],aliases[alias]]
253		    print "  {"
254		    print "    \"" aliases[alias] "\", " \
255			cpu_opt_remove[cpus[n],equiv] ", true, "
256		    print_isa_bits_for(cpu_opt_isa[cpus[n],equiv], "    ")
257		    print "\n  },"
258		}
259	    }
260	    print "  { NULL, false, false, {isa_nobit}}"
261	    print "};\n"
262	}
263    }
264
265    print "const cpu_option all_cores[] ="
266    print "{"
267
268    for (n = 1; n <= ncpus; n++) {
269	print "  {"
270	print "    {"
271	# common.name
272	print "      \"" cpus[n] "\","
273	# common.extensions
274	if (cpus[n] in cpu_opts) {
275	    print "      cpu_opttab_" cpu_cnames[cpus[n]] ","
276	} else print "      NULL,"
277	# common.isa_bits
278	nfeats = split (cpu_arch[cpus[n]], feats, "+")
279	if (! (feats[1] in arch_isa)) {
280	    fatal("unknown arch " feats[1] " for cpu " cpus[n])
281	}
282	all_isa_bits = arch_isa[feats[1]]
283	for (m = 2; m <= nfeats; m++) {
284	    if (! ((feats[1], feats[m]) in arch_opt_isa)) {
285		fatal("unknown feature " feats[m] " for architecture " feats[1])
286	    }
287	    if (arch_opt_remove[feats[1],feats[m]] == "true") {
288		fatal("cannot remove features from architecture specs")
289	    }
290	    all_isa_bits = all_isa_bits " " arch_opt_isa[feats[1],feats[m]]
291	}
292	if (cpus[n] in cpu_fpu) {
293	    all_isa_bits = all_isa_bits " " fpu_isa[cpu_fpu[cpus[n]]]
294	}
295	if (cpus[n] in cpu_isa) {
296	    all_isa_bits = all_isa_bits " " cpu_isa[cpus[n]]
297	}
298	print_isa_bits_for(all_isa_bits, "      ")
299	print "\n    },"
300	# arch
301	print "    TARGET_ARCH_" arch_cnames[feats[1]]
302	print "  },"
303    }
304
305    print "  {{NULL, NULL, {isa_nobit}}, TARGET_ARCH_arm_none}"
306    print "};"
307
308    narchs = split (arch_list, archs)
309
310    for (n = 1; n <= narchs; n++) {
311	if (archs[n] in arch_opts) {
312	    print "static const struct cpu_arch_extension arch_opttab_" \
313		arch_cnames[archs[n]] "[] = {"
314	    nopts = split (arch_opts[archs[n]], opts)
315	    for (opt = 1; opt <= nopts; opt++) {
316		print "  {"
317		print "    \"" opts[opt] "\", " \
318		    arch_opt_remove[archs[n],opts[opt]] ", false,"
319		print_isa_bits_for(arch_opt_isa[archs[n],opts[opt]], "    ")
320		print "\n  },"
321	    }
322	    if (archs[n] in arch_optaliases) {
323		naliases = split (arch_optaliases[archs[n]], aliases)
324		for (alias = 1; alias <= naliases; alias++) {
325		    if (! ((archs[n], \
326			    arch_opt_alias[archs[n],aliases[alias]]) in \
327			   arch_opt_isa)) {
328			fatal("Alias " aliases[alias] " target not defined " \
329			      "for architecture " archs[n])
330		    }
331		    equiv=arch_opt_alias[archs[n],aliases[alias]]
332		    print "  {"
333		    print "    \"" aliases[alias] "\", " \
334			arch_opt_remove[archs[n],equiv] ", true, "
335		    print_isa_bits_for(arch_opt_isa[archs[n],equiv], "    ")
336		    print "\n  },"
337		}
338	    }
339	    print "  { NULL, false, false, {isa_nobit}}"
340	    print "};\n"
341	} else if (archs[n] in arch_optaliases) {
342	    fatal("Architecture " archs[n] " has option aliases but no options")
343	}
344    }
345
346    print "const arch_option all_architectures[] ="
347    print "{"
348
349    for (n = 1; n <= narchs; n++) {
350	print "  {"
351	if (! (arch_tune_for[archs[n]] in cpu_cnames)) {
352	    fatal("unknown \"tune for\" target " arch_tune_for[archs[n]] \
353		  " for architecture " archs[n])
354	}
355	# common.name
356	print "    \"" archs[n] "\","
357	# common.extensions
358	if (archs[n] in arch_opts) {
359	    print "    arch_opttab_" arch_cnames[archs[n]] ","
360	} else print "    NULL,"
361	# common.isa_bits
362	print_isa_bits_for(arch_isa[archs[n]], "    ")
363	print ","
364	# arch, base_arch
365	print "    \"" arch_base[archs[n]] "\", BASE_ARCH_" \
366	    arch_base[archs[n]] ","
367	# profile letter code, or zero if none.
368	if (archs[n] in arch_prof) {
369	    print "    '" arch_prof[archs[n]] "',"
370	} else {
371	    print "    0,"
372	}
373	# tune_id
374	print "    TARGET_CPU_" cpu_cnames[arch_tune_for[archs[n]]] ","
375	print "  },"
376    }
377
378    print "  {{NULL, NULL, {isa_nobit}},"
379    print "   NULL, BASE_ARCH_0, 0, TARGET_CPU_arm_none}"
380    print "};\n"
381
382    print "const arm_fpu_desc all_fpus[] ="
383    print "{"
384
385    nfpus = split (fpu_list, fpus)
386
387    for (n = 1; n <= nfpus; n++) {
388	print "  {"
389	print "    \"" fpus[n] "\","
390	print_isa_bits_for(fpu_isa[fpus[n]], "    ")
391	print "\n  },"
392    }
393
394    print "};"
395}
396
397function gen_md () {
398    boilerplate("md")
399
400    z = ORS
401    ORS = ""
402    print "(define_attr \"tune\"\n\t\""
403
404    ncpus = split (cpu_list, cpus)
405
406    for (n = 1; n < ncpus; n++) {
407	if ((n % 3) != 0) {
408	    ORS = ","
409	} else ORS = ",\n\t"
410	print cpu_cnames[cpus[n]]
411    }
412    ORS = z
413    print cpu_cnames[cpus[ncpus]]"\""
414    print "\t(const (symbol_ref \"((enum attr_tune) arm_tune)\")))"
415}
416
417function gen_opt () {
418    boilerplate("md")
419
420    print "Enum"
421    print "Name(processor_type) Type(enum processor_type)"
422    print "Known ARM CPUs (for use with the -mcpu= and -mtune= options):\n"
423
424    ncpus = split (cpu_list, cpus)
425
426    for (n = 1; n <= ncpus; n++) {
427	print "EnumValue"
428	print "Enum(processor_type) String(" cpus[n] \
429	    ") Value( TARGET_CPU_"cpu_cnames[cpus[n]]")"
430	print ""
431    }
432
433    print "Enum"
434    print "Name(arm_arch) Type(int)"
435    print "Known ARM architectures (for use with the -march= option):\n"
436
437    narchs = split (arch_list, archs)
438
439    for (n = 1; n <= narchs; n++) {
440	print "EnumValue"
441	print "Enum(arm_arch) String(" archs[n] \
442	    ") Value("n - 1")"
443	print ""
444    }
445
446    print "Enum"
447    print "Name(arm_fpu) Type(enum fpu_type)"
448    print "Known ARM FPUs (for use with the -mfpu= option):\n"
449
450    nfpus = split (fpu_list, fpus)
451
452    for (n = 1; n <= nfpus; n++) {
453	print "EnumValue"
454	print "Enum(arm_fpu) String(" fpus[n] \
455	    ") Value(TARGET_FPU_"fpu_cnames[fpus[n]]")"
456	print ""
457    }
458
459    print "EnumValue"
460    print "Enum(arm_fpu) String(auto) Value(TARGET_FPU_auto)"
461}
462
463function check_cpu (name) {
464    exts = split (name, extensions, "+")
465
466    if (! (extensions[1] in cpu_cnames)) {
467	return "error"
468    }
469
470    for (n = 2; n <= exts; n++) {
471	if (!((extensions[1], extensions[n]) in cpu_opt_remove)	\
472	    && !((extensions[1], extensions[n]) in cpu_optaliases)) {
473	    return "error"
474	}
475    }
476    return name
477}
478
479function check_fpu (name) {
480    if (! (name in fpu_cnames)) {
481	return "error"
482    }
483    return fpu_cnames[name]
484}
485
486function check_arch (name) {
487    exts = split (name, extensions, "+")
488
489    if (! (extensions[1] in arch_isa)) {
490	return "error"
491    }
492
493    for (n = 2; n <= exts; n++) {
494	if (!((extensions[1], extensions[n]) in arch_opt_remove)	\
495	    && !((extensions[1], extensions[n]) in arch_optaliases)) {
496	    return "error"
497	}
498    }
499    return name
500}
501
502BEGIN {
503    cpu_name = ""
504    arch_name = ""
505    fpu_name = ""
506    lineno = 0
507    fatal_err = 0
508    parse_done = 0
509    if (cmd == "") fatal("Usage parsecpu.awk -v cmd=<xyz>")
510}
511
512# New line.  Reset parse status and increment line count for error messages
513// {
514    lineno++
515    parse_ok = 0
516}
517
518# Comments must be on a line on their own.
519/^#/ {
520    parse_ok = 1
521}
522
523/^define feature / {
524    if (NF != 3) fatal("syntax: define feature <name>")
525    toplevel()
526    fbit = $3
527    if (fbit in features) fatal("feature " fbit " already defined")
528    features[fbit] = 1
529    parse_ok = 1
530}
531
532/^define fgroup / {
533    if (NF < 4) fatal("syntax: define fgroup <name> <feature> [<feature>]*")
534    toplevel()
535    fgrp = $3
536    if (fgrp in fgroup) fatal("feature group " fgrp " already defined")
537    if (fgrp in features) fatal("feature group " fgrp " aliases a feature")
538    fcount = NF
539    for (n = 4; n <= fcount; n++) {
540	feat = $n
541	if (feat in features) {
542	    fgrp_bits[fgrp,feat] = 1
543	} else if (feat in fgroup) {
544	    # fgroups may reference other fgroups, copy their bits
545	    # to our bits.  To avoid recursion we don't set fgroup[fgrp]
546	    # until after we have done this, so such attempts will result
547	    # in an invalid group definition.
548	    for (bitcomb in fgrp_bits) {
549		split (bitcomb, bitsep, SUBSEP)
550		if (bitsep[1] == feat) {
551		    fgrp_bits[fgrp,bitsep[2]] = 1
552		}
553	    }
554	} else fatal("feature group member " feat " unrecognized")
555    }
556    fgroup[fgrp] = 1
557    parse_ok = 1
558}
559
560/^begin fpu / {
561    if (NF != 3) fatal("syntax: begin fpu <name>")
562    toplevel()
563    fpu_name = $3
564    parse_ok = 1
565}
566
567/^end fpu / {
568    if (NF != 3) fatal("syntax: end fpu <name>")
569    if (fpu_name != $3) fatal("mimatched end fpu")
570    if (! (fpu_name in fpu_isa)) {
571	fatal("fpu definition \"" fpu_name "\" lacks an \"isa\" statement")
572    }
573    fpu_cnames[fpu_name] = fpu_name
574    gsub(/[-+.]/, "_", fpu_cnames[fpu_name])
575    fpu_list = fpu_list " " fpu_name
576    fpu_name = ""
577    parse_ok = 1
578}
579
580/^begin arch / {
581    if (NF != 3) fatal("syntax: begin arch <name>")
582    toplevel()
583    arch_name = $3
584    parse_ok = 1
585}
586
587/^[ 	]*base / {
588    if (NF != 2) fatal("syntax: base <architecture-base-name>")
589    if (arch_name == "") fatal("\"base\" statement outside of arch block")
590    arch_base[arch_name] = $2
591    parse_ok = 1
592}
593
594/^[ 	]*profile / {
595    if (NF != 2) fatal("syntax: profile <profile-name>")
596    if (arch_name == "") fatal("\"profile\" statement outside of arch block")
597    arch_prof[arch_name] = $2
598    parse_ok = 1
599}
600
601/^end arch / {
602    if (NF != 3) fatal("syntax: end arch <name>")
603    if (arch_name != $3) fatal("mimatched end arch")
604    if (! (arch_name in arch_tune_for)) {
605	fatal("arch definition lacks a \"tune for\" statement")
606    }
607    if (! (arch_name in arch_isa)) {
608	fatal("arch definition lacks an \"isa\" statement")
609    }
610    arch_list = arch_list " " arch_name
611    arch_cnames[arch_name] = arch_name
612    gsub(/[-+.]/, "_", arch_cnames[arch_name])
613    arch_name = ""
614    parse_ok = 1
615}
616
617/^begin cpu / {
618    if (NF != 3) fatal("syntax: begin cpu <name>")
619    toplevel()
620    cpu_name = $3
621    parse_ok = 1
622}
623
624/^[ 	]*cname / {
625    if (NF != 2) fatal("syntax: cname <identifier>")
626    if (cpu_name == "") fatal("\"cname\" outside of cpu block")
627    cpu_cnames[cpu_name] = $2
628    parse_ok = 1
629}
630
631/^[ 	]*tune for / {
632    if (NF != 3) fatal("syntax: tune for <cpu-name>")
633    if (cpu_name != "") {
634	cpu_tune_for[cpu_name] = $3
635    } else if (arch_name != "") {
636	arch_tune_for[arch_name] = $3
637    } else fatal("\"tune for\" outside of cpu or arch block")
638    parse_ok = 1
639}
640
641/^[ 	]*tune flags / {
642    if (NF < 3) fatal("syntax: tune flags <flag> [<flag>]*")
643    flags=""
644    flag_count = NF
645    for (n = 3; n <= flag_count; n++) {
646	if (n == 3) {
647	    flags = tune_flag_pfx($n)
648	} else flags = flags " | " tune_flag_pfx($n)
649    }
650    if (cpu_name != "") {
651	cpu_tune_flags[cpu_name] = flags
652    } else if (arch_name != "") {
653	arch_tune_flags[arch_name] = flags
654    } else fatal("\"tune flags\" outside of cpu or arch block")
655    parse_ok = 1
656}
657
658/^[ 	]*architecture / {
659    if (NF != 2) fatal("syntax: architecture <arch-name>")
660    if (cpu_name == "") fatal("\"architecture\" outside of cpu block")
661    cpu_arch[cpu_name] = $2
662    parse_ok = 1
663}
664
665/^[ 	]*fpu / {
666    if (NF != 2) fatal("syntax: fpu <fpu-name>")
667    if (cpu_name == "") fatal("\"fpu\" outside of cpu block")
668    cpu_fpu[cpu_name] = $2
669    parse_ok = 1
670}
671
672/^[ 	]*isa / {
673    if (NF < 2) fatal("syntax: isa <feature-or-fgroup> [<feature-or-fgroup>]*")
674    flags=""
675    flag_count = NF
676    for (n = 2; n <= flag_count; n++) {
677	if (n == 2) {
678	    flags = $n
679	} else flags = flags " " $n
680    }
681    if (cpu_name != "") {
682	cpu_isa[cpu_name] = flags
683    } else if (arch_name != "") {
684	arch_isa[arch_name] = flags
685    } else  if (fpu_name != "") {
686	fpu_isa[fpu_name] = flags
687    } else fatal("\"isa\" outside of cpu, fpu or arch block")
688    parse_ok = 1
689}
690
691/^[ 	]*option / {
692    if (NF < 4) fatal("syntax: option <name> add|remove <feature-or-fgroup>+")
693    name=$2
694    if ($3 == "add") {
695	remove = "false"
696    } else if ($3 == "remove") {
697	remove = "true"
698    } else fatal("syntax: option <name> add|remove isa-list")
699    flags=""
700    flag_count = NF
701    for (n = 4; n <= flag_count; n++) {
702	if (n == 4) {
703	    flags = $n
704	} else flags = flags " " $n
705    }
706    if (cpu_name != "") {
707	cpu_opts[cpu_name] = cpu_opts[cpu_name] " " name
708	cpu_opt_remove[cpu_name,name] = remove
709	cpu_opt_isa[cpu_name,name] = flags
710    } else if (arch_name != "") {
711	arch_opts[arch_name] = arch_opts[arch_name] " " name
712	arch_opt_remove[arch_name,name] = remove
713	arch_opt_isa[arch_name,name] = flags
714    } else fatal("\"option\" outside of cpu or arch block")
715    parse_ok = 1
716}
717
718/^[ 	]*optalias / {
719    if (NF != 3) fatal("syntax: optalias <name> <option-name>")
720    name=$2
721    alias=$3
722    if (cpu_name != "") {
723	cpu_optaliases[cpu_name] = cpu_optaliases[cpu_name] " " name
724	cpu_opt_alias[cpu_name,name] = alias
725    } else if (arch_name != "") {
726	arch_optaliases[arch_name] = arch_optaliases[arch_name] " " name
727	arch_opt_alias[arch_name,name] = alias
728    } else fatal("\"optalias\" outside of cpu or arch block")
729    parse_ok = 1
730}
731
732/^[ 	]*costs / {
733    if (NF != 2) fatal("syntax: costs <identifier>")
734    if (cpu_name == "") fatal("\"costs\" outside of cpu block")
735    cpu_cost[cpu_name] = $2
736    parse_ok = 1
737}
738
739/^end cpu / {
740    if (NF != 3) fatal("syntax: end cpu <name>")
741    if (cpu_name != $3) fatal("mimatched end cpu")
742    if (! (cpu_name in cpu_cnames)) {
743	cpu_cnames[cpu_name] = cpu_name
744	gsub(/[-+.]/, "_", cpu_cnames[cpu_name])
745    }
746    if (! (cpu_name in cpu_arch)) fatal("cpu definition lacks an architecture")
747    cpu_list = cpu_list " " cpu_name
748    cpu_name = ""
749    parse_ok = 1
750}
751
752/[^\s]/ {
753    if (! parse_ok) fatal("Unrecognized statement: " $0)
754}
755
756END {
757    parse_done = 1
758    if (fatal_err) exit 1
759    toplevel()
760    if (cmd == "data") {
761	gen_data()
762    } else if (cmd == "common-data") {
763	gen_comm_data()
764    } else if (cmd == "headers") {
765	gen_headers()
766    } else if (cmd == "isa") {
767	gen_isa()
768    } else if (cmd == "md") {
769	gen_md()
770    } else if (cmd == "opt") {
771	gen_opt()
772    } else if (cmd ~ /^chk(cpu|tune) /) {
773	split (cmd, target)
774	print check_cpu(target[2])
775    } else if (cmd ~ /^chkarch /) {
776	split (cmd, target)
777	print check_arch(target[2])
778    } else if (cmd ~ /^chkfpu /) {
779	split (cmd, target)
780	print check_fpu(target[2])
781    } else fatal("unrecognized command: "cmd)
782}
783