7fc6cc2caa7dc90acca2fd650365cdd7fe78cae1
3 # RISC-V multilib list generator.
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/>.
23 # Each argument to this script is of the form
24 # <primary arch>-<abi>-<additional arches>-<extensions>
26 # rv32imafd-ilp32d-rv32g-c,v
27 # means that, in addition to rv32imafd, these configurations can also use the
28 # rv32imafd-ilp32d libraries: rv32imafdc, rv32imafdv, rv32g, rv32gc, rv32gv
31 # rv32imafd-ilp32d--c*b
32 # means that, in addition to rv32imafd, these configurations can also use the
33 # rv32imafd-ilp32d libraries: rv32imafdc-ilp32d, rv32imafdb-ilp32d,
36 from __future__
import print_function
41 from functools
import reduce
45 # TODO: Add test for this script.
48 arches
= collections
.OrderedDict()
49 abis
= collections
.OrderedDict()
53 def arch_canonicalize(arch
):
54 this_file
= os
.path
.abspath(os
.path
.join( __file__
))
56 os
.path
.join(os
.path
.dirname(this_file
), "arch-canonicalize")
57 proc
= subprocess
.Popen([sys
.executable
, arch_can_script
, arch
],
58 stdout
=subprocess
.PIPE
)
59 out
, err
= proc
.communicate()
60 return out
.decode().strip()
63 # Handle expansion operation.
65 # e.g. "a*b" -> [("a",), ("b",), ("a", "b")]
68 def _expand_combination(ext
):
69 exts
= list(ext
.split("*"))
71 # No need to expand if there is no `*`.
75 # Add underline to every extension.
77 # _b * zvamo => _b * _zvamo
78 exts
= list(map(lambda x
: '_' + x
, exts
))
80 # Generate combination!
82 for comb_len
in range(1, len(exts
)+1):
83 for ext_comb
in itertools
.combinations(exts
, comb_len
):
84 ext_combs
.append(ext_comb
)
89 # Input a list and drop duplicated entry.
91 # ["a", "b", "ab", "a"] -> ["a", "b", "ab"]
95 # Drop duplicated entry.
96 # Convert list to set and then convert back to list.
98 # Add sorted to prevent non-deterministic results in different env.
100 return list(sorted(list(set(x
))))
103 # Expand EXT string if there is any expansion operator (*).
105 # "a*b,c" -> ["a", "b", "ab", "c"]
107 def expand_combination(ext
):
108 ext
= list(filter(None, ext
.split(',')))
110 # Expand combination for EXT, got lots of list.
112 # a * b => [[("a",), ("b",)], [("a", "b")]]
113 ext_combs
= list(map(_expand_combination
, ext
))
115 # Then fold to single list.
117 # [[("a",), ("b",)], [("a", "b")]] => [("a",), ("b",), ("a", "b")]
118 ext
= list(reduce(lambda x
, y
: x
+ y
, ext_combs
, []))
120 # Fold the tuple to string.
122 # [("a",), ("b",), ("a", "b")] => ["a", "b", "ab"]
123 ext
= map(lambda e
: reduce(lambda x
, y
: x
+ y
, e
), ext
)
125 # Drop duplicated entry.
130 for cfg
in sys
.argv
[1:]:
132 (arch
, abi
, extra
, ext
) = cfg
.split('-')
134 print ("Invalid configure string %s, <arch>-<abi>-<extra>-<extensions>\n"
135 "<extra> and <extensions> can be empty, "
136 "e.g. rv32imafd-ilp32--" % cfg
)
139 arch
= arch_canonicalize (arch
)
142 extra
= list(filter(None, extra
.split(',')))
143 ext_combs
= expand_combination(ext
)
144 alts
= sum([[x
] + [x
+ y
for y
in ext_combs
] for x
in [arch
] + extra
], [])
145 alts
= list(map(arch_canonicalize
, alts
))
147 # Drop duplicated entry.
152 reuse
.append('march.%s/mabi.%s=march.%s/mabi.%s' % (arch
, abi
, alt
, abi
))
153 required
.append('march=%s/mabi=%s' % (arch
, abi
))
155 arch_options
= '/'.join(['march=%s' % x
for x
in arches
.keys()])
156 arch_dirnames
= ' \\\n'.join(arches
.keys())
158 abi_options
= '/'.join(['mabi=%s' % x
for x
in abis
.keys()])
159 abi_dirnames
= ' \\\n'.join(abis
.keys())
161 prog
= sys
.argv
[0].split('/')[-1]
162 print('# This file was generated by %s with the command:' % prog
)
163 print('# %s' % ' '.join(sys
.argv
))
165 print('MULTILIB_OPTIONS = %s %s' % (arch_options
, abi_options
))
166 print('MULTILIB_DIRNAMES = %s %s' % (arch_dirnames
, abi_dirnames
))
167 print('MULTILIB_REQUIRED = %s' % ' \\\n'.join(required
))
168 print('MULTILIB_REUSE = %s' % ' \\\n'.join(reuse
))