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)
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-2017 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
) {
481 print fpu_cnames
[name
]
485 function check_arch
(name
) {
486 exts =
split (name
, extensions
, "+")
488 if (! extensions
[1] in arch_isa
) {
492 for (n =
2; n
<= exts
; n
++) {
493 if (!
((extensions
[1], extensions
[n
]) in arch_opt_remove
) \
494 && !
((extensions
[1], extensions
[n
]) in arch_optaliases
)) {
508 if (cmd ==
"") fatal
("Usage parsecpu.awk -v cmd=<xyz>")
511 # New line. Reset parse status and increment line count for error messages
517 # Comments must be on a line on their own.
523 if (NF != 3) fatal
("syntax: define feature <name>")
526 if (fbit in features
) fatal
("feature " fbit
" already defined")
532 if (NF < 4) fatal
("syntax: define fgroup <name> <feature> [<feature>]*")
535 if (fgrp in fgroup
) fatal
("feature group " fgrp
" already defined")
536 if (fgrp in features
) fatal
("feature group " fgrp
" aliases a feature")
538 for (n =
4; n
<= fcount
; n
++) {
540 if (feat in features
) {
541 fgrp_bits
[fgrp
,feat
] =
1
542 } else if (feat in fgroup
) {
543 # fgroups may reference other fgroups, copy their bits
544 # to our bits. To avoid recursion we don't set fgroup[fgrp]
545 # until after we have done this, so such attempts will result
546 # in an invalid group definition.
547 for (bitcomb in fgrp_bits
) {
548 split (bitcomb
, bitsep
, SUBSEP
)
549 if (bitsep
[1] == feat
) {
550 fgrp_bits
[fgrp
,bitsep
[2]] =
1
553 } else fatal
("feature group member " feat
" unrecognized")
560 if (NF != 3) fatal
("syntax: begin fpu <name>")
567 if (NF != 3) fatal
("syntax: end fpu <name>")
568 if (fpu_name
!= $
3) fatal
("mimatched end fpu")
569 if (!
(fpu_name in fpu_isa
)) {
570 fatal
("fpu definition \"" fpu_name
"\" lacks an \"isa\" statement")
572 fpu_cnames
[fpu_name
] = fpu_name
573 gsub(/[-+.
]/, "_", fpu_cnames
[fpu_name
])
574 fpu_list = fpu_list
" " fpu_name
580 if (NF != 3) fatal
("syntax: begin arch <name>")
587 if (NF != 2) fatal
("syntax: base <architecture-base-name>")
588 if (arch_name ==
"") fatal
("\"base\" statement outside of arch block")
589 arch_base
[arch_name
] = $
2
594 if (NF != 2) fatal
("syntax: profile <profile-name>")
595 if (arch_name ==
"") fatal
("\"profile\" statement outside of arch block")
596 arch_prof
[arch_name
] = $
2
601 if (NF != 3) fatal
("syntax: end arch <name>")
602 if (arch_name
!= $
3) fatal
("mimatched end arch")
603 if (! arch_name in arch_tune_for
) {
604 fatal
("arch definition lacks a \"tune for\" statement")
606 if (! arch_name in arch_isa
) {
607 fatal
("arch definition lacks an \"isa\" statement")
609 arch_list = arch_list
" " arch_name
610 arch_cnames
[arch_name
] = arch_name
611 gsub(/[-+.
]/, "_", arch_cnames
[arch_name
])
617 if (NF != 3) fatal
("syntax: begin cpu <name>")
624 if (NF != 2) fatal
("syntax: cname <identifier>")
625 if (cpu_name ==
"") fatal
("\"cname\" outside of cpu block")
626 cpu_cnames
[cpu_name
] = $
2
631 if (NF != 3) fatal
("syntax: tune for <cpu-name>")
632 if (cpu_name
!= "") {
633 cpu_tune_for
[cpu_name
] = $
3
634 } else if (arch_name
!= "") {
635 arch_tune_for
[arch_name
] = $
3
636 } else fatal
("\"tune for\" outside of cpu or arch block")
641 if (NF < 3) fatal
("syntax: tune flags <flag> [<flag>]*")
644 for (n =
3; n
<= flag_count
; n
++) {
646 flags = tune_flag_pfx
($n
)
647 } else flags = flags
" | " tune_flag_pfx
($n
)
649 if (cpu_name
!= "") {
650 cpu_tune_flags
[cpu_name
] = flags
651 } else if (arch_name
!= "") {
652 arch_tune_flags
[arch_name
] = flags
653 } else fatal
("\"tune flags\" outside of cpu or arch block")
657 /^
[ ]*architecture
/ {
658 if (NF != 2) fatal
("syntax: architecture <arch-name>")
659 if (cpu_name ==
"") fatal
("\"architecture\" outside of cpu block")
660 cpu_arch
[cpu_name
] = $
2
665 if (NF != 2) fatal
("syntax: fpu <fpu-name>")
666 if (cpu_name ==
"") fatal
("\"fpu\" outside of cpu block")
667 cpu_fpu
[cpu_name
] = $
2
672 if (NF < 2) fatal
("syntax: isa <feature-or-fgroup> [<feature-or-fgroup>]*")
675 for (n =
2; n
<= flag_count
; n
++) {
678 } else flags = flags
" " $n
680 if (cpu_name
!= "") {
681 cpu_isa
[cpu_name
] = flags
682 } else if (arch_name
!= "") {
683 arch_isa
[arch_name
] = flags
684 } else if (fpu_name
!= "") {
685 fpu_isa
[fpu_name
] = flags
686 } else fatal
("\"isa\" outside of cpu, fpu or arch block")
691 if (NF < 4) fatal
("syntax: option <name> add|remove <feature-or-fgroup>+")
695 } else if ($
3 ==
"remove") {
697 } else fatal
("syntax: option <name> add|remove isa-list")
700 for (n =
4; n
<= flag_count
; n
++) {
703 } else flags = flags
" " $n
705 if (cpu_name
!= "") {
706 cpu_opts
[cpu_name
] = cpu_opts
[cpu_name
] " " name
707 cpu_opt_remove
[cpu_name
,name
] = remove
708 cpu_opt_isa
[cpu_name
,name
] = flags
709 } else if (arch_name
!= "") {
710 arch_opts
[arch_name
] = arch_opts
[arch_name
] " " name
711 arch_opt_remove
[arch_name
,name
] = remove
712 arch_opt_isa
[arch_name
,name
] = flags
713 } else fatal
("\"option\" outside of cpu or arch block")
718 if (NF != 3) fatal
("syntax: optalias <name> <option-name>")
721 if (cpu_name
!= "") {
722 cpu_optaliases
[cpu_name
] = cpu_optaliases
[cpu_name
] " " name
723 cpu_opt_alias
[cpu_name
,name
] = alias
724 } else if (arch_name
!= "") {
725 arch_optaliases
[arch_name
] = arch_optaliases
[arch_name
] " " name
726 arch_opt_alias
[arch_name
,name
] = alias
727 } else fatal
("\"optalias\" outside of cpu or arch block")
732 if (NF != 2) fatal
("syntax: costs <identifier>")
733 if (cpu_name ==
"") fatal
("\"costs\" outside of cpu block")
734 cpu_cost
[cpu_name
] = $
2
739 if (NF != 3) fatal
("syntax: end cpu <name>")
740 if (cpu_name
!= $
3) fatal
("mimatched end cpu")
741 if (!
(cpu_name in cpu_cnames
)) {
742 cpu_cnames
[cpu_name
] = cpu_name
743 gsub(/[-+.
]/, "_", cpu_cnames
[cpu_name
])
745 if (! cpu_name in cpu_arch
) fatal
("cpu definition lacks an architecture")
746 cpu_list = cpu_list
" " cpu_name
752 if (! parse_ok
) fatal
("Unrecognized statement: " $
0)
757 if (fatal_err
) exit 1
761 } else if (cmd ==
"common-data") {
763 } else if (cmd ==
"headers") {
765 } else if (cmd ==
"isa") {
767 } else if (cmd ==
"md") {
769 } else if (cmd ==
"opt") {
771 } else if (cmd ~
/^chk
(cpu
|tune
) /) {
773 print check_cpu
(target
[2])
774 } else if (cmd ~
/^chkarch
/) {
776 print check_arch
(target
[2])
777 } else if (cmd ~
/^chkfpu
/) {
780 } else fatal
("unrecognized command: "cmd
)