ZCC User Manual
Terapines compiler ZCC is a high-performance C/C++ compiler for RISC-V based on LLVM. It supports the most recent C and C++ standards, including C17, C99, C11, C++17, C++14 and C++11 etc and brings the following key features.
-
Offers tailored editions and customizable services.
-
RVV auto-vectorization and other compiler optimizations.
-
Support RISC-V ISAs, including extensions and vendor extensions from Andes and Nuclei
This manual aims to help getting started with the ZCC compiler. Since ZCC is based on LLVM 18.1.0 development branch, most of the LLVM compiler options are applicable to ZCC. This document ONLY highlights the options and behaviors that are different from LLVM/GCC.
Download and Installation
You can review the system requirements to check if your computer configuration is supported.
-
Windows : Windows 10 (32-bit and 64-bit) and above
-
Linux:
-
Ubuntu 20.04, Ubuntu 22.04 and Ubuntu 24.04
-
CentOS 7
-
Fedora 41
-
Please visit Terapines Products to download ZCC toolchain and supported software libraries. ZCC toolchain by default included libzcc with base ISAs. For additional features, choose to download and add in your toolchain with the help of following instructions.Besides, Vendor-specific feature packages are also provided.
- libzcc: standard C and C++ libraries, including newlib, compiler-rt
and libc++
- newlib: Implementation of the standard C library intended for use on embedded systems.
- compiler-rt: Runtime library includes built-in functions and routines necessary for efficient execution of compiled code.
- libc++: Implementation of the C++ standard library and is designed to be highly optimized and standards-compliant.
- libdsp: It offers a collection of functions and tools specifically designed for digital signal processing (DSP).
- libnn: Specialized library for implementing and running neural network algorithms.
Packages | Features |
---|---|
All | All features |
Base* | Base ISA (I/EMAFDC) |
Base_Zb* | RISC-V Bit-Manipulation ISA-extensions |
Base_Zc* | RISC-V Code Size Reduction |
Base_Zb*_Zc* | Combined features of Zb* and Zc* extensions |
Base_V | RISC-V Vector Extension |
Base
- rv32ec/ilp32e
- rv32emc/ilp32e
- rv32emac/ilp32e
- rv32ic/ilp32
- rv32imc/ilp32
- rv32imac/ilp32
- rv32imafc/ilp32f
- rv32imafdc/ilp32d
- rv64imac/lp64
- rv64imafc/lp64f
- rv64imafdc/lp64d
Base_Zb*
- rv32imac_zba_zbb_zbc_zbs/ilp32
- rv32imafc_zba_zbb_zbc_zbs/ilp32f
- rv32imafdc_zba_zbb_zbc_zbs/ilp32d
- rv64imac_zba_zbb_zbc_zbs/lp64
- rv64imafc_zba_zbb_zbc_zbs/lp64f
- rv64imafdc_zba_zbb_zbc_zbs/lp64d
Base_Zc*
- rv32e_zca_zcb_zcmp_zcmt/ilp32e
- rv32em_zca_zcb_zcmp_zcmt/ilp32e
- rv32e_zmmul_zca_zcb_zcmp_zcmt/ilp32e
- rv32ea_zca_zcb_zcmp_zcmt/ilp32e
- rv32ema_zca_zcb_zcmp_zcmt/ilp32e
- rv32i_zca_zcb_zcmp_zcmt/ilp32
- rv32ia_zca_zcb_zcmp_zcmt/ilp32
- rv32im_zca_zcb_zcmp_zcmt/ilp32
- rv32ima_zca_zcb_zcmp_zcmt/ilp32
- rv32i_zmmul_zca_zcb_zcmp_zcmt/ilp32
- rv32imaf_zca_zcb_zcf_zcmp_zcmt/ilp32f
- rv32imafd_zca_zcb_zcf_zcmp_zcmt/ilp32d
- rv32imafd_zca_zcb_zcd_zcf/ilp32d
- rv64ima_zca_zcb_zcmp_zcmt/lp64
- rv64imaf_zca_zcb_zcmp_zcmt/lp64f
- rv64imafd_zca_zcb_zcd/lp64d
- rv64imafd_zca_zcb_zcmp_zcmt/lp64d
Base_Zb*_Zc*
- rv32ima_zca_zcb_zcmp_zcmt_zba_zbb_zbc_zbs/ilp32
- rv32imaf_zca_zcb_zcf_zcmp_zcmt_zba_zbb_zbc_zbs/ilp32f
- rv32imafd_zca_zcb_zcd_zcf_zba_zbb_zbc_zbs/ilp32d
- rv32imafd_zca_zcb_zcf_zcmp_zcmt_zba_zbb_zbc_zbs/ilp32d
- rv64ima_zca_zcb_zcmp_zcmt_zba_zbb_zbc_zbs/lp64
- rv64imaf_zca_zcb_zcmp_zcmt_zba_zbb_zbc_zbs/lp64f
- rv64imafd_zca_zcb_zcmp_zcmt_zba_zbb_zbc_zbs/lp64d
- rv64imafd_zca_zcb_zcd_zba_zbb_zbc_zbs/lp64d
Base_V
- rv64imafdcv/lp64d
- rv64imafdcv/lp64d
- rv64gcv/lp64d
- rv64gv/lp64d
Packages | Features |
---|---|
Nuclei | Support Nuclei SDK |
HPMicro | Support HPMicro SDK |
Nuclei
- rv32ec/ilp32e
- rv32eac/ilp32e
- rv32emc/ilp32e
- rv32ec_zmmul/ilp32e
- rv32emac/ilp32e
- rv32ic/ilp32
- rv32iac/ilp32
- rv32imc/ilp32
- rv32ic_zmmul/ilp32
- rv32e_zca_zcb_zcmp/ilp32e
- rv32em_zca_zcb_zcmp/ilp32e
- rv32e_zmmul_zca_zcb_zcmp/ilp32e
- rv32ea_zca_zcb_zcmp/ilp32e
- rv32ema_zca_zcb_zcmp/ilp32e
- rv32i_zca_zcb_zcmp/ilp32
- rv32ia_zca_zcb_zcmp/ilp32
- rv32im_zca_zcb_zcmp/ilp32
- rv32i_zmmul_zca_zcb_zcmp/ilp32
- rv32imac/ilp32
- rv32imafc/ilp32f
- rv32imafdc/ilp32d
- rv32imac_zba_zbb_zbs/ilp32
- rv32imafc_zba_zbb_zbs/ilp32f
- rv32imafdc_zba_zbb_zbs/ilp32d
- rv32ima_zca_zcb_zcmp/ilp32
- rv32imaf_zca_zcb_zcf_zcmp/ilp32f
- rv32imafd_zca_zcb_zcf_zcmp/ilp32d
- rv32imafd_zca_zcb_zcd_zcf/ilp32d
- rv32ima_zca_zcb_zcmp_zba_zbb_zbs/ilp32
- rv32imaf_zca_zcb_zcf_zcmp_zba_zbb_zbs/ilp32f
- rv32imafd_zca_zcb_zcd_zcf_zba_zbb_zbs/ilp32d
- rv32imafd_zca_zcb_zcf_zcmp_zba_zbb_zbs/ilp32d
- rv32imac_xxldsp/ilp32
- rv32imafc_xxldsp/ilp32f
- rv32imafdc_xxldsp/ilp32d
- rv32imac_zba_zbb_zbs_xxldsp/ilp32
- rv32imafc_zba_zbb_zbs_xxldsp/ilp32f
- rv32imafdc_zba_zbb_zbs_xxldsp/ilp32d
- rv32ima_zca_zcb_zcmp_xxldsp/ilp32
- rv32imaf_zca_zcb_zcf_zcmp_xxldsp/ilp32f
- rv32imafd_zca_zcb_zcd_zcf_xxldsp/ilp32d
- rv32imafd_zca_zcb_zcf_zcmp_xxldsp/ilp32d
- rv32ima_zca_zcb_zcmp_zba_zbb_zbs_xxldsp/ilp32
- rv32imaf_zca_zcb_zcf_zcmp_zba_zbb_zbs_xxldsp/ilp32f
- rv32imafd_zca_zcb_zcd_zcf_zba_zbb_zbs_xxldsp/ilp32d
- rv32imafd_zca_zcb_zcf_zcmp_zba_zbb_zbs_xxldsp/ilp32d
- rv64imac/lp64
- rv64imafc/lp64f
- rv64imafdc/lp64d
- rv64imac_zba_zbb_zbs/lp64
- rv64imafc_zba_zbb_zbs/lp64f
- rv64imafdc_zba_zbb_zbs/lp64d
- rv64ima_zca_zcb_zcmp/lp64
- rv64imaf_zca_zcb_zcmp/lp64f
- rv64imafd_zca_zcb_zcd/lp64d
- rv64ima_zca_zcb_zcmp_zba_zbb_zbs/lp64
- rv64imaf_zca_zcb_zcmp_zba_zbb_zbs/lp64f
- rv64imafd_zca_zcb_zcd_zba_zbb_zbs/lp64d
HPMicro
- rv32imac/ilp32
- rv32imac_zba_zbb_zbc_zbs/ilp32
- rv32imac_zba_zbb_zbc_zbs_zp052b/ilp32
- rv32imac_zba_zbb_zbc_zbs_zp052b_xandes/ilp32
- rv32imac_zp052b/ilp32
- rv32imac_zp052b_xandes/ilp32
- rv32imafc/ilp32f
- rv32imafc_zba_zbb_zbc_zbs/ilp32f
- rv32imafc_zba_zbb_zbc_zbs_zp052b/ilp32f
- rv32imafc_zba_zbb_zbc_zbs_zp052b_xandes/ilp32f
- rv32imafc_zp052b/ilp32f
- rv32imafc_zp052b_xandes/ilp32f
- rv32imafdc/ilp32d
- rv32imafdc_zba_zbb_zbc_zbs/ilp32d
- rv32imafdc_zba_zbb_zbc_zbs_zp052b/ilp32d
- rv32imafdc_zba_zbb_zbc_zbs_zp052b_xandes/ilp32d
- rv32imafdc_zp052b/ilp32d
- rv32imafdc_zp052b_xandes/ilp32d
- ZCC Lite on Linux
- ZCC Lite on Windows
-
Set environment variables
The script
zstudio.sh
is provided in the directory ofbin
. Please specify the path of the zcc executable file as instructed in the script to set environment variables for ZCC Lite. -
Install additional packages
Unzip the package you downloaded and execute the
install.sh
script. You are supposed to specify the root path of ZCC Lite. The script will add all libraries in the toolchain.
-
Set environment variables
The script
zstudio.ps1
andzstudio.bat
is provided in the directory ofbin
. Please specify the path of the zcc executable file as instructed in the script to set environment variables for ZCC Lite. -
Install additional feature packages
Unzip the package you downloaded and execute the
install.ps1
orinstall.bat
script. You are supposed to specify the root path of ZCC Lite to add all libraries in the toolchain.
- ZCC Pro on Linux
- ZCC Pro on Windows
- Offline authorization
-
Authorization and set environment variables
The script
zstudio.sh
is provided in the directory ofbin
. Please set your account and specify the path of the zcc executable file as instructed in the script. The available flags are:-
-d, --daemon
Required for continuous activation. Specify
-d, --daemon
to schedule a background task to refresh the license every 30 minutes. This option also enablese, --enable_cache
by default, allowing cached credentials to be used for authorization. -
-z, --zcc-path <zcc_executable_path>
Manually specify the path of another version of ZCC for setting environment variables.
-
-r, --remove-daemon
Cancel the background timed task.
-
-c, --clear
Clear the previous binding to switch betwwen different machines. The use of this flag is limited to three times per hour.
-
--curl <args>
Pass args to curl as-is.
-
-h, --help
-
-
Install additional packages
Unzip the package you downloaded and execute the
install.sh
script. You are supposed to specify the root path of ZCC Pro. The script will add all libraries in the toolchain.
Please make sure you have curl installed to send HTTP requests.
-
Authorization and set environment variables
The script
zstudio.ps1
andzstudio.bat
is provided in the directory ofbin
. Please set your account and specify the path of the zcc executable file as instructed in the script (administrator privileges are needed on Windows). The available flags are:-
-d, --daemon
Required for continuous activation. Specify
-d, --daemon
to schedule a background task to refresh the license every 30 minutes. This option also enablese, --enable_cache
by default, allowing cached credentials to be used for authorization. -
-z, --zcc-path <zcc_executable_path>
Manually specify the path of another version of ZCC for setting environment variables.
-
-r, --remove-daemon
Cancel the background timed task.
-
-c, --clear
Clear the previous binding to switch betwwen different machines. The use of this flag is limited to three times per hour.
-
--curl <args>
Pass args to curl as-is.
-
-h, --help
-
-
Install additional feature packages
Unzip the package you downloaded and execute the
install.ps1
orinstall.bat
script. You are supposed to specify the root path of ZCC Pro to add all libraries in the toolchain.
Please make sure you have curl installed to send HTTP requests.
Suitable for users who can only use ZCC in an offline environment
Offline authorization is suitable for users who need to use ZCC in an offline environment without IDE.
-
You need to navigate to the bindirectory of ZCC. Run the command
zcc --gen-id
to generate an ID that is bound to your computer. -
Email the generated ID to us, and we will provide you with an authorization file named
TERAPINES_LICENSE_TERA
, which contains the necessary authorization information. -
Just store the file in the .terapines folder in the user directory to complete the authorization. The file should be saved at the following path:
~/.terapines/TERAPINES_LICENSE_TERA
.
C/C++ compilation options
-
The auto-vectorization in ZCC is highly aggressive. For the vast majority of inner-most loops, the auto-vectorization can achieve performance on par with or even exceeding handwritten intrinsics. For nested (outer) loop vectorization, the results are also impressive.For AI kernels commonly used in practical scenarios, such as correlation and resizing, the code performance generated by ZCC's auto-vectorization is very close to that of handwritten intrinsic.
When enabling auto-vectorization with the options
-march=rv32/64gcv -O3
, you can activate aggressive optimizations for operations less than 32 (or 64) bits by adding the option-mllvm --no-integer-promotions
. Note that when using this option, there should be no implicit type conversions in the source code, as this could result in undefined behavior. Examples of correct and incorrect usage are as follows:-
Correct Example
void foo(size_t count, int8_t* channel1, int8_t* channel2, int16_t* output) {
for (size_t i = 0; i < count; i++) {
// With --no-integer-promotions, only explicit type promotion from int8_t to int16_t occurs
output[i] = (int16_t)channel1[i] * (int16_t)channel2[i];
}
} -
Error example
void foo(size_t count, int8_t* channel1, int8_t* channel2, int16_t* output) {
for (size_t i = 0; i < count; i++) {
// Implicit type promotion from int16_t and int8_t to int32_t occurs
output[i] = channel1[i] * channel2[i];
}
-
-
It is sometimes impossible for the compiler to determine which loops require what kind of vectorization, especially in the case of nested loop vectorization. In such cases, users need to use
#pragma
directives to explicitly instruct the compiler on which loop levels to vectorize, how to configure the maximum register grouping, and other related optimizations. See the example below for reference://Currently, multi-level loop vectors only support loops without dependencies, or the user can ensure that the program will not have dependencies when vectorizing loops at this level.
// The option vectorize(assume_safety) is required. It mainly tells the compiler that the memory accesses in the loop will not overlap (pointer alias or partial alias). This option can also ignore unknown accesses like a[idx[i]] Due to memory limitations, please ensure that loops do not have dependencies.
//The option vectorize_width(16, scalable) optionally determines the number of RVV register groups, based on the width of the widest element in the loop multiplied by 16. If not selected, the compiler will automatically calculate an appropriate number of RVV register groups.
// as follows
// mf8 # LMUL=1/8 base on 8bit
// mf4 # LMUL=1/4 base on 16bit
// mf2 # LMUL=1/2 base on 32bit
// m1 # LMUL=1 base on 64bit
// m2 # LMUL=2 base on 128bit
// m4 # LMUL=4 base on 256bit
// m8 # LMUL=8 base on 512bit
#pragma clang loop vectorize(assume_safety) vectorize_width(16, scalable)
for (uint16_t w = 0; w < width: w++) {
.......
}infoPlease refer to the LLVM User Manual for specific usage examples.
-
To enable nested (outer) loop auto-vectorization, an additional option
-mllvm --enable-vplan-native-path
needs to be added.tipThis option is in the development stage and only needs to be added if the outer loop uses pragma. It will be removed when auto-vectorization is fully optimized.
-
ZCC enables link-time optimization by default, so the generated intermediate result files (generated with the
-c
option) are in LLVM bytecode. If you need to analyze the assembly code of the intermediate results or disable link-time optimization, you can add the-fno-lto
option. -
More aggressive code size optimization options:
-
-mllvm --riscv-machine-outliner=true
: In the case of LTO (which is enabled by default in ZCC), this option requires appending-Wl,-mllvm,--riscv-machine-outliner=true
. This optimization is focused on reducing code size, but it may result in a decrease in program performance. -
-config size.cfg
: This option enables ZCC to link libraries optimized for code size.
-
-
By default, ZCC does not enable the
fp-contract
optimization. When the F and D extensions are available, you can manually enable this optimization using the-ffp-contract
option, which allows the generation of additional FMAD-type instructions. -
The
-munaligned-access
option can generate unaligned memory access instructions and align global variables to 1 byte. -
ZCC does not generate RVV strided/index load instructions by default. The
-mllvm --riscv-enable-gather
option can be used to generate RVV strided/index load instructions. -
ZCC RVV auto-vectorization uses a default register grouping of LMUL = 8. The
-mllvm --riscv-v-register-bit-width-lmul
option allows you to specify the vector register grouping, supporting LMUL values of 1, 2, 4, and 8. -
Data locality optimization
The
-fdlo
option enables data locality optimization and must be included in both the compile and link options. Please note that this optimization is still in the testing phase. -
The default minimum trip count for RVV loop vectorization is 5.
The
-mllvm --rvv-vectorizer-min-trip-count
option allows you to specify the minimum trip count for loop vectorization. If the loop count is smaller than this value, the loop will not be vectorized. -
Delayed loop unrolling optimization can be enabled using the
-flate-loop-unroll
option. This allows ZCC to use more efficient loop unrolling algorithms during both the compilation and linking processes.
Fortran compilation options
When using ZFC, you need to add the following options to specify tartget and libraries with their path in local file system.
--target=riscv64-unknown-linux-gnu -L ./install-zcc_protected/riscv64-unknown-linux-gnu/lib -lFortran_main -lFortranRuntime -lpthread -lm
The Fortran compiler ZFC currently only supports Linux rv64imafdc. Other architectures will be supported in the future.
Link options incompatible with GCC
gcc -specs
GCC allows multiple --specs
options to specify configuration files that override default settings. For newlib, spec files like nano.specs, nosys.specs, and simihost.specs can be used.
In contrast, ZCC uses a single combined cfg file specified with the --config
option. Since ZCC does not allow multiple --config
options, the cfg file for newlib in ZCC includes nano-nosys.cfg, nano.cfg, nosys .cfg, sim.cfg and semihost.cfg.
Multi target
ZCC is a multi-target, multi-arch, multi-abi compiler. By default, ZCC will generate code for rv64imafdc/ilp32d. If you need to use ZCC to generate code for other targets, you need to use -march=<arch>
and -mabi=<abi>
at the same time. The supported arch/abi for the RISC-V architecture of ZCC are listed in Multilib.
When using ZCC to generate RV64 code, you must also specify --target=riscv64-unknown-elf
; otherwise it will cause a link error.
Code model
ZCC compiler supports the medany
and medlow
options, which are equivalent to the medium
and small
options in the GCC compiler for the RISC-V architecture.
Align arguments (RISC-V)
align target | GCC | ZCC |
---|---|---|
align function | -falign-functions=n:m:n2:m2 ;--align-functions=n:m:n2:m2 | -falign-functions=N ;-mllvm --align-all-functions=unit |
align all branch targets | -falign-labels=n:m:n2:m2 ;--align-labels=n:m:n2:m2 | -falign-labels=N(ignore) ;--align-labels=N(ignore) ;-mllvm --align-all-blocks=unit |
align loops | -falign-loops=n:m:n2:m2 ; --align-loops=n:m:n2:m2 | -falign-loops=N ;--align-loops=N(ignore) |
align branch target can only be reached by jumping | -falign-jumps=n:m:n2:m2 ;--align-jumps=n:m:n2:m2 | -falign-jumps=N(ignore) ; --align-jumps=N(ignore) ;-mllvm --align-all-nofallthru-blocks=unit |
-
ignore: ZCC will only consume this argument and do nothing.
-
N: Must be power of 2 (e.g 4 means align on 4B boundaries, -falign-functions=8 means that functions will be aligned to 8 bytes boundary.).
-
unit: Force the alignment in log2 format (e.g 4 means align on 16B boundaries,
-mllvm --align-all-functions=8
means that functions will be aligned to 256 bytes boundary.)
linker script
-
The ZCC linker does not support the
DEFINED
macro in linker scripts. For linker scripts that useDEFINED
, the following modification is currently required:- __stack_size = DEFINED(__stack_size) ? __stack_size : 2K;
+ __stack_size = 2K; -
For the support of GNU's ld for linker script's MEMORY command, refer to sourceware docs. Currently, ZCC supports most MEMORY commands, but does not support the "I" attribute. For the "I" command in ldscript, you need to make modifications as following:
MEMORY
{
- ilm (rxai!w) : ORIGIN = 0x80000000, LENGTH = 64K
- ram (wxa!ri) : ORIGIN = 0x90000000, LENGTH = 64K
+ ilm (rxa!w) : ORIGIN = 0x80000000, LENGTH = 64K
+ ram (wxa!r) : ORIGIN = 0x90000000, LENGTH = 64K
} -
The ZCC linker script does not support GNU ld's position-based cumulative operations in output sections. If you need to set an offset at the current location in the output section, you should use an absolute address. For example, replace
. = __stack_size;
with. += __stack_size;
..stack ORIGIN(ram) + LENGTH(ram) - __stack_size :
{
PROVIDE( _heap_end = . );
- . = __stack_size;
+ . += __stack_size;
PROVIDE( _sp = . );
} >ram AT>ram -
By default, ZCC compiles non-builtin sections from linker scripts into the
.data
segment. To place these sections in .bss instead, use theNOLOAD
attribute. For example, in thegcc_demosoc_ilm.ld
script fromnuclei_sdk
, you can modify the.stack
section as shown below for compatibility with ZCC.- .stack ORIGIN(ram) + LENGTH(ram) - __stack_size :
+ .stack ORIGIN(ram) + LENGTH(ram) - __stack_size (NOLOAD) :
{
PROVIDE( _heap_end = . );
- . = __stack_size;
+ . += __stack_size;
PROVIDE( _sp = . );
} >ram AT>ram
} -
If you manually use
__attribute__((section(".sec_abc")))
to place a specific initialization function pointer into a designated section, but the C/C++ source code does not directly reference the object containing the function pointer, the compiler may optimize away the object. To prevent this, you need to manually add theused
attribute, like so:__attribute__((section(".sec_abc"), used))
. This forces the compiler to retain the unused object and prevent it from being optimized away. -
Negative number representation in assembly code/inline assembly
GNU assembler (as) will perform sign extension for 32/64-bit numbers, depending on the corresponding 32/64-bit platform. For example, in the case of GNU as on RV32, it will recognize 0xFFFFF800 as -2048. However, in RV64, GNU as will throw an error for the code below. However, ZCC's assembler (ZCC as), regardless of whether it is on RV32 or RV64, treats
0xFFFFF800
as a positive number.and a0, a0, 0xFFFFF800
Furthermore, the GNU Assembler user guide clearly indicates that when working with negative numbers in assembly code, the negative sign must be placed directly before the number, as demonstrated below:
and a0, a0, -0x800
-
The lld does not support the
ALIGN_WITH_INPUT
attribute for output sections. Instead, you can use theALIGN(x)
attribute to specify alignment. For example:- .data : ALIGN_WITH_INPUT
+ .data : ALIGN(8)
{
. = ALIGN(8)
...
} -
Issue when using -M and -Map parameters at the same time in linker
-
GCC behavior dictates that the last parameter takes effect. For example, in
-Wl,-M,-Map
,-Map
takes effect, while in-Wl,-Map,-M
,-M
takes effect. -
Clang always gives priority to the
-M
option when both parameters are used together. Currently, ZCC follows the same behavior as Clang.
-
-
In the libunwind library used by ZCC, symbols such as
eh_frame_start
,eh_frame_end
,eh_frame_hdr_start
, andeh_frame_hdr_end
are referenced. When using a custom linker script, you need to include the following code to set the values of these symbols.eh_frame :
{
__eh_frame_start = .;
KEEP(*(.eh_frame))
__eh_frame_end = .;
}
.eh_frame_hdr :
{
KEEP(*(.eh_frame_hdr))
}
__eh_frame_hdr_start = SIZEOF(.eh_frame_hdr) > 0 ? ADDR(.eh_frame_hdr) : 0;
__eh_frame_hdr_end = SIZEOF(.eh_frame_hdr) > 0 ? . : 0;
Behavior different from GCC
Uninitialized local variables
Using uninitialized local variables in C/C++ results in undefined behavior because the value of uninitialized local variables may be 0, random memory values, or arbitrary values. If the source code makes use of uninitialized local variables, the assignment from different compilers might legitimately be different.
For example, in the code below, a
is an uninitialized local variable. GCC initializes a
to 0, while ZCC/Clang initializes a
to 0xFFFFFFFF
.
#include <stdio.h>
#include <stdlib.h>
void main()
{
unsigned int a, b;
b = 1;
a |= b;
printf("a %d, b %d\n", a, b);
}
Additionally, it's important to note that compilers' treatment of uninitialized local variables is not consistent. Therefore, you should not rely on compiler-specific behavior for variable initialization. For instance, in the example below, ZCC/Clang initializes a
to 0.
#include <stdio.h>
#include <stdlib.h>
void main()
{
unsigned int a, b;
b = 1;
a &= b;
printf("a %d, b %d\n", a, b);
}
To avoid undefined behavior, you can use the -Wuninitialized
flag during compilation. This enables warnings for the use of uninitialized local variables, allowing the compiler to notify you about potential issues.
Multilib
The supported arch/abi for the RISC-V architecture of ZCC are:
march=rv32eac/ilp32e@march=rv32eac@mabi=ilp32e
march=rv32ea_zca_zcb_zcmp_zcmt/ilp32e@march=rv32ea_zca_zcb_zcmp_zcmt@mabi=ilp32e
march=rv32ec/ilp32e@march=rv32ec@mabi=ilp32e
march=rv32ec_zmmul/ilp32e@march=rv32ec_zmmul@mabi=ilp32e
march=rv32emac/ilp32e@march=rv32emac@mabi=ilp32e
march=rv32ema_zca_zcb_zcmp_zcmt/ilp32e@march=rv32ema_zca_zcb_zcmp_zcmt@mabi=ilp32e
march=rv32emc/ilp32e@march=rv32emc@mabi=ilp32e
march=rv32em_zca_zcb_zcmp_zcmt/ilp32e@march=rv32em_zca_zcb_zcmp_zcmt@mabi=ilp32e
march=rv32e_zca_zcb_zcmp_zcmt/ilp32e@march=rv32e_zca_zcb_zcmp_zcmt@mabi=ilp32e
march=rv32e_zmmul_zca_zcb_zcmp_zcmt/ilp32e@march=rv32e_zmmul_zca_zcb_zcmp_zcmt@mabi=ilp32e
march=rv32iac/ilp32@march=rv32iac@mabi=ilp32
march=rv32ia_zca_zcb_zcmp_zcmt/ilp32@march=rv32ia_zca_zcb_zcmp_zcmt@mabi=ilp32
march=rv32ic/ilp32@march=rv32ic@mabi=ilp32
march=rv32ic_zmmul/ilp32@march=rv32ic_zmmul@mabi=ilp32
march=rv32imac/ilp32@march=rv32imac@mabi=ilp32
march=rv32imac_xxldsp/ilp32@march=rv32imac_xxldsp@mabi=ilp32
march=rv32imac_zba_zbb_zbc_zbs/ilp32@march=rv32imac_zba_zbb_zbc_zbs@mabi=ilp32
march=rv32imac_zba_zbb_zbc_zbs_xxldsp/ilp32@march=rv32imac_zba_zbb_zbc_zbs_xxldsp@mabi=ilp32
march=rv32imafc/ilp32f@march=rv32imafc@mabi=ilp32f
march=rv32imafc_xxldsp/ilp32f@march=rv32imafc_xxldsp@mabi=ilp32f
march=rv32imafc_zba_zbb_zbc_zbs/ilp32f@march=rv32imafc_zba_zbb_zbc_zbs@mabi=ilp32f
march=rv32imafc_zba_zbb_zbc_zbs_xxldsp/ilp32f@march=rv32imafc_zba_zbb_zbc_zbs_xxldsp@mabi=ilp32f
march=rv32imafc_zp052b/ilp32f@march=rv32imafc_zp052b@mabi=ilp32f
march=rv32imafc_zp052b_xandes/ilp32f@march=rv32imafc_zp052b_xandes@mabi=ilp32f
march=rv32imafdc/ilp32d@march=rv32imafdc@mabi=ilp32d
march=rv32imafdc_xxldsp/ilp32d@march=rv32imafdc_xxldsp@mabi=ilp32d
march=rv32imafdc_zba_zbb_zbc_zbs/ilp32d@march=rv32imafdc_zba_zbb_zbc_zbs@mabi=ilp32d
march=rv32imafdc_zba_zbb_zbc_zbs_xxldsp/ilp32d@march=rv32imafdc_zba_zbb_zbc_zbs_xxldsp@mabi=ilp32d
march=rv32imafdc_zp052b/ilp32d@march=rv32imafdc_zp052b@mabi=ilp32d
march=rv32imafdc_zp052b_xandes/ilp32d@march=rv32imafdc_zp052b_xandes@mabi=ilp32d
march=rv32imafd_zca_zcb_zcd_zcf/ilp32d@march=rv32imafd_zca_zcb_zcd_zcf@mabi=ilp32d
march=rv32imafd_zca_zcb_zcd_zcf_xxldsp/ilp32d@march=rv32imafd_zca_zcb_zcd_zcf_xxldsp@mabi=ilp32d
march=rv32imafd_zca_zcb_zcd_zcf_zba_zbb_zbc_zbs/ilp32d@march=rv32imafd_zca_zcb_zcd_zcf_zba_zbb_zbc_zbs@mabi=ilp32d
march=rv32imafd_zca_zcb_zcd_zcf_zba_zbb_zbc_zbs_xxldsp/ilp32d@march=rv32imafd_zca_zcb_zcd_zcf_zba_zbb_zbc_zbs_xxldsp@mabi=ilp32d
march=rv32imafd_zca_zcb_zcf_zcmp_zcmt/ilp32d@march=rv32imafd_zca_zcb_zcf_zcmp_zcmt@mabi=ilp32d
march=rv32imafd_zca_zcb_zcf_zcmp_zcmt_xxldsp/ilp32d@march=rv32imafd_zca_zcb_zcf_zcmp_zcmt_xxldsp@mabi=ilp32d
march=rv32imafd_zca_zcb_zcf_zcmp_zcmt_zba_zbb_zbc_zbs/ilp32d@march=rv32imafd_zca_zcb_zcf_zcmp_zcmt_zba_zbb_zbc_zbs@mabi=ilp32d
march=rv32imafd_zca_zcb_zcf_zcmp_zcmt_zba_zbb_zbc_zbs_xxldsp/ilp32d@march=rv32imafd_zca_zcb_zcf_zcmp_zcmt_zba_zbb_zbc_zbs_xxldsp@mabi=ilp32d
march=rv32imaf_zca_zcb_zcf_zcmp_zcmt/ilp32f@march=rv32imaf_zca_zcb_zcf_zcmp_zcmt@mabi=ilp32f
march=rv32imaf_zca_zcb_zcf_zcmp_zcmt_xxldsp/ilp32f@march=rv32imaf_zca_zcb_zcf_zcmp_zcmt_xxldsp@mabi=ilp32f
march=rv32imaf_zca_zcb_zcf_zcmp_zcmt_zba_zbb_zbc_zbs/ilp32f@march=rv32imaf_zca_zcb_zcf_zcmp_zcmt_zba_zbb_zbc_zbs@mabi=ilp32f
march=rv32imaf_zca_zcb_zcf_zcmp_zcmt_zba_zbb_zbc_zbs_xxldsp/ilp32f@march=rv32imaf_zca_zcb_zcf_zcmp_zcmt_zba_zbb_zbc_zbs_xxldsp@mabi=ilp32f
march=rv32ima_zca_zcb_zcmp_zcmt/ilp32@march=rv32ima_zca_zcb_zcmp_zcmt@mabi=ilp32
march=rv32ima_zca_zcb_zcmp_zcmt_xxldsp/ilp32@march=rv32ima_zca_zcb_zcmp_zcmt_xxldsp@mabi=ilp32
march=rv32ima_zca_zcb_zcmp_zcmt_zba_zbb_zbc_zbs/ilp32@march=rv32ima_zca_zcb_zcmp_zcmt_zba_zbb_zbc_zbs@mabi=ilp32
march=rv32ima_zca_zcb_zcmp_zcmt_zba_zbb_zbc_zbs_xxldsp/ilp32@march=rv32ima_zca_zcb_zcmp_zcmt_zba_zbb_zbc_zbs_xxldsp@mabi=ilp32
march=rv32imc/ilp32@march=rv32imc@mabi=ilp32
march=rv32im_zca_zcb_zcmp_zcmt/ilp32@march=rv32im_zca_zcb_zcmp_zcmt@mabi=ilp32
march=rv32i_zca_zcb_zcmp_zcmt/ilp32@march=rv32i_zca_zcb_zcmp_zcmt@mabi=ilp32
march=rv32i_zmmul_zca_zcb_zcmp_zcmt/ilp32@march=rv32i_zmmul_zca_zcb_zcmp_zcmt@mabi=ilp32
march=rv64imafdcv/lp64d@march=rv64imafdcv@mabi=lp64d
march=rv64imafdv/lp64d@march=rv64imafdv@mabi=lp64d
march=rv64imac/lp64@march=rv64imac@mabi=lp64
march=rv64imac_zba_zbb_zbc_zbs/lp64@march=rv64imac_zba_zbb_zbc_zbs@mabi=lp64
march=rv64imafc/lp64f@march=rv64imafc@mabi=lp64f
march=rv64imafc_zba_zbb_zbc_zbs/lp64f@march=rv64imafc_zba_zbb_zbc_zbs@mabi=lp64f
march=rv64imafdc/lp64d@march=rv64imafdc@mabi=lp64d
march=rv64imafdc_zba_zbb_zbc_zbs/lp64d@march=rv64imafdc_zba_zbb_zbc_zbs@mabi=lp64d
march=rv64imafd_zca_zcb_zcd/lp64d@march=rv64imafd_zca_zcb_zcd@mabi=lp64d
march=rv64imafd_zca_zcb_zcd_zba_zbb_zbc_zbs/lp64d@march=rv64imafd_zca_zcb_zcd_zba_zbb_zbc_zbs@mabi=lp64d
march=rv64imafd_zca_zcb_zcmp_zcmt/lp64d@march=rv64imafd_zca_zcb_zcmp_zcmt@mabi=lp64d
march=rv64imafd_zca_zcb_zcmp_zcmt_zba_zbb_zbc_zbs/lp64d@march=rv64imafd_zca_zcb_zcmp_zcmt_zba_zbb_zbc_zbs@mabi=lp64d
march=rv64imaf_zca_zcb_zcmp_zcmt/lp64f@march=rv64imaf_zca_zcb_zcmp_zcmt@mabi=lp64f
march=rv64imaf_zca_zcb_zcmp_zcmt_zba_zbb_zbc_zbs/lp64f@march=rv64imaf_zca_zcb_zcmp_zcmt_zba_zbb_zbc_zbs@mabi=lp64f
march=rv64ima_zca_zcb_zcmp_zcmt/lp64@march=rv64ima_zca_zcb_zcmp_zcmt@mabi=lp64
march=rv64ima_zca_zcb_zcmp_zcmt_zba_zbb_zbc_zbs/lp64@march=rv64ima_zca_zcb_zcmp_zcmt_zba_zbb_zbc_zbs@mabi=lp64
Get help
ZCC Lite
If you need help or have a question with any aspect of ZCC, feel free to discuss on 1nfinite developer forum. Our team is here to provide responses and enhance your user experience.
ZCC Pro/ZCC FuSa
We open issue tracking system for ZCC Pro/ZCC FuSa users. Please report bugs on ticket page of Terapines Support.