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.

Reply via email to