Skip to content

Commit dccfa30

Browse files
committed
Intrinsics: Define intrinsics naming guidelines
Let's establish a naming guideline for intrinsics. Signed-off-by: Christoph Müllner <christoph.muellner@vrull.eu>
1 parent aec3c3b commit dccfa30

File tree

1 file changed

+41
-2
lines changed

1 file changed

+41
-2
lines changed

riscv-c-api.md

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -172,5 +172,44 @@ For example:
172172

173173
## Intrinsic Functions
174174

175-
Do we really have none of these? I can't figure out
176-
`gcc/gcc/config/riscv/riscv-builtins.c`...
175+
Intrinsic functions (or intrinsics or built-ins) are expanded into instruction sequences by compilers.
176+
They typically provide access to functionality that is otherwise not synthesizable by compilers.
177+
Some intrinsics expand to different code sequences depending on the available instructions from the enabled ISA extensions.
178+
179+
Compilers typically come with their own architecture-independent intrinsics (e.g. synchronization primitives, byte-swap, etc.).
180+
The RISC-V compiler backend can define additional target-specific intrinsics.
181+
Providing functionality via architecture-independent intrinsics is the preferred method, as it improves code portability.
182+
183+
Some intrinsics are only available if a particular header file is included.
184+
RISC-V header files that enable intrinsics require the prefix `riscv_` (e.g. `riscv_vector.h` or `riscv_crypto.h`).
185+
186+
RISC-V specific intrinsics use the common prefix "__riscv_" to avoid namespace collisions.
187+
188+
The intrinsic name describes the functional behaviour of the function.
189+
In case the functionality can be expressed with a single instruction, the instruction's name (any '.' replaced by '_') is the preferred choice.
190+
Note, that intrinsics that are restricted to RISC-V vendor extensions need to include the vendor prefix (as documented in the RISC-V toolchain conventions).
191+
192+
If intrinsics are available for multiple data types, then function overloading is preferred over multiple type-specific functions.
193+
If an intrinsic function is has parameters or return values that reference registers with XLEN bits, then the data type `long` should be used.
194+
In case a function is only available for one data type and this type cannot be derived from the function's name, then the type should be appended to the function name, delimited by a '_' character.
195+
Typical type postfixes are "32" (32-bit), "i32" (signed 32-bit), "i8m4" (vector register group consisting of 4 signed 8-bit vector registers).
196+
197+
RISC-V intrinsics follow the following naming rule:
198+
199+
```
200+
INTRINSIC ::= PREFIX NAME [ '_' TYPE ]
201+
PREFIX ::= "__riscv_"
202+
NAME ::= Name of the intrinsic function.
203+
TYPE ::= Optional type postfix.
204+
```
205+
206+
RISC-V intrinsics examples:
207+
208+
```
209+
type __riscv_orc_b (type rs); // orc.b rd, rs
210+
211+
long __riscv_clmul (long a, long b); // clmul rd, rs1, rs2
212+
213+
#include <riscv_vector.h> // make RISC-V vector intrinsics available
214+
vint8m1_t __riscv_vadd_vv_i8m1(vint8m1_t vs2, vint8m1_t vs1, size_t vl); // vadd.vv vd, vs2, vs1
215+
```

0 commit comments

Comments
 (0)