1#!/usr/bin/env python 2 3# RISC-V multilib list generator. 4# Copyright (C) 2011-2020 Free Software Foundation, Inc. 5# Contributed by Andrew Waterman (andrew@sifive.com). 6# 7# This file is part of GCC. 8# 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) 12# any later version. 13# 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. 18# 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/>. 22 23# Each argument to this script is of the form 24# <primary arch>-<abi>-<additional arches>-<extensions> 25# For example, 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 29 30from __future__ import print_function 31import sys 32import collections 33 34arches = collections.OrderedDict() 35abis = collections.OrderedDict() 36required = [] 37reuse = [] 38 39canonical_order = "mafdgqlcbjtpvn" 40 41def arch_canonicalize(arch): 42 # TODO: Support Z, S, H, or X extensions. 43 # TODO: Support implied extensions, e.g. D implied F in latest spec. 44 # TODO: Support extension version. 45 new_arch = "" 46 if arch[:5] in ['rv32e', 'rv32i', 'rv32g', 'rv64i', 'rv64g']: 47 new_arch = arch[:5] 48 else: 49 raise Exception("Unexpected arch: `%s`" % arch[:5]) 50 51 # Find any Z, S, H or X 52 long_ext_prefixes = ['z', 's', 'h', 'x'] 53 long_ext_prefixes_idx = map(lambda x: arch.find(x), long_ext_prefixes) 54 55 # Filter out any non-existent index. 56 long_ext_prefixes_idx = list(filter(lambda x: x != -1, long_ext_prefixes_idx)) 57 if long_ext_prefixes_idx: 58 first_long_ext_idx = min(long_ext_prefixes_idx) 59 long_exts = arch[first_long_ext_idx:] 60 std_exts = arch[5:first_long_ext_idx] 61 else: 62 long_exts = "" 63 std_exts = arch[5:] 64 65 # Put extensions in canonical order. 66 for ext in canonical_order: 67 if ext in std_exts: 68 new_arch += ext 69 70 # Concat rest of the multi-char extensions. 71 new_arch += long_exts 72 return new_arch 73 74for cfg in sys.argv[1:]: 75 (arch, abi, extra, ext) = cfg.split('-') 76 arches[arch] = 1 77 abis[abi] = 1 78 extra = list(filter(None, extra.split(','))) 79 ext = list(filter(None, ext.split(','))) 80 alts = sum([[x] + [x + y for y in ext] for x in [arch] + extra], []) 81 # TODO: We should expand g to imadzifencei once we support newer spec. 82 alts = alts + [x.replace('imafd', 'g') for x in alts if 'imafd' in x] 83 alts = list(map(arch_canonicalize, alts)) 84 for alt in alts[1:]: 85 arches[alt] = 1 86 reuse.append('march.%s/mabi.%s=march.%s/mabi.%s' % (arch, abi, alt, abi)) 87 required.append('march=%s/mabi=%s' % (arch, abi)) 88 89arch_options = '/'.join(['march=%s' % x for x in arches.keys()]) 90arch_dirnames = ' \\\n'.join(arches.keys()) 91 92abi_options = '/'.join(['mabi=%s' % x for x in abis.keys()]) 93abi_dirnames = ' \\\n'.join(abis.keys()) 94 95prog = sys.argv[0].split('/')[-1] 96print('# This file was generated by %s with the command:' % prog) 97print('# %s' % ' '.join(sys.argv)) 98 99print('MULTILIB_OPTIONS = %s %s' % (arch_options, abi_options)) 100print('MULTILIB_DIRNAMES = %s %s' % (arch_dirnames, abi_dirnames)) 101print('MULTILIB_REQUIRED = %s' % ' \\\n'.join(required)) 102print('MULTILIB_REUSE = %s' % ' \\\n'.join(reuse)) 103