https://gcc.gnu.org/g:4e05c2ca43252e52a265d38c89b0f01abaeea6bd
commit r17-643-g4e05c2ca43252e52a265d38c89b0f01abaeea6bd Author: Christoph Müllner <[email protected]> Date: Mon May 18 13:42:33 2026 +0200 RISC-V: Add intrinsic detection macros 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 <[email protected]> Diff: --- gcc/config/riscv/andes_vector.h | 5 ++ gcc/config/riscv/riscv_bitmanip.h | 27 ++++++- gcc/config/riscv/riscv_crypto.h | 25 ++++++ gcc/config/riscv/riscv_vector.h | 48 ++++++++++++ gcc/config/riscv/sifive_vector.h | 5 ++ gcc/doc/extend.texi | 10 +++ .../riscv/intrinsic-detection-bitmanip.c | 30 +++++++ .../gcc.target/riscv/intrinsic-detection-crypto.c | 30 +++++++ .../riscv/intrinsic-detection-scalar-reverse.c | 13 ++++ .../gcc.target/riscv/intrinsic-detection-scalar.c | 44 +++++++++++ .../riscv/rvv/base/intrinsic-detection.c | 91 ++++++++++++++++++++++ 11 files changed, 327 insertions(+), 1 deletion(-) diff --git a/gcc/config/riscv/andes_vector.h b/gcc/config/riscv/andes_vector.h index 712ca77c27ca..94355aec2716 100644 --- a/gcc/config/riscv/andes_vector.h +++ b/gcc/config/riscv/andes_vector.h @@ -25,6 +25,11 @@ #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> diff --git a/gcc/config/riscv/riscv_bitmanip.h b/gcc/config/riscv/riscv_bitmanip.h index ea0eb4fd6af6..3cc9b7034d54 100644 --- a/gcc/config/riscv/riscv_bitmanip.h +++ b/gcc/config/riscv/riscv_bitmanip.h @@ -27,6 +27,31 @@ #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 diff --git a/gcc/config/riscv/riscv_crypto.h b/gcc/config/riscv/riscv_crypto.h index 2f3f431ce295..23141286ff36 100644 --- a/gcc/config/riscv/riscv_crypto.h +++ b/gcc/config/riscv/riscv_crypto.h @@ -27,6 +27,31 @@ #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 diff --git a/gcc/config/riscv/riscv_vector.h b/gcc/config/riscv/riscv_vector.h index 4128c75de86f..bda75833ef2e 100644 --- a/gcc/config/riscv/riscv_vector.h +++ b/gcc/config/riscv/riscv_vector.h @@ -28,6 +28,54 @@ #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 diff --git a/gcc/config/riscv/sifive_vector.h b/gcc/config/riscv/sifive_vector.h index cb4182415433..841e7c8a64a9 100644 --- a/gcc/config/riscv/sifive_vector.h +++ b/gcc/config/riscv/sifive_vector.h @@ -25,6 +25,11 @@ #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> diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index be04402e0939..e14d033267dd 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -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 index 000000000000..826163977dea --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/intrinsic-detection-bitmanip.c @@ -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 index 000000000000..726f0d6327dc --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/intrinsic-detection-crypto.c @@ -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 index 000000000000..5bc6bbd6e236 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/intrinsic-detection-scalar-reverse.c @@ -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 index 000000000000..f60a76afa650 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/intrinsic-detection-scalar.c @@ -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 index 000000000000..d11cd26afa38 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/intrinsic-detection.c @@ -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
