5.2. Nuclei C Runtime Library for Nuclei Toolchain
5.2.1. Usage
For Nuclei GNU Toolchain(riscv64-unknown-elf-gcc) case:
riscv64-unknown-elf-gcc --specs=libncrt_small.specs -Wl,--start-group -lncrt_small -lheapops_basic -lfileops_uart -Wl,--end-group
For Nuclei LLVM Toolchain(riscv64-unknown-elf-clang) case:
You can’t use –specs=libncrt_small.specs option, since it is not supported, gcc can also use following command just like clang.
riscv64-unknown-elf-clang -nodefaultlibs -isystem=/include/libncrt -Wl,--start-group -lncrt_small -lheapops_basic -lfileops_uart -Wl,--end-group
For details about libncrt, ‘heapops’ and ‘fileops’ variant, please read following documentation.
When using this method, please don’t link with -lm/lc_nano/-lgcc/-lc library to avoid potential linker error and code size increasement. Please also note that libncrt requires a few functions to be provided by the application itself, such as exit and the basic I/O functions used by the selected ‘fileops’ library, see Quick start for the minimal set of functions to implement.
5.2.2. zicfilp landing pad usage
libncrt supports the zicfilp control-flow integrity extension: when the runtime library is built with CFI landing pads enabled, every assembly language routine starts with a valid lpad instruction, so indirect calls guarded by zicfilp can safely land in runtime library code.
Using it requires a zicfilp-enabled toolchain: the standard released toolchain neither supports -fcf-protection=branch for RISC-V targets nor ships the CFI variants of the libncrt, ‘heapops’ and ‘fileops’ libraries. On a zicfilp-enabled toolchain, simply add _zicfilp to -march and compile and link with -fcf-protection=branch: the CFI variants of the runtime libraries (the cfi multilib directory) are then selected automatically, and there is no separate library variant to select. An example is as follows:
riscv64-unknown-elf-gcc -march=rv32ima_zicfilp_zicond_zaamo_zalrsc_zca_zcb_zcmp_zba_zbb_zbs -mabi=ilp32 -fcf-protection=branch --specs=libncrt_small.specs -Wl,--start-group -lncrt_small -lheapops_basic -lfileops_uart -Wl,--end-group
5.2.3. Big-endian usage
libncrt also supports RISC-V big-endian targets. The big-endian toolchain is not publicly released: to use the big-endian C library, you need to use the tools prefixed with riscv64be-unknown-elf- together with the -mbig-endian compile option. There is no separate library variant to select for big-endian: the byte order used by the runtime library is automatically configured from the byte-order macros predefined by the compiler, so the libraries are used in exactly the same way as on little-endian targets, taking the small variant with basic ‘heapops’ and uart ‘fileops’ as an example:
riscv64be-unknown-elf-gcc -mbig-endian --specs=libncrt_small.specs -Wl,--start-group -lncrt_small -lheapops_basic -lfileops_uart -Wl,--end-group
5.2.4. Varieties
5.2.4.1. Libncrt Library choice
GCC Specs |
Library |
|
|---|---|---|
Fast |
libncrt_fast.specs |
libncrt_fast.a |
Balanced |
libncrt_balanced.specs |
libncrt_balanced.a |
Small |
libncrt_small.specs |
libncrt_small.a |
Nano |
libncrt_nano.specs |
libncrt_nano.a |
Pico |
libncrt_pico.specs |
libncrt_pico.a |
If you are not using gcc, and want to use libncrt small variant, you can pass -isystem=/include/libncrt during compile phase, and -nodefaultlibs -lncrt_small during link phase.
5.2.4.2. Optimization
Optimization |
|
|---|---|
Fast |
Favor speed at the expense of size |
Balanced |
Balanced |
Small |
Favor size at the expense of speed |
Nano |
Favor size at the expense of speed |
Pico |
Favor size at the expense of speed |
5.2.4.3. Formatted I/O
int |
long |
long long |
float |
double |
wide character |
input character class |
Width and precision specification |
stdout formatting buffer (byte) |
|
|---|---|---|---|---|---|---|---|---|---|
Fast |
yes |
yes |
yes |
yes |
yes |
yes |
yes |
yes |
64 |
Balanced |
yes |
yes |
yes |
yes |
yes |
yes |
yes |
yes |
64 |
Small |
yes |
yes |
yes |
yes |
yes |
yes |
yes |
yes |
64 |
Nano |
yes |
yes |
yes |
no |
no |
no |
no |
yes |
64 |
Pico |
yes |
no |
no |
no |
no |
no |
no |
no |
32 |
5.2.4.4. Algorithm
Scaled-integer Algorithm |
|
|---|---|
Fast |
Algorithms use C-language floating-point arithmetic. |
Balanced |
Algorithms use C-language floating-point arithmetic. |
Small |
Algorithms use C-language floating-point arithmetic. |
Nano |
Algorithms use C-language floating-point arithmetic. |
Pico |
IEEE single-precision functions use scaled integer arithmetic if there is a scaled-integer implementation of the function. |
5.2.4.5. Extra fileops and heapops libraries used together with libncrt
Library Type |
Library description |
|
|---|---|---|
fileops |
Using a UART for I/O, need to implement at least metal_tty_putc and metal_tty_getc |
|
fileops |
Using semihosting for I/O |
|
fileops |
Using SEGGER RTT for I/O |
|
heapops |
Using a basic heap implementation |
|
heapops |
Using a real-time heap implementation |
|
heapops |
Using a minimal heap implementation |