3.1.1. About GNU Toolchain
The official toolchain repository is located at https://github.com/riscv-collab/riscv-gnu-toolchain.git.
Nuclei maintained toolchain repo is located at https://github.com/riscv-mcu/riscv-gnu-toolchain, and the branch is nuclei/2024-gcc13
, in which the tools included versions are: gcc13, binutils2.40, gdb13.2, and also have merged some important patches from their upstream, as well as additional support for Nuclei custom extensions and pipelines, etc.
3.1.2. Extensions Support
Standard Extensions
Basic Extensions
i, m, a, f, d, c, h, q(Assembly only), zicsr, zifencei, zicond, zawrs, zfh, zfhmin, zmmul, svinval, svnapot.
Z*Inx Extensions
zfinx, zdinx, zhinx, zhinxmin.
CMO Extensions
zicboz, zicbom, zicbop.
Bitmanip Extensions
zba, zbb, zbc, zbs
Crypto Extensions
zbkb, zbkc, zbkx, zknd, zkne, zknh, zkr, zks, zksed, zksh, zkt.
Vector Extensions
zve32x, zve32f, zve64x, zve64f, zve64d, zvfh, zvfhmin, v.
Zc Extensions
zca, zcb, zce, zcf, zcd, zcmp, zcmt(Assembly only).
zce = zca + zcb + zcmp + zcmt
f + zce = zca + zcb + zcf + zcmp + zcmt
f + d + zce = zca + zcb + zcf + zcd + zcmp + zcmt
Zvb Extensions
zvbb, zvbc
Zvk Extensions
zvkg, zvkned, zvknha, zvknhb, zvksed, zvksh, zvkn, zvknc, zvkng, zvks, zvksc, zvksg, zvkt.
BFloat 16 Extensions
Zfbfmin, Zvfbfmin, Zvfbfwma
Zilsd Extensions
Zilsd, Zcmlsd
Nuclei Custom Extensions
Packed SIMD Extension 0.5.4
xxldsp, xxldspn1x, xxldspn2x, xxldspn3x.
xxldsp: P-spec-v0.54 + Nuclei Custom EXPD* instructions
xxldspn1x: xxldsp + Nuclei Custom N1
xxldspn2x: xxldsp + Nuclei Custom N1 & N2
xxldspn3x: xxldsp + Nuclei Custom N1 & N2 & N3
Xxlcz Extensions
xxlczpstinc, xxlczbmrk, xxlczbitop, xxlczslet, xxlczabs, xxlczmac, xxlczbri, xxlczbitrev, xxlczgp.
Note
Extensions starting with x are generally reserved for manufacturers to customize, and should be placed after extensions starting with z when used.
3.1.3. General Options
-march=ISA-string
Generate code for given RISC-V ISA. ISA strings must be lower-case. Examples include
rv64i
,rv32g
,rv32e
, andrv32imaf
. When-march=
is not specified, use the setting from-mcpu
. If both-march
and-mcpu=
are not specified, the default for this argument is system dependent, users who want a specific architecture extensions should specify one explicitly.
-mabi=ABI-string
Specify integer and floating-point calling convention. ABI-string contains two parts: the size of integer types and the registers used for floating-point types. For example
-march=rv64ifd -mabi=lp64d
means that long and pointers are 64-bit (implicitly defining int to be 32-bit), and that floating-point values up to 64 bits wide are passed in F registers. Contrast this with-march=rv64ifd -mabi=lp64f
, which still allows the compiler to generate code that uses the F and D extensions but only allows floating-point values up to 32 bits long to be passed in registers; or-march=rv64ifd -mabi=lp64
, in which no floating-point arguments will be passed in registers.The default for this argument is system dependent, users who want a specific calling convention should specify one explicitly. The valid calling conventions are:
ilp32
,ilp32f
,ilp32d
,lp64
,lp64f
, andlp64d
. Some calling conventions are impossible to implement on some ISAs: for example,-march=rv32if -mabi=ilp32d
is invalid because the ABI requires 64-bit values be passed in F registers, but F registers are only 32 bits wide. There is also theilp32e
ABI that can only be used with therv32e
architecture. This ABI is not well specified at present, and is subject to change.
-mcmodel=medlow
Generate code for the medium-low code model. The program and its statically defined symbols must lie within a single 2 GiB address range and must lie between absolute addresses -2 GiB and +2 GiB. Programs can be statically or dynamically linked. This is the default code model.
-mcmodel=medany
Generate code for the medium-any code model. The program and its statically defined symbols must be within any single 2 GiB address range. Programs can be statically or dynamically linked.
The code generated by the medium-any code model is position-independent, but is not guaranteed to function correctly when linked into position-independent executables or libraries.
-mtune=processor-string
Optimize the output for the given processor, specified by microarchitecture or particular CPU name. Permissible values for this option are:
nuclei-100-series
,nuclei-200-series
,nuclei-300-series
,nuclei-600-series
,nuclei-900-series
,nuclei-1000-series
, and all valid options for-mcpu=
.When
-mtune=
is not specified, use the setting from-mcpu
, the default isrocket
if both are not specified.The
size
choice is not intended for use by end-users. This is used when -Os is specified. It overrides the instruction cost info provided by-mtune=
, but does not override the pipeline info. This helps reduce code size while still giving good performance.
Optimization Options
- -O0
Reduce compilation time and make debugging produce the expected results. This is the default.
- -O/-O1
With -O, the compiler tries to reduce code size and execution time, without performing any optimizations that take a great deal of compilation time.
- -O2
Optimize even more. GCC performs nearly all supported optimizations that do not involve a space-speed tradeoff. As compared to -O, this option increases both compilation time and the performance of the generated code.
- -O3
This option turns on all options in -O2, as well as several other optimizations to improve the performance of the object code.
- -Os
This optimization option is often used to tell the compiler to reduce the size of the object code as much as possible while maintaining performance. It will remove some optimization strategies that increase the object code size from all options enabled by -O2.
- -Ofast
Disregard strict standards compliance. -Ofast enables all -O3 optimizations. It also enables optimizations that are not valid for all standard-compliant programs.
For more information about RISC-V Options used in GCC, please check https://gcc.gnu.org/onlinedocs/gcc-13.1.0/gcc/RISC-V-Options.html
For RISC-V ELF psABI Document, please check https://github.com/riscv-non-isa/riscv-elf-psabi-doc
3.1.4. Libraries
Note
glibc
is used in Linux GNU Glibc toolchain used to compile linux kernel, opensbi, uboot, and linux applications.newlibc
is used in Baremetal or RTOS toolchain, used to compile baremetal or rtos source code, which containsnewlib
,newlib-nano
andlibncrt
glibc
glibc stands for GNU C Library which is the standard system C library for all GNU systems. It provides the system API for all programs written in C and C-compatible languages such as C++ and Objective C; the runtime facilities of other programming languages use the C library to access the underlying operating system. This library is only supported on Nuclei linux toolchain, not on Nuclei bare-metal toolchain.
newlib
newlib is written as a glibc replacement for embedded systems. It can be used with no OS (“bare metal”) or with a lightweight RTOS. Newlib is the default library for embedded GCC distributions.
newlib-nano
Newlib-nano is a derivative of the newlib C library for embedded systems. It is smaller and faster than newlib by code and data size reduction through optimization and removal of non-MCU features.
libncrt
libncrt
is short of Nuclei C Runtime Library, which currently support Nuclei RV32 processor, which is released by Nuclei to reduce c library code size, and improve math library speed, for details, please refer to the user guide located ingcc\share\pdf\Nuclei C Runtime Library Doc.pdf
3.1.5. Significant Changes Brought by GCC13 Compared to GCC10
Instead of using single-letter
bkp
to enable these extensions as we did on gcc10, we split them all into corresponding sub-extensions, for example,_zba_zkr_zve32f
, please check https://doc.nucleisys.com/nuclei_sdk/develop/buildsystem.html#arch-ext to learn about how to adapt Nuclei SDK to support gcc13 upgraded from gcc10.Implement new style of architecture extension test macros: each architecture extension has a corresponding feature test macro, which can be used to test its existence and version information. In addition, we add several custom macros,
__riscv_dsp
,__riscv_bitmanip
.Add new option
-misa-spec=*
to control ISA spec version. This controls the default version of each extensions. The official version is20191213
, but it is set to2.2
when configuring nuclei toolchain. The difference between them is that in20191213
version,Zicsr
andZifencei
are separated from thei
extension into two independent extensions, and using-misa-spec=2.2
can avoid incompatible errors when theZicsr
andZifencei
are not passed to-march=
. See for details at https://github.com/riscv-collab/riscv-gnu-toolchain/issues/1315Support for vector intrinsics as specified in version 0.12 of the RISC-V vector intrinsic specification.
The toolchain component prefix is
riscv-nuclei-elf-
on gcc10, but isriscv64-unknown-elf-
on gcc13.On gcc10, RISCV intrinsic api heads contain
riscv_vector.h
,riscv_vector_itr.h
,rvintrin.h
,rvp_intrinsic.h
, but now onlyriscv_vector.h
,rvp_intrinsic.h
,riscv_nuclei_xlcz.h
are provided in gcc13, if you want to findb
ork
intrinsic API, please check https://github.com/riscv/riscv-crypto/blob/main/benchmarks/share/rvintrin.h and https://github.com/riscv/riscv-crypto/blob/main/benchmarks/share/riscv-crypto-intrinsics.h , and for RVV intrinsic API, we support 0.12 in gcc13 now, see https://github.com/riscv-non-isa/rvv-intrinsic-doc/releases/tag/v1.0-rc0The version of the libncrt was changed from v2.0.0 to v3.0.0, and libncrt is now split into three parts, ‘libncrt’, ‘heapops’ and ‘fileops’, click https://doc.nucleisys.com/nuclei_sdk/develop/buildsystem.html#stdclib to learn about how the newlib/libncrt are used in Nuclei SDK with gcc13.
3.1.6. Install and Setup
Build Toolchain
For more information about how to build a toolchain, see https://github.com/riscv-mcu/riscv-gnu-toolchain/tree/nuclei/2024-gcc13/scripts/toolchain. (Only for Nuclei internal use, no technical support is provided)
Development
The process of user compilation and development can see from https://github.com/riscv-mcu/riscv-gnu-toolchain/blob/nuclei/2024-gcc13/README.md. To get other technical support, please send issues directly to the upstream repository https://github.com/riscv-collab/riscv-gnu-toolchain.
Examples
If you choose a core of Nuclei N300FD, then the parameter you pass to ‘march’ should be
rv32*fd*
, and ‘mabi’ should chooseilp32d
.If you want to bring the full
B/K/P
extension, then you also need to bring all the subsets of them in the ‘march’. For example, for theB
extension, the parameter you pass to ‘march’ is_zba_zbb_zbc_zbs
.
3. When using a library, we can tell the linker which library we need to link by using the ‘-l’, for example, -lc
for newlib-full, -lc_nano
for newlib-nano. For libncrt, you should pass --specs=libncrt_xxx.specs
when using gcc. In addition, you need to link extra ‘fileops’ and ‘heapops’ static libraries during the linking phase by using the ‘-l’, and for the ‘fileops’, you must select one of the three options: ‘uart’, ‘semi’ or ‘rtt’,
and for the ‘heapops’, you must select one of the three options: ‘basic’, ‘realtime’ or ‘minimal’.