Note: In this document, the terms "architecture", "instruction set architecture" and "ISA" are used synonymously and refer to a certain set of instructions and the set of registers they can operate upon.
Compiler Options
Rationale
Compiler options that are specific to LoongArch should denote a change in the following compiler settings:
-
Target architecture: the allowed set of instructions and registers to be used by the compiler.
-
Target ABI type: the data model and calling conventions.
-
Target microarchitecture: microarchitectural features that guides compiler optimizations.
For this model, two categories of LoongArch-specific compiler options should be implemented:
-
Basic options: select the base configuration of the compilation target. (include only
-march
-mabi
and-mtune
) -
Extended options: make incremental changes to the target configuration.
Option | Possible values | Description |
---|---|---|
|
|
Selects the target architecture, i.e. the basic set of ISA modules to be enabled. |
|
|
Selects the base ABI type. |
|
|
Selects the type of target microarchitecture, defaults to the value of |
-
Valid parameter values of
-march
and-mtune
options should correspond to actual LoongArch processor implementations / families. -
In principle, different
-march
values should not imply the same set of ISA modules.
Option | Possible values | Description |
---|---|---|
|
Prevent the compiler from generating hardware floating-point instructions,
and adjust the selected base ABI type to use soft-float calling convention.
(The adjusted base ABI identifier should have suffix |
|
|
Allow generating 32-bit floating-point instructions,
and adjust the selected base ABI type to use 32-bit FP calling convention.
(The adjusted base ABI identifier should have suffix |
|
|
Allow generating 32- and 64-bit floating-point instructions.
and adjust the selected base ABI type to use 64-bit FP calling convention.
(The adjusted base ABI identifier should have suffix |
|
|
|
Selects the allowed set of basic floating-point instructions and registers.
This option should not change the FP calling convention unless it’s necessary.
(The implementation of this option is not mandatory. It is recommended to use
|
As a general rule, the effect of all LoongArch-specific compiler options
that are given for one compiler invocation should be as if they are
processed in the order they appear on the command line.
The only exception to this rule is -m*-float
: their configuration of
floating-point instruction set and calling convention will not be changed
by subsequent options other than -m*-float
.
Configuring Target ISA
The LoongArch ISA is organized in a "base-extension" manner. For future updates, each component in the base or extened part of the ISA may evolve independently while keeping compatibility with previous versions of itself.
For this purpose, the compiler should make a modular abstraction about the target ISA.
The ISA modules are divided into two categories: base architectures and ISA extensions.
A base architecture is the core component of the target ISA, which defines the base
set of functionalities like integer and floating-point operations, and is decided
by the value of -march
. An ISA extension may represent either the base of a certain
extended ISA component or an incremental update to it, and is enabled / disabled by
extended options.
For a complier, the final ISA configuration should be derived by applying various
ISA extension configurations from extended options to the base ISA,
which is selected via the -march
option and consists of the base
architecture and the set of default ISA extensions.
Among all ISA modules listed below, the compiler should at least implement one base architecture.
Name | -march values that selects this module |
Description |
---|---|---|
LA64 basic architecture v1.00 ( |
|
ISA defined in LoongArch Reference Manual - Volume 1: Basic Architecture v1.00. |
The following table lists all ISA extensions that should be abstracted by the compiler and the compiler options to enable / disable them.
Name | Related compiler options | Description |
---|---|---|
Basic Floating-Point Processing Unit ( |
|
Selects the allowed set of basic floating-point instructions and floating-point registers. This is a constituent part of the base architecture, where it gets its default value. |
The following table lists the properties of all target CPU models
that can serve as arguments to -march
and -mtune
options
at the same time.
Name / Value | ISA modules that are enabled by default | Target of optimization |
---|---|---|
|
auto-detected with |
auto-detected microarchitecture model / features |
|
|
generic LoongArch LA64 processors |
|
|
LA464 processor core |
Configuring Target ABI
Like configuring the target ISA, a complete ABI configuration of LoongArch consists of two parts, the base ABI and the ABI extension. The former describes the data model and calling convention in general, while the latter denotes an overall adjustment to the base ABI, which may require support from certain ISA extensions.
Please be noted that there is only ONE ABI extension slot in an ABI configuration. They do not combine with one another, and are, in principle, mutually incompatible.
A new ABI extension type will not be added to this document unless it implies certain significant performance / functional advantage that no compiler optimization techniques can provide without altering the ABI.
There are six base ABI types, whose standard names are the same as
the -mabi
values that select them. The compiler may choose to implement
one or more of these base ABI types, possibly according to the range of
implemented target ISA variants.
Standard name | Data model | Bit-width of argument / return value GPRs / FPRs |
---|---|---|
|
LP64 |
64 / 64 |
|
LP64 |
64 / 32 |
|
LP64 |
64 / (none) |
|
ILP32 |
32 / 64 |
|
ILP32 |
32 / 32 |
|
ILP32 |
32 / (none) |
The following table lists all ABI extension types and
related compiler options. A compiler may choose to implement
any subset of these extensions that contains base
.
The default ABI extension type is base
when referring to
an ABI type with only the "base" component.
Name | Compiler options | Description |
---|---|---|
|
(none) |
conforms to the LoongArch ELF psABI |
The compiler should know the default ABI to use during its build time.
If the ABI extension type is not explicitly configured,
base
should be used.
In principle, the target ISA configuration should not affect the decision of the target ABI. When certain ISA feature required by explicit (i.e. from the compiler’s command-line arguments) ABI configuration cannot be met due constraints imposed by ISA options, the compiler should abort with an error message to complain about the conflict.
When the ABI is not fully constrained by the compiler options, the default configuration of either the base ABI or the ABI extension, whichever is missing from the command line, should be attempted. If this default ABI setting cannot be implemented by the explicitly configured target ISA, the expected behavior is undefined since the user is encouraged to specify which ABI to use when choosing a smaller instruction set than the default.
In this case, it is suggested that the compiler should abort with
an error message, however, for user-friendliness, it may also choose
to ignore the default base ABI or ABI extension and select a viable
fallback ABI for the currently enabled ISA modules with caution.
It is also recommended that the compiler should notify the user about the
ABI change, optionally with a compiler warning.
For example, passing -mfpu=none
as the only command-line argument
may cause a compiler configured with lp64d
/ base
default ABI
to automatically select lp64s
/ base
instead.
When the target ISA configuration cannot be uniquely decided from the given compiler options, the build-time default should be consulted first. If the default ISA setting is insufficient for implementing the ABI configuration, the compiler should try enabling the missing ISA modules according to the following table, as long as they are not explicitly disabled or excluded from usage.
Base ABI type | ABI extension type | Minimal required ISA modules |
---|---|---|
|
|
|
|
|
|
|
|
|
GNU Target Triplets and Multiarch Specifiers
Target triplet is a core concept in the GNU build system.
It describes a platform on which the code runs and mostly consists of three fields:
the CPU family / model (machine
), the vendor (vendor
), and the operating
system name (os
).
Multiarch architecture apecifiers are essentially standard directory names where libraries are installed on a multiarch-flavored filesystem. These strings are normalized GNU target triplets. See debian documentation for details.
This document recognizes the following machine
strings
for the GNU triplets of LoongArch:
machine |
Description |
---|---|
|
LA64 base architecture (implies |
|
LA32 base architecture (implies |
As standard library directory names, the canonical multiarch architecture specifiers of LoongArch should contain information about the ABI type of the libraries that are meant to be released in the binary form and installed there.
While the integer base ABI is implied by the machine
field,
the floating-point base ABI and the ABI extension type are encoded
with two string suffices (<fabi-suffix><abiext-suffix>
) to the os
field of the
specifier, respectively.
<fabi-suffix> |
Description |
---|---|
(empty string) |
The base ABI uses 64-bit FPRs for parameter passing. ( |
|
The base ABI uses 32-bit FPRs for parameter passing. ( |
|
The base ABI uses no FPR for parameter passing. ( |
<abiext-suffix> |
ABI extension type |
---|---|
(empty string) |
|
(Note: Since in principle, The default ISA configuration of the ABI should be used in this binary-release scenario, it is not necessary to reserve multiple multiarch specifiers for one OS / ABI combination.)
ABI type (Base ABI / ABI extension) | C Library | Kernel | Multiarch specifier |
---|---|---|---|
|
glibc |
Linux |
|
|
glibc |
Linux |
|
|
glibc |
Linux |
|
|
musl libc |
Linux |
|
|
musl libc |
Linux |
|
|
musl libc |
Linux |
|
C/C++ Preprocessor Built-in Macro Definitions
The definitions listed below is not specific to LoongArch. Amount of LoongArch-specific code can be minimized by utilizing them, while achieving expected portability in most of cases.
Name | Possible Values | Description |
---|---|---|
|
(omitted) |
Byte order |
|
(omitted) |
Byte order for floating-point data |
|
(omitted) |
Whether the ABI passes arguments in 64-bit GPRs and uses the |
|
(omitted) |
Width of C/C++ |
|
(omitted) |
Width of C/C++ |
|
(omitted) |
Width of C/C++ |
|
(omitted) |
Width of C/C++ |
|
(omitted) |
Width of C/C++ |
|
(omitted) |
Width of C/C++ pointer types, in bytes |
|
(omitted) |
Width of C/C++ |
|
(omitted) |
Width of C/C++ |
|
(omitted) |
Width of C/C++ |
|
(omitted) |
Width of C/C++ |
|
(omitted) |
Width of C/C++ |
|
(omitted) |
Width of C/C++ |
|
(omitted) |
Width of C/C++ |
Apart from the generic definitions described above, some architecture-specific macros are still needed to convey those information strongly tied to the architecture; these macros are listed below.
Name | Possible Values | Description |
---|---|---|
|
|
Defined if the target is LoongArch. |
|
|
Bit-width of general purpose registers. |
|
|
Bit-width of floating-point registers ( |
|
|
Processor model as specified by |
|
|
Processor model as specified by |
|
undefined or |
Defined if ABI uses the LP64 data model and 64-bit GPRs for parameter passing. |
|
undefined or |
Defined if floating-point/extended ABI type is |
|
undefined or |
Defined if floating-point/extended ABI type is |
|
undefined or |
Defined if floating-point/extended ABI type is |
|
undefined or |
Defined if floating-point/extended ABI type is |
For historical reasons, the earliest LoongArch C/C++ compilers provided some MIPS-style built-in macros. Because legacy code dependent on those macros is possibly still in use, compilers conformant to this specification may provide the macros as listed below.
Because the naming style and usage of these macros are more-or-less inconsistent with the other macros described above, there is learning cost involved in using these macros. As they bring no advantage over the other macros, it is not recommended for newer compilers to implement them; portable code should not assume existence of these macros, nor use them.
Name | Equivalent to | Description |
---|---|---|
|
|
Similar to |
|
|
n/a |
|
|
n/a |
|
n/a |
Similar to |
|
|
n/a |
|
|
n/a |
|
|
n/a |