1ac8e35e1Smrg# Manipulate the CPU, FPU and architecture descriptions for ARM.
2*0bfacb9bSmrg# Copyright (C) 2017-2020 Free Software Foundation, Inc.
3ac8e35e1Smrg#
4ac8e35e1Smrg# This file is part of GCC.
5ac8e35e1Smrg#
6ac8e35e1Smrg# GCC is free software; you can redistribute it and/or modify
7ac8e35e1Smrg# it under the terms of the GNU General Public License as published by
8ac8e35e1Smrg# the Free Software Foundation; either version 3, or (at your option)
9ac8e35e1Smrg# any later version.
10ac8e35e1Smrg#
11ac8e35e1Smrg# GCC is distributed in the hope that it will be useful,
12ac8e35e1Smrg# but WITHOUT ANY WARRANTY; without even the implied warranty of
13ac8e35e1Smrg# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14ac8e35e1Smrg# GNU General Public License for more details.
15ac8e35e1Smrg#
16ac8e35e1Smrg# You should have received a copy of the GNU General Public License
17ac8e35e1Smrg# along with GCC; see the file COPYING3.  If not see
18ac8e35e1Smrg# <http://www.gnu.org/licenses/>.
19ac8e35e1Smrg
20ac8e35e1Smrg# Invoke this with '-v cmd=<cmd>"
21ac8e35e1Smrg# where <cmd> is one of:
22ac8e35e1Smrg#	data: Print the standard 'C' data tables for the CPUs
23ac8e35e1Smrg#	common-data: Print the 'C' data for shared driver/compiler files
24760c2415Smrg#	native: Print the data structures used by the native driver
25ac8e35e1Smrg#	headers: Print the standard 'C' headers for the CPUs
268dd4bdcdSmrg#	isa: Generate the arm-isa.h header
27ac8e35e1Smrg#	md: Print the machine description fragment
28ac8e35e1Smrg#	opt: Print the option tables fragment
29ac8e35e1Smrg#	chkcpu <name>: Checks that <name> is a valid CPU
30ac8e35e1Smrg#	chktune <name>: Checks that <name> is a valid CPU
31ac8e35e1Smrg#	chkfpu <name>: Checks that <name> is a valid FPU
32ac8e35e1Smrg#	chkarch <name>: Checks that <arch> is a valid architecture
33ac8e35e1Smrg
34ac8e35e1Smrgfunction fatal (m) {
35ac8e35e1Smrg    print "error ("lineno"): " m > "/dev/stderr"
368dd4bdcdSmrg    fatal_err = 1
378dd4bdcdSmrg    if (parse_done) exit 1
38ac8e35e1Smrg}
39ac8e35e1Smrg
40ac8e35e1Smrgfunction toplevel () {
41ac8e35e1Smrg    if (cpu_name != "") fatal("missing \"end cpu\"")
42ac8e35e1Smrg    if (arch_name != "") fatal("missing \"end arch\"")
43ac8e35e1Smrg    if (fpu_name != "") fatal("missing \"end fpu\"")
44ac8e35e1Smrg}
45ac8e35e1Smrg
46ac8e35e1Smrgfunction boilerplate (style) {
47ac8e35e1Smrg    ce = ""
48ac8e35e1Smrg    if (style == "C" ) {
49ac8e35e1Smrg	cs = "/* "
50ac8e35e1Smrg	cc = "   "
51ac8e35e1Smrg	ce = "  */"
52ac8e35e1Smrg    } else if (style == "md") {
53ac8e35e1Smrg	cc = "; "
54ac8e35e1Smrg	cs = cc
55ac8e35e1Smrg    } else if (style == "sh") {
56ac8e35e1Smrg	cc = "# "
57ac8e35e1Smrg	cs = cc
58ac8e35e1Smrg    } else fatal("Unknown comment style: "style)
59ac8e35e1Smrg
60ac8e35e1Smrg    print cs "-*- buffer-read-only: t -*-"
61ac8e35e1Smrg
62ac8e35e1Smrg    print cc "Generated automatically by parsecpu.awk from arm-cpus.in."
63ac8e35e1Smrg    print cc "Do not edit."
64ac8e35e1Smrg    print ""
65*0bfacb9bSmrg    print cc "Copyright (C) 2011-2020 Free Software Foundation, Inc."
66ac8e35e1Smrg    print ""
67ac8e35e1Smrg    print cc "This file is part of GCC."
68ac8e35e1Smrg    print ""
69ac8e35e1Smrg    print cc "GCC is free software; you can redistribute it and/or modify"
70ac8e35e1Smrg    print cc "it under the terms of the GNU General Public License as"
71ac8e35e1Smrg    print cc "published by the Free Software Foundation; either version 3,"
72ac8e35e1Smrg    print cc "or (at your option) any later version."
73ac8e35e1Smrg    print ""
74ac8e35e1Smrg    print cc "GCC is distributed in the hope that it will be useful,"
75ac8e35e1Smrg    print cc "but WITHOUT ANY WARRANTY; without even the implied warranty of"
76ac8e35e1Smrg    print cc "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the"
77ac8e35e1Smrg    print cc "GNU General Public License for more details."
78ac8e35e1Smrg    print ""
79ac8e35e1Smrg    print cc "You should have received a copy of the GNU General Public"
80ac8e35e1Smrg    print cc "License along with GCC; see the file COPYING3.  If not see"
81ac8e35e1Smrg    print cc "<http://www.gnu.org/licenses/>." ce
82ac8e35e1Smrg    print ""
83ac8e35e1Smrg}
84ac8e35e1Smrg
85ac8e35e1Smrgfunction tune_flag_pfx (f) {
86ac8e35e1Smrg    return "TF_" f
87ac8e35e1Smrg}
88ac8e35e1Smrg
898dd4bdcdSmrg# Print out the bits for the features in FLIST, which may be a
908dd4bdcdSmrg# mixture of fgroup and individual bits.  Print each feature needed
918dd4bdcdSmrg# exactly once.  Terminate the list with isa_nobit.  Prefix each line by
928dd4bdcdSmrg# INDENT.  Does not print a new line at the end.
938dd4bdcdSmrgfunction print_isa_bits_for (flist, indent) {
948dd4bdcdSmrg    nbits = split (flist, bits)
958dd4bdcdSmrg
968dd4bdcdSmrg    for (bit = 1; bit <= nbits; bit++) {
978dd4bdcdSmrg	if (bits[bit] in features) {
988dd4bdcdSmrg	    pbit[bits[bit]] = 1
998dd4bdcdSmrg	} else if (bits[bit] in fgroup) {
1008dd4bdcdSmrg	    for (gbits in fgrp_bits) {
1018dd4bdcdSmrg		split (gbits, bitsep, SUBSEP)
1028dd4bdcdSmrg		if (bitsep[1] == bits[bit]) {
1038dd4bdcdSmrg		    pbit[bitsep[2]] = 1
1048dd4bdcdSmrg		}
1058dd4bdcdSmrg	    }
1068dd4bdcdSmrg	} else fatal("feature " bits[bit] " not declared")
1078dd4bdcdSmrg    }
1088dd4bdcdSmrg    zbit = ORS
1098dd4bdcdSmrg    ORS = ""
1108dd4bdcdSmrg    print indent "{\n" indent "  "
1118dd4bdcdSmrg    ORS = ", "
1128dd4bdcdSmrg    count = 0
1138dd4bdcdSmrg    for (bname in pbit) {
1148dd4bdcdSmrg	print "isa_bit_" bname
1158dd4bdcdSmrg	count++
1168dd4bdcdSmrg	if (count == 4) {
1178dd4bdcdSmrg	    count = 0
1188dd4bdcdSmrg	    ORS = ""
1198dd4bdcdSmrg	    print "\n" indent "  "
1208dd4bdcdSmrg	    ORS = ", "
1218dd4bdcdSmrg	}
1228dd4bdcdSmrg    }
1238dd4bdcdSmrg    ORS = ""
1248dd4bdcdSmrg    print "isa_nobit\n" indent "}"
1258dd4bdcdSmrg    ORS = zbit
1268dd4bdcdSmrg    delete pbit
127ac8e35e1Smrg}
128ac8e35e1Smrg
129ac8e35e1Smrgfunction gen_headers () {
130ac8e35e1Smrg    boilerplate("C")
131ac8e35e1Smrg
132ac8e35e1Smrg    print "enum processor_type"
133ac8e35e1Smrg    print "{"
134ac8e35e1Smrg
135ac8e35e1Smrg    ncpus = split (cpu_list, cpus)
136ac8e35e1Smrg
137ac8e35e1Smrg    for (n = 1; n <= ncpus; n++) {
138ac8e35e1Smrg	print "  TARGET_CPU_"cpu_cnames[cpus[n]]","
139ac8e35e1Smrg    }
140ac8e35e1Smrg    print "  TARGET_CPU_arm_none"
141ac8e35e1Smrg    print "};\n"
142ac8e35e1Smrg
1438dd4bdcdSmrg    print "enum arch_type"
1448dd4bdcdSmrg    print "{"
1458dd4bdcdSmrg
1468dd4bdcdSmrg    narchs = split (arch_list, archs)
1478dd4bdcdSmrg
1488dd4bdcdSmrg    for (n = 1; n <= narchs; n++) {
1498dd4bdcdSmrg	print "  TARGET_ARCH_"arch_cnames[archs[n]]","
1508dd4bdcdSmrg    }
1518dd4bdcdSmrg    print "  TARGET_ARCH_arm_none"
1528dd4bdcdSmrg    print "};\n"
1538dd4bdcdSmrg
154ac8e35e1Smrg    print "enum fpu_type"
155ac8e35e1Smrg    print "{"
156ac8e35e1Smrg
157ac8e35e1Smrg    nfpus = split (fpu_list, fpus)
158ac8e35e1Smrg
159ac8e35e1Smrg    for (n = 1; n <= nfpus; n++) {
160ac8e35e1Smrg	print "  TARGET_FPU_"fpu_cnames[fpus[n]]","
161ac8e35e1Smrg    }
162ac8e35e1Smrg    print "  TARGET_FPU_auto"
163ac8e35e1Smrg    print "};"
164ac8e35e1Smrg}
165ac8e35e1Smrg
1668dd4bdcdSmrgfunction gen_isa () {
1678dd4bdcdSmrg    boilerplate("C")
1688dd4bdcdSmrg    print "enum isa_feature {"
1698dd4bdcdSmrg    print "  isa_nobit = 0,"
1708dd4bdcdSmrg    for (fbit in features) {
1718dd4bdcdSmrg	print "  isa_bit_" fbit ","
1728dd4bdcdSmrg    }
1738dd4bdcdSmrg    print "  isa_num_bits"
1748dd4bdcdSmrg    print "};\n"
1758dd4bdcdSmrg
1768dd4bdcdSmrg    for (fgrp in fgroup) {
1778dd4bdcdSmrg	print "#define ISA_"fgrp " \\"
1788dd4bdcdSmrg	z = ORS
1798dd4bdcdSmrg	ORS = ""
1808dd4bdcdSmrg	first = 1
1818dd4bdcdSmrg	for (bitcomb in fgrp_bits) {
1828dd4bdcdSmrg	    split (bitcomb, bitsep, SUBSEP)
1838dd4bdcdSmrg	    if (bitsep[1] == fgrp) {
1848dd4bdcdSmrg		if (first) {
1858dd4bdcdSmrg		    first = 0
1868dd4bdcdSmrg		} else print ", \\\n"
1878dd4bdcdSmrg		print "  isa_bit_" bitsep[2]
1888dd4bdcdSmrg	    }
1898dd4bdcdSmrg	}
1908dd4bdcdSmrg	ORS = z
1918dd4bdcdSmrg	print "\n"
1928dd4bdcdSmrg    }
193*0bfacb9bSmrg
194*0bfacb9bSmrg    print "struct fbit_implication {"
195*0bfacb9bSmrg    print "  /* Represents a feature implication, where:"
196*0bfacb9bSmrg    print "     ante IMPLIES cons"
197*0bfacb9bSmrg    print "     meaning that if ante is enabled then we should"
198*0bfacb9bSmrg    print "     also implicitly enable cons.  */"
199*0bfacb9bSmrg    print "  enum isa_feature ante;"
200*0bfacb9bSmrg    print "  enum isa_feature cons;"
201*0bfacb9bSmrg    print "};\n"
202*0bfacb9bSmrg    print "static const struct fbit_implication all_implied_fbits[] ="
203*0bfacb9bSmrg    print "{"
204*0bfacb9bSmrg    for (impl in implied_bits) {
205*0bfacb9bSmrg      split (impl, impl_parts, SUBSEP)
206*0bfacb9bSmrg      print "  { isa_bit_" impl_parts[2] ", isa_bit_" impl_parts[1] " },"
207*0bfacb9bSmrg    }
208*0bfacb9bSmrg    print "  { isa_nobit, isa_nobit }"
209*0bfacb9bSmrg    print "};\n"
2108dd4bdcdSmrg}
2118dd4bdcdSmrg
212ac8e35e1Smrgfunction gen_data () {
213ac8e35e1Smrg    boilerplate("C")
214ac8e35e1Smrg
2158dd4bdcdSmrg    print "static const cpu_tune all_tunes[] ="
216ac8e35e1Smrg    print "{"
217ac8e35e1Smrg
218ac8e35e1Smrg    ncpus = split (cpu_list, cpus)
219ac8e35e1Smrg
220ac8e35e1Smrg    for (n = 1; n <= ncpus; n++) {
2218dd4bdcdSmrg	print "  { /* " cpus[n] ".  */"
2228dd4bdcdSmrg	# scheduler
223ac8e35e1Smrg	if (cpus[n] in cpu_tune_for) {
224ac8e35e1Smrg	    if (! (cpu_tune_for[cpus[n]] in cpu_cnames)) {
225ac8e35e1Smrg		fatal("unknown \"tune for\" target " cpu_tune_for[cpus[n]] \
226ac8e35e1Smrg		      " for CPU " cpus[n])
227ac8e35e1Smrg	    }
228ac8e35e1Smrg	    print "    TARGET_CPU_" cpu_cnames[cpu_tune_for[cpus[n]]] ","
229ac8e35e1Smrg	} else {
230ac8e35e1Smrg	    print "    TARGET_CPU_" cpu_cnames[cpus[n]] ","
231ac8e35e1Smrg	}
2328dd4bdcdSmrg	# tune_flags
233ac8e35e1Smrg	if (cpus[n] in cpu_tune_flags) {
234ac8e35e1Smrg	    print "    (" cpu_tune_flags[cpus[n]] "),"
235ac8e35e1Smrg	} else print "    0,"
2368dd4bdcdSmrg	# tune
237ac8e35e1Smrg	print "    &arm_" cpu_cost[cpus[n]] "_tune"
238ac8e35e1Smrg	print "  },"
239ac8e35e1Smrg    }
2408dd4bdcdSmrg    print "  {TARGET_CPU_arm_none, 0, NULL}"
2418dd4bdcdSmrg    print "};"
2428dd4bdcdSmrg}
243ac8e35e1Smrg
2448dd4bdcdSmrgfunction gen_comm_data () {
2458dd4bdcdSmrg    boilerplate("C")
2468dd4bdcdSmrg
2478dd4bdcdSmrg    ncpus = split (cpu_list, cpus)
2488dd4bdcdSmrg
2498dd4bdcdSmrg    for (n = 1; n <= ncpus; n++) {
2508dd4bdcdSmrg	if (cpus[n] in cpu_opts) {
2518dd4bdcdSmrg	    print "static const cpu_arch_extension cpu_opttab_" \
2528dd4bdcdSmrg		cpu_cnames[cpus[n]] "[] = {"
2538dd4bdcdSmrg	    nopts = split (cpu_opts[cpus[n]], opts)
2548dd4bdcdSmrg	    for (opt = 1; opt <= nopts; opt++) {
2558dd4bdcdSmrg		print "  {"
2568dd4bdcdSmrg		print "    \"" opts[opt] "\", " \
2578dd4bdcdSmrg		    cpu_opt_remove[cpus[n],opts[opt]] ", false,"
2588dd4bdcdSmrg		print_isa_bits_for(cpu_opt_isa[cpus[n],opts[opt]], "    ")
2598dd4bdcdSmrg		print "\n  },"
2608dd4bdcdSmrg	    }
2618dd4bdcdSmrg	    if (cpus[n] in cpu_optaliases) {
2628dd4bdcdSmrg		naliases = split (cpu_optaliases[cpus[n]], aliases)
2638dd4bdcdSmrg		for (alias = 1; alias <= naliases; alias++) {
2648dd4bdcdSmrg		    if (! ((cpus[n], \
2658dd4bdcdSmrg			    cpu_opt_alias[cpus[n],aliases[alias]]) in \
2668dd4bdcdSmrg			   cpu_opt_isa)) {
2678dd4bdcdSmrg			fatal("Alias " aliases[alias] " target not defined " \
2688dd4bdcdSmrg			      "for CPU " cpus[n])
2698dd4bdcdSmrg		    }
2708dd4bdcdSmrg		    equiv=cpu_opt_alias[cpus[n],aliases[alias]]
2718dd4bdcdSmrg		    print "  {"
2728dd4bdcdSmrg		    print "    \"" aliases[alias] "\", " \
2738dd4bdcdSmrg			cpu_opt_remove[cpus[n],equiv] ", true, "
2748dd4bdcdSmrg		    print_isa_bits_for(cpu_opt_isa[cpus[n],equiv], "    ")
2758dd4bdcdSmrg		    print "\n  },"
2768dd4bdcdSmrg		}
2778dd4bdcdSmrg	    }
2788dd4bdcdSmrg	    print "  { NULL, false, false, {isa_nobit}}"
279ac8e35e1Smrg	    print "};\n"
2808dd4bdcdSmrg	}
281760c2415Smrg
282760c2415Smrg	if (cpus[n] in cpu_aliases) {
283760c2415Smrg	    print "static const cpu_alias cpu_aliastab_" \
284760c2415Smrg		cpu_cnames[cpus[n]] "[] = {"
285760c2415Smrg	    naliases = split (cpu_aliases[cpus[n]], aliases)
286760c2415Smrg	    for (alias = 1; alias <= naliases; alias++) {
287760c2415Smrg		print "  { \"" aliases[alias] "\", " \
288760c2415Smrg		    cpu_alias_visible[cpus[n],aliases[alias]] "},"
289760c2415Smrg	    }
290760c2415Smrg	    print "  { NULL, false}"
291760c2415Smrg	    print "};\n"
292760c2415Smrg	}
2938dd4bdcdSmrg    }
294ac8e35e1Smrg
2958dd4bdcdSmrg    print "const cpu_option all_cores[] ="
296ac8e35e1Smrg    print "{"
297ac8e35e1Smrg
2988dd4bdcdSmrg    for (n = 1; n <= ncpus; n++) {
2998dd4bdcdSmrg	print "  {"
3008dd4bdcdSmrg	print "    {"
3018dd4bdcdSmrg	# common.name
3028dd4bdcdSmrg	print "      \"" cpus[n] "\","
3038dd4bdcdSmrg	# common.extensions
3048dd4bdcdSmrg	if (cpus[n] in cpu_opts) {
3058dd4bdcdSmrg	    print "      cpu_opttab_" cpu_cnames[cpus[n]] ","
3068dd4bdcdSmrg	} else print "      NULL,"
3078dd4bdcdSmrg	# common.isa_bits
3088dd4bdcdSmrg	nfeats = split (cpu_arch[cpus[n]], feats, "+")
3098dd4bdcdSmrg	if (! (feats[1] in arch_isa)) {
3108dd4bdcdSmrg	    fatal("unknown arch " feats[1] " for cpu " cpus[n])
3118dd4bdcdSmrg	}
3128dd4bdcdSmrg	all_isa_bits = arch_isa[feats[1]]
3138dd4bdcdSmrg	for (m = 2; m <= nfeats; m++) {
3148dd4bdcdSmrg	    if (! ((feats[1], feats[m]) in arch_opt_isa)) {
3158dd4bdcdSmrg		fatal("unknown feature " feats[m] " for architecture " feats[1])
3168dd4bdcdSmrg	    }
3178dd4bdcdSmrg	    if (arch_opt_remove[feats[1],feats[m]] == "true") {
3188dd4bdcdSmrg		fatal("cannot remove features from architecture specs")
3198dd4bdcdSmrg	    }
3208dd4bdcdSmrg	    all_isa_bits = all_isa_bits " " arch_opt_isa[feats[1],feats[m]]
3218dd4bdcdSmrg	}
3228dd4bdcdSmrg	if (cpus[n] in cpu_isa) {
3238dd4bdcdSmrg	    all_isa_bits = all_isa_bits " " cpu_isa[cpus[n]]
3248dd4bdcdSmrg	}
3258dd4bdcdSmrg	print_isa_bits_for(all_isa_bits, "      ")
3268dd4bdcdSmrg	print "\n    },"
327760c2415Smrg	# aliases
328760c2415Smrg	if (cpus[n] in cpu_aliases) {
329760c2415Smrg	    print "    cpu_aliastab_" cpu_cnames[cpus[n]] ","
330760c2415Smrg	} else print "    NULL,"
3318dd4bdcdSmrg	# arch
3328dd4bdcdSmrg	print "    TARGET_ARCH_" arch_cnames[feats[1]]
3338dd4bdcdSmrg	print "  },"
3348dd4bdcdSmrg    }
3358dd4bdcdSmrg
336760c2415Smrg    print "  {{NULL, NULL, {isa_nobit}}, NULL, TARGET_ARCH_arm_none}"
3378dd4bdcdSmrg    print "};"
3388dd4bdcdSmrg
339ac8e35e1Smrg    narchs = split (arch_list, archs)
340ac8e35e1Smrg
341ac8e35e1Smrg    for (n = 1; n <= narchs; n++) {
3428dd4bdcdSmrg	if (archs[n] in arch_opts) {
3438dd4bdcdSmrg	    print "static const struct cpu_arch_extension arch_opttab_" \
3448dd4bdcdSmrg		arch_cnames[archs[n]] "[] = {"
3458dd4bdcdSmrg	    nopts = split (arch_opts[archs[n]], opts)
3468dd4bdcdSmrg	    for (opt = 1; opt <= nopts; opt++) {
3478dd4bdcdSmrg		print "  {"
3488dd4bdcdSmrg		print "    \"" opts[opt] "\", " \
3498dd4bdcdSmrg		    arch_opt_remove[archs[n],opts[opt]] ", false,"
3508dd4bdcdSmrg		print_isa_bits_for(arch_opt_isa[archs[n],opts[opt]], "    ")
3518dd4bdcdSmrg		print "\n  },"
3528dd4bdcdSmrg	    }
3538dd4bdcdSmrg	    if (archs[n] in arch_optaliases) {
3548dd4bdcdSmrg		naliases = split (arch_optaliases[archs[n]], aliases)
3558dd4bdcdSmrg		for (alias = 1; alias <= naliases; alias++) {
3568dd4bdcdSmrg		    if (! ((archs[n], \
3578dd4bdcdSmrg			    arch_opt_alias[archs[n],aliases[alias]]) in \
3588dd4bdcdSmrg			   arch_opt_isa)) {
3598dd4bdcdSmrg			fatal("Alias " aliases[alias] " target not defined " \
3608dd4bdcdSmrg			      "for architecture " archs[n])
3618dd4bdcdSmrg		    }
3628dd4bdcdSmrg		    equiv=arch_opt_alias[archs[n],aliases[alias]]
3638dd4bdcdSmrg		    print "  {"
3648dd4bdcdSmrg		    print "    \"" aliases[alias] "\", " \
3658dd4bdcdSmrg			arch_opt_remove[archs[n],equiv] ", true, "
3668dd4bdcdSmrg		    print_isa_bits_for(arch_opt_isa[archs[n],equiv], "    ")
3678dd4bdcdSmrg		    print "\n  },"
3688dd4bdcdSmrg		}
3698dd4bdcdSmrg	    }
3708dd4bdcdSmrg	    print "  { NULL, false, false, {isa_nobit}}"
3718dd4bdcdSmrg	    print "};\n"
3728dd4bdcdSmrg	} else if (archs[n] in arch_optaliases) {
3738dd4bdcdSmrg	    fatal("Architecture " archs[n] " has option aliases but no options")
3748dd4bdcdSmrg	}
3758dd4bdcdSmrg    }
3768dd4bdcdSmrg
3778dd4bdcdSmrg    print "const arch_option all_architectures[] ="
3788dd4bdcdSmrg    print "{"
3798dd4bdcdSmrg
3808dd4bdcdSmrg    for (n = 1; n <= narchs; n++) {
381ac8e35e1Smrg	print "  {"
382ac8e35e1Smrg	if (! (arch_tune_for[archs[n]] in cpu_cnames)) {
383ac8e35e1Smrg	    fatal("unknown \"tune for\" target " arch_tune_for[archs[n]] \
384ac8e35e1Smrg		  " for architecture " archs[n])
385ac8e35e1Smrg	}
3868dd4bdcdSmrg	# common.name
3878dd4bdcdSmrg	print "    \"" archs[n] "\","
3888dd4bdcdSmrg	# common.extensions
3898dd4bdcdSmrg	if (archs[n] in arch_opts) {
3908dd4bdcdSmrg	    print "    arch_opttab_" arch_cnames[archs[n]] ","
3918dd4bdcdSmrg	} else print "    NULL,"
3928dd4bdcdSmrg	# common.isa_bits
3938dd4bdcdSmrg	print_isa_bits_for(arch_isa[archs[n]], "    ")
3948dd4bdcdSmrg	print ","
3958dd4bdcdSmrg	# arch, base_arch
396ac8e35e1Smrg	print "    \"" arch_base[archs[n]] "\", BASE_ARCH_" \
397ac8e35e1Smrg	    arch_base[archs[n]] ","
3988dd4bdcdSmrg	# profile letter code, or zero if none.
3998dd4bdcdSmrg	if (archs[n] in arch_prof) {
4008dd4bdcdSmrg	    print "    '" arch_prof[archs[n]] "',"
4018dd4bdcdSmrg	} else {
4028dd4bdcdSmrg	    print "    0,"
4038dd4bdcdSmrg	}
4048dd4bdcdSmrg	# tune_id
4058dd4bdcdSmrg	print "    TARGET_CPU_" cpu_cnames[arch_tune_for[archs[n]]] ","
406ac8e35e1Smrg	print "  },"
407ac8e35e1Smrg    }
408ac8e35e1Smrg
4098dd4bdcdSmrg    print "  {{NULL, NULL, {isa_nobit}},"
4108dd4bdcdSmrg    print "   NULL, BASE_ARCH_0, 0, TARGET_CPU_arm_none}"
411ac8e35e1Smrg    print "};\n"
412ac8e35e1Smrg
4138dd4bdcdSmrg    print "const arm_fpu_desc all_fpus[] ="
414ac8e35e1Smrg    print "{"
415ac8e35e1Smrg
416ac8e35e1Smrg    nfpus = split (fpu_list, fpus)
417ac8e35e1Smrg
418ac8e35e1Smrg    for (n = 1; n <= nfpus; n++) {
419ac8e35e1Smrg	print "  {"
420ac8e35e1Smrg	print "    \"" fpus[n] "\","
4218dd4bdcdSmrg	print_isa_bits_for(fpu_isa[fpus[n]], "    ")
4228dd4bdcdSmrg	print "\n  },"
423ac8e35e1Smrg    }
424ac8e35e1Smrg
425ac8e35e1Smrg    print "};"
426ac8e35e1Smrg}
427ac8e35e1Smrg
428760c2415Smrgfunction gen_native () {
429760c2415Smrg    boilerplate("C")
430760c2415Smrg
431760c2415Smrg    for (vendor in vendor_ids) {
432760c2415Smrg	print "static struct vendor_cpu vendor"vendor"_cpu_table[] = {"
433760c2415Smrg	ncpus = split (cpu_list, cpus)
434760c2415Smrg
435760c2415Smrg	for (n = 1; n <= ncpus; n++) {
436760c2415Smrg	    if ((cpus[n] in cpu_vendor) && (cpus[n] in cpu_part)	\
437760c2415Smrg		&& cpu_vendor[cpus[n]] == vendor) {
438760c2415Smrg		print "  {\"0x"cpu_part[cpus[n]]"\", \""cpu_arch[cpus[n]]"\", \""cpus[n]"\"},"
439760c2415Smrg	    }
440760c2415Smrg	}
441760c2415Smrg	print "  {NULL, NULL, NULL}"
442760c2415Smrg	print "};"
443760c2415Smrg    }
444760c2415Smrg
445760c2415Smrg    print "\nstatic struct vendor vendors_table[] = {"
446760c2415Smrg    for (vendor in vendor_ids) {
447760c2415Smrg	print "  {\"0x"vendor"\", vendor"vendor"_cpu_table},"
448760c2415Smrg    }
449760c2415Smrg    print "  {NULL, NULL}"
450760c2415Smrg    print "};"
451760c2415Smrg}
452760c2415Smrg
453ac8e35e1Smrgfunction gen_md () {
454ac8e35e1Smrg    boilerplate("md")
455ac8e35e1Smrg
456ac8e35e1Smrg    z = ORS
457ac8e35e1Smrg    ORS = ""
458ac8e35e1Smrg    print "(define_attr \"tune\"\n\t\""
459ac8e35e1Smrg
460ac8e35e1Smrg    ncpus = split (cpu_list, cpus)
461ac8e35e1Smrg
462ac8e35e1Smrg    for (n = 1; n < ncpus; n++) {
463ac8e35e1Smrg	if ((n % 3) != 0) {
464ac8e35e1Smrg	    ORS = ","
465ac8e35e1Smrg	} else ORS = ",\n\t"
466ac8e35e1Smrg	print cpu_cnames[cpus[n]]
467ac8e35e1Smrg    }
468ac8e35e1Smrg    ORS = z
469ac8e35e1Smrg    print cpu_cnames[cpus[ncpus]]"\""
470ac8e35e1Smrg    print "\t(const (symbol_ref \"((enum attr_tune) arm_tune)\")))"
471ac8e35e1Smrg}
472ac8e35e1Smrg
473ac8e35e1Smrgfunction gen_opt () {
474ac8e35e1Smrg    boilerplate("md")
475ac8e35e1Smrg
476ac8e35e1Smrg    print "Enum"
477ac8e35e1Smrg    print "Name(processor_type) Type(enum processor_type)"
478ac8e35e1Smrg    print "Known ARM CPUs (for use with the -mcpu= and -mtune= options):\n"
479ac8e35e1Smrg
480ac8e35e1Smrg    ncpus = split (cpu_list, cpus)
481ac8e35e1Smrg
482ac8e35e1Smrg    for (n = 1; n <= ncpus; n++) {
483ac8e35e1Smrg	print "EnumValue"
484ac8e35e1Smrg	print "Enum(processor_type) String(" cpus[n] \
485ac8e35e1Smrg	    ") Value( TARGET_CPU_"cpu_cnames[cpus[n]]")"
486ac8e35e1Smrg	print ""
487ac8e35e1Smrg    }
488ac8e35e1Smrg
489ac8e35e1Smrg    print "Enum"
490ac8e35e1Smrg    print "Name(arm_arch) Type(int)"
491ac8e35e1Smrg    print "Known ARM architectures (for use with the -march= option):\n"
492ac8e35e1Smrg
493ac8e35e1Smrg    narchs = split (arch_list, archs)
494ac8e35e1Smrg
495ac8e35e1Smrg    for (n = 1; n <= narchs; n++) {
496ac8e35e1Smrg	print "EnumValue"
497ac8e35e1Smrg	print "Enum(arm_arch) String(" archs[n] \
498ac8e35e1Smrg	    ") Value("n - 1")"
499ac8e35e1Smrg	print ""
500ac8e35e1Smrg    }
501ac8e35e1Smrg
502ac8e35e1Smrg    print "Enum"
503ac8e35e1Smrg    print "Name(arm_fpu) Type(enum fpu_type)"
504ac8e35e1Smrg    print "Known ARM FPUs (for use with the -mfpu= option):\n"
505ac8e35e1Smrg
506ac8e35e1Smrg    nfpus = split (fpu_list, fpus)
507ac8e35e1Smrg
508ac8e35e1Smrg    for (n = 1; n <= nfpus; n++) {
509ac8e35e1Smrg	print "EnumValue"
510ac8e35e1Smrg	print "Enum(arm_fpu) String(" fpus[n] \
511ac8e35e1Smrg	    ") Value(TARGET_FPU_"fpu_cnames[fpus[n]]")"
512ac8e35e1Smrg	print ""
513ac8e35e1Smrg    }
514ac8e35e1Smrg
515ac8e35e1Smrg    print "EnumValue"
516ac8e35e1Smrg    print "Enum(arm_fpu) String(auto) Value(TARGET_FPU_auto)"
517ac8e35e1Smrg}
518ac8e35e1Smrg
519ac8e35e1Smrgfunction check_cpu (name) {
5208dd4bdcdSmrg    exts = split (name, extensions, "+")
5218dd4bdcdSmrg
522760c2415Smrg    cpu_name = extensions[1]
523760c2415Smrg    if (! (cpu_name in cpu_cnames)) {
524760c2415Smrg	if (! (cpu_name in cpu_all_aliases)) {
5258dd4bdcdSmrg	    return "error"
5268dd4bdcdSmrg	}
527760c2415Smrg	cpu_name = cpu_all_aliases[cpu_name]
528760c2415Smrg    }
5298dd4bdcdSmrg
5308dd4bdcdSmrg    for (n = 2; n <= exts; n++) {
531760c2415Smrg	if (!((cpu_name, extensions[n]) in cpu_opt_remove)	\
532760c2415Smrg	    && !((cpu_name, extensions[n]) in cpu_optaliases)) {
5338dd4bdcdSmrg	    return "error"
5348dd4bdcdSmrg	}
5358dd4bdcdSmrg    }
5368dd4bdcdSmrg    return name
537ac8e35e1Smrg}
538ac8e35e1Smrg
539ac8e35e1Smrgfunction check_fpu (name) {
5408dd4bdcdSmrg    if (! (name in fpu_cnames)) {
5418dd4bdcdSmrg	return "error"
5428dd4bdcdSmrg    }
5438dd4bdcdSmrg    return fpu_cnames[name]
544ac8e35e1Smrg}
545ac8e35e1Smrg
546ac8e35e1Smrgfunction check_arch (name) {
5478dd4bdcdSmrg    exts = split (name, extensions, "+")
5488dd4bdcdSmrg
5498dd4bdcdSmrg    if (! (extensions[1] in arch_isa)) {
5508dd4bdcdSmrg	return "error"
5518dd4bdcdSmrg    }
5528dd4bdcdSmrg
5538dd4bdcdSmrg    for (n = 2; n <= exts; n++) {
5548dd4bdcdSmrg	if (!((extensions[1], extensions[n]) in arch_opt_remove)	\
5558dd4bdcdSmrg	    && !((extensions[1], extensions[n]) in arch_optaliases)) {
5568dd4bdcdSmrg	    return "error"
5578dd4bdcdSmrg	}
5588dd4bdcdSmrg    }
5598dd4bdcdSmrg    return name
560ac8e35e1Smrg}
561ac8e35e1Smrg
562ac8e35e1SmrgBEGIN {
563ac8e35e1Smrg    cpu_name = ""
564ac8e35e1Smrg    arch_name = ""
565ac8e35e1Smrg    fpu_name = ""
566ac8e35e1Smrg    lineno = 0
5678dd4bdcdSmrg    fatal_err = 0
5688dd4bdcdSmrg    parse_done = 0
569ac8e35e1Smrg    if (cmd == "") fatal("Usage parsecpu.awk -v cmd=<xyz>")
570ac8e35e1Smrg}
571ac8e35e1Smrg
5728dd4bdcdSmrg# New line.  Reset parse status and increment line count for error messages
573ac8e35e1Smrg// {
574ac8e35e1Smrg    lineno++
575ac8e35e1Smrg    parse_ok = 0
576ac8e35e1Smrg}
577ac8e35e1Smrg
5788dd4bdcdSmrg# Comments must be on a line on their own.
579ac8e35e1Smrg/^#/ {
580ac8e35e1Smrg    parse_ok = 1
581ac8e35e1Smrg}
582ac8e35e1Smrg
5838dd4bdcdSmrg/^define feature / {
5848dd4bdcdSmrg    if (NF != 3) fatal("syntax: define feature <name>")
5858dd4bdcdSmrg    toplevel()
5868dd4bdcdSmrg    fbit = $3
5878dd4bdcdSmrg    if (fbit in features) fatal("feature " fbit " already defined")
5888dd4bdcdSmrg    features[fbit] = 1
5898dd4bdcdSmrg    parse_ok = 1
5908dd4bdcdSmrg}
5918dd4bdcdSmrg
5928dd4bdcdSmrg/^define fgroup / {
5938dd4bdcdSmrg    if (NF < 4) fatal("syntax: define fgroup <name> <feature> [<feature>]*")
5948dd4bdcdSmrg    toplevel()
5958dd4bdcdSmrg    fgrp = $3
5968dd4bdcdSmrg    if (fgrp in fgroup) fatal("feature group " fgrp " already defined")
5978dd4bdcdSmrg    if (fgrp in features) fatal("feature group " fgrp " aliases a feature")
5988dd4bdcdSmrg    fcount = NF
5998dd4bdcdSmrg    for (n = 4; n <= fcount; n++) {
6008dd4bdcdSmrg	feat = $n
6018dd4bdcdSmrg	if (feat in features) {
6028dd4bdcdSmrg	    fgrp_bits[fgrp,feat] = 1
6038dd4bdcdSmrg	} else if (feat in fgroup) {
6048dd4bdcdSmrg	    # fgroups may reference other fgroups, copy their bits
6058dd4bdcdSmrg	    # to our bits.  To avoid recursion we don't set fgroup[fgrp]
6068dd4bdcdSmrg	    # until after we have done this, so such attempts will result
6078dd4bdcdSmrg	    # in an invalid group definition.
6088dd4bdcdSmrg	    for (bitcomb in fgrp_bits) {
6098dd4bdcdSmrg		split (bitcomb, bitsep, SUBSEP)
6108dd4bdcdSmrg		if (bitsep[1] == feat) {
6118dd4bdcdSmrg		    fgrp_bits[fgrp,bitsep[2]] = 1
6128dd4bdcdSmrg		}
6138dd4bdcdSmrg	    }
6148dd4bdcdSmrg	} else fatal("feature group member " feat " unrecognized")
6158dd4bdcdSmrg    }
6168dd4bdcdSmrg    fgroup[fgrp] = 1
6178dd4bdcdSmrg    parse_ok = 1
6188dd4bdcdSmrg}
6198dd4bdcdSmrg
620*0bfacb9bSmrg/^define implied / {
621*0bfacb9bSmrg  if (NF < 4) fatal("syntax: define implied <name> [<feature-or-fgroup>]+\n" \
622*0bfacb9bSmrg		    "Implied bits must be defined with at least one antecedent.")
623*0bfacb9bSmrg  toplevel()
624*0bfacb9bSmrg  fbit = $3
625*0bfacb9bSmrg  if (fbit in features) fatal("implied feature " fbit " aliases a real feature")
626*0bfacb9bSmrg  if (fbit in fgroup) fatal("implied feature " fbit " aliases a feature group")
627*0bfacb9bSmrg  fcount = NF
628*0bfacb9bSmrg  features[fbit] = 1
629*0bfacb9bSmrg  for (n = 4; n <= fcount; n++) {
630*0bfacb9bSmrg    ante = $n
631*0bfacb9bSmrg    if (fbit == ante) fatal("feature cannot imply itself")
632*0bfacb9bSmrg    else if (ante in features) {
633*0bfacb9bSmrg      for (impl in implied_bits) {
634*0bfacb9bSmrg	split(impl, impl_sep, SUBSEP)
635*0bfacb9bSmrg	if (ante == impl_sep[1])
636*0bfacb9bSmrg	  fatal(ante " implies implied bit " fbit		\
637*0bfacb9bSmrg		". Chained implications not currently supported")
638*0bfacb9bSmrg      }
639*0bfacb9bSmrg      implied_bits[fbit, ante] = 1
640*0bfacb9bSmrg    } else if (ante in fgroup) {
641*0bfacb9bSmrg      for (bitcomb in fgrp_bits) {
642*0bfacb9bSmrg	split(bitcomb, bitsep, SUBSEP)
643*0bfacb9bSmrg	if (bitsep[1] == ante) {
644*0bfacb9bSmrg	  implied_bits[fbit, bitsep[2]] = 1
645*0bfacb9bSmrg	}
646*0bfacb9bSmrg      }
647*0bfacb9bSmrg    } else {
648*0bfacb9bSmrg      fatal("implied bit antecedent " ante " unrecognized")
649*0bfacb9bSmrg    }
650*0bfacb9bSmrg  }
651*0bfacb9bSmrg  parse_ok = 1
652*0bfacb9bSmrg}
653*0bfacb9bSmrg
654ac8e35e1Smrg/^begin fpu / {
6558dd4bdcdSmrg    if (NF != 3) fatal("syntax: begin fpu <name>")
656ac8e35e1Smrg    toplevel()
657ac8e35e1Smrg    fpu_name = $3
658ac8e35e1Smrg    parse_ok = 1
659ac8e35e1Smrg}
660ac8e35e1Smrg
661ac8e35e1Smrg/^end fpu / {
6628dd4bdcdSmrg    if (NF != 3) fatal("syntax: end fpu <name>")
663ac8e35e1Smrg    if (fpu_name != $3) fatal("mimatched end fpu")
664ac8e35e1Smrg    if (! (fpu_name in fpu_isa)) {
665ac8e35e1Smrg	fatal("fpu definition \"" fpu_name "\" lacks an \"isa\" statement")
666ac8e35e1Smrg    }
667ac8e35e1Smrg    fpu_cnames[fpu_name] = fpu_name
668ac8e35e1Smrg    gsub(/[-+.]/, "_", fpu_cnames[fpu_name])
669ac8e35e1Smrg    fpu_list = fpu_list " " fpu_name
670ac8e35e1Smrg    fpu_name = ""
671ac8e35e1Smrg    parse_ok = 1
672ac8e35e1Smrg}
673ac8e35e1Smrg
674ac8e35e1Smrg/^begin arch / {
6758dd4bdcdSmrg    if (NF != 3) fatal("syntax: begin arch <name>")
676ac8e35e1Smrg    toplevel()
677ac8e35e1Smrg    arch_name = $3
678ac8e35e1Smrg    parse_ok = 1
679ac8e35e1Smrg}
680ac8e35e1Smrg
681ac8e35e1Smrg/^[ 	]*base / {
6828dd4bdcdSmrg    if (NF != 2) fatal("syntax: base <architecture-base-name>")
683ac8e35e1Smrg    if (arch_name == "") fatal("\"base\" statement outside of arch block")
684ac8e35e1Smrg    arch_base[arch_name] = $2
685ac8e35e1Smrg    parse_ok = 1
686ac8e35e1Smrg}
687ac8e35e1Smrg
6888dd4bdcdSmrg/^[ 	]*profile / {
6898dd4bdcdSmrg    if (NF != 2) fatal("syntax: profile <profile-name>")
6908dd4bdcdSmrg    if (arch_name == "") fatal("\"profile\" statement outside of arch block")
6918dd4bdcdSmrg    arch_prof[arch_name] = $2
6928dd4bdcdSmrg    parse_ok = 1
6938dd4bdcdSmrg}
6948dd4bdcdSmrg
695ac8e35e1Smrg/^end arch / {
6968dd4bdcdSmrg    if (NF != 3) fatal("syntax: end arch <name>")
697ac8e35e1Smrg    if (arch_name != $3) fatal("mimatched end arch")
6988dd4bdcdSmrg    if (! (arch_name in arch_tune_for)) {
699ac8e35e1Smrg	fatal("arch definition lacks a \"tune for\" statement")
700ac8e35e1Smrg    }
7018dd4bdcdSmrg    if (! (arch_name in arch_isa)) {
702ac8e35e1Smrg	fatal("arch definition lacks an \"isa\" statement")
703ac8e35e1Smrg    }
704ac8e35e1Smrg    arch_list = arch_list " " arch_name
7058dd4bdcdSmrg    arch_cnames[arch_name] = arch_name
7068dd4bdcdSmrg    gsub(/[-+.]/, "_", arch_cnames[arch_name])
707ac8e35e1Smrg    arch_name = ""
708ac8e35e1Smrg    parse_ok = 1
709ac8e35e1Smrg}
710ac8e35e1Smrg
711ac8e35e1Smrg/^begin cpu / {
7128dd4bdcdSmrg    if (NF != 3) fatal("syntax: begin cpu <name>")
713ac8e35e1Smrg    toplevel()
714ac8e35e1Smrg    cpu_name = $3
715ac8e35e1Smrg    parse_ok = 1
716760c2415Smrg    if (cpu_name in cpu_cnames) {
717760c2415Smrg	fatal(cpu_name " is already defined")
718760c2415Smrg    }
719760c2415Smrg    if (cpu_name in cpu_all_aliases) {
720760c2415Smrg	fatal(cpu_name " has already been defined as an alias")
721760c2415Smrg    }
722ac8e35e1Smrg}
723ac8e35e1Smrg
724ac8e35e1Smrg/^[ 	]*cname / {
7258dd4bdcdSmrg    if (NF != 2) fatal("syntax: cname <identifier>")
726ac8e35e1Smrg    if (cpu_name == "") fatal("\"cname\" outside of cpu block")
727ac8e35e1Smrg    cpu_cnames[cpu_name] = $2
728ac8e35e1Smrg    parse_ok = 1
729ac8e35e1Smrg}
730ac8e35e1Smrg
731760c2415Smrg/^[ 	]*alias / {
732760c2415Smrg    if (NF < 2) fatal("syntax: alias <name>+")
733760c2415Smrg    if (cpu_name == "") fatal("\"alias\" outside of cpu block")
734760c2415Smrg    alias_count = NF
735760c2415Smrg    for (n = 2; n <= alias_count; n++) {
736760c2415Smrg	visible = "true"
737760c2415Smrg	alias = $n
738760c2415Smrg	if (alias ~ /^!.*/) {
739760c2415Smrg	    visible = "false"
740760c2415Smrg	    gsub(/^!/, "", alias)
741760c2415Smrg	}
742760c2415Smrg	if (alias in cpu_cnames) {
743760c2415Smrg	    fatal(alias " is already defined as a cpu name")
744760c2415Smrg	}
745760c2415Smrg	if (n == 2) {
746760c2415Smrg	    cpu_aliases[cpu_name] = alias
747760c2415Smrg	} else cpu_aliases[cpu_name] = cpu_aliases[cpu_name] " " alias
748760c2415Smrg	cpu_alias_visible[cpu_name,alias] = visible
749760c2415Smrg	if (alias in cpu_all_aliases) {
750760c2415Smrg	    fatal(alias " is already an alias for " cpu_all_aliases[alias])
751760c2415Smrg	}
752760c2415Smrg	cpu_all_aliases[alias] = cpu_name
753760c2415Smrg    }
754760c2415Smrg    parse_ok = 1
755760c2415Smrg}
756760c2415Smrg
757ac8e35e1Smrg/^[ 	]*tune for / {
7588dd4bdcdSmrg    if (NF != 3) fatal("syntax: tune for <cpu-name>")
759ac8e35e1Smrg    if (cpu_name != "") {
760ac8e35e1Smrg	cpu_tune_for[cpu_name] = $3
761ac8e35e1Smrg    } else if (arch_name != "") {
762ac8e35e1Smrg	arch_tune_for[arch_name] = $3
763ac8e35e1Smrg    } else fatal("\"tune for\" outside of cpu or arch block")
764ac8e35e1Smrg    parse_ok = 1
765ac8e35e1Smrg}
766ac8e35e1Smrg
767ac8e35e1Smrg/^[ 	]*tune flags / {
7688dd4bdcdSmrg    if (NF < 3) fatal("syntax: tune flags <flag> [<flag>]*")
769ac8e35e1Smrg    flags=""
770ac8e35e1Smrg    flag_count = NF
771ac8e35e1Smrg    for (n = 3; n <= flag_count; n++) {
772ac8e35e1Smrg	if (n == 3) {
773ac8e35e1Smrg	    flags = tune_flag_pfx($n)
774ac8e35e1Smrg	} else flags = flags " | " tune_flag_pfx($n)
775ac8e35e1Smrg    }
776ac8e35e1Smrg    if (cpu_name != "") {
777ac8e35e1Smrg	cpu_tune_flags[cpu_name] = flags
778ac8e35e1Smrg    } else if (arch_name != "") {
779ac8e35e1Smrg	arch_tune_flags[arch_name] = flags
780ac8e35e1Smrg    } else fatal("\"tune flags\" outside of cpu or arch block")
781ac8e35e1Smrg    parse_ok = 1
782ac8e35e1Smrg}
783ac8e35e1Smrg
784ac8e35e1Smrg/^[ 	]*architecture / {
7858dd4bdcdSmrg    if (NF != 2) fatal("syntax: architecture <arch-name>")
786ac8e35e1Smrg    if (cpu_name == "") fatal("\"architecture\" outside of cpu block")
787ac8e35e1Smrg    cpu_arch[cpu_name] = $2
788ac8e35e1Smrg    parse_ok = 1
789ac8e35e1Smrg}
790ac8e35e1Smrg
791ac8e35e1Smrg/^[ 	]*isa / {
7928dd4bdcdSmrg    if (NF < 2) fatal("syntax: isa <feature-or-fgroup> [<feature-or-fgroup>]*")
793ac8e35e1Smrg    flags=""
794ac8e35e1Smrg    flag_count = NF
795ac8e35e1Smrg    for (n = 2; n <= flag_count; n++) {
796ac8e35e1Smrg	if (n == 2) {
7978dd4bdcdSmrg	    flags = $n
7988dd4bdcdSmrg	} else flags = flags " " $n
799ac8e35e1Smrg    }
800ac8e35e1Smrg    if (cpu_name != "") {
801ac8e35e1Smrg	cpu_isa[cpu_name] = flags
802ac8e35e1Smrg    } else if (arch_name != "") {
803ac8e35e1Smrg	arch_isa[arch_name] = flags
804ac8e35e1Smrg    } else  if (fpu_name != "") {
805ac8e35e1Smrg	fpu_isa[fpu_name] = flags
806ac8e35e1Smrg    } else fatal("\"isa\" outside of cpu, fpu or arch block")
807ac8e35e1Smrg    parse_ok = 1
808ac8e35e1Smrg}
809ac8e35e1Smrg
8108dd4bdcdSmrg/^[ 	]*option / {
8118dd4bdcdSmrg    if (NF < 4) fatal("syntax: option <name> add|remove <feature-or-fgroup>+")
8128dd4bdcdSmrg    name=$2
8138dd4bdcdSmrg    if ($3 == "add") {
8148dd4bdcdSmrg	remove = "false"
8158dd4bdcdSmrg    } else if ($3 == "remove") {
8168dd4bdcdSmrg	remove = "true"
8178dd4bdcdSmrg    } else fatal("syntax: option <name> add|remove isa-list")
8188dd4bdcdSmrg    flags=""
8198dd4bdcdSmrg    flag_count = NF
8208dd4bdcdSmrg    for (n = 4; n <= flag_count; n++) {
8218dd4bdcdSmrg	if (n == 4) {
8228dd4bdcdSmrg	    flags = $n
8238dd4bdcdSmrg	} else flags = flags " " $n
8248dd4bdcdSmrg    }
8258dd4bdcdSmrg    if (cpu_name != "") {
8268dd4bdcdSmrg	cpu_opts[cpu_name] = cpu_opts[cpu_name] " " name
8278dd4bdcdSmrg	cpu_opt_remove[cpu_name,name] = remove
8288dd4bdcdSmrg	cpu_opt_isa[cpu_name,name] = flags
8298dd4bdcdSmrg    } else if (arch_name != "") {
8308dd4bdcdSmrg	arch_opts[arch_name] = arch_opts[arch_name] " " name
8318dd4bdcdSmrg	arch_opt_remove[arch_name,name] = remove
8328dd4bdcdSmrg	arch_opt_isa[arch_name,name] = flags
8338dd4bdcdSmrg    } else fatal("\"option\" outside of cpu or arch block")
8348dd4bdcdSmrg    parse_ok = 1
8358dd4bdcdSmrg}
8368dd4bdcdSmrg
8378dd4bdcdSmrg/^[ 	]*optalias / {
8388dd4bdcdSmrg    if (NF != 3) fatal("syntax: optalias <name> <option-name>")
8398dd4bdcdSmrg    name=$2
8408dd4bdcdSmrg    alias=$3
8418dd4bdcdSmrg    if (cpu_name != "") {
8428dd4bdcdSmrg	cpu_optaliases[cpu_name] = cpu_optaliases[cpu_name] " " name
8438dd4bdcdSmrg	cpu_opt_alias[cpu_name,name] = alias
8448dd4bdcdSmrg    } else if (arch_name != "") {
8458dd4bdcdSmrg	arch_optaliases[arch_name] = arch_optaliases[arch_name] " " name
8468dd4bdcdSmrg	arch_opt_alias[arch_name,name] = alias
8478dd4bdcdSmrg    } else fatal("\"optalias\" outside of cpu or arch block")
8488dd4bdcdSmrg    parse_ok = 1
8498dd4bdcdSmrg}
8508dd4bdcdSmrg
851ac8e35e1Smrg/^[ 	]*costs / {
8528dd4bdcdSmrg    if (NF != 2) fatal("syntax: costs <identifier>")
853ac8e35e1Smrg    if (cpu_name == "") fatal("\"costs\" outside of cpu block")
854ac8e35e1Smrg    cpu_cost[cpu_name] = $2
855ac8e35e1Smrg    parse_ok = 1
856ac8e35e1Smrg}
857ac8e35e1Smrg
858760c2415Smrg/^[ 	]*vendor / {
859760c2415Smrg    if (NF != 2) fatal("syntax: vendor <vendor-id>")
860760c2415Smrg    if (cpu_name == "") fatal("\"vendor\" outside of cpu block")
861760c2415Smrg    cpu_vendor[cpu_name] = $2
862760c2415Smrg    vendor_ids[$2] = 1
863760c2415Smrg    parse_ok = 1
864760c2415Smrg}
865760c2415Smrg
866760c2415Smrg/^[ 	]*part / {
867760c2415Smrg    if (NF < 2 || NF > 4) fatal("syntax: part <part-id> [minrev [maxrev]]")
868760c2415Smrg    if (cpu_name == "") fatal("\"part\" outside of cpu block")
869760c2415Smrg    cpu_part[cpu_name] = $2
870760c2415Smrg    if (NF > 2) cpu_minrev[cpu_name] = $3
871760c2415Smrg    if (NF == 4) cpu_maxrev[cpu_name] = $4
872760c2415Smrg    parse_ok = 1
873760c2415Smrg}
874760c2415Smrg
875ac8e35e1Smrg/^end cpu / {
8768dd4bdcdSmrg    if (NF != 3) fatal("syntax: end cpu <name>")
877ac8e35e1Smrg    if (cpu_name != $3) fatal("mimatched end cpu")
878ac8e35e1Smrg    if (! (cpu_name in cpu_cnames)) {
879ac8e35e1Smrg	cpu_cnames[cpu_name] = cpu_name
880ac8e35e1Smrg	gsub(/[-+.]/, "_", cpu_cnames[cpu_name])
881ac8e35e1Smrg    }
8828dd4bdcdSmrg    if (! (cpu_name in cpu_arch)) fatal("cpu definition lacks an architecture")
883760c2415Smrg    if ((cpu_name in cpu_part) && !(cpu_name in cpu_vendor)) {
884760c2415Smrg	fatal("part number specified for " cpu_name " but no vendor")
885760c2415Smrg    }
886ac8e35e1Smrg    cpu_list = cpu_list " " cpu_name
887ac8e35e1Smrg    cpu_name = ""
888ac8e35e1Smrg    parse_ok = 1
889ac8e35e1Smrg}
890ac8e35e1Smrg
891ac8e35e1Smrg/[^\s]/ {
892ac8e35e1Smrg    if (! parse_ok) fatal("Unrecognized statement: " $0)
893ac8e35e1Smrg}
894ac8e35e1Smrg
895ac8e35e1SmrgEND {
8968dd4bdcdSmrg    parse_done = 1
8978dd4bdcdSmrg    if (fatal_err) exit 1
898ac8e35e1Smrg    toplevel()
899ac8e35e1Smrg    if (cmd == "data") {
900ac8e35e1Smrg	gen_data()
901ac8e35e1Smrg    } else if (cmd == "common-data") {
902ac8e35e1Smrg	gen_comm_data()
903760c2415Smrg    } else if (cmd == "native") {
904760c2415Smrg	gen_native()
905ac8e35e1Smrg    } else if (cmd == "headers") {
906ac8e35e1Smrg	gen_headers()
9078dd4bdcdSmrg    } else if (cmd == "isa") {
9088dd4bdcdSmrg	gen_isa()
909ac8e35e1Smrg    } else if (cmd == "md") {
910ac8e35e1Smrg	gen_md()
911ac8e35e1Smrg    } else if (cmd == "opt") {
912ac8e35e1Smrg	gen_opt()
913ac8e35e1Smrg    } else if (cmd ~ /^chk(cpu|tune) /) {
914ac8e35e1Smrg	split (cmd, target)
9158dd4bdcdSmrg	print check_cpu(target[2])
916ac8e35e1Smrg    } else if (cmd ~ /^chkarch /) {
917ac8e35e1Smrg	split (cmd, target)
9188dd4bdcdSmrg	print check_arch(target[2])
919ac8e35e1Smrg    } else if (cmd ~ /^chkfpu /) {
920ac8e35e1Smrg	split (cmd, target)
9218dd4bdcdSmrg	print check_fpu(target[2])
922ac8e35e1Smrg    } else fatal("unrecognized command: "cmd)
923ac8e35e1Smrg}
924