https://gcc.gnu.org/g:88d305a2de8bf5b7786c517f692e050082bb6787
commit r17-3847-g88d305a2de8bf5b7786c517f692e050082bb6787 Author: Haochen Jiang <[email protected]> Date: Wed Sep 2 16:38:39 2026 +0800 Initial support for ACEv1 ACEv1 is a new ISA documented here: https://x86ecosystem.org/resource/ai-compute-extensions-ace-specification/ In this patch, we will first add initial support for ACEv1. The instruction support will come afterwards. gcc/ChangeLog: * common/config/i386/cpuinfo.h (get_available_features): Add ACEV1. * common/config/i386/i386-common.cc (OPTION_MASK_ISA2_ACEV1_SET): New. (OPTION_MASK_ISA2_AVX10V2AUX_UNSET): Disable ACEV1. (OPTION_MASK_ISA2_ACEV1_UNSET): New. (ix86_handle_option): Handle ACEV1. * common/config/i386/i386-cpuinfo.h (enum processor_features): Add FEATURE_ACEV1. * common/config/i386/i386-isas.h: Handle acev1. * config/i386/cpuid.h (bit_ACE): New. * config/i386/i386-c.cc (ix86_target_macros_internal): Handle acev1. * config/i386/i386-isa.def (ACEV1): Add DEF_PTA. * config/i386/i386-options.cc (isa2_opts): Handle acev1. (ix86_valid_target_attribute_inner_p): Ditto. * config/i386/i386.opt: Add macev1. * config/i386/i386.opt.urls: Regenerated. * doc/extend.texi: Add acev1 documentation. * doc/invoke.texi: Ditto. * doc/sourcebuild.texi: Ditto. Co-authored-by: Dipesh Sharma <[email protected]> Diff: --- gcc/common/config/i386/cpuinfo.h | 46 ++++++++++++++++++++++++++++--- gcc/common/config/i386/i386-common.cc | 22 ++++++++++++++- gcc/common/config/i386/i386-cpuinfo.h | 1 + gcc/common/config/i386/i386-isas.h | 1 + gcc/config/i386/cpuid.h | 3 +++ gcc/config/i386/i386-c.cc | 2 ++ gcc/config/i386/i386-isa.def | 1 + gcc/config/i386/i386-options.cc | 4 ++- gcc/config/i386/i386.opt | 5 ++++ gcc/config/i386/i386.opt.urls | 3 +++ gcc/doc/extend.texi | 5 ++++ gcc/doc/invoke.texi | 8 +++++- gcc/doc/sourcebuild.texi | 51 ++++++++++++++++++----------------- 13 files changed, 122 insertions(+), 30 deletions(-) diff --git a/gcc/common/config/i386/cpuinfo.h b/gcc/common/config/i386/cpuinfo.h index 37dcd79e39ca..a689afabd3d1 100644 --- a/gcc/common/config/i386/cpuinfo.h +++ b/gcc/common/config/i386/cpuinfo.h @@ -802,8 +802,9 @@ get_available_features (struct __processor_model *cpu_model, #define XSTATE_ZMM 0x40 #define XSTATE_HI_ZMM 0x80 #define XSTATE_TILECFG 0x20000 -#define XSTATE_TILEDATA 0x40000 +#define XSTATE_TILEDATA 0x40000 #define XSTATE_APX_F 0x80000 +#define XSTATE_BSR 0x100000 #define XCR_AVX_ENABLED_MASK \ (XSTATE_SSE | XSTATE_YMM) @@ -811,17 +812,21 @@ get_available_features (struct __processor_model *cpu_model, (XSTATE_SSE | XSTATE_YMM | XSTATE_OPMASK | XSTATE_ZMM | XSTATE_HI_ZMM) #define XCR_AMX_ENABLED_MASK \ (XSTATE_TILECFG | XSTATE_TILEDATA) +#define XCR_ACE_ENABLED_MASK \ + (XSTATE_TILECFG | XSTATE_TILEDATA | XSTATE_BSR) #define XCR_APX_F_ENABLED_MASK XSTATE_APX_F - /* Check if AVX, AVX512 and APX are usable. */ + /* Check if AVX, AVX512, AMX, APX and ACE are usable. */ int avx_usable = 0; int avx512_usable = 0; int amx_usable = 0; int apx_usable = 0; + int ace_usable = 0; /* Check if KL is usable. */ int has_kl = 0; /* Record AVX10 version. */ int avx10_set = 0; + int ace_set = 0, avx10v2aux_set = 0; int version = 0; if ((ecx & bit_OSXSAVE)) { @@ -842,6 +847,8 @@ get_available_features (struct __processor_model *cpu_model, == XCR_AMX_ENABLED_MASK); apx_usable = ((xcrlow & XCR_APX_F_ENABLED_MASK) == XCR_APX_F_ENABLED_MASK); + ace_usable = ((xcrlow & XCR_ACE_ENABLED_MASK) + == XCR_ACE_ENABLED_MASK); } #define set_feature(f) \ @@ -1045,6 +1052,14 @@ get_available_features (struct __processor_model *cpu_model, if (edx & bit_AVX10) avx10_set = 1; } + if (avx10_set) + { + /* The XSTATE for vector registers has been checked + when setting avx10_set. */ + if (ace_usable) + if (ecx & bit_ACE) + ace_set = 1; + } if (amx_usable) { if (eax & bit_AMX_FP16) @@ -1133,7 +1148,32 @@ get_available_features (struct __processor_model *cpu_model, { __cpuid_count (0x24, 1, eax, ebx, ecx, edx); if (ecx & bit_AVX10V2AUX) - set_feature (FEATURE_AVX10V2AUX); + { + set_feature (FEATURE_AVX10V2AUX); + avx10v2aux_set = 1; + } + } + } + + /* Get Advanced Features at level 0x1d (eax = 0x1d). + ACE check must be put after AVX10 check to get AVX10 features. + TODO: Change the condition after AVX10V1AUX is added. */ + if (version >= 2 && avx10v2aux_set && ace_set && max_cpuid_level >= 0x1d) + { + __cpuid_count (0x1d, 0, eax, ebx, ecx, edx); + if (eax == 2) + { + __cpuid_count (0x1d, 2, eax, ebx, ecx, edx); + version = eax & 0xff; + switch (version) + { + case 1: + set_feature (FEATURE_ACEV1); + break; + default: + set_feature (FEATURE_ACEV1); + break; + } } } diff --git a/gcc/common/config/i386/i386-common.cc b/gcc/common/config/i386/i386-common.cc index 931e9d8a16d4..ed126f4c70dc 100644 --- a/gcc/common/config/i386/i386-common.cc +++ b/gcc/common/config/i386/i386-common.cc @@ -140,6 +140,9 @@ along with GCC; see the file COPYING3. If not see #define OPTION_MASK_ISA2_AVX512BMM_SET OPTION_MASK_ISA2_AVX512BMM #define OPTION_MASK_ISA2_AVX10V2AUX_SET \ (OPTION_MASK_ISA2_AVX10_1_SET | OPTION_MASK_ISA2_AVX10V2AUX) +#define OPTION_MASK_ISA2_ACEV1_SET \ + (OPTION_MASK_ISA2_AVX10V2AUX_SET | OPTION_MASK_ISA2_ACEV1) + /* SSE4 includes both SSE4.1 and SSE4.2. -msse4 should be the same as -msse4.2. */ #define OPTION_MASK_ISA_SSE4_SET OPTION_MASK_ISA_SSE4_2_SET @@ -332,7 +335,9 @@ along with GCC; see the file COPYING3. If not see #define OPTION_MASK_ISA2_MOVRS_UNSET OPTION_MASK_ISA2_MOVRS #define OPTION_MASK_ISA2_AMX_MOVRS_UNSET OPTION_MASK_ISA2_AMX_MOVRS #define OPTION_MASK_ISA2_AVX512BMM_UNSET OPTION_MASK_ISA2_AVX512BMM -#define OPTION_MASK_ISA2_AVX10V2AUX_UNSET OPTION_MASK_ISA2_AVX10V2AUX +#define OPTION_MASK_ISA2_AVX10V2AUX_UNSET \ + (OPTION_MASK_ISA2_AVX10V2AUX | OPTION_MASK_ISA2_ACEV1_UNSET) +#define OPTION_MASK_ISA2_ACEV1_UNSET OPTION_MASK_ISA2_ACEV1 /* SSE4 includes both SSE4.1 and SSE4.2. -mno-sse4 should the same as -mno-sse4.1. */ @@ -1488,6 +1493,21 @@ ix86_handle_option (struct gcc_options *opts, } return true; + case OPT_macev1: + if (value) + { + opts->x_ix86_isa_flags2 |= OPTION_MASK_ISA2_ACEV1_SET; + opts->x_ix86_isa_flags2_explicit |= OPTION_MASK_ISA2_ACEV1_SET; + opts->x_ix86_isa_flags |= OPTION_MASK_ISA_AVX10_1_SET; + opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_AVX10_1_SET; + } + else + { + opts->x_ix86_isa_flags2 &= ~OPTION_MASK_ISA2_ACEV1_UNSET; + opts->x_ix86_isa_flags2_explicit |= OPTION_MASK_ISA2_ACEV1_UNSET; + } + return true; + case OPT_mfma: if (value) { diff --git a/gcc/common/config/i386/i386-cpuinfo.h b/gcc/common/config/i386/i386-cpuinfo.h index dd3b4e46d8b8..ed989667e020 100644 --- a/gcc/common/config/i386/i386-cpuinfo.h +++ b/gcc/common/config/i386/i386-cpuinfo.h @@ -284,6 +284,7 @@ enum processor_features FEATURE_AMX_MOVRS, FEATURE_AVX512BMM, FEATURE_AVX10V2AUX, + FEATURE_ACEV1, CPU_FEATURE_MAX }; diff --git a/gcc/common/config/i386/i386-isas.h b/gcc/common/config/i386/i386-isas.h index d280418c2617..171226ab07b7 100644 --- a/gcc/common/config/i386/i386-isas.h +++ b/gcc/common/config/i386/i386-isas.h @@ -193,4 +193,5 @@ ISA_NAMES_TABLE_START ISA_NAMES_TABLE_ENTRY("avx512bmm", FEATURE_AVX512BMM, P_NONE, "-mavx512bmm") ISA_NAMES_TABLE_ENTRY("avx10v2aux", FEATURE_AVX10V2AUX, P_NONE, "-mavx10v2aux") + ISA_NAMES_TABLE_ENTRY("acev1", FEATURE_ACEV1, P_NONE, "-macev1") ISA_NAMES_TABLE_END diff --git a/gcc/config/i386/cpuid.h b/gcc/config/i386/cpuid.h index 4a21672a9be1..c40970df872d 100644 --- a/gcc/config/i386/cpuid.h +++ b/gcc/config/i386/cpuid.h @@ -145,6 +145,9 @@ #define bit_AVXIFMA (1 << 23) #define bit_MOVRS (1 << 31) +/* %ecx */ +#define bit_ACE (1 << 11) + /* %edx */ #define bit_AVXVNNIINT8 (1 << 4) #define bit_AVXNECONVERT (1 << 5) diff --git a/gcc/config/i386/i386-c.cc b/gcc/config/i386/i386-c.cc index 4c56ff6dad9c..f6a4093c2776 100644 --- a/gcc/config/i386/i386-c.cc +++ b/gcc/config/i386/i386-c.cc @@ -792,6 +792,8 @@ ix86_target_macros_internal (HOST_WIDE_INT isa_flag, def_or_undef (parse_in, "__AVX512BMM__"); if (isa_flag2 & OPTION_MASK_ISA2_AVX10V2AUX) def_or_undef (parse_in, "__AVX10V2AUX__"); + if (isa_flag2 & OPTION_MASK_ISA2_ACEV1) + def_or_undef (parse_in, "__ACEV1__"); if (TARGET_IAMCU) { def_or_undef (parse_in, "__iamcu"); diff --git a/gcc/config/i386/i386-isa.def b/gcc/config/i386/i386-isa.def index e50cb6768fa7..28835b1d542e 100644 --- a/gcc/config/i386/i386-isa.def +++ b/gcc/config/i386/i386-isa.def @@ -126,3 +126,4 @@ DEF_PTA(MOVRS) DEF_PTA(AMX_MOVRS) DEF_PTA(AVX512BMM) DEF_PTA(AVX10V2AUX) +DEF_PTA(ACEV1) diff --git a/gcc/config/i386/i386-options.cc b/gcc/config/i386/i386-options.cc index e7f06154103b..37bb75a75c2f 100644 --- a/gcc/config/i386/i386-options.cc +++ b/gcc/config/i386/i386-options.cc @@ -275,7 +275,8 @@ static struct ix86_target_opts isa2_opts[] = { "-mmovrs", OPTION_MASK_ISA2_MOVRS }, { "-mamx-movrs", OPTION_MASK_ISA2_AMX_MOVRS }, { "-mavx512bmm", OPTION_MASK_ISA2_AVX512BMM }, - { "-mavx10v2aux", OPTION_MASK_ISA2_AVX10V2AUX } + { "-mavx10v2aux", OPTION_MASK_ISA2_AVX10V2AUX }, + { "-macev1", OPTION_MASK_ISA2_ACEV1 } }; static struct ix86_target_opts isa_opts[] = { @@ -1141,6 +1142,7 @@ ix86_valid_target_attribute_inner_p (tree fndecl, tree args, char *p_strings[], IX86_ATTR_ISA ("amx-movrs", OPT_mamx_movrs), IX86_ATTR_ISA ("avx512bmm", OPT_mavx512bmm), IX86_ATTR_ISA ("avx10v2aux", OPT_mavx10v2aux), + IX86_ATTR_ISA ("acev1", OPT_macev1), /* enum options */ IX86_ATTR_ENUM ("fpmath=", OPT_mfpmath_), diff --git a/gcc/config/i386/i386.opt b/gcc/config/i386/i386.opt index 57ba3fbfa8f1..f9aeeac08faf 100644 --- a/gcc/config/i386/i386.opt +++ b/gcc/config/i386/i386.opt @@ -1394,3 +1394,8 @@ mavx10v2aux Target Mask(ISA2_AVX10V2AUX) Var(ix86_isa_flags2) Save Support MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, AVX, AVX2, AVX10.1 and AVX10V2AUX built-in functions and code generation. + +macev1 +Target Mask(ISA2_ACEV1) Var(ix86_isa_flags2) Save +Support MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, AVX, AVX2, +AVX10.1 and ACEV1 built-in functions and code generation. diff --git a/gcc/config/i386/i386.opt.urls b/gcc/config/i386/i386.opt.urls index d52e6de80146..5cfa30c07e3b 100644 --- a/gcc/config/i386/i386.opt.urls +++ b/gcc/config/i386/i386.opt.urls @@ -638,3 +638,6 @@ UrlSuffix(gcc/x86-Options.html#index-mavx512bmm) mavx10v2aux UrlSuffix(gcc/x86-Options.html#index-mavx10v2aux) +macev1 +UrlSuffix(gcc/x86-Options.html#index-macev1) + diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index 397b05ab87da..a4981eb0debd 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -9566,6 +9566,11 @@ Enable/disable the generation of the AMX-MOVRS instructions. @itemx no-avx10v2aux Enable/disable the generation of the AVX10V2AUX instructions. +@atindex @code{target("acev1")}, x86 +@item acev1 +@itemx no-acev1 +Enable/disable the generation of the ACEV1 instructions. + @atindex @code{target("cld")}, x86 @item cld @itemx no-cld diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index e1870c9c227b..86a00df78cf6 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -1553,7 +1553,7 @@ See RS/6000 and PowerPC Options. -mavxneconvert -mcmpccxadd -mamx-fp16 -mprefetchi -mraoint -mamx-complex -mavxvnniint16 -msm3 -msha512 -msm4 -mapxf -musermsr -mavx10.1 -mavx10.2 -mamx-avx512 -mmovrs -mamx-movrs --mavx512bmm -mavx10v2aux +-mavx512bmm -mavx10v2aux -macev1 -mcldemote -mms-bitfields -mno-align-stringops -minline-all-stringops -minline-stringops-dynamically -mstringop-strategy=@var{alg} -mkl -mwidekl @@ -36309,6 +36309,12 @@ Support AMX-MOVRS built-in functions and code generation. @item -mavx10v2aux Support MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, AVX, AVX2, AVX10.1 and AVX10V2AUX built-in functions and code generation. + +@opindex macev1 +@opindex mno-acev1 +@item -macev1 +Support MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, AVX, AVX2, +AVX10.1 and ACEV1 built-in functions and code generation. @end table These additional options are available for the x86 processor family. diff --git a/gcc/doc/sourcebuild.texi b/gcc/doc/sourcebuild.texi index aad51550eba4..b02cb28db512 100644 --- a/gcc/doc/sourcebuild.texi +++ b/gcc/doc/sourcebuild.texi @@ -2682,6 +2682,33 @@ Test system has support for the CORE-V BI extension. @item autoincdec Target supports autoincrement/decrement addressing. +@item acev1 +Target supports the execution of @code{acev1} instructions. + +@item amx_avx512 +Target supports the execution of @code{amx-avx512} instructions. + +@item amx_bf16 +Target supports the execution of @code{amx-bf16} instructions. + +@item amx_complex +Target supports the execution of @code{amx-complex} instructions. + +@item amx_fp16 +Target supports the execution of @code{amx-fp16} instructions. + +@item amx_fp8 +Target supports the execution of @code{amx-fp8} instructions. + +@item amx_int8 +Target supports the execution of @code{amx-int8} instructions. + +@item amx_movrs +Target supports the execution of @code{amx-movrs} instructions. + +@item amx_tile +Target supports the execution of @code{amx-tile} instructions. + @item avx Target supports compiling @code{avx} instructions. @@ -2727,30 +2754,6 @@ Target supports the execution of @code{avxvnniint8} instructions. @item avxvnniint16 Target supports the execution of @code{avxvnniint16} instructions. -@item amx_tile -Target supports the execution of @code{amx-tile} instructions. - -@item amx_int8 -Target supports the execution of @code{amx-int8} instructions. - -@item amx_bf16 -Target supports the execution of @code{amx-bf16} instructions. - -@item amx_avx512 -Target supports the execution of @code{amx-avx512} instructions. - -@item amx_complex -Target supports the execution of @code{amx-complex} instructions. - -@item amx_fp16 -Target supports the execution of @code{amx-fp16} instructions. - -@item amx_movrs -Target supports the execution of @code{amx-movrs} instructions. - -@item amx_fp8 -Target supports the execution of @code{amx-fp8} instructions. - @item can_deref_null Target runtime permits dereferencing a null pointer without trapping, for example because address zero is mapped and readable.
