GNU tools for ARC-V =================== The GNU toolchain for ARC-V processors is a pre-built and verified distribution of a GCC-based set of tools for building applications targeting supported ARC-V processors. This toolchain is built on the pillars of proven and widely used open-source components such as GCC, Binutils, GDB, and Newlib. While many pre-built GCC-based toolchains are available around the Internet, and it is reasonably easy to build your own, the ARC GNU toolchain is prepared specifically to produce the best possible results for ARC processors. It also makes sure the results produced are reliable in all supported environments. GNU Toolchain for ARC-V Processors v2024.06 ------------------------------------------- This is the 2024.06 version of the GNU Toolchain for Synopsys ARC-V Processor IP. This is the first release that supports the latest GNU tools for both ARC Classic and ARC-V processors simultaneously. More information about these processors can be found on Synopsys website: * `Power-Efficient RISC-V Processors for Embedded Applications `_. * `Maximum Performance Efficiency for Real-time Applications `_. New Features and Enhancements ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ There are no major changes for ARC targets except ARC-specific fixes. All components are updated on top of upstream releases. Binary Distribution ^^^^^^^^^^^^^^^^^^^ * Supported host operating systems: Windows 10/11 64-bit, 20.04.x, CentOS/RHEL 7.x * Prebuilt bare-metal toolchains for 64-bit Windows and Linux hosts; see table with references and list of artifacts. Toolchain Components ^^^^^^^^^^^^^^^^^^^^ * GCC 14.1 with ARC patches * Uses upstream 14.1 release; see `release announcement `__ and `complete list of changes `__. * Initial support of RVV extensions is added in upstream GCC 14. * Binutils 2.42 with ARC patches * Uses upstream 2.42 release; see `release notes `_. * GDB 14.2 with ARC patches * Uses upstream 14.2 release; see `release announcement for 14.1 `_ and `complete list of changes for 14.1 `_ for major changes. * Newlib 4.4.0 with ARC patches * Uses upstream 4.4.0 release; see `release announcement `_. * The upstream Newlib source tree now contains the latest changes for ARC Classic. Known Issues ~~~~~~~~~~~~ * The size-optimized Newlib Nano configuration (used when ``-specs=nano.specs`` is passed to GCC) does not support **printf()** for ``float`` and ``double`` by default. Nano **printf()** is size-optimized and does not include support of ``float`` and ``double``. If you need that feature, pass ``-u _printf_float`` to GCC when you compile your applications. This option picks up support of ``float`` and ``double`` for size optimized **printf()** on demand. * Some complex combinations of ``-march=`` and ``-mabi=`` options might lead to unpredictable errors during compilation. Such issues are related to general support of RISC-V extensions in GCC. See `#610 `_. * GCC 14 generates incorrect include directories if it's configured with the ``--with-sysroot=...`` and ``--with-native-system-header-dir=...`` options. This is a valid set of options for building GCC, but it leads to GCC including invalid paths in an include search list when ``-save-temps`` is used while building binaries. This issue is not critical and will be addressed later. See `#628 `_. Getting Help ~~~~~~~~~~~~ Visit the GitHub discussions link for a community forum tailored to ARC-V processors. To report issues and enhancement requests, use GitHub issues (if you are not sure, start with discussions, as a discussion can always be converted into an issue). * GitHub discussions: https://github.com/foss-for-synopsys-dwc-arc-processors/arc-v-getting-started/discussions * GitHub issues: https://github.com/foss-for-synopsys-dwc-arc-processors/arc-v-getting-started/issues Prebuilt Toolchains Available for Download ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * `Bare-metal ARC-V cross-toolchain for 64-bit Linux hosts `__ * `Bare-metal ARC-V cross-toolchain for 64-bit Windows 10 & 11 hosts `__ Archive SHA-256 checksums are: .. code-block:: b7c2b3f1ce3cda1d1472a0412c474e9a6ca1fe5ee48db4910664050456e28ceb arc_gnu_2024.06-rc1_prebuilt_riscv64_elf_le_win_install.tar.bz2 02580b4b8194695c3f5a6248fc52c1c0e16b252d7b4c2a24a059f653e2eb9eef arc_gnu_2024.06-rc1_prebuilt_riscv64_elf_le_linux_install.tar.bz2 GNU Toolchain for ARC-V Processors v2023.12 ------------------------------------------- This is the 2023.12 version of the GNU Toolchain for Synopsys ARC-V Processor IP. This release introduces support for the ARC-V RMX and RHX processors series based on the RISC-V instruction-set architecture. More information about these processors can be found on Synopsys website: * `Power-Efficient RISC-V Processors for Embedded Applications `_ * `Maximum Performance Efficiency for Real-time Applications `_. .. note:: This release of the ARC GNU tools doesn't include prebuilt toolchains for `ARC Classic processor families `_. Users of ARC 600, ARC 700, ARC EM, ARCv2 HS (HS3x and HS4x) and ARCv3 HS (HS5x and HS6x) should keep using `ARC GNU Tools 2023.09 `_ (latest version). New Features and Enhancements ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Support for RISC-V based ARC-V RMX and RHX Processors ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ * In this release the following RISC-V extensions are supported: ``Zba``, ``Zbb``, ``Zbs``, ``Zdinx``, ``Zfinx``, ``Zicbom``, ``Zicbop``, and ``Zicboz``. * Support for ARC-V RMX and RHX processors: * Instruction scheduling tuning for ARC-V RMX-100 (``-mtune=rmx100``) and RMX-500 (``-mtune=rmx500``) * Instruction fusion for the ARC-V RHX series (``-mtune=rhx``) * Implementation of the code-size reduction extensions ``Zcb`` and ``Zcmp`` * As this is the first release of prebuilt GNU tools with ARC-V support, some functionality might have issues, some processor features might not yet be fully supported, and performance might be lower than expected performance of the final product. Binary Distribution ^^^^^^^^^^^^^^^^^^^ * Supported host operating systems: Windows 10/11 64-bit, Ubuntu 18.04.x, 20.04.x, CentOS/RHEL 7.x * Prebuilt bare-metal toolchains for 64-bit Windows & Linux hosts; see table with references and list of artifacts. Toolchain Components ^^^^^^^^^^^^^^^^^^^^ * GCC 13.2 with ARC patches * Uses upstream 13.2 release; see `GCC release announcement `_ and `complete list of changes `_. * Added support for ARC-V RMX-100, RMX-500, and RHX processors. * Added code size reduction ``Zcb`` and ``Zcmp`` extensions. * Binutils pre-2.41 with ARC patches * Upstream sources of pre-v2.41; see `Binutils release announcement `_. * Added code size reduction ``Zcb`` and ``Zcmp`` extensions. * GDB 12.1 with ARC patches * Upstream sources of v12.1; see `GDB release announcement `_. * Newlib 4.3.0 with ARC patches * Updated sources of 4.3.0 release; see `Newlib release announcement `_. * Improved start-up code to initialize GP (global pointer), SP (stack pointer), clear ``.bss`` section, and similar enhancements. * Provided custom linker command file for use with fast on-chip memories (DCCM and ICCM). Known Issues ~~~~~~~~~~~~ No known issues for this release so far. Getting Help ~~~~~~~~~~~~ Also visit the GitHub discussions link for a community forum tailored to ARC-V processors. To report issues and enhancement requests, use GitHub issues (if you are not sure, start with discussions, since a discussion can always be converted into an issue). * GitHub discussions: https://github.com/foss-for-synopsys-dwc-arc-processors/arc-v-getting-started/discussions * GitHub issues: https://github.com/foss-for-synopsys-dwc-arc-processors/arc-v-getting-started/issues Prebuilt Toolchains Available for Download ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * `Bare-metal ARC-V cross-toolchain for 64-bit Linux hosts `_ * `Bare-metal ARC-V cross-toolchain for 64-bit Windows 10 & 11 hosts `_ Archive SHA-256 checksums are: .. code-block:: 4e555c1b214eb97fd3bf9e1ffa43d69a0d274deb295fec66bdfdebef714b7bf7 arc_gnu_2023.12_prebuilt_riscv64_elf_le_win_install.tar.bz2 9dedb6e496e52a45ce536c9a1970a44401319c42ea17b7b8f6655b6204b9b444 arc_gnu_2023.12_prebuilt_riscv64_elf_le_linux_install.tar.bz2 Command-Line Reference ---------------------- Because the ARC-V GNU toolchain is built on top of standard components such as GCC, Binutils, and GDB, all functionality of these tools stays in place and can be studied in detail in the corresponding manuals: * GCC documentation: https://gcc.gnu.org/onlinedocs/gcc/ * GNU LD documentation: https://sourceware.org/binutils/docs/ld/ * GDB documentation: https://www.sourceware.org/gdb/documentation/ On top of the functionality that comes with the standard releases of these tools, the ARC GNU toolchain adds some ARC-V specific options: The ARC-V GNU compiler has support for the ARC-V RMX-100, RMX-500, and RHX CPU families. To enable compiler optimizations for those CPU families you must use certain ``-mtune`` options. The valid ``-mtune`` options are: * ``arc-v-rmx-100-series`` for the ARC-V RMX-100 family (``rmx100`` in v2023.12 and v2024.06 releases) * ``arc-v-rmx-500-series`` for the ARC-V RMX-500 family (``rmx500`` in v2023.12 and v2024.06 releases) * ``arc-v-rhx-100-series`` for the ARC-V RHX-100 family (``rhx`` in v2023.12 and v2024.06 releases) The architecture options used by the ARC-V RMX-100, RMX-500 and RHX-100 families are ``-march=rv32im_zba_zbb_zbs_zicsr_zca_zcb_zcmp -mabi=ilp32``. ARC-V .specs File ~~~~~~~~~~~~~~~~~ The new ``arcv.specs`` file uses a custom starting routine based on the original ``crt0.S`` with a special linker command file. The latter is highly configurable, introducing four new linker defines: * ``txtmem_addr`` if defined sets the ICCM start address; otherwise the ICCM start address is set to ``0x0`` * ``txtmem_len`` if defined sets the ICCM length; otherwise the length is set to ``128K`` * ``datamem_addr`` if defined sets the DCCM start address; otherwise the DCCM start address is set to ``0x8000_0000`` * ``datamem_len`` if defined sets the DCCM length, otherwise the length is set to ``128K`` Where: * ICCM is usually flash memory or ROM. * DCCM is usually SRAM. * You can set a linker define as follows (using the GCC driver): For example: ``-Wl,-defsym=datamem_addr=0x10000`` This spec file can be used with other spec files too. For example, using semihosting: ``--specs=semihost.specs --specs=arcv.specs``. The First Sample Application ---------------------------- Consider the following sample application: .. code-block:: c #include extern void init_semihosting (); int main(void) { init_semihosting(); printf("Hello world!\n"); return 0; } Build and Run a Simple Application for Synopsys nSIM ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The following commands can be used for compiling the sample for later execution in the nSIM simulator: * For an ARC-V RMX-100 processor: .. code-block:: shell $ riscv64-elf-gcc --specs=semihost.specs --specs=arcv.specs -mabi=ilp32 \ -mtune=arc-v-rmx-100-series -march=rv32im_zba_zbb_zbs_zca_zcb_zcmp_zicsr \ -T arcv.ld test.c -o a.out * For an ARC-V RMX-500 processor: .. code-block:: shell $ riscv64-elf-gcc --specs=semihost.specs --specs=arcv.specs -mabi=ilp32 \ -mtune=arc-v-rmx-500-series -march=rv32im_zba_zbb_zbs_zca_zcb_zcmp_zicsr \ -T arcv.ld test.c -o a.out * For an ARC-V RHX-100 processors: .. code-block:: shell $ riscv64-elf-gcc --specs=semihost.specs --specs=arcv.specs -mabi=ilp32 \ -mtune=arc-v-rhx-100-series -march=rv32im_zba_zbb_zbs_zca_zcb_zcmp_zicsr \ -T arcv.ld test.c -o a.out After building, use the following command line to run the sample in nSIM: .. code-block:: shell $ nsimdrv -prop=nsim_isa_family=rv32 \ -prop=nsim_isa_ext=-all.i.zicsr.zifencei.zihintpause.b.zca.zcb.zcmp.zcmt.a.m.zbb.zba.zbs \ -prop=nsim_semihosting=1 -off=enable_exceptions a.out Hello world! For more details on use of the Synopsys nSIM simulator, see the section dedicated to it here: :doc:`nsim-ncam`. Build and Run a Simple Application for QEMU (32-Bit Targets) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ It is best to use the latest official QEMU version for the following exercises. As of today, it's v9.0; see the release notes here: https://wiki.qemu.org/ChangeLog/9.0. The sources are on GitLab (https://gitlab.com/qemu-project/qemu) or in the official GitHub mirror (https://github.com/qemu/qemu). .. note:: To get the latest version of QEMU on your system it might be much easier to build it from sources rather than trying to find a pre-built version which suits your host type and operating system. Instructions for building on Linux are on QEMU's Wiki: https://wiki.qemu.org/Hosts/Linux First you need to install required additional packages, which depend on the Linux distribution used on the host. For example, for Ubuntu 20.04 the following needs to be done: .. code-block:: shell $ apt install build-essential git libglib2.0-dev libfdt-dev \ libpixman-1-dev zlib1g-dev ninja-build python3-venv For AlmaLinux 8 the following needs to be done: .. code-block:: shell $ dnf install git glib2-devel libfdt-devel pixman-devel zlib-devel \ bzip2 ninja-build python3 python38 After installation of prerequisites you can download sources, configure, and build in the following way: .. code-block:: shell # Clone v9.0 from GitHub repository $ git clone --depth 1 -b stable-9.0 https://github.com/qemu/qemu.git # Configure project for build selecting only RISCV32 full system emulation $ ./configure --target-list=riscv32-softmmu # Build QEMU $ make After the build is complete ``qemu-system-riscv32`` is placed in the ``build`` folder, which you can add to the ``PATH`` environment variable for convenience, and use the short binary name instead of the full path. The following commands can be used for compiling the sample for later execution in QEMU. Basically the same compiler options are used, except that you need to make sure DDR memory is used and the ``.text`` section starts in the DDR beginning at ``0x8000_0000``, where the board jumps on start automatically. For that, you need to override two linker symbols otherwise defined in ARC-V's default linker script ``arcv.ld``: ``txtmem_addr`` and ``datamem_addr``. Then the command lines look like this: * For an ARC-V RMX-100 processor: .. code-block:: shell $ riscv64-elf-gcc -specs=semihost.specs -specs=arcv.specs -mabi=ilp32 \ -mtune=arc-v-rmx-100-series -march=rv32im_zba_zbb_zbs_zca_zcb_zcmp_zicsr \ -Wl,-defsym=txtmem_addr=0x80000000 -Wl,-defsym=datamem_addr=0x80100000 \ -T arcv.ld test.c -o a.out * For an ARC-V RMX-500 processor: .. code-block:: shell $ riscv64-elf-gcc -specs=semihost.specs -specs=arcv.specs -mabi=ilp32 \ -mtune=arc-v-rmx-500-series -march=rv32im_zba_zbb_zbs_zca_zcb_zcmp_zicsr \ -Wl,-defsym=txtmem_addr=0x80000000 -Wl,-defsym=datamem_addr=0x80100000 \ -T arcv.ld test.c -o a.out * For an ARC-V RHX-100 processor: .. code-block:: shell $ riscv64-elf-gcc -specs=semihost.specs -specs=arcv.specs -mabi=ilp32 \ -mtune=arc-v-rhx-100-series -march=rv32im_zba_zbb_zbs_zca_zcb_zcmp_zicsr \ -Wl,-defsym=txtmem_addr=0x80000000 -Wl,-defsym=datamem_addr=0x80100000 \ -T arcv.ld test.c -o a.out After building, use the following command line to run the sample in QEMU: .. code-block:: shell $ qemu-system-riscv32 -semihosting -nographic -machine virt -cpu rv32 -bios none -kernel a.out Hello world! For more details on use of the QEMU simulator, see the official documentation here: https://www.qemu.org/docs/master/. Build and Run a Simple Application for QEMU (64-Bit Targets) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ According to the RISC-V ABI specification: .. code-block:: The medium low code model, or medlow, allows the code to address the whole RV32 address space or the lower 2 GiB and highest 2 GiB of the RV64 address space (0xFFFFFFFF7FFFF800 ~ 0xFFFFFFFFFFFFFFFF and 0x0 ~ 0x000000007FFFF7FF). By using the lui and load / store instructions, when referring to an object, or addi, when calculating an address literal, for example, a 32-bit address literal can be produced. The medium any code model, or medany, allows the code to address the range between -2 GiB and +2 GiB from its position. By using auipc and load / store instructions, when referring to an object, or addi, when calculating an address literal, for example, a signed 32-bit offset, relative to the value of the pc register, can be produced. All pseudo-options like ``li``, ``la``, and so on, are transformed to real instructions according to the memory model used. By default, GCC uses ``-mcmodel=medlow``. That means that the final binary cannot use memory regions above ``0x000000007FFFF7FF`` and below ``0xFFFFFFFF7FFFF800`` for 64-bit targets. To overcome those restrictions, it is necessary to pass ``-mcmodel=medany`` to choose the ``medany`` memory model. Note that the Synopsys GNU toolchain for ARC-V contains precompiled libraries for both the ``medlow`` and ``medany`` memory models. When ``-mcmodel=...`` is passed the appropriate libraries are linked with an application. Consider this example: .. code-block:: c #include int main(int argc, char *argv[]) { printf("argc: %d\n", argc); for (int i = 0; i < argc; i++) { printf("argv[%d] = %s\n", i, argv[i]); } return 0; } Compiler this program and run using QEMU: .. code-block:: $ riscv64-elf-gcc \ -march=rv64imac -mabi=lp64 -mcmodel=medany -O2 -g3 \ -Wl,-defsym=txtmem_addr=0x80000000 -Wl,-defsym=datamem_addr=0x80100000 \ -specs=semihost.specs -specs=arcv.specs -T arcv.ld \ main.c -o main.elf $ qemu-system-riscv64 \ -semihosting -nographic -display none -monitor none \ -machine virt -cpu rv64 -bios none -kernel main.elf -append "1 2 3" argc: 4 argv[0] = main.elf argv[1] = 1 argv[2] = 2 argv[3] = 3 Debugging a Simple Application ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. With Synopsys nSIM .. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ With the Synopsys LLDB Debugger and Visual Studio Code IDE ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ For detailed information on how to debug an application with the Synopsys LLDB Debugger and Visual Studio Code IDE, see the following section: :doc:`mwdt`. With QEMU and GDB ^^^^^^^^^^^^^^^^^ You can debug an application that is being run on QEMU with help of the built-in GDB server of QEMU. On the QEMU side, you need to enable the GDB sever and optionally instruct the QEMU not to start the application execution automatically, but instead wait for user input. For that you need to pass ``-s -S`` commands to `qemu-system-riscv32` so that the full command-line looks like this: .. code-block:: shell $ qemu-system-riscv32 -semihosting -nographic -machine virt -cpu rv32 -bios none -kernel a.out -s -S Then you can attach the GDB client and start debugging. Do the following in a separate console: .. code-block:: shell $ riscv64-elf-gdb a.out (gdb) target remote :1234 Remote debugging using :1234 0x00001000 in ?? () (gdb) b main Breakpoint 1 at 0x800000b4: file ~/test.c, line 10. (gdb) continue Continuing. Breakpoint 1, main () at ~/test.c:10 10 init_semihosting(); (gdb) c Continuing. [Inferior 1 (process 1) exited normally] Note that the first location where the CPU is waiting for commands is 0x0000_1000. It's a virt board reset vector location; see https://elixir.bootlin.com/qemu/v8.2.0/source/hw/riscv/boot.c#L396. It is not possible to suppress execution of that reset vector code as it's an essential part of the QEMU board (think of it as a boot-ROM). You can only bypass it if you load the target executable from the GDB client with the ``load`` command. Then execution starts from the loaded application entry point. Testing Specific RISC-V Extensions ---------------------------------- One of the benefits of RISC-V ISA is its extensibility. As a matter of fact, only a handful of instructions form the minimally required base. But the most interesting part is in utilizing application-specific extensions, which let you achieve benefits in certain situations. In embedded and especially deeply embedded applications, one of the key objectives is to keep the memory footprint of the target application as tiny as possible. And the RISC-V Zc* extensions help to achieve exactly that. This section demonstrates a couple of those extensions in action. See also the documentation and related information on each extension on the corresponding GitHub resource here: https://github.com/riscv/riscv-code-size-reduction. Zcmp Extension ~~~~~~~~~~~~~~ Consider the following code snippet: .. code-block:: $ cat t01.c void test (void) { asm volatile ("" : : : "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", "s8", "s9", "s10", "s11"); } Here is a generated assembly listing targeting the Zcmp extension: .. code-block:: $ riscv64-elf-gcc -march=rv32im_zcmp -mabi=ilp32 t01.c -S -O1 -o - .file "t01.c" .option nopic .attribute arch, "rv32i2p1_m2p0_zca1p0_zcmp1p0" .attribute unaligned_access, 0 .attribute stack_align, 16 .text .align 1 .globl test .type test, @function test: cm.push {ra, s0-s11}, -64 cm.popret {ra, s0-s11}, 64 .size test, .-test .ident "GCC: (RISC-V elf toolchain - build 6278) 13.2.0" Note the generated ``cm.push`` and ``cm.popret`` instructions, which confirm that the compiler is capable of using the extension. Zcb Extension ~~~~~~~~~~~~~ Another RISC-V extension that is easy to see in action also comes from the code-size-reduction group: Zcb. Consider the following C function: .. code-block:: $ cat t03.c int test (int a, int b) { return a + b; } Now compile and disassemble it: .. code-block:: $ riscv64-elf-gcc -march=rv32im_zca_zcb -mabi=ilp32 t03.c -c -O1 $ riscv64-elf-objdump -d t03.o t03.o: file format elf32-littleriscv Disassembly of section .text: 00000000 : 0: 952e add a0,a0,a1 2: 8082 ret Note the short 16-bit encoding of the ``add`` instruction. Without use of Zc extensions, compiler generates a full 32-bit encoding as in the example below. .. code-block:: $ riscv64-elf-gcc -march=rv32im -mabi=ilp32 t03.c -c -O1 $ riscv64-elf-objdump -d t03.o t03.o: file format elf32-littleriscv Disassembly of section .text: 00000000 : 0: 00b50533 add a0,a0,a1 4: 00008067 ret Building a Toolchain for a Particular Architecture -------------------------------------------------- The GNU toolchain for ARC-V targets contains a set of precompiled standard libraries for different combinations of ``-march``, ``-mabi`` and ``-mcmodel``. You can find a list of available configurations this way: .. code-block:: $ riscv64-elf-gcc --print-multi-lib .; rv32i/ilp32;@march=rv32i@mabi=ilp32 rv32i/ilp32/medany;@march=rv32i@mabi=ilp32@mcmodel=medany rv32iac/ilp32;@march=rv32iac@mabi=ilp32 rv32iac/ilp32/medany;@march=rv32iac@mabi=ilp32@mcmodel=medany rv32im/ilp32;@march=rv32im@mabi=ilp32 rv32im/ilp32/medany;@march=rv32im@mabi=ilp32@mcmodel=medany rv32imac/ilp32;@march=rv32imac@mabi=ilp32 rv32imac/ilp32/medany;@march=rv32imac@mabi=ilp32@mcmodel=medany rv32imafc_zicsr/ilp32f;@march=rv32imafc_zicsr@mabi=ilp32f rv32imafc_zicsr/ilp32f/medany;@march=rv32imafc_zicsr@mabi=ilp32f@mcmodel=medany rv32imafd_zicsr/ilp32d;@march=rv32imafd_zicsr@mabi=ilp32d rv32imafd_zicsr/ilp32d/medany;@march=rv32imafd_zicsr@mabi=ilp32d@mcmodel=medany rv32imafdc_zicsr/ilp32d;@march=rv32imafdc_zicsr@mabi=ilp32d rv32imafdc_zicsr/ilp32d/medany;@march=rv32imafdc_zicsr@mabi=ilp32d@mcmodel=medany rv64imac/lp64;@march=rv64imac@mabi=lp64 rv64imac/lp64/medany;@march=rv64imac@mabi=lp64@mcmodel=medany rv64imafdc_zicsr/lp64d;@march=rv64imafdc_zicsr@mabi=lp64d rv64imafdc_zicsr/lp64d/medany;@march=rv64imafdc_zicsr@mabi=lp64d@mcmodel=medany Libraries for this toolchain were built with these combinations of configurations: * ``-march=rv32i -mabi=ilp32 -mcmodel=medlow`` * ``-march=rv32i -mabi=ilp32 -mcmodel=medany`` * ... * ``-march=rv32imafc_zicsr -mabi=ilp32f -mcmodel=medlow`` * ... The easiest way to build a toolchain for another custom configuration is to add a combination to the Crosstool-NG configuration. You can find a comprehensive guide about how to get and prepare Crosstool-NG here: https://github.com/foss-for-synopsys-dwc-arc-processors/toolchain. First, set up a standard ARC-V configuration file and enter a configuration menu: .. code-block:: ./ct-ng snps-riscv64-unknown-elf ./ct-ng menuconfig For example, if you want to build Crosstool-NG with just these configurations: - ``-march=rv32imafc_zicond_zicsr_zifencei -mabi=ilp32f`` - ``-march=rv64imafdc_zicsr -mabi=lp64d`` Navigate to the **C compiler** menu and replace the value of **Generator of RISC-V multilib variants** with this string: ``rv32imafc_zicond_zicsr_zifencei-ilp32f--;rv64imafdc_zicsr-lp64d--;`` (place it right after the **gcc extra config** field). Then build the toolchain as usual: .. code-block:: ./ct-ng build The output toolchain is located in the ``riscv64-unknown-elf`` directory: .. code-block:: $ ./riscv64-unknown-elf/bin/riscv64-elf-gcc --print-multi-lib .; rv32imafc_zicond_zicsr_zifencei/ilp32f;@march=rv32imafc_zicond_zicsr_zifencei@mabi=ilp32f rv64imafdc_zicsr/lp64d;@march=rv64imafdc_zicsr@mabi=lp64d Now when you use ``-march=rv32imafc_zicond_zicsr_zifencei -mabi=ilp32f`` or compatible combinations, a corresponding precompiled library is used.