057a8033b3903aa74e05630a0bda5bf6c73a3eed
3 # Tool for canonical RISC-V architecture string.
4 # Copyright (C) 2011-2021 Free Software Foundation, Inc.
5 # Contributed by Andrew Waterman (andrew@sifive.com).
7 # This file is part of GCC.
9 # GCC is free software; you can redistribute it and/or modify
10 # it under the terms of the GNU General Public License as published by
11 # the Free Software Foundation; either version 3, or (at your option)
14 # GCC is distributed in the hope that it will be useful,
15 # but WITHOUT ANY WARRANTY; without even the implied warranty of
16 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 # GNU General Public License for more details.
19 # You should have received a copy of the GNU General Public License
20 # along with GCC; see the file COPYING3. If not see
21 # <http://www.gnu.org/licenses/>.
24 from __future__
import print_function
28 from functools
import reduce
31 CANONICAL_ORDER
= "mafdgqlcbjtpvn"
32 LONG_EXT_PREFIXES
= ['z', 's', 'h', 'x']
35 # IMPLIED_EXT(ext) -> implied extension list.
41 def arch_canonicalize(arch
):
42 # TODO: Support extension version.
44 if arch
[:5] in ['rv32e', 'rv32i', 'rv32g', 'rv64i', 'rv64g']:
45 # TODO: We should expand g to imad_zifencei once we support newer spec.
46 new_arch
= arch
[:5].replace("g", "imafd")
48 raise Exception("Unexpected arch: `%s`" % arch
[:5])
50 # Find any Z, S, H or X
51 long_ext_prefixes_idx
= map(lambda x
: arch
.find(x
), LONG_EXT_PREFIXES
)
53 # Filter out any non-existent index.
54 long_ext_prefixes_idx
= list(filter(lambda x
: x
!= -1, long_ext_prefixes_idx
))
55 if long_ext_prefixes_idx
:
56 first_long_ext_idx
= min(long_ext_prefixes_idx
)
57 long_exts
= arch
[first_long_ext_idx
:].split("_")
58 std_exts
= list(arch
[5:first_long_ext_idx
])
61 std_exts
= list(arch
[5:])
64 # Handle implied extensions.
66 for ext
in std_exts
+ long_exts
:
67 if ext
in IMPLIED_EXT
:
68 implied_exts
= IMPLIED_EXT
[ext
]
69 for implied_ext
in implied_exts
:
70 if implied_ext
not in std_exts
+ long_exts
:
71 long_exts
.append(implied_ext
)
73 # Single letter extension might appear in the long_exts list,
74 # becasue we just append extensions list to the arch string.
75 std_exts
+= list(filter(lambda x
:len(x
) == 1, long_exts
))
77 # Multi-letter extension must be in lexicographic order.
78 long_exts
= list(sorted(filter(lambda x
:len(x
) != 1, long_exts
)))
80 # Put extensions in canonical order.
81 for ext
in CANONICAL_ORDER
:
85 # Check every extension is processed.
89 if ext
not in CANONICAL_ORDER
:
90 raise Exception("Unsupported extension `%s`" % ext
)
92 # Concat rest of the multi-char extensions.
94 new_arch
+= "_" + "_".join(long_exts
)
98 print ("Usage: %s <arch_str> [<arch_str>*]" % sys
.argv
)
101 for arg
in sys
.argv
[1:]:
102 print (arch_canonicalize(arg
))