From: Christoph Müllner Date: Mon, 18 May 2026 11:42:33 +0000 (+0200) Subject: RISC-V: Add intrinsic detection macros X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=4e05c2ca43252e52a265d38c89b0f01abaeea6bd;p=thirdparty%2Fgcc.git 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_ 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 --- diff --git a/gcc/config/riscv/andes_vector.h b/gcc/config/riscv/andes_vector.h index 712ca77c27c..94355aec271 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 diff --git a/gcc/config/riscv/riscv_bitmanip.h b/gcc/config/riscv/riscv_bitmanip.h index ea0eb4fd6af..3cc9b7034d5 100644 --- a/gcc/config/riscv/riscv_bitmanip.h +++ b/gcc/config/riscv/riscv_bitmanip.h @@ -27,6 +27,31 @@ #include +#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 2f3f431ce29..23141286ff3 100644 --- a/gcc/config/riscv/riscv_crypto.h +++ b/gcc/config/riscv/riscv_crypto.h @@ -27,6 +27,31 @@ #include +#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 4128c75de86..bda75833ef2 100644 --- a/gcc/config/riscv/riscv_vector.h +++ b/gcc/config/riscv/riscv_vector.h @@ -28,6 +28,54 @@ #include #include +#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 cb418241543..841e7c8a64a 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 diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index be04402e093..e14d033267d 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 00000000000..826163977de --- /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 + +#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 00000000000..726f0d6327d --- /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 + +#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 00000000000..5bc6bbd6e23 --- /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 +#include + +#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 00000000000..f60a76afa65 --- /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 +#include + +#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 00000000000..d11cd26afa3 --- /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 +#include +#include + +#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