[arm] Fix bootstrap - missing initializer in tail entry of autogenerated code
[official-gcc.git] / gcc / config / arm / parsecpu.awk
blobd096bca33b31cc6dcd2c22e3fd31592cb8ffb84c
1 # Manipulate the CPU, FPU and architecture descriptions for ARM.
2 # Copyright (C) 2017 Free Software Foundation, Inc.
4 # This file is part of GCC.
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.
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.
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/>.
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 # md: Print the machine description fragment
26 # opt: Print the option tables fragment
27 # chkcpu <name>: Checks that <name> is a valid CPU
28 # chktune <name>: Checks that <name> is a valid CPU
29 # chkfpu <name>: Checks that <name> is a valid FPU
30 # chkarch <name>: Checks that <arch> is a valid architecture
32 function fatal (m) {
33 print "error ("lineno"): " m > "/dev/stderr"
34 exit 1
37 function toplevel () {
38 if (cpu_name != "") fatal("missing \"end cpu\"")
39 if (arch_name != "") fatal("missing \"end arch\"")
40 if (fpu_name != "") fatal("missing \"end fpu\"")
43 function boilerplate (style) {
44 ce = ""
45 if (style == "C" ) {
46 cs = "/* "
47 cc = " "
48 ce = " */"
49 } else if (style == "md") {
50 cc = "; "
51 cs = cc
52 } else if (style == "sh") {
53 cc = "# "
54 cs = cc
55 } else fatal("Unknown comment style: "style)
57 print cs "-*- buffer-read-only: t -*-"
59 print cc "Generated automatically by parsecpu.awk from arm-cpus.in."
60 print cc "Do not edit."
61 print ""
62 print cc "Copyright (C) 2011-2017 Free Software Foundation, Inc."
63 print ""
64 print cc "This file is part of GCC."
65 print ""
66 print cc "GCC is free software; you can redistribute it and/or modify"
67 print cc "it under the terms of the GNU General Public License as"
68 print cc "published by the Free Software Foundation; either version 3,"
69 print cc "or (at your option) any later version."
70 print ""
71 print cc "GCC is distributed in the hope that it will be useful,"
72 print cc "but WITHOUT ANY WARRANTY; without even the implied warranty of"
73 print cc "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the"
74 print cc "GNU General Public License for more details."
75 print ""
76 print cc "You should have received a copy of the GNU General Public"
77 print cc "License along with GCC; see the file COPYING3. If not see"
78 print cc "<http://www.gnu.org/licenses/>." ce
79 print ""
82 function tune_flag_pfx (f) {
83 return "TF_" f
86 function isa_pfx (f) {
87 if (f ~ /^(bit|quirk)_.*/) return "isa_" f
88 return "ISA_" f
91 function gen_headers () {
92 boilerplate("C")
94 print "enum processor_type"
95 print "{"
97 ncpus = split (cpu_list, cpus)
99 for (n = 1; n <= ncpus; n++) {
100 print " TARGET_CPU_"cpu_cnames[cpus[n]]","
102 print " TARGET_CPU_arm_none"
103 print "};\n"
105 print "enum arch_type"
106 print "{"
108 narchs = split (arch_list, archs)
110 for (n = 1; n <= narchs; n++) {
111 print " TARGET_ARCH_"arch_cnames[archs[n]]","
113 print " TARGET_ARCH_arm_none"
114 print "};\n"
116 print "enum fpu_type"
117 print "{"
119 nfpus = split (fpu_list, fpus)
121 for (n = 1; n <= nfpus; n++) {
122 print " TARGET_FPU_"fpu_cnames[fpus[n]]","
124 print " TARGET_FPU_auto"
125 print "};"
128 function gen_data () {
129 boilerplate("C")
131 print "static const cpu_tune all_tunes[] ="
132 print "{"
134 ncpus = split (cpu_list, cpus)
136 for (n = 1; n <= ncpus; n++) {
137 print " { /* " cpus[n] ". */"
138 # scheduler
139 if (cpus[n] in cpu_tune_for) {
140 if (! (cpu_tune_for[cpus[n]] in cpu_cnames)) {
141 fatal("unknown \"tune for\" target " cpu_tune_for[cpus[n]] \
142 " for CPU " cpus[n])
144 print " TARGET_CPU_" cpu_cnames[cpu_tune_for[cpus[n]]] ","
145 } else {
146 print " TARGET_CPU_" cpu_cnames[cpus[n]] ","
148 # tune_flags
149 if (cpus[n] in cpu_tune_flags) {
150 print " (" cpu_tune_flags[cpus[n]] "),"
151 } else print " 0,"
152 # tune
153 print " &arm_" cpu_cost[cpus[n]] "_tune"
154 print " },"
156 print " {TARGET_CPU_arm_none, 0, NULL}"
157 print "};"
161 function gen_comm_data () {
162 boilerplate("C")
164 ncpus = split (cpu_list, cpus)
166 for (n = 1; n <= ncpus; n++) {
167 if (cpus[n] in cpu_opts) {
168 print "static const cpu_arch_extension cpu_opttab_" \
169 cpu_cnames[cpus[n]] "[] = {"
170 nopts = split (cpu_opts[cpus[n]], opts)
171 for (opt = 1; opt <= nopts; opt++) {
172 print " {"
173 print " \"" opts[opt] "\", " \
174 cpu_opt_remove[cpus[n],opts[opt]] ", false,"
175 print " { " cpu_opt_isa[cpus[n],opts[opt]] ", isa_nobit }"
176 print " },"
178 if (cpus[n] in cpu_optaliases) {
179 naliases = split (cpu_optaliases[cpus[n]], aliases)
180 for (alias = 1; alias <= naliases; alias++) {
181 if (! ((cpus[n], \
182 cpu_opt_alias[cpus[n],aliases[alias]]) in \
183 cpu_opt_isa)) {
184 fatal("Alias " aliases[alias] " target not defined " \
185 "for CPU " cpus[n])
187 equiv=cpu_opt_alias[cpus[n],aliases[alias]]
188 print " {"
189 print " \"" aliases[alias] "\", " \
190 cpu_opt_remove[cpus[n],equiv] ", true, "
191 print " { " cpu_opt_isa[cpus[n],equiv] ", isa_nobit }"
192 print " },"
195 print " { NULL, false, false, {isa_nobit}}"
196 print "};\n"
200 print "const cpu_option all_cores[] ="
201 print "{"
203 for (n = 1; n <= ncpus; n++) {
204 print " {"
205 print " {"
206 # common.name
207 print " \"" cpus[n] "\","
208 # common.extensions
209 if (cpus[n] in cpu_opts) {
210 print " cpu_opttab_" cpu_cnames[cpus[n]] ","
211 } else print " NULL,"
212 # common.isa_bits
213 nfeats = split (cpu_arch[cpus[n]], feats, "+")
214 if (! (feats[1] in arch_isa)) {
215 fatal("unknown arch " feats[1] " for cpu " cpus[n])
217 print " {"
218 print " " arch_isa[feats[1]] ","
219 for (m = 2; m <= nfeats; m++) {
220 if (! ((feats[1], feats[m]) in arch_opt_isa)) {
221 fatal("unknown feature " feats[m] " for architecture " feats[1])
223 if (arch_opt_remove[feats[1],feats[m]] == "true") {
224 fatal("cannot remove features from architecture specs")
226 print " " arch_opt_isa[feats[1],feats[m]] ","
228 if (cpus[n] in cpu_fpu) print " " fpu_isa[cpu_fpu[cpus[n]]] ","
229 if (cpus[n] in cpu_isa) print " " cpu_isa[cpus[n]] ","
230 print " isa_nobit"
231 print " }"
232 print " },"
233 # arch
234 print " TARGET_ARCH_" arch_cnames[feats[1]]
235 print " },"
238 print " {{NULL, NULL, {isa_nobit}}, TARGET_ARCH_arm_none}"
239 print "};"
241 narchs = split (arch_list, archs)
243 for (n = 1; n <= narchs; n++) {
244 if (archs[n] in arch_opts) {
245 print "static const struct cpu_arch_extension arch_opttab_" \
246 arch_cnames[archs[n]] "[] = {"
247 nopts = split (arch_opts[archs[n]], opts)
248 for (opt = 1; opt <= nopts; opt++) {
249 print " {"
250 print " \"" opts[opt] "\", " \
251 arch_opt_remove[archs[n],opts[opt]] ", false,"
252 print " { " arch_opt_isa[archs[n],opts[opt]] ", isa_nobit }"
253 print " },"
255 if (archs[n] in arch_optaliases) {
256 naliases = split (arch_optaliases[archs[n]], aliases)
257 for (alias = 1; alias <= naliases; alias++) {
258 if (! ((archs[n], \
259 arch_opt_alias[archs[n],aliases[alias]]) in \
260 arch_opt_isa)) {
261 fatal("Alias " aliases[alias] " target not defined " \
262 "for architecture " archs[n])
264 equiv=arch_opt_alias[archs[n],aliases[alias]]
265 print " {"
266 print " \"" aliases[alias] "\", " \
267 arch_opt_remove[archs[n],equiv] ", true, "
268 print " { " arch_opt_isa[archs[n],equiv] ", isa_nobit }"
269 print " },"
272 print " { NULL, false, false, {isa_nobit}}"
273 print "};\n"
274 } else if (archs[n] in arch_optaliases) {
275 fatal("Architecture " archs[n] " has option aliases but no options")
279 print "const arch_option all_architectures[] ="
280 print "{"
282 for (n = 1; n <= narchs; n++) {
283 print " {"
284 if (! (arch_tune_for[archs[n]] in cpu_cnames)) {
285 fatal("unknown \"tune for\" target " arch_tune_for[archs[n]] \
286 " for architecture " archs[n])
288 # common.name
289 print " \"" archs[n] "\","
290 # common.extensions
291 if (archs[n] in arch_opts) {
292 print " arch_opttab_" arch_cnames[archs[n]] ","
293 } else print " NULL,"
294 # common.isa_bits
295 print " {"
296 print " " arch_isa[archs[n]] ","
297 print " isa_nobit"
298 print " },"
299 # arch, base_arch
300 print " \"" arch_base[archs[n]] "\", BASE_ARCH_" \
301 arch_base[archs[n]] ","
302 # profile letter code, or zero if none.
303 if (archs[n] in arch_prof) {
304 print " \'" arch_prof[archs[n]] "\',"
305 } else {
306 print " 0,"
308 # tune_id
309 print " TARGET_CPU_" cpu_cnames[arch_tune_for[archs[n]]] ","
310 print " },"
313 print " {{NULL, NULL, {isa_nobit}},"
314 print " NULL, BASE_ARCH_0, 0, TARGET_CPU_arm_none}"
315 print "};\n"
317 print "const arm_fpu_desc all_fpus[] ="
318 print "{"
320 nfpus = split (fpu_list, fpus)
322 for (n = 1; n <= nfpus; n++) {
323 print " {"
324 print " \"" fpus[n] "\","
325 print " {"
326 print " " fpu_isa[fpus[n]] ","
327 print " isa_nobit"
328 print " }"
329 print " },"
332 print "};"
335 function gen_md () {
336 boilerplate("md")
338 z = ORS
339 ORS = ""
340 print "(define_attr \"tune\"\n\t\""
342 ncpus = split (cpu_list, cpus)
344 for (n = 1; n < ncpus; n++) {
345 if ((n % 3) != 0) {
346 ORS = ","
347 } else ORS = ",\n\t"
348 print cpu_cnames[cpus[n]]
350 ORS = z
351 print cpu_cnames[cpus[ncpus]]"\""
352 print "\t(const (symbol_ref \"((enum attr_tune) arm_tune)\")))"
355 function gen_opt () {
356 boilerplate("md")
358 print "Enum"
359 print "Name(processor_type) Type(enum processor_type)"
360 print "Known ARM CPUs (for use with the -mcpu= and -mtune= options):\n"
362 ncpus = split (cpu_list, cpus)
364 for (n = 1; n <= ncpus; n++) {
365 print "EnumValue"
366 print "Enum(processor_type) String(" cpus[n] \
367 ") Value( TARGET_CPU_"cpu_cnames[cpus[n]]")"
368 print ""
371 print "Enum"
372 print "Name(arm_arch) Type(int)"
373 print "Known ARM architectures (for use with the -march= option):\n"
375 narchs = split (arch_list, archs)
377 for (n = 1; n <= narchs; n++) {
378 print "EnumValue"
379 print "Enum(arm_arch) String(" archs[n] \
380 ") Value("n - 1")"
381 print ""
384 print "Enum"
385 print "Name(arm_fpu) Type(enum fpu_type)"
386 print "Known ARM FPUs (for use with the -mfpu= option):\n"
388 nfpus = split (fpu_list, fpus)
390 for (n = 1; n <= nfpus; n++) {
391 print "EnumValue"
392 print "Enum(arm_fpu) String(" fpus[n] \
393 ") Value(TARGET_FPU_"fpu_cnames[fpus[n]]")"
394 print ""
397 print "EnumValue"
398 print "Enum(arm_fpu) String(auto) Value(TARGET_FPU_auto)"
401 function check_cpu (name) {
402 exts = split (name, extensions, "+")
404 if (! extensions[1] in cpu_cnames) {
405 return "error"
408 for (n = 2; n <= exts; n++) {
409 if (!((extensions[1], extensions[n]) in cpu_opt_remove) \
410 && !((extensions[1], extensions[n]) in cpu_optaliases)) {
411 return "error"
414 return name
417 function check_fpu (name) {
418 if (name in fpu_cnames) {
419 print fpu_cnames[name]
420 } else print "error"
423 function check_arch (name) {
424 exts = split (name, extensions, "+")
426 if (! extensions[1] in arch_isa) {
427 return "error"
430 for (n = 2; n <= exts; n++) {
431 if (!((extensions[1], extensions[n]) in arch_opt_remove) \
432 && !((extensions[1], extensions[n]) in arch_optaliases)) {
433 return "error"
436 return name
439 BEGIN {
440 cpu_name = ""
441 arch_name = ""
442 fpu_name = ""
443 lineno = 0
444 if (cmd == "") fatal("Usage parsecpu.awk -v cmd=<xyz>")
447 // {
448 lineno++
449 parse_ok = 0
452 /^#/ {
453 parse_ok = 1
456 /^begin fpu / {
457 toplevel()
458 fpu_name = $3
459 parse_ok = 1
462 /^end fpu / {
463 if (fpu_name != $3) fatal("mimatched end fpu")
464 if (! (fpu_name in fpu_isa)) {
465 fatal("fpu definition \"" fpu_name "\" lacks an \"isa\" statement")
467 fpu_cnames[fpu_name] = fpu_name
468 gsub(/[-+.]/, "_", fpu_cnames[fpu_name])
469 fpu_list = fpu_list " " fpu_name
470 fpu_name = ""
471 parse_ok = 1
474 /^begin arch / {
475 toplevel()
476 arch_name = $3
477 parse_ok = 1
480 /^[ ]*base / {
481 if (arch_name == "") fatal("\"base\" statement outside of arch block")
482 arch_base[arch_name] = $2
483 parse_ok = 1
486 /^[ ]*profile / {
487 if (arch_name == "") fatal("\"profile\" statement outside of arch block")
488 arch_prof[arch_name] = $2
489 parse_ok = 1
492 /^end arch / {
493 if (arch_name != $3) fatal("mimatched end arch")
494 if (! arch_name in arch_tune_for) {
495 fatal("arch definition lacks a \"tune for\" statement")
497 if (! arch_name in arch_isa) {
498 fatal("arch definition lacks an \"isa\" statement")
500 arch_list = arch_list " " arch_name
501 arch_cnames[arch_name] = arch_name
502 gsub(/[-+.]/, "_", arch_cnames[arch_name])
503 arch_name = ""
504 parse_ok = 1
507 /^begin cpu / {
508 toplevel()
509 cpu_name = $3
510 parse_ok = 1
513 /^[ ]*cname / {
514 if (cpu_name == "") fatal("\"cname\" outside of cpu block")
515 cpu_cnames[cpu_name] = $2
516 parse_ok = 1
519 /^[ ]*tune for / {
520 if (cpu_name != "") {
521 cpu_tune_for[cpu_name] = $3
522 } else if (arch_name != "") {
523 arch_tune_for[arch_name] = $3
524 } else fatal("\"tune for\" outside of cpu or arch block")
525 parse_ok = 1
528 /^[ ]*tune flags / {
529 flags=""
530 flag_count = NF
531 for (n = 3; n <= flag_count; n++) {
532 if (n == 3) {
533 flags = tune_flag_pfx($n)
534 } else flags = flags " | " tune_flag_pfx($n)
536 if (cpu_name != "") {
537 cpu_tune_flags[cpu_name] = flags
538 } else if (arch_name != "") {
539 arch_tune_flags[arch_name] = flags
540 } else fatal("\"tune flags\" outside of cpu or arch block")
541 parse_ok = 1
544 /^[ ]*architecture / {
545 if (cpu_name == "") fatal("\"architecture\" outside of cpu block")
546 cpu_arch[cpu_name] = $2
547 parse_ok = 1
550 /^[ ]*fpu / {
551 if (cpu_name == "") fatal("\"fpu\" outside of cpu block")
552 cpu_fpu[cpu_name] = $2
553 parse_ok = 1
556 /^[ ]*isa / {
557 flags=""
558 flag_count = NF
559 for (n = 2; n <= flag_count; n++) {
560 if (n == 2) {
561 flags = isa_pfx($n)
562 } else flags = flags "," isa_pfx($n)
564 if (cpu_name != "") {
565 cpu_isa[cpu_name] = flags
566 } else if (arch_name != "") {
567 arch_isa[arch_name] = flags
568 } else if (fpu_name != "") {
569 fpu_isa[fpu_name] = flags
570 } else fatal("\"isa\" outside of cpu, fpu or arch block")
571 parse_ok = 1
574 /^[ ]*option / {
575 name=$2
576 if ($3 == "add") {
577 remove = "false"
578 } else if ($3 == "remove") {
579 remove = "true"
580 } else fatal("syntax: option <name> add|remove isa-list")
581 flags=""
582 flag_count = NF
583 for (n = 4; n <= flag_count; n++) {
584 if (n == 4) {
585 flags = isa_pfx($n)
586 } else flags = flags "," isa_pfx($n)
588 if (cpu_name != "") {
589 cpu_opts[cpu_name] = cpu_opts[cpu_name] " " name
590 cpu_opt_remove[cpu_name,name] = remove
591 cpu_opt_isa[cpu_name,name] = flags
592 } else if (arch_name != "") {
593 arch_opts[arch_name] = arch_opts[arch_name] " " name
594 arch_opt_remove[arch_name,name] = remove
595 arch_opt_isa[arch_name,name] = flags
596 } else fatal("\"option\" outside of cpu or arch block")
597 parse_ok = 1
600 /^[ ]*optalias / {
601 name=$2
602 alias=$3
603 if (cpu_name != "") {
604 cpu_optaliases[cpu_name] = cpu_optaliases[cpu_name] " " name
605 cpu_opt_alias[cpu_name,name] = alias
606 } else if (arch_name != "") {
607 arch_optaliases[arch_name] = arch_optaliases[arch_name] " " name
608 arch_opt_alias[arch_name,name] = alias
609 } else fatal("\"optalias\" outside of cpu or arch block")
610 parse_ok = 1
613 /^[ ]*costs / {
614 if (cpu_name == "") fatal("\"costs\" outside of cpu block")
615 cpu_cost[cpu_name] = $2
616 parse_ok = 1
619 /^end cpu / {
620 if (cpu_name != $3) fatal("mimatched end cpu")
621 if (! (cpu_name in cpu_cnames)) {
622 cpu_cnames[cpu_name] = cpu_name
623 gsub(/[-+.]/, "_", cpu_cnames[cpu_name])
625 if (! cpu_name in cpu_arch) fatal("cpu definition lacks an architecture")
626 cpu_list = cpu_list " " cpu_name
627 cpu_name = ""
628 parse_ok = 1
631 /[^\s]/ {
632 if (! parse_ok) fatal("Unrecognized statement: " $0)
635 END {
636 toplevel()
637 if (cmd == "data") {
638 gen_data()
639 } else if (cmd == "common-data") {
640 gen_comm_data()
641 } else if (cmd == "headers") {
642 gen_headers()
643 } else if (cmd == "md") {
644 gen_md()
645 } else if (cmd == "opt") {
646 gen_opt()
647 } else if (cmd ~ /^chk(cpu|tune) /) {
648 split (cmd, target)
649 print check_cpu(target[2])
650 } else if (cmd ~ /^chkarch /) {
651 split (cmd, target)
652 print check_arch(target[2])
653 } else if (cmd ~ /^chkfpu /) {
654 split (cmd, target)
655 check_fpu(target[2])
656 } else fatal("unrecognized command: "cmd)