1 # Manipulate the CPU, FPU and architecture descriptions for ARM.
2 # Copyright (C) 2017-2018 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)
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 # 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
34 print "error ("lineno
"): " m
> "/dev/stderr"
36 if (parse_done
) exit 1
39 function 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\"")
45 function boilerplate
(style
) {
51 } else if (style ==
"md") {
54 } else if (style ==
"sh") {
57 } else fatal
("Unknown comment style: "style
)
59 print cs
"-*- buffer-read-only: t -*-"
61 print cc
"Generated automatically by parsecpu.awk from arm-cpus.in."
62 print cc
"Do not edit."
64 print cc
"Copyright (C) 2011-2018 Free Software Foundation, Inc."
66 print cc
"This file is part of GCC."
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."
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."
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
84 function tune_flag_pfx
(f
) {
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.
92 function print_isa_bits_for
(flist
, indent
) {
93 nbits =
split (flist
, bits
)
95 for (bit =
1; bit
<= nbits
; bit
++) {
96 if (bits
[bit
] in features
) {
98 } else if (bits
[bit
] in fgroup
) {
99 for (gbits in fgrp_bits
) {
100 split (gbits
, bitsep
, SUBSEP
)
101 if (bitsep
[1] == bits
[bit
]) {
105 } else fatal
("feature " bits
[bit
] " not declared")
109 print indent
"{\n" indent
" "
112 for (bname in pbit
) {
113 print "isa_bit_" bname
118 print "\n" indent
" "
123 print "isa_nobit\n" indent
"}"
128 function gen_headers
() {
131 print "enum processor_type"
134 ncpus =
split (cpu_list
, cpus
)
136 for (n =
1; n
<= ncpus
; n
++) {
137 print " TARGET_CPU_"cpu_cnames
[cpus
[n
]]","
139 print " TARGET_CPU_arm_none"
142 print "enum arch_type"
145 narchs =
split (arch_list
, archs
)
147 for (n =
1; n
<= narchs
; n
++) {
148 print " TARGET_ARCH_"arch_cnames
[archs
[n
]]","
150 print " TARGET_ARCH_arm_none"
153 print "enum fpu_type"
156 nfpus =
split (fpu_list
, fpus
)
158 for (n =
1; n
<= nfpus
; n
++) {
159 print " TARGET_FPU_"fpu_cnames
[fpus
[n
]]","
161 print " TARGET_FPU_auto"
165 function gen_isa
() {
167 print "enum isa_feature {"
168 print " isa_nobit = 0,"
169 for (fbit in features
) {
170 print " isa_bit_" fbit
","
172 print " isa_num_bits"
175 for (fgrp in fgroup
) {
176 print "#define ISA_"fgrp
" \\"
180 for (bitcomb in fgrp_bits
) {
181 split (bitcomb
, bitsep
, SUBSEP
)
182 if (bitsep
[1] == fgrp
) {
185 } else print ", \\\n"
186 print " isa_bit_" bitsep
[2]
194 function gen_data
() {
197 print "static const cpu_tune all_tunes[] ="
200 ncpus =
split (cpu_list
, cpus
)
202 for (n =
1; n
<= ncpus
; n
++) {
203 print " { /* " cpus
[n
] ". */"
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
]] \
210 print " TARGET_CPU_" cpu_cnames
[cpu_tune_for
[cpus
[n
]]] ","
212 print " TARGET_CPU_" cpu_cnames
[cpus
[n
]] ","
215 if (cpus
[n
] in cpu_tune_flags
) {
216 print " (" cpu_tune_flags
[cpus
[n
]] "),"
219 print " &arm_" cpu_cost
[cpus
[n
]] "_tune"
222 print " {TARGET_CPU_arm_none, 0, NULL}"
226 function gen_comm_data
() {
229 ncpus =
split (cpu_list
, cpus
)
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
++) {
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
]], " ")
243 if (cpus
[n
] in cpu_optaliases
) {
244 naliases =
split (cpu_optaliases
[cpus
[n
]], aliases
)
245 for (alias =
1; alias
<= naliases
; alias
++) {
247 cpu_opt_alias
[cpus
[n
],aliases
[alias
]]) in \
249 fatal
("Alias " aliases
[alias
] " target not defined " \
252 equiv=cpu_opt_alias
[cpus
[n
],aliases
[alias
]]
254 print " \"" aliases
[alias
] "\", " \
255 cpu_opt_remove
[cpus
[n
],equiv
] ", true, "
256 print_isa_bits_for
(cpu_opt_isa
[cpus
[n
],equiv
], " ")
260 print " { NULL, false, false, {isa_nobit}}"
265 print "const cpu_option all_cores[] ="
268 for (n =
1; n
<= ncpus
; n
++) {
272 print " \"" cpus
[n
] "\","
274 if (cpus
[n
] in cpu_opts
) {
275 print " cpu_opttab_" cpu_cnames
[cpus
[n
]] ","
276 } else print " NULL,"
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
])
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])
287 if (arch_opt_remove
[feats
[1],feats
[m
]] ==
"true") {
288 fatal
("cannot remove features from architecture specs")
290 all_isa_bits = all_isa_bits
" " arch_opt_isa
[feats
[1],feats
[m
]]
292 if (cpus
[n
] in cpu_fpu
) {
293 all_isa_bits = all_isa_bits
" " fpu_isa
[cpu_fpu
[cpus
[n
]]]
295 if (cpus
[n
] in cpu_isa
) {
296 all_isa_bits = all_isa_bits
" " cpu_isa
[cpus
[n
]]
298 print_isa_bits_for
(all_isa_bits
, " ")
301 print " TARGET_ARCH_" arch_cnames
[feats
[1]]
305 print " {{NULL, NULL, {isa_nobit}}, TARGET_ARCH_arm_none}"
308 narchs =
split (arch_list
, archs
)
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
++) {
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
]], " ")
322 if (archs
[n
] in arch_optaliases
) {
323 naliases =
split (arch_optaliases
[archs
[n
]], aliases
)
324 for (alias =
1; alias
<= naliases
; alias
++) {
326 arch_opt_alias
[archs
[n
],aliases
[alias
]]) in \
328 fatal
("Alias " aliases
[alias
] " target not defined " \
329 "for architecture " archs
[n
])
331 equiv=arch_opt_alias
[archs
[n
],aliases
[alias
]]
333 print " \"" aliases
[alias
] "\", " \
334 arch_opt_remove
[archs
[n
],equiv
] ", true, "
335 print_isa_bits_for
(arch_opt_isa
[archs
[n
],equiv
], " ")
339 print " { NULL, false, false, {isa_nobit}}"
341 } else if (archs
[n
] in arch_optaliases
) {
342 fatal
("Architecture " archs
[n
] " has option aliases but no options")
346 print "const arch_option all_architectures[] ="
349 for (n =
1; n
<= narchs
; n
++) {
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
])
356 print " \"" archs
[n
] "\","
358 if (archs
[n
] in arch_opts
) {
359 print " arch_opttab_" arch_cnames
[archs
[n
]] ","
360 } else print " NULL,"
362 print_isa_bits_for
(arch_isa
[archs
[n
]], " ")
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
]] "',"
374 print " TARGET_CPU_" cpu_cnames
[arch_tune_for
[archs
[n
]]] ","
378 print " {{NULL, NULL, {isa_nobit}},"
379 print " NULL, BASE_ARCH_0, 0, TARGET_CPU_arm_none}"
382 print "const arm_fpu_desc all_fpus[] ="
385 nfpus =
split (fpu_list
, fpus
)
387 for (n =
1; n
<= nfpus
; n
++) {
389 print " \"" fpus
[n
] "\","
390 print_isa_bits_for
(fpu_isa
[fpus
[n
]], " ")
402 print "(define_attr \"tune\"\n\t\""
404 ncpus =
split (cpu_list
, cpus
)
406 for (n =
1; n
< ncpus
; n
++) {
410 print cpu_cnames
[cpus
[n
]]
413 print cpu_cnames
[cpus
[ncpus
]]"\""
414 print "\t(const (symbol_ref \"((enum attr_tune) arm_tune)\")))"
417 function gen_opt
() {
421 print "Name(processor_type) Type(enum processor_type)"
422 print "Known ARM CPUs (for use with the -mcpu= and -mtune= options):\n"
424 ncpus =
split (cpu_list
, cpus
)
426 for (n =
1; n
<= ncpus
; n
++) {
428 print "Enum(processor_type) String(" cpus
[n
] \
429 ") Value( TARGET_CPU_"cpu_cnames
[cpus
[n
]]")"
434 print "Name(arm_arch) Type(int)"
435 print "Known ARM architectures (for use with the -march= option):\n"
437 narchs =
split (arch_list
, archs
)
439 for (n =
1; n
<= narchs
; n
++) {
441 print "Enum(arm_arch) String(" archs
[n
] \
447 print "Name(arm_fpu) Type(enum fpu_type)"
448 print "Known ARM FPUs (for use with the -mfpu= option):\n"
450 nfpus =
split (fpu_list
, fpus
)
452 for (n =
1; n
<= nfpus
; n
++) {
454 print "Enum(arm_fpu) String(" fpus
[n
] \
455 ") Value(TARGET_FPU_"fpu_cnames
[fpus
[n
]]")"
460 print "Enum(arm_fpu) String(auto) Value(TARGET_FPU_auto)"
463 function check_cpu
(name
) {
464 exts =
split (name
, extensions
, "+")
466 if (!
(extensions
[1] in cpu_cnames
)) {
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
)) {
479 function check_fpu
(name
) {
480 if (!
(name in fpu_cnames
)) {
483 return fpu_cnames
[name
]
486 function check_arch
(name
) {
487 exts =
split (name
, extensions
, "+")
489 if (!
(extensions
[1] in arch_isa
)) {
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
)) {
509 if (cmd ==
"") fatal
("Usage parsecpu.awk -v cmd=<xyz>")
512 # New line. Reset parse status and increment line count for error messages
518 # Comments must be on a line on their own.
524 if (NF != 3) fatal
("syntax: define feature <name>")
527 if (fbit in features
) fatal
("feature " fbit
" already defined")
533 if (NF < 4) fatal
("syntax: define fgroup <name> <feature> [<feature>]*")
536 if (fgrp in fgroup
) fatal
("feature group " fgrp
" already defined")
537 if (fgrp in features
) fatal
("feature group " fgrp
" aliases a feature")
539 for (n =
4; n
<= fcount
; 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
554 } else fatal
("feature group member " feat
" unrecognized")
561 if (NF != 3) fatal
("syntax: begin fpu <name>")
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")
573 fpu_cnames
[fpu_name
] = fpu_name
574 gsub(/[-+.
]/, "_", fpu_cnames
[fpu_name
])
575 fpu_list = fpu_list
" " fpu_name
581 if (NF != 3) fatal
("syntax: begin arch <name>")
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
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
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")
607 if (!
(arch_name in arch_isa
)) {
608 fatal
("arch definition lacks an \"isa\" statement")
610 arch_list = arch_list
" " arch_name
611 arch_cnames
[arch_name
] = arch_name
612 gsub(/[-+.
]/, "_", arch_cnames
[arch_name
])
618 if (NF != 3) fatal
("syntax: begin cpu <name>")
625 if (NF != 2) fatal
("syntax: cname <identifier>")
626 if (cpu_name ==
"") fatal
("\"cname\" outside of cpu block")
627 cpu_cnames
[cpu_name
] = $
2
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")
642 if (NF < 3) fatal
("syntax: tune flags <flag> [<flag>]*")
645 for (n =
3; n
<= flag_count
; n
++) {
647 flags = tune_flag_pfx
($n
)
648 } else flags = flags
" | " tune_flag_pfx
($n
)
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")
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
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
673 if (NF < 2) fatal
("syntax: isa <feature-or-fgroup> [<feature-or-fgroup>]*")
676 for (n =
2; n
<= flag_count
; n
++) {
679 } else flags = flags
" " $n
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")
692 if (NF < 4) fatal
("syntax: option <name> add|remove <feature-or-fgroup>+")
696 } else if ($
3 ==
"remove") {
698 } else fatal
("syntax: option <name> add|remove isa-list")
701 for (n =
4; n
<= flag_count
; n
++) {
704 } else flags = flags
" " $n
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")
719 if (NF != 3) fatal
("syntax: optalias <name> <option-name>")
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")
733 if (NF != 2) fatal
("syntax: costs <identifier>")
734 if (cpu_name ==
"") fatal
("\"costs\" outside of cpu block")
735 cpu_cost
[cpu_name
] = $
2
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
])
746 if (!
(cpu_name in cpu_arch
)) fatal
("cpu definition lacks an architecture")
747 cpu_list = cpu_list
" " cpu_name
753 if (! parse_ok
) fatal
("Unrecognized statement: " $
0)
758 if (fatal_err
) exit 1
762 } else if (cmd ==
"common-data") {
764 } else if (cmd ==
"headers") {
766 } else if (cmd ==
"isa") {
768 } else if (cmd ==
"md") {
770 } else if (cmd ==
"opt") {
772 } else if (cmd ~
/^chk
(cpu
|tune
) /) {
774 print check_cpu
(target
[2])
775 } else if (cmd ~
/^chkarch
/) {
777 print check_arch
(target
[2])
778 } else if (cmd ~
/^chkfpu
/) {
780 print check_fpu
(target
[2])
781 } else fatal
("unrecognized command: "cmd
)