]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
RISC-V: Add intrinsic detection macros
authorChristoph Müllner <christoph.muellner@vrull.eu>
Mon, 18 May 2026 11:42:33 +0000 (13:42 +0200)
committerChristoph Müllner <christoph.muellner@vrull.eu>
Thu, 21 May 2026 10:54:09 +0000 (12:54 +0200)
RISC-V C API pull request #183 specifies macros that let users
detect compiler support for intrinsic APIs independent of -march:
https://github.com/riscv-non-isa/riscv-c-api-doc/pull/183

Define __riscv_intrinsic_<extension> macros in the corresponding
RISC-V intrinsic headers.  The macros describe compiler support for
an intrinsic API and do not depend on whether the related ISA
extension is enabled by -march.

Derive scalar composite macros from their component macros so they
are only defined when all component intrinsic headers have been
included.

gcc/
* config/riscv/andes_vector.h: Define intrinsic detection macros.
* config/riscv/riscv_bitmanip.h: Likewise.
* config/riscv/riscv_crypto.h: Likewise.
* config/riscv/riscv_vector.h: Likewise.
* config/riscv/sifive_vector.h: Likewise.
* doc/extend.texi: Document RISC-V intrinsic detection macros.

gcc/testsuite/
* gcc.target/riscv/intrinsic-detection-bitmanip.c: New test.
* gcc.target/riscv/intrinsic-detection-crypto.c: New test.
* gcc.target/riscv/intrinsic-detection-scalar-reverse.c: New test.
* gcc.target/riscv/intrinsic-detection-scalar.c: New test.
* gcc.target/riscv/rvv/base/intrinsic-detection.c: New test.

Signed-off-by: Christoph Müllner <christoph.muellner@vrull.eu>
gcc/config/riscv/andes_vector.h
gcc/config/riscv/riscv_bitmanip.h
gcc/config/riscv/riscv_crypto.h
gcc/config/riscv/riscv_vector.h
gcc/config/riscv/sifive_vector.h
gcc/doc/extend.texi
gcc/testsuite/gcc.target/riscv/intrinsic-detection-bitmanip.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/intrinsic-detection-crypto.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/intrinsic-detection-scalar-reverse.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/intrinsic-detection-scalar.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/base/intrinsic-detection.c [new file with mode: 0644]

index 712ca77c27cadb7d6e7ef694e52c76f9ac8e407d..94355aec271624211f086537e885c4e079aac9a8 100644 (file)
 #ifndef __ANDES_VECTOR_H
 #define __ANDES_VECTOR_H
 
+#define __riscv_intrinsic_xandesvbfhcvt 1
+#define __riscv_intrinsic_xandesvdot 1
+#define __riscv_intrinsic_xandesvpackfph 1
+#define __riscv_intrinsic_xandesvsintload 1
+
 /* TODO: This should have a separate pragma to include only the Andes
         vector intrinsics.  For now, we are including riscv_vector.h.  */
 #include <riscv_vector.h>
index ea0eb4fd6af662cb9e072bcf99c2387456a891d5..3cc9b7034d54df757c7e83f721cdbbc33971e6d1 100644 (file)
 
 #include <stdint.h>
 
+#define __riscv_intrinsic_zbb 1
+#define __riscv_intrinsic_zbc 1
+#define __riscv_intrinsic_zbkb 1
+#define __riscv_intrinsic_zbkc 1
+#define __riscv_intrinsic_zbkx 1
+
+#if !defined (__riscv_intrinsic_zkn) \
+    && defined (__riscv_intrinsic_zbkb) \
+    && defined (__riscv_intrinsic_zbkc) \
+    && defined (__riscv_intrinsic_zbkx) \
+    && defined (__riscv_intrinsic_zknd) \
+    && defined (__riscv_intrinsic_zkne) \
+    && defined (__riscv_intrinsic_zknh)
+#define __riscv_intrinsic_zkn 1
+#endif
+
+#if !defined (__riscv_intrinsic_zks) \
+    && defined (__riscv_intrinsic_zbkb) \
+    && defined (__riscv_intrinsic_zbkc) \
+    && defined (__riscv_intrinsic_zbkx) \
+    && defined (__riscv_intrinsic_zksed) \
+    && defined (__riscv_intrinsic_zksh)
+#define __riscv_intrinsic_zks 1
+#endif
+
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -294,4 +319,4 @@ __riscv_xperm8_64 (uint64_t rs1, uint64_t rs2)
 #if defined (__cplusplus)
 }
 #endif // __cplusplus
-#endif // __RISCV_BITMANIP_H
\ No newline at end of file
+#endif // __RISCV_BITMANIP_H
index 2f3f431ce2953941a12a1f1b52c37729c378dc87..23141286ff360185b828ece173b9e7c4e52ca7f1 100644 (file)
 
 #include <stdint.h>
 
+#define __riscv_intrinsic_zknd 1
+#define __riscv_intrinsic_zkne 1
+#define __riscv_intrinsic_zknh 1
+#define __riscv_intrinsic_zksed 1
+#define __riscv_intrinsic_zksh 1
+
+#if !defined (__riscv_intrinsic_zkn) \
+    && defined (__riscv_intrinsic_zbkb) \
+    && defined (__riscv_intrinsic_zbkc) \
+    && defined (__riscv_intrinsic_zbkx) \
+    && defined (__riscv_intrinsic_zknd) \
+    && defined (__riscv_intrinsic_zkne) \
+    && defined (__riscv_intrinsic_zknh)
+#define __riscv_intrinsic_zkn 1
+#endif
+
+#if !defined (__riscv_intrinsic_zks) \
+    && defined (__riscv_intrinsic_zbkb) \
+    && defined (__riscv_intrinsic_zbkc) \
+    && defined (__riscv_intrinsic_zbkx) \
+    && defined (__riscv_intrinsic_zksed) \
+    && defined (__riscv_intrinsic_zksh)
+#define __riscv_intrinsic_zks 1
+#endif
+
 #ifdef __cplusplus
 extern "C" {
 #endif
index 4128c75de86fb8efc060104a676cc422a34b771f..bda75833ef2eb22feefcab0b225fb34f8d1adb04 100644 (file)
 #include <stdint.h>
 #include <stddef.h>
 
+#define __riscv_intrinsic_v 1
+#define __riscv_intrinsic_zve32f 1
+#define __riscv_intrinsic_zve32x 1
+#define __riscv_intrinsic_zve64d 1
+#define __riscv_intrinsic_zve64f 1
+#define __riscv_intrinsic_zve64x 1
+#define __riscv_intrinsic_zvbb 1
+#define __riscv_intrinsic_zvbc 1
+#define __riscv_intrinsic_zvfbfmin 1
+#define __riscv_intrinsic_zvfbfwma 1
+#define __riscv_intrinsic_zvfh 1
+#define __riscv_intrinsic_zvfhmin 1
+#define __riscv_intrinsic_zvkb 1
+#define __riscv_intrinsic_zvkg 1
+#define __riscv_intrinsic_zvkned 1
+#define __riscv_intrinsic_zvknha 1
+#define __riscv_intrinsic_zvknhb 1
+#define __riscv_intrinsic_zvksed 1
+#define __riscv_intrinsic_zvksh 1
+
+#if defined (__riscv_intrinsic_zvkned) \
+    && defined (__riscv_intrinsic_zvknhb) \
+    && defined (__riscv_intrinsic_zvkb)
+#define __riscv_intrinsic_zvkn 1
+#endif
+
+#if defined (__riscv_intrinsic_zvkn) && defined (__riscv_intrinsic_zvbc)
+#define __riscv_intrinsic_zvknc 1
+#endif
+
+#if defined (__riscv_intrinsic_zvkn) && defined (__riscv_intrinsic_zvkg)
+#define __riscv_intrinsic_zvkng 1
+#endif
+
+#if defined (__riscv_intrinsic_zvksed) \
+    && defined (__riscv_intrinsic_zvksh) \
+    && defined (__riscv_intrinsic_zvkb)
+#define __riscv_intrinsic_zvks 1
+#endif
+
+#if defined (__riscv_intrinsic_zvks) && defined (__riscv_intrinsic_zvbc)
+#define __riscv_intrinsic_zvksc 1
+#endif
+
+#if defined (__riscv_intrinsic_zvks) && defined (__riscv_intrinsic_zvkg)
+#define __riscv_intrinsic_zvksg 1
+#endif
+
 #ifdef __cplusplus
 extern "C" {
 #endif
index cb4182415433f04639fc8dc6e06e9e95ec8ad28a..841e7c8a64a9b9942da910d198c5b9c99ee387ee 100644 (file)
 #ifndef __SIFIVE_VECTOR_H
 #define __SIFIVE_VECTOR_H
 
+#define __riscv_intrinsic_xsfvcp 1
+#define __riscv_intrinsic_xsfvfnrclipxfqf 1
+#define __riscv_intrinsic_xsfvqmaccdod 1
+#define __riscv_intrinsic_xsfvqmaccqoq 1
+
 /* TODO: This should have a separate pragma to include only the SiFive
          vector intrinsics. For now, we are including riscv_vector.h. */
 #include <riscv_vector.h>
index be04402e09395bb64343d03b98fb93f1bec44920..e14d033267ddad4daf8240f6ec9f072fb254f15f 100644 (file)
@@ -27193,6 +27193,16 @@ of @var{bitval} is taken into account.
 These built-in functions are available for the RISC-V family of
 processors.
 
+RISC-V intrinsic headers define macros of the form
+@code{__riscv_intrinsic_@var{extension}} with the value @code{1} when
+GCC supports intrinsics for @var{extension}.  These macros indicate
+compiler support for the intrinsic API and are independent of whether the
+corresponding ISA extension is enabled for the current compilation unit.
+Include @file{riscv_bitmanip.h} for scalar bit-manipulation intrinsics,
+@file{riscv_crypto.h} for scalar cryptography intrinsics,
+@file{riscv_vector.h} for vector intrinsics, and vendor intrinsic
+headers for vendor intrinsic extensions.
+
 @defbuiltin{{void *} __builtin_thread_pointer (void)}
 Returns the value that is currently set in the @samp{tp} register.
 @enddefbuiltin
diff --git a/gcc/testsuite/gcc.target/riscv/intrinsic-detection-bitmanip.c b/gcc/testsuite/gcc.target/riscv/intrinsic-detection-bitmanip.c
new file mode 100644 (file)
index 0000000..8261639
--- /dev/null
@@ -0,0 +1,30 @@
+/* { dg-do preprocess } */
+/* { dg-options "-march=rv64gc -mabi=lp64d" } */
+
+#include <riscv_bitmanip.h>
+
+#if defined (__riscv_zbb) || defined (__riscv_zbc) \
+    || defined (__riscv_zbkb) || defined (__riscv_zbkc) \
+    || defined (__riscv_zbkx)
+#error "unexpected scalar bitmanip ISA extension macro"
+#endif
+
+#if !defined (__riscv_intrinsic_zbb) \
+    || !defined (__riscv_intrinsic_zbc) \
+    || !defined (__riscv_intrinsic_zbkb) \
+    || !defined (__riscv_intrinsic_zbkc) \
+    || !defined (__riscv_intrinsic_zbkx)
+#error "missing scalar bitmanip intrinsic detection macro"
+#endif
+
+#if defined (__riscv_intrinsic_zkn) || defined (__riscv_intrinsic_zks)
+#error "unexpected scalar crypto composite intrinsic detection macro"
+#endif
+
+#if __riscv_intrinsic_zbb != 1 \
+    || __riscv_intrinsic_zbc != 1 \
+    || __riscv_intrinsic_zbkb != 1 \
+    || __riscv_intrinsic_zbkc != 1 \
+    || __riscv_intrinsic_zbkx != 1
+#error "bad scalar bitmanip intrinsic detection macro value"
+#endif
diff --git a/gcc/testsuite/gcc.target/riscv/intrinsic-detection-crypto.c b/gcc/testsuite/gcc.target/riscv/intrinsic-detection-crypto.c
new file mode 100644 (file)
index 0000000..726f0d6
--- /dev/null
@@ -0,0 +1,30 @@
+/* { dg-do preprocess } */
+/* { dg-options "-march=rv64gc -mabi=lp64d" } */
+
+#include <riscv_crypto.h>
+
+#if defined (__riscv_zkne) || defined (__riscv_zknd) \
+    || defined (__riscv_zknh) || defined (__riscv_zksed) \
+    || defined (__riscv_zksh)
+#error "unexpected scalar crypto ISA extension macro"
+#endif
+
+#if !defined (__riscv_intrinsic_zknd) \
+    || !defined (__riscv_intrinsic_zkne) \
+    || !defined (__riscv_intrinsic_zknh) \
+    || !defined (__riscv_intrinsic_zksed) \
+    || !defined (__riscv_intrinsic_zksh)
+#error "missing scalar crypto intrinsic detection macro"
+#endif
+
+#if defined (__riscv_intrinsic_zkn) || defined (__riscv_intrinsic_zks)
+#error "unexpected scalar crypto composite intrinsic detection macro"
+#endif
+
+#if __riscv_intrinsic_zknd != 1 \
+    || __riscv_intrinsic_zkne != 1 \
+    || __riscv_intrinsic_zknh != 1 \
+    || __riscv_intrinsic_zksed != 1 \
+    || __riscv_intrinsic_zksh != 1
+#error "bad scalar crypto intrinsic detection macro value"
+#endif
diff --git a/gcc/testsuite/gcc.target/riscv/intrinsic-detection-scalar-reverse.c b/gcc/testsuite/gcc.target/riscv/intrinsic-detection-scalar-reverse.c
new file mode 100644 (file)
index 0000000..5bc6bbd
--- /dev/null
@@ -0,0 +1,13 @@
+/* { dg-do preprocess } */
+/* { dg-options "-march=rv64gc -mabi=lp64d" } */
+
+#include <riscv_crypto.h>
+#include <riscv_bitmanip.h>
+
+#if !defined (__riscv_intrinsic_zkn) || !defined (__riscv_intrinsic_zks)
+#error "missing scalar composite intrinsic detection macro"
+#endif
+
+#if __riscv_intrinsic_zkn != 1 || __riscv_intrinsic_zks != 1
+#error "bad scalar composite intrinsic detection macro value"
+#endif
diff --git a/gcc/testsuite/gcc.target/riscv/intrinsic-detection-scalar.c b/gcc/testsuite/gcc.target/riscv/intrinsic-detection-scalar.c
new file mode 100644 (file)
index 0000000..f60a76a
--- /dev/null
@@ -0,0 +1,44 @@
+/* { dg-do preprocess } */
+/* { dg-options "-march=rv64gc -mabi=lp64d" } */
+
+#include <riscv_bitmanip.h>
+#include <riscv_crypto.h>
+
+#if defined (__riscv_zbb) || defined (__riscv_zbc) \
+    || defined (__riscv_zbkb) || defined (__riscv_zbkc) \
+    || defined (__riscv_zbkx) || defined (__riscv_zkne) \
+    || defined (__riscv_zknd) || defined (__riscv_zknh) \
+    || defined (__riscv_zkn) || defined (__riscv_zks) \
+    || defined (__riscv_zksed) || defined (__riscv_zksh)
+#error "unexpected scalar ISA extension macro"
+#endif
+
+#if !defined (__riscv_intrinsic_zbb) \
+    || !defined (__riscv_intrinsic_zbc) \
+    || !defined (__riscv_intrinsic_zbkb) \
+    || !defined (__riscv_intrinsic_zbkc) \
+    || !defined (__riscv_intrinsic_zbkx) \
+    || !defined (__riscv_intrinsic_zkn) \
+    || !defined (__riscv_intrinsic_zknd) \
+    || !defined (__riscv_intrinsic_zkne) \
+    || !defined (__riscv_intrinsic_zknh) \
+    || !defined (__riscv_intrinsic_zks) \
+    || !defined (__riscv_intrinsic_zksed) \
+    || !defined (__riscv_intrinsic_zksh)
+#error "missing scalar intrinsic detection macro"
+#endif
+
+#if __riscv_intrinsic_zbb != 1 \
+    || __riscv_intrinsic_zbc != 1 \
+    || __riscv_intrinsic_zbkb != 1 \
+    || __riscv_intrinsic_zbkc != 1 \
+    || __riscv_intrinsic_zbkx != 1 \
+    || __riscv_intrinsic_zkn != 1 \
+    || __riscv_intrinsic_zknd != 1 \
+    || __riscv_intrinsic_zkne != 1 \
+    || __riscv_intrinsic_zknh != 1 \
+    || __riscv_intrinsic_zks != 1 \
+    || __riscv_intrinsic_zksed != 1 \
+    || __riscv_intrinsic_zksh != 1
+#error "bad scalar intrinsic detection macro value"
+#endif
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/intrinsic-detection.c b/gcc/testsuite/gcc.target/riscv/rvv/base/intrinsic-detection.c
new file mode 100644 (file)
index 0000000..d11cd26
--- /dev/null
@@ -0,0 +1,91 @@
+/* { dg-do preprocess } */
+/* { dg-options "-march=rv64gc -mabi=lp64d" } */
+
+#include <riscv_vector.h>
+#include <sifive_vector.h>
+#include <andes_vector.h>
+
+#if defined (__riscv_vector) || defined (__riscv_zvbb) \
+    || defined (__riscv_zve32f) || defined (__riscv_zve32x) \
+    || defined (__riscv_zve64d) || defined (__riscv_zve64f) \
+    || defined (__riscv_zve64x) \
+    || defined (__riscv_zvbc) || defined (__riscv_zvfbfmin) \
+    || defined (__riscv_zvfbfwma) || defined (__riscv_zvfh) \
+    || defined (__riscv_zvfhmin) || defined (__riscv_zvkb) \
+    || defined (__riscv_zvkg) || defined (__riscv_zvkned) \
+    || defined (__riscv_zvknha) || defined (__riscv_zvknhb) \
+    || defined (__riscv_zvksed) || defined (__riscv_zvksh)
+#error "unexpected vector ISA extension macro"
+#endif
+
+#if !defined (__riscv_intrinsic_v) \
+    || !defined (__riscv_intrinsic_zve32f) \
+    || !defined (__riscv_intrinsic_zve32x) \
+    || !defined (__riscv_intrinsic_zve64d) \
+    || !defined (__riscv_intrinsic_zve64f) \
+    || !defined (__riscv_intrinsic_zve64x) \
+    || !defined (__riscv_intrinsic_zvbb) \
+    || !defined (__riscv_intrinsic_zvbc) \
+    || !defined (__riscv_intrinsic_zvfbfmin) \
+    || !defined (__riscv_intrinsic_zvfbfwma) \
+    || !defined (__riscv_intrinsic_zvfh) \
+    || !defined (__riscv_intrinsic_zvfhmin) \
+    || !defined (__riscv_intrinsic_zvkb) \
+    || !defined (__riscv_intrinsic_zvkg) \
+    || !defined (__riscv_intrinsic_zvkn) \
+    || !defined (__riscv_intrinsic_zvknc) \
+    || !defined (__riscv_intrinsic_zvkned) \
+    || !defined (__riscv_intrinsic_zvkng) \
+    || !defined (__riscv_intrinsic_zvknha) \
+    || !defined (__riscv_intrinsic_zvknhb) \
+    || !defined (__riscv_intrinsic_zvks) \
+    || !defined (__riscv_intrinsic_zvksc) \
+    || !defined (__riscv_intrinsic_zvksed) \
+    || !defined (__riscv_intrinsic_zvksg) \
+    || !defined (__riscv_intrinsic_zvksh) \
+    || !defined (__riscv_intrinsic_xsfvcp) \
+    || !defined (__riscv_intrinsic_xsfvfnrclipxfqf) \
+    || !defined (__riscv_intrinsic_xsfvqmaccdod) \
+    || !defined (__riscv_intrinsic_xsfvqmaccqoq) \
+    || !defined (__riscv_intrinsic_xandesvbfhcvt) \
+    || !defined (__riscv_intrinsic_xandesvdot) \
+    || !defined (__riscv_intrinsic_xandesvpackfph) \
+    || !defined (__riscv_intrinsic_xandesvsintload)
+#error "missing vector intrinsic detection macro"
+#endif
+
+#if __riscv_intrinsic_v != 1 \
+    || __riscv_intrinsic_zve32f != 1 \
+    || __riscv_intrinsic_zve32x != 1 \
+    || __riscv_intrinsic_zve64d != 1 \
+    || __riscv_intrinsic_zve64f != 1 \
+    || __riscv_intrinsic_zve64x != 1 \
+    || __riscv_intrinsic_zvbb != 1 \
+    || __riscv_intrinsic_zvbc != 1 \
+    || __riscv_intrinsic_zvfbfmin != 1 \
+    || __riscv_intrinsic_zvfbfwma != 1 \
+    || __riscv_intrinsic_zvfh != 1 \
+    || __riscv_intrinsic_zvfhmin != 1 \
+    || __riscv_intrinsic_zvkb != 1 \
+    || __riscv_intrinsic_zvkg != 1 \
+    || __riscv_intrinsic_zvkn != 1 \
+    || __riscv_intrinsic_zvknc != 1 \
+    || __riscv_intrinsic_zvkned != 1 \
+    || __riscv_intrinsic_zvkng != 1 \
+    || __riscv_intrinsic_zvknha != 1 \
+    || __riscv_intrinsic_zvknhb != 1 \
+    || __riscv_intrinsic_zvks != 1 \
+    || __riscv_intrinsic_zvksc != 1 \
+    || __riscv_intrinsic_zvksed != 1 \
+    || __riscv_intrinsic_zvksg != 1 \
+    || __riscv_intrinsic_zvksh != 1 \
+    || __riscv_intrinsic_xsfvcp != 1 \
+    || __riscv_intrinsic_xsfvfnrclipxfqf != 1 \
+    || __riscv_intrinsic_xsfvqmaccdod != 1 \
+    || __riscv_intrinsic_xsfvqmaccqoq != 1 \
+    || __riscv_intrinsic_xandesvbfhcvt != 1 \
+    || __riscv_intrinsic_xandesvdot != 1 \
+    || __riscv_intrinsic_xandesvpackfph != 1 \
+    || __riscv_intrinsic_xandesvsintload != 1
+#error "bad vector intrinsic detection macro value"
+#endif