https://gcc.gnu.org/g:3e33ea4b66214e37b3425111308effa1314fe294
commit r17-1345-g3e33ea4b66214e37b3425111308effa1314fe294 Author: Kito Cheng <[email protected]> Date: Wed Jun 3 16:14:18 2026 +0800 RISC-V: Support multilib with extra options The syntax of multilib-generator was defined as below: ``` <primary arch>-<abi>-<additional arches>-<extensions> ``` And now extend with one more optional argument: ``` <primary arch>-<abi>-<additional arches>-<extensions>[-<extra-options>] ``` Detail syntax of `<extra-option>`: ``` <extra-options> := <extra-option> ',' <extra-options> | <extra-option> <extra-option> := <option> '/' <multi-lib-folder> ``` NOTE: Dash ('-') in the option name must replace with underline ('_'), and leading dash should skip, e.g. `-fcf-protection=full` become `fcf_protection=full`. e.g. rv64imafdc_zicfiss_zicfilp-lp64d---fcf_protection=full/cfi It will build a multilib with `-march=rv64imafdc_zicfiss_zicfilp -mabi=lp64d -fcf-protection=full` And will use `rv64imafdc_zicfiss_zicfilp/lp64d/cfi` as multilib folder. gcc/ChangeLog: * config/riscv/multilib-generator: Support extra options in the multilib config string. * doc/install.texi (--with-multilib-generator): Document the extra options syntax. Diff: --- gcc/config/riscv/multilib-generator | 50 +++++++++++++++++++++++++++---------- gcc/doc/install.texi | 35 ++++++++++++++++++++++++-- 2 files changed, 70 insertions(+), 15 deletions(-) diff --git a/gcc/config/riscv/multilib-generator b/gcc/config/riscv/multilib-generator index d8e56563a5f1..94e663baf762 100755 --- a/gcc/config/riscv/multilib-generator +++ b/gcc/config/riscv/multilib-generator @@ -51,6 +51,7 @@ arches = collections.OrderedDict() abis = collections.OrderedDict() required = [] reuse = [] +extra_multlib_option_dict = collections.OrderedDict() def arch_canonicalize(arch, isa_spec): this_file = os.path.abspath(os.path.join( __file__)) @@ -143,25 +144,45 @@ args = parser.parse_args() if args.cmodel: cmodels = [None] + args.cmodel.split(",") + for cmodel in cmodels[1:]: + extra_multlib_option_dict['mcmodel=%s' % cmodel] = cmodel else: cmodels = [None] -cmodel_options = '/'.join(['mcmodel=%s' % x for x in cmodels[1:]]) -cmodel_dirnames = ' \\\n'.join(cmodels[1:]) - for cmodel in cmodels: for cfg in args.cfgs: + local_extra_multlib_option_dict = collections.OrderedDict() try: - (arch, abi, extra, ext) = cfg.split('-') + if cfg.count('-') == 3: + (arch, abi, extra, ext) = cfg.split('-') + extra_multlib_options = [] + elif cfg.count('-') == 4: + (arch, abi, extra, ext, extra_multlib_option) = cfg.split('-') + # <extra-multilib-option> is a list of options separated by slash, and + # each option is consisted of option name and multi-lib dir separated by + # semicolon, the dash within the option should rewrite as underscore to + # prevent confusion of parsing. + # e.g. + # fcf_protection=full/cfi : -fcf-protection=full as option name and cfi + # as multilib path. + extra_multlib_options = extra_multlib_option.split(',') + for option in extra_multlib_options: + option = option.replace('_', '-') + option = option.split('/') + local_extra_multlib_option_dict[option[0]] = option[1] + extra_multlib_option_dict.update(local_extra_multlib_option_dict) except: - print ("Invalid configure string %s, <arch>-<abi>-<extra>-<extensions>\n" + print ("Invalid configure string %s, <arch>-<abi>-<extra>-<extensions>" + "[-<extra-multilib-option>]\n" "<extra> and <extensions> can be empty, " "e.g. rv32imafd-ilp32--" % cfg) sys.exit(1) - # Large code model only support rv64. - if cmodel == "large" and arch.startswith("rv32"): + # Compact and large code model only support rv64. + if cmodel in ["compact", "large"] and arch.startswith("rv32"): continue + elif cmodel: + local_extra_multlib_option_dict['mcmodel=%s' % cmodel] = cmodel arch = arch_canonicalize (arch, args.misa_spec) arches[arch] = 1 @@ -181,10 +202,13 @@ for cmodel in cmodels: arches[alt] = 1 reuse.append('march.%s/mabi.%s=march.%s/mabi.%s' % (arch, abi, alt, abi)) - if cmodel: - required.append('march=%s/mabi=%s/mcmodel=%s' % (arch, abi, cmodel)) - else: - required.append('march=%s/mabi=%s' % (arch, abi)) + extra_multlib_option_str = '/'.join(local_extra_multlib_option_dict.keys()) + + multilib_cfg_line = 'march=%s/mabi=%s' % (arch, abi) + + if (len(extra_multlib_option_str) > 0): + multilib_cfg_line += '/' + extra_multlib_option_str + required.append(multilib_cfg_line) arch_options = '/'.join(['march=%s' % x for x in arches.keys()]) arch_dirnames = ' \\\n'.join(arches.keys()) @@ -196,7 +220,7 @@ prog = sys.argv[0].split('/')[-1] print('# This file was generated by %s with the command:' % prog) print('# %s' % ' '.join(sys.argv)) -print('MULTILIB_OPTIONS = %s %s %s' % (arch_options, abi_options, cmodel_options)) -print('MULTILIB_DIRNAMES = %s %s %s' % (arch_dirnames, abi_dirnames, cmodel_dirnames)) +print('MULTILIB_OPTIONS = %s %s %s' % (arch_options, abi_options, " ".join(extra_multlib_option_dict.keys()))) +print('MULTILIB_DIRNAMES = %s %s %s' % (arch_dirnames, abi_dirnames, " ".join(extra_multlib_option_dict.values()))) print('MULTILIB_REQUIRED = %s' % ' \\\n'.join(required)) print('MULTILIB_REUSE = %s' % ' \\\n'.join(reuse)) diff --git a/gcc/doc/install.texi b/gcc/doc/install.texi index 202edff03408..406862b31958 100644 --- a/gcc/doc/install.texi +++ b/gcc/doc/install.texi @@ -1558,8 +1558,9 @@ values, possibly consisting of a single value. Currently only implemented for riscv*-*-elf*. The accepted values and meanings are given below. -Every config is constructed with four components: architecture string, ABI, -reuse rule with architecture string and reuse rule with sub-extension. +Every config is constructed with four mandatory components and one optional +component: architecture string, ABI, reuse rule with architecture string, +reuse rule with sub-extension and an optional list of extra options. Example 1: Add multi-lib support for rv32i with ilp32. @smallexample @@ -1600,6 +1601,36 @@ medlow code model; rv64ima with lp64 and medany code model rv64ima-lp64--;--cmodel=medlow,medany @end smallexample +A config may carry an optional fifth component, a list of extra options, which +is appended after the sub-extension reuse rule: +@smallexample +<arch>-<abi>-<extra-arch>-<sub-ext>[-<extra-options>] +@end smallexample + +The extra options are a comma separated list, and each entry pairs an option +name with the multilib directory it should map to, separated by a slash: +@smallexample +<extra-options> := <extra-option> ',' <extra-options> + | <extra-option> + +<extra-option> := <option> '/' <multilib-folder> +@end smallexample + +Because the dash (@samp{-}) is used as the component separator, any dash in an +option name must be rewritten as an underscore (@samp{_}), and the leading dash +of the option must be dropped. For example, @option{-fcf-protection=full} is +written as @code{fcf_protection=full}. + +Example 7: Add multi-lib support for rv64imafdc with lp64d, plus a variant +built with @option{-fcf-protection=full} placed in the @file{cfi} directory. +@smallexample +rv64imafdc_zicfiss_zicfilp-lp64d---fcf_protection=full/cfi +@end smallexample + +This builds a multilib with +@option{-march=rv64imafdc_zicfiss_zicfilp -mabi=lp64d -fcf-protection=full} +and uses @file{rv64imafdc_zicfiss_zicfilp/lp64d/cfi} as the multilib folder. + @item --with-multi-buildlist=@var{file} Specify a file containing a list of multilib directories to build.
