diff mbox series

[v2] x86: Add support for AVX10 version and vec size in cpu-features

Message ID 20230824191430.3220651-1-goldstein.w.n@gmail.com
State New
Headers show
Series [v2] x86: Add support for AVX10 version and vec size in cpu-features | expand

Commit Message

Noah Goldstein Aug. 24, 2023, 7:14 p.m. UTC
This commit add support for the new AVX10 cpu features:
https://cdrdv2-public.intel.com/784267/355989-intel-avx10-spec.pdf

We add checks for:
    - `AVX10`: Check if AVX10 is present.
    - `AVX10_V{1..255}`: Check if a given version is active.
    - `AVX10_{X,Y,Z}MM`: Check if a given vec class has AVX10 support.

The version checks are not ideal, the reason for the reason for this
is the version information in AVX10 is encoded as complete a byte
value, but the `CPU_FEATURES` interface is only able to query bools.

To get around this, we add a feature for each possible version value
(starting at 1 as there is no AVX10 version 0).

`make check` passes and cpuid output was checked against GNR/DMR on an
emulator.
---
 manual/platform.texi               |  28 +++
 sysdeps/x86/bits/platform/x86.h    | 281 ++++++++++++++++++++++++++++-
 sysdeps/x86/cpu-features.c         |  25 +++
 sysdeps/x86/include/cpu-features.h |  27 ++-
 sysdeps/x86/sys/platform/x86.h     |  40 ++++
 sysdeps/x86/tst-get-cpu-features.c | 263 +++++++++++++++++++++++++++
 6 files changed, 661 insertions(+), 3 deletions(-)

Comments

Florian Weimer Aug. 25, 2023, 7:12 a.m. UTC | #1
* Noah Goldstein via Libc-alpha:

> +/* AVX10 version information is handled differently from all other CPUID
> +   related logic.  Rather than being encoded in cpuid as discrete booleans, the
> +   AVX10 version is encoded is a full byte that represents the version number
> +   (greater than or equal to 1).  Since the CPUID API is only able to handle
> +   boolean returns, we enumerate `x86_cpu_AVX10_V{1..255}` which can be queried
> +   by the user and have special logic in `x86_cpu_{present,active}`.  This is
> +   unpleasant on our end, but is the only way to make the existing API also
> +   support version queries.  */
> +
> +  /* All 1s should never be a value feature index.  */
> +  x86_cpu_AVX10_V255 = ~0,
> +  x86_cpu_AVX10_V254 = x86_cpu_AVX10_V255 - 1,
> +  x86_cpu_AVX10_V253 = x86_cpu_AVX10_V254 - 1,
> +  x86_cpu_AVX10_V252 = x86_cpu_AVX10_V253 - 1,
> +  x86_cpu_AVX10_V251 = x86_cpu_AVX10_V252 - 1,

Is this really necessary?  We can define an x86_cpu_avx10_version inline
function that calls __x86_get_cpuid_feature_leaf and extracts the
version byte.  Is it really necessary to support something like this?

  CPU_FEATURE_ACTIVE (AVX10_V2)

This would be the alternative:

  x86_cpu_avx10_version () >= 2

Let's hope that version 0 means no AVX10. 8-)

Thanks,
Florian
Noah Goldstein Aug. 25, 2023, 5:39 p.m. UTC | #2
On Fri, Aug 25, 2023 at 2:12 AM Florian Weimer <fweimer@redhat.com> wrote:
>
> * Noah Goldstein via Libc-alpha:
>
> > +/* AVX10 version information is handled differently from all other CPUID
> > +   related logic.  Rather than being encoded in cpuid as discrete booleans, the
> > +   AVX10 version is encoded is a full byte that represents the version number
> > +   (greater than or equal to 1).  Since the CPUID API is only able to handle
> > +   boolean returns, we enumerate `x86_cpu_AVX10_V{1..255}` which can be queried
> > +   by the user and have special logic in `x86_cpu_{present,active}`.  This is
> > +   unpleasant on our end, but is the only way to make the existing API also
> > +   support version queries.  */
> > +
> > +  /* All 1s should never be a value feature index.  */
> > +  x86_cpu_AVX10_V255 = ~0,
> > +  x86_cpu_AVX10_V254 = x86_cpu_AVX10_V255 - 1,
> > +  x86_cpu_AVX10_V253 = x86_cpu_AVX10_V254 - 1,
> > +  x86_cpu_AVX10_V252 = x86_cpu_AVX10_V253 - 1,
> > +  x86_cpu_AVX10_V251 = x86_cpu_AVX10_V252 - 1,
>
> Is this really necessary?  We can define an x86_cpu_avx10_version inline
> function that calls __x86_get_cpuid_feature_leaf and extracts the
> version byte.  Is it really necessary to support something like this?
>

I agree it's not the best API. My feelings are two fold on this.
1) The existing API that users know should support the feature, even if its
not the best way for users query the logic. Adding support for specific version
queries in CPU_FEATURE_{ACTIVE,PRESENT} doesn't prevent us from
adding an API that allows for querying the full byte. But only adding the byte
might be disruptive to users that expect to be able to do all their querying
through the existing API.
2) For a lot of use cases, this is sufficient. Currently we only have
two versions
and I think the common use case is not "is feature above level X?",
but "do I have
feature X?". The latter can reasonably be supported with a single query of:
CPU_FEATURE_{ACTIVE,PRESENT}(AVX10_<MIN_VERSION_WITH_X>).

>   CPU_FEATURE_ACTIVE (AVX10_V2)
>
> This would be the alternative:
>
>   x86_cpu_avx10_version () >= 2
>
We do plan to propose a new byte API in a follow up :)

> Let's hope that version 0 means no AVX10. 8-)
>
versions start at 1.



> Thanks,
> Florian
>
Noah Goldstein Sept. 1, 2023, 6:52 p.m. UTC | #3
On Fri, Aug 25, 2023 at 12:39 PM Noah Goldstein <goldstein.w.n@gmail.com> wrote:
>
> On Fri, Aug 25, 2023 at 2:12 AM Florian Weimer <fweimer@redhat.com> wrote:
> >
> > * Noah Goldstein via Libc-alpha:
> >
> > > +/* AVX10 version information is handled differently from all other CPUID
> > > +   related logic.  Rather than being encoded in cpuid as discrete booleans, the
> > > +   AVX10 version is encoded is a full byte that represents the version number
> > > +   (greater than or equal to 1).  Since the CPUID API is only able to handle
> > > +   boolean returns, we enumerate `x86_cpu_AVX10_V{1..255}` which can be queried
> > > +   by the user and have special logic in `x86_cpu_{present,active}`.  This is
> > > +   unpleasant on our end, but is the only way to make the existing API also
> > > +   support version queries.  */
> > > +
> > > +  /* All 1s should never be a value feature index.  */
> > > +  x86_cpu_AVX10_V255 = ~0,
> > > +  x86_cpu_AVX10_V254 = x86_cpu_AVX10_V255 - 1,
> > > +  x86_cpu_AVX10_V253 = x86_cpu_AVX10_V254 - 1,
> > > +  x86_cpu_AVX10_V252 = x86_cpu_AVX10_V253 - 1,
> > > +  x86_cpu_AVX10_V251 = x86_cpu_AVX10_V252 - 1,
> >
> > Is this really necessary?  We can define an x86_cpu_avx10_version inline
> > function that calls __x86_get_cpuid_feature_leaf and extracts the
> > version byte.  Is it really necessary to support something like this?
> >
>
> I agree it's not the best API. My feelings are two fold on this.
> 1) The existing API that users know should support the feature, even if its
> not the best way for users query the logic. Adding support for specific version
> queries in CPU_FEATURE_{ACTIVE,PRESENT} doesn't prevent us from
> adding an API that allows for querying the full byte. But only adding the byte
> might be disruptive to users that expect to be able to do all their querying
> through the existing API.
> 2) For a lot of use cases, this is sufficient. Currently we only have
> two versions
> and I think the common use case is not "is feature above level X?",
> but "do I have
> feature X?". The latter can reasonably be supported with a single query of:
> CPU_FEATURE_{ACTIVE,PRESENT}(AVX10_<MIN_VERSION_WITH_X>).
>
> >   CPU_FEATURE_ACTIVE (AVX10_V2)
> >
> > This would be the alternative:
> >
> >   x86_cpu_avx10_version () >= 2
> >
> We do plan to propose a new byte API in a follow up :)
>
> > Let's hope that version 0 means no AVX10. 8-)
> >
> versions start at 1.
>
>
>
> > Thanks,
> > Florian
> >

Ping.
Florian, you okay with this going in?
Noah Goldstein Sept. 8, 2023, 4:55 a.m. UTC | #4
On Fri, Sep 1, 2023 at 1:52 PM Noah Goldstein <goldstein.w.n@gmail.com> wrote:
>
> On Fri, Aug 25, 2023 at 12:39 PM Noah Goldstein <goldstein.w.n@gmail.com> wrote:
> >
> > On Fri, Aug 25, 2023 at 2:12 AM Florian Weimer <fweimer@redhat.com> wrote:
> > >
> > > * Noah Goldstein via Libc-alpha:
> > >
> > > > +/* AVX10 version information is handled differently from all other CPUID
> > > > +   related logic.  Rather than being encoded in cpuid as discrete booleans, the
> > > > +   AVX10 version is encoded is a full byte that represents the version number
> > > > +   (greater than or equal to 1).  Since the CPUID API is only able to handle
> > > > +   boolean returns, we enumerate `x86_cpu_AVX10_V{1..255}` which can be queried
> > > > +   by the user and have special logic in `x86_cpu_{present,active}`.  This is
> > > > +   unpleasant on our end, but is the only way to make the existing API also
> > > > +   support version queries.  */
> > > > +
> > > > +  /* All 1s should never be a value feature index.  */
> > > > +  x86_cpu_AVX10_V255 = ~0,
> > > > +  x86_cpu_AVX10_V254 = x86_cpu_AVX10_V255 - 1,
> > > > +  x86_cpu_AVX10_V253 = x86_cpu_AVX10_V254 - 1,
> > > > +  x86_cpu_AVX10_V252 = x86_cpu_AVX10_V253 - 1,
> > > > +  x86_cpu_AVX10_V251 = x86_cpu_AVX10_V252 - 1,
> > >
> > > Is this really necessary?  We can define an x86_cpu_avx10_version inline
> > > function that calls __x86_get_cpuid_feature_leaf and extracts the
> > > version byte.  Is it really necessary to support something like this?
> > >
> >
> > I agree it's not the best API. My feelings are two fold on this.
> > 1) The existing API that users know should support the feature, even if its
> > not the best way for users query the logic. Adding support for specific version
> > queries in CPU_FEATURE_{ACTIVE,PRESENT} doesn't prevent us from
> > adding an API that allows for querying the full byte. But only adding the byte
> > might be disruptive to users that expect to be able to do all their querying
> > through the existing API.
> > 2) For a lot of use cases, this is sufficient. Currently we only have
> > two versions
> > and I think the common use case is not "is feature above level X?",
> > but "do I have
> > feature X?". The latter can reasonably be supported with a single query of:
> > CPU_FEATURE_{ACTIVE,PRESENT}(AVX10_<MIN_VERSION_WITH_X>).
> >
> > >   CPU_FEATURE_ACTIVE (AVX10_V2)
> > >
> > > This would be the alternative:
> > >
> > >   x86_cpu_avx10_version () >= 2
> > >
> > We do plan to propose a new byte API in a follow up :)
> >
> > > Let's hope that version 0 means no AVX10. 8-)
> > >
> > versions start at 1.
> >
> >
> >
> > > Thanks,
> > > Florian
> > >
>
> Ping.
> Florian, you okay with this going in?

Ping
diff mbox series

Patch

diff --git a/manual/platform.texi b/manual/platform.texi
index 2a2d557067..99dc57b568 100644
--- a/manual/platform.texi
+++ b/manual/platform.texi
@@ -222,6 +222,22 @@  Leaf (EAX = 23H).
 @item
 @code{AVX} -- The AVX instruction extensions.
 
+@item
+@code{AVX10} -- The AVX10 instruction extensions.
+
+@item
+@code{AVX10_XMM} -- Whether AVX10 includes xmm registers.
+
+@item
+@code{AVX10_YMM} -- Whether AVX10 includes ymm registers.
+
+@item
+@code{AVX10_ZMM} -- Whether AVX10 includes zmm registers.
+
+@item
+@code{AVX10_V1}..@code{AVX10_V255} -- Whether AVX10 supports a given
+version.
+
 @item
 @code{AVX2} -- The AVX2 instruction extensions.
 
@@ -760,3 +776,15 @@  avx_active (void)
   return CPU_FEATURE_ACTIVE (AVX);
 @}
 @end smallexample
+
+You could query @code{AVX10} version number with:
+
+@smallexample
+#include <sys/platform/x86.h>
+
+int
+has_avx10_version1 (void)
+@{
+  return CPU_FEATURE_ACTIVE (AVX10_V1); // Up to AVX10_V255
+@}
+@end smallexample
diff --git a/sysdeps/x86/bits/platform/x86.h b/sysdeps/x86/bits/platform/x86.h
index 88ca071aa7..777fb6ce18 100644
--- a/sysdeps/x86/bits/platform/x86.h
+++ b/sysdeps/x86/bits/platform/x86.h
@@ -30,7 +30,8 @@  enum
   CPUID_INDEX_80000008,
   CPUID_INDEX_7_ECX_1,
   CPUID_INDEX_19,
-  CPUID_INDEX_14_ECX_0
+  CPUID_INDEX_14_ECX_0,
+  CPUID_INDEX_24_ECX_0
 };
 
 struct cpuid_feature
@@ -312,6 +313,7 @@  enum
   x86_cpu_AVX_NE_CONVERT	= x86_cpu_index_7_ecx_1_edx + 5,
   x86_cpu_AMX_COMPLEX		= x86_cpu_index_7_ecx_1_edx + 8,
   x86_cpu_PREFETCHI		= x86_cpu_index_7_ecx_1_edx + 14,
+  x86_cpu_AVX10			= x86_cpu_index_7_ecx_1_edx + 19,
   x86_cpu_APX_F			= x86_cpu_index_7_ecx_1_edx + 21,
 
   x86_cpu_index_19_ebx
@@ -325,5 +327,280 @@  enum
     = (CPUID_INDEX_14_ECX_0 * 8 * 4 * sizeof (unsigned int)
        + cpuid_register_index_ebx * 8 * sizeof (unsigned int)),
 
-  x86_cpu_PTWRITE		= x86_cpu_index_14_ecx_0_ebx + 4
+  x86_cpu_PTWRITE		= x86_cpu_index_14_ecx_0_ebx + 4,
+
+  x86_cpu_index_24_ecx_0_ebx
+    = (CPUID_INDEX_24_ECX_0 * 8 * 4 * sizeof (unsigned int)
+       + cpuid_register_index_ebx * 8 * sizeof (unsigned int)),
+
+  x86_cpu_AVX10_XMM = x86_cpu_index_24_ecx_0_ebx + 16,
+  x86_cpu_AVX10_YMM = x86_cpu_index_24_ecx_0_ebx + 17,
+  x86_cpu_AVX10_ZMM = x86_cpu_index_24_ecx_0_ebx + 18,
+
+/* AVX10 version information is handled differently from all other CPUID
+   related logic.  Rather than being encoded in cpuid as discrete booleans, the
+   AVX10 version is encoded is a full byte that represents the version number
+   (greater than or equal to 1).  Since the CPUID API is only able to handle
+   boolean returns, we enumerate `x86_cpu_AVX10_V{1..255}` which can be queried
+   by the user and have special logic in `x86_cpu_{present,active}`.  This is
+   unpleasant on our end, but is the only way to make the existing API also
+   support version queries.  */
+
+  /* All 1s should never be a value feature index.  */
+  x86_cpu_AVX10_V255 = ~0,
+  x86_cpu_AVX10_V254 = x86_cpu_AVX10_V255 - 1,
+  x86_cpu_AVX10_V253 = x86_cpu_AVX10_V254 - 1,
+  x86_cpu_AVX10_V252 = x86_cpu_AVX10_V253 - 1,
+  x86_cpu_AVX10_V251 = x86_cpu_AVX10_V252 - 1,
+  x86_cpu_AVX10_V250 = x86_cpu_AVX10_V251 - 1,
+  x86_cpu_AVX10_V249 = x86_cpu_AVX10_V250 - 1,
+  x86_cpu_AVX10_V248 = x86_cpu_AVX10_V249 - 1,
+  x86_cpu_AVX10_V247 = x86_cpu_AVX10_V248 - 1,
+  x86_cpu_AVX10_V246 = x86_cpu_AVX10_V247 - 1,
+  x86_cpu_AVX10_V245 = x86_cpu_AVX10_V246 - 1,
+  x86_cpu_AVX10_V244 = x86_cpu_AVX10_V245 - 1,
+  x86_cpu_AVX10_V243 = x86_cpu_AVX10_V244 - 1,
+  x86_cpu_AVX10_V242 = x86_cpu_AVX10_V243 - 1,
+  x86_cpu_AVX10_V241 = x86_cpu_AVX10_V242 - 1,
+  x86_cpu_AVX10_V240 = x86_cpu_AVX10_V241 - 1,
+  x86_cpu_AVX10_V239 = x86_cpu_AVX10_V240 - 1,
+  x86_cpu_AVX10_V238 = x86_cpu_AVX10_V239 - 1,
+  x86_cpu_AVX10_V237 = x86_cpu_AVX10_V238 - 1,
+  x86_cpu_AVX10_V236 = x86_cpu_AVX10_V237 - 1,
+  x86_cpu_AVX10_V235 = x86_cpu_AVX10_V236 - 1,
+  x86_cpu_AVX10_V234 = x86_cpu_AVX10_V235 - 1,
+  x86_cpu_AVX10_V233 = x86_cpu_AVX10_V234 - 1,
+  x86_cpu_AVX10_V232 = x86_cpu_AVX10_V233 - 1,
+  x86_cpu_AVX10_V231 = x86_cpu_AVX10_V232 - 1,
+  x86_cpu_AVX10_V230 = x86_cpu_AVX10_V231 - 1,
+  x86_cpu_AVX10_V229 = x86_cpu_AVX10_V230 - 1,
+  x86_cpu_AVX10_V228 = x86_cpu_AVX10_V229 - 1,
+  x86_cpu_AVX10_V227 = x86_cpu_AVX10_V228 - 1,
+  x86_cpu_AVX10_V226 = x86_cpu_AVX10_V227 - 1,
+  x86_cpu_AVX10_V225 = x86_cpu_AVX10_V226 - 1,
+  x86_cpu_AVX10_V224 = x86_cpu_AVX10_V225 - 1,
+  x86_cpu_AVX10_V223 = x86_cpu_AVX10_V224 - 1,
+  x86_cpu_AVX10_V222 = x86_cpu_AVX10_V223 - 1,
+  x86_cpu_AVX10_V221 = x86_cpu_AVX10_V222 - 1,
+  x86_cpu_AVX10_V220 = x86_cpu_AVX10_V221 - 1,
+  x86_cpu_AVX10_V219 = x86_cpu_AVX10_V220 - 1,
+  x86_cpu_AVX10_V218 = x86_cpu_AVX10_V219 - 1,
+  x86_cpu_AVX10_V217 = x86_cpu_AVX10_V218 - 1,
+  x86_cpu_AVX10_V216 = x86_cpu_AVX10_V217 - 1,
+  x86_cpu_AVX10_V215 = x86_cpu_AVX10_V216 - 1,
+  x86_cpu_AVX10_V214 = x86_cpu_AVX10_V215 - 1,
+  x86_cpu_AVX10_V213 = x86_cpu_AVX10_V214 - 1,
+  x86_cpu_AVX10_V212 = x86_cpu_AVX10_V213 - 1,
+  x86_cpu_AVX10_V211 = x86_cpu_AVX10_V212 - 1,
+  x86_cpu_AVX10_V210 = x86_cpu_AVX10_V211 - 1,
+  x86_cpu_AVX10_V209 = x86_cpu_AVX10_V210 - 1,
+  x86_cpu_AVX10_V208 = x86_cpu_AVX10_V209 - 1,
+  x86_cpu_AVX10_V207 = x86_cpu_AVX10_V208 - 1,
+  x86_cpu_AVX10_V206 = x86_cpu_AVX10_V207 - 1,
+  x86_cpu_AVX10_V205 = x86_cpu_AVX10_V206 - 1,
+  x86_cpu_AVX10_V204 = x86_cpu_AVX10_V205 - 1,
+  x86_cpu_AVX10_V203 = x86_cpu_AVX10_V204 - 1,
+  x86_cpu_AVX10_V202 = x86_cpu_AVX10_V203 - 1,
+  x86_cpu_AVX10_V201 = x86_cpu_AVX10_V202 - 1,
+  x86_cpu_AVX10_V200 = x86_cpu_AVX10_V201 - 1,
+  x86_cpu_AVX10_V199 = x86_cpu_AVX10_V200 - 1,
+  x86_cpu_AVX10_V198 = x86_cpu_AVX10_V199 - 1,
+  x86_cpu_AVX10_V197 = x86_cpu_AVX10_V198 - 1,
+  x86_cpu_AVX10_V196 = x86_cpu_AVX10_V197 - 1,
+  x86_cpu_AVX10_V195 = x86_cpu_AVX10_V196 - 1,
+  x86_cpu_AVX10_V194 = x86_cpu_AVX10_V195 - 1,
+  x86_cpu_AVX10_V193 = x86_cpu_AVX10_V194 - 1,
+  x86_cpu_AVX10_V192 = x86_cpu_AVX10_V193 - 1,
+  x86_cpu_AVX10_V191 = x86_cpu_AVX10_V192 - 1,
+  x86_cpu_AVX10_V190 = x86_cpu_AVX10_V191 - 1,
+  x86_cpu_AVX10_V189 = x86_cpu_AVX10_V190 - 1,
+  x86_cpu_AVX10_V188 = x86_cpu_AVX10_V189 - 1,
+  x86_cpu_AVX10_V187 = x86_cpu_AVX10_V188 - 1,
+  x86_cpu_AVX10_V186 = x86_cpu_AVX10_V187 - 1,
+  x86_cpu_AVX10_V185 = x86_cpu_AVX10_V186 - 1,
+  x86_cpu_AVX10_V184 = x86_cpu_AVX10_V185 - 1,
+  x86_cpu_AVX10_V183 = x86_cpu_AVX10_V184 - 1,
+  x86_cpu_AVX10_V182 = x86_cpu_AVX10_V183 - 1,
+  x86_cpu_AVX10_V181 = x86_cpu_AVX10_V182 - 1,
+  x86_cpu_AVX10_V180 = x86_cpu_AVX10_V181 - 1,
+  x86_cpu_AVX10_V179 = x86_cpu_AVX10_V180 - 1,
+  x86_cpu_AVX10_V178 = x86_cpu_AVX10_V179 - 1,
+  x86_cpu_AVX10_V177 = x86_cpu_AVX10_V178 - 1,
+  x86_cpu_AVX10_V176 = x86_cpu_AVX10_V177 - 1,
+  x86_cpu_AVX10_V175 = x86_cpu_AVX10_V176 - 1,
+  x86_cpu_AVX10_V174 = x86_cpu_AVX10_V175 - 1,
+  x86_cpu_AVX10_V173 = x86_cpu_AVX10_V174 - 1,
+  x86_cpu_AVX10_V172 = x86_cpu_AVX10_V173 - 1,
+  x86_cpu_AVX10_V171 = x86_cpu_AVX10_V172 - 1,
+  x86_cpu_AVX10_V170 = x86_cpu_AVX10_V171 - 1,
+  x86_cpu_AVX10_V169 = x86_cpu_AVX10_V170 - 1,
+  x86_cpu_AVX10_V168 = x86_cpu_AVX10_V169 - 1,
+  x86_cpu_AVX10_V167 = x86_cpu_AVX10_V168 - 1,
+  x86_cpu_AVX10_V166 = x86_cpu_AVX10_V167 - 1,
+  x86_cpu_AVX10_V165 = x86_cpu_AVX10_V166 - 1,
+  x86_cpu_AVX10_V164 = x86_cpu_AVX10_V165 - 1,
+  x86_cpu_AVX10_V163 = x86_cpu_AVX10_V164 - 1,
+  x86_cpu_AVX10_V162 = x86_cpu_AVX10_V163 - 1,
+  x86_cpu_AVX10_V161 = x86_cpu_AVX10_V162 - 1,
+  x86_cpu_AVX10_V160 = x86_cpu_AVX10_V161 - 1,
+  x86_cpu_AVX10_V159 = x86_cpu_AVX10_V160 - 1,
+  x86_cpu_AVX10_V158 = x86_cpu_AVX10_V159 - 1,
+  x86_cpu_AVX10_V157 = x86_cpu_AVX10_V158 - 1,
+  x86_cpu_AVX10_V156 = x86_cpu_AVX10_V157 - 1,
+  x86_cpu_AVX10_V155 = x86_cpu_AVX10_V156 - 1,
+  x86_cpu_AVX10_V154 = x86_cpu_AVX10_V155 - 1,
+  x86_cpu_AVX10_V153 = x86_cpu_AVX10_V154 - 1,
+  x86_cpu_AVX10_V152 = x86_cpu_AVX10_V153 - 1,
+  x86_cpu_AVX10_V151 = x86_cpu_AVX10_V152 - 1,
+  x86_cpu_AVX10_V150 = x86_cpu_AVX10_V151 - 1,
+  x86_cpu_AVX10_V149 = x86_cpu_AVX10_V150 - 1,
+  x86_cpu_AVX10_V148 = x86_cpu_AVX10_V149 - 1,
+  x86_cpu_AVX10_V147 = x86_cpu_AVX10_V148 - 1,
+  x86_cpu_AVX10_V146 = x86_cpu_AVX10_V147 - 1,
+  x86_cpu_AVX10_V145 = x86_cpu_AVX10_V146 - 1,
+  x86_cpu_AVX10_V144 = x86_cpu_AVX10_V145 - 1,
+  x86_cpu_AVX10_V143 = x86_cpu_AVX10_V144 - 1,
+  x86_cpu_AVX10_V142 = x86_cpu_AVX10_V143 - 1,
+  x86_cpu_AVX10_V141 = x86_cpu_AVX10_V142 - 1,
+  x86_cpu_AVX10_V140 = x86_cpu_AVX10_V141 - 1,
+  x86_cpu_AVX10_V139 = x86_cpu_AVX10_V140 - 1,
+  x86_cpu_AVX10_V138 = x86_cpu_AVX10_V139 - 1,
+  x86_cpu_AVX10_V137 = x86_cpu_AVX10_V138 - 1,
+  x86_cpu_AVX10_V136 = x86_cpu_AVX10_V137 - 1,
+  x86_cpu_AVX10_V135 = x86_cpu_AVX10_V136 - 1,
+  x86_cpu_AVX10_V134 = x86_cpu_AVX10_V135 - 1,
+  x86_cpu_AVX10_V133 = x86_cpu_AVX10_V134 - 1,
+  x86_cpu_AVX10_V132 = x86_cpu_AVX10_V133 - 1,
+  x86_cpu_AVX10_V131 = x86_cpu_AVX10_V132 - 1,
+  x86_cpu_AVX10_V130 = x86_cpu_AVX10_V131 - 1,
+  x86_cpu_AVX10_V129 = x86_cpu_AVX10_V130 - 1,
+  x86_cpu_AVX10_V128 = x86_cpu_AVX10_V129 - 1,
+  x86_cpu_AVX10_V127 = x86_cpu_AVX10_V128 - 1,
+  x86_cpu_AVX10_V126 = x86_cpu_AVX10_V127 - 1,
+  x86_cpu_AVX10_V125 = x86_cpu_AVX10_V126 - 1,
+  x86_cpu_AVX10_V124 = x86_cpu_AVX10_V125 - 1,
+  x86_cpu_AVX10_V123 = x86_cpu_AVX10_V124 - 1,
+  x86_cpu_AVX10_V122 = x86_cpu_AVX10_V123 - 1,
+  x86_cpu_AVX10_V121 = x86_cpu_AVX10_V122 - 1,
+  x86_cpu_AVX10_V120 = x86_cpu_AVX10_V121 - 1,
+  x86_cpu_AVX10_V119 = x86_cpu_AVX10_V120 - 1,
+  x86_cpu_AVX10_V118 = x86_cpu_AVX10_V119 - 1,
+  x86_cpu_AVX10_V117 = x86_cpu_AVX10_V118 - 1,
+  x86_cpu_AVX10_V116 = x86_cpu_AVX10_V117 - 1,
+  x86_cpu_AVX10_V115 = x86_cpu_AVX10_V116 - 1,
+  x86_cpu_AVX10_V114 = x86_cpu_AVX10_V115 - 1,
+  x86_cpu_AVX10_V113 = x86_cpu_AVX10_V114 - 1,
+  x86_cpu_AVX10_V112 = x86_cpu_AVX10_V113 - 1,
+  x86_cpu_AVX10_V111 = x86_cpu_AVX10_V112 - 1,
+  x86_cpu_AVX10_V110 = x86_cpu_AVX10_V111 - 1,
+  x86_cpu_AVX10_V109 = x86_cpu_AVX10_V110 - 1,
+  x86_cpu_AVX10_V108 = x86_cpu_AVX10_V109 - 1,
+  x86_cpu_AVX10_V107 = x86_cpu_AVX10_V108 - 1,
+  x86_cpu_AVX10_V106 = x86_cpu_AVX10_V107 - 1,
+  x86_cpu_AVX10_V105 = x86_cpu_AVX10_V106 - 1,
+  x86_cpu_AVX10_V104 = x86_cpu_AVX10_V105 - 1,
+  x86_cpu_AVX10_V103 = x86_cpu_AVX10_V104 - 1,
+  x86_cpu_AVX10_V102 = x86_cpu_AVX10_V103 - 1,
+  x86_cpu_AVX10_V101 = x86_cpu_AVX10_V102 - 1,
+  x86_cpu_AVX10_V100 = x86_cpu_AVX10_V101 - 1,
+  x86_cpu_AVX10_V99 = x86_cpu_AVX10_V100 - 1,
+  x86_cpu_AVX10_V98 = x86_cpu_AVX10_V99 - 1,
+  x86_cpu_AVX10_V97 = x86_cpu_AVX10_V98 - 1,
+  x86_cpu_AVX10_V96 = x86_cpu_AVX10_V97 - 1,
+  x86_cpu_AVX10_V95 = x86_cpu_AVX10_V96 - 1,
+  x86_cpu_AVX10_V94 = x86_cpu_AVX10_V95 - 1,
+  x86_cpu_AVX10_V93 = x86_cpu_AVX10_V94 - 1,
+  x86_cpu_AVX10_V92 = x86_cpu_AVX10_V93 - 1,
+  x86_cpu_AVX10_V91 = x86_cpu_AVX10_V92 - 1,
+  x86_cpu_AVX10_V90 = x86_cpu_AVX10_V91 - 1,
+  x86_cpu_AVX10_V89 = x86_cpu_AVX10_V90 - 1,
+  x86_cpu_AVX10_V88 = x86_cpu_AVX10_V89 - 1,
+  x86_cpu_AVX10_V87 = x86_cpu_AVX10_V88 - 1,
+  x86_cpu_AVX10_V86 = x86_cpu_AVX10_V87 - 1,
+  x86_cpu_AVX10_V85 = x86_cpu_AVX10_V86 - 1,
+  x86_cpu_AVX10_V84 = x86_cpu_AVX10_V85 - 1,
+  x86_cpu_AVX10_V83 = x86_cpu_AVX10_V84 - 1,
+  x86_cpu_AVX10_V82 = x86_cpu_AVX10_V83 - 1,
+  x86_cpu_AVX10_V81 = x86_cpu_AVX10_V82 - 1,
+  x86_cpu_AVX10_V80 = x86_cpu_AVX10_V81 - 1,
+  x86_cpu_AVX10_V79 = x86_cpu_AVX10_V80 - 1,
+  x86_cpu_AVX10_V78 = x86_cpu_AVX10_V79 - 1,
+  x86_cpu_AVX10_V77 = x86_cpu_AVX10_V78 - 1,
+  x86_cpu_AVX10_V76 = x86_cpu_AVX10_V77 - 1,
+  x86_cpu_AVX10_V75 = x86_cpu_AVX10_V76 - 1,
+  x86_cpu_AVX10_V74 = x86_cpu_AVX10_V75 - 1,
+  x86_cpu_AVX10_V73 = x86_cpu_AVX10_V74 - 1,
+  x86_cpu_AVX10_V72 = x86_cpu_AVX10_V73 - 1,
+  x86_cpu_AVX10_V71 = x86_cpu_AVX10_V72 - 1,
+  x86_cpu_AVX10_V70 = x86_cpu_AVX10_V71 - 1,
+  x86_cpu_AVX10_V69 = x86_cpu_AVX10_V70 - 1,
+  x86_cpu_AVX10_V68 = x86_cpu_AVX10_V69 - 1,
+  x86_cpu_AVX10_V67 = x86_cpu_AVX10_V68 - 1,
+  x86_cpu_AVX10_V66 = x86_cpu_AVX10_V67 - 1,
+  x86_cpu_AVX10_V65 = x86_cpu_AVX10_V66 - 1,
+  x86_cpu_AVX10_V64 = x86_cpu_AVX10_V65 - 1,
+  x86_cpu_AVX10_V63 = x86_cpu_AVX10_V64 - 1,
+  x86_cpu_AVX10_V62 = x86_cpu_AVX10_V63 - 1,
+  x86_cpu_AVX10_V61 = x86_cpu_AVX10_V62 - 1,
+  x86_cpu_AVX10_V60 = x86_cpu_AVX10_V61 - 1,
+  x86_cpu_AVX10_V59 = x86_cpu_AVX10_V60 - 1,
+  x86_cpu_AVX10_V58 = x86_cpu_AVX10_V59 - 1,
+  x86_cpu_AVX10_V57 = x86_cpu_AVX10_V58 - 1,
+  x86_cpu_AVX10_V56 = x86_cpu_AVX10_V57 - 1,
+  x86_cpu_AVX10_V55 = x86_cpu_AVX10_V56 - 1,
+  x86_cpu_AVX10_V54 = x86_cpu_AVX10_V55 - 1,
+  x86_cpu_AVX10_V53 = x86_cpu_AVX10_V54 - 1,
+  x86_cpu_AVX10_V52 = x86_cpu_AVX10_V53 - 1,
+  x86_cpu_AVX10_V51 = x86_cpu_AVX10_V52 - 1,
+  x86_cpu_AVX10_V50 = x86_cpu_AVX10_V51 - 1,
+  x86_cpu_AVX10_V49 = x86_cpu_AVX10_V50 - 1,
+  x86_cpu_AVX10_V48 = x86_cpu_AVX10_V49 - 1,
+  x86_cpu_AVX10_V47 = x86_cpu_AVX10_V48 - 1,
+  x86_cpu_AVX10_V46 = x86_cpu_AVX10_V47 - 1,
+  x86_cpu_AVX10_V45 = x86_cpu_AVX10_V46 - 1,
+  x86_cpu_AVX10_V44 = x86_cpu_AVX10_V45 - 1,
+  x86_cpu_AVX10_V43 = x86_cpu_AVX10_V44 - 1,
+  x86_cpu_AVX10_V42 = x86_cpu_AVX10_V43 - 1,
+  x86_cpu_AVX10_V41 = x86_cpu_AVX10_V42 - 1,
+  x86_cpu_AVX10_V40 = x86_cpu_AVX10_V41 - 1,
+  x86_cpu_AVX10_V39 = x86_cpu_AVX10_V40 - 1,
+  x86_cpu_AVX10_V38 = x86_cpu_AVX10_V39 - 1,
+  x86_cpu_AVX10_V37 = x86_cpu_AVX10_V38 - 1,
+  x86_cpu_AVX10_V36 = x86_cpu_AVX10_V37 - 1,
+  x86_cpu_AVX10_V35 = x86_cpu_AVX10_V36 - 1,
+  x86_cpu_AVX10_V34 = x86_cpu_AVX10_V35 - 1,
+  x86_cpu_AVX10_V33 = x86_cpu_AVX10_V34 - 1,
+  x86_cpu_AVX10_V32 = x86_cpu_AVX10_V33 - 1,
+  x86_cpu_AVX10_V31 = x86_cpu_AVX10_V32 - 1,
+  x86_cpu_AVX10_V30 = x86_cpu_AVX10_V31 - 1,
+  x86_cpu_AVX10_V29 = x86_cpu_AVX10_V30 - 1,
+  x86_cpu_AVX10_V28 = x86_cpu_AVX10_V29 - 1,
+  x86_cpu_AVX10_V27 = x86_cpu_AVX10_V28 - 1,
+  x86_cpu_AVX10_V26 = x86_cpu_AVX10_V27 - 1,
+  x86_cpu_AVX10_V25 = x86_cpu_AVX10_V26 - 1,
+  x86_cpu_AVX10_V24 = x86_cpu_AVX10_V25 - 1,
+  x86_cpu_AVX10_V23 = x86_cpu_AVX10_V24 - 1,
+  x86_cpu_AVX10_V22 = x86_cpu_AVX10_V23 - 1,
+  x86_cpu_AVX10_V21 = x86_cpu_AVX10_V22 - 1,
+  x86_cpu_AVX10_V20 = x86_cpu_AVX10_V21 - 1,
+  x86_cpu_AVX10_V19 = x86_cpu_AVX10_V20 - 1,
+  x86_cpu_AVX10_V18 = x86_cpu_AVX10_V19 - 1,
+  x86_cpu_AVX10_V17 = x86_cpu_AVX10_V18 - 1,
+  x86_cpu_AVX10_V16 = x86_cpu_AVX10_V17 - 1,
+  x86_cpu_AVX10_V15 = x86_cpu_AVX10_V16 - 1,
+  x86_cpu_AVX10_V14 = x86_cpu_AVX10_V15 - 1,
+  x86_cpu_AVX10_V13 = x86_cpu_AVX10_V14 - 1,
+  x86_cpu_AVX10_V12 = x86_cpu_AVX10_V13 - 1,
+  x86_cpu_AVX10_V11 = x86_cpu_AVX10_V12 - 1,
+  x86_cpu_AVX10_V10 = x86_cpu_AVX10_V11 - 1,
+  x86_cpu_AVX10_V9 = x86_cpu_AVX10_V10 - 1,
+  x86_cpu_AVX10_V8 = x86_cpu_AVX10_V9 - 1,
+  x86_cpu_AVX10_V7 = x86_cpu_AVX10_V8 - 1,
+  x86_cpu_AVX10_V6 = x86_cpu_AVX10_V7 - 1,
+  x86_cpu_AVX10_V5 = x86_cpu_AVX10_V6 - 1,
+  x86_cpu_AVX10_V4 = x86_cpu_AVX10_V5 - 1,
+  x86_cpu_AVX10_V3 = x86_cpu_AVX10_V4 - 1,
+  x86_cpu_AVX10_V2 = x86_cpu_AVX10_V3 - 1,
+  x86_cpu_AVX10_V1 = x86_cpu_AVX10_V2 - 1
+/* x86_cpu_AVX10_V0 is invalid.  */
 };
diff --git a/sysdeps/x86/cpu-features.c b/sysdeps/x86/cpu-features.c
index badf088874..0bf923d48b 100644
--- a/sysdeps/x86/cpu-features.c
+++ b/sysdeps/x86/cpu-features.c
@@ -115,11 +115,18 @@  update_active (struct cpu_features *cpu_features)
   CPU_FEATURE_SET_ACTIVE (cpu_features, SHSTK);
 #endif
 
+  enum
+  {
+    os_xmm = 1,
+    os_ymm = 2,
+    os_zmm = 4
+  } os_vector_size = os_xmm;
   /* Can we call xgetbv?  */
   if (CPU_FEATURES_CPU_P (cpu_features, OSXSAVE))
     {
       unsigned int xcrlow;
       unsigned int xcrhigh;
+      CPU_FEATURE_SET_ACTIVE (cpu_features, AVX10);
       asm ("xgetbv" : "=a" (xcrlow), "=d" (xcrhigh) : "c" (0));
       /* Is YMM and XMM state usable?  */
       if ((xcrlow & (bit_YMM_state | bit_XMM_state))
@@ -128,6 +135,7 @@  update_active (struct cpu_features *cpu_features)
 	  /* Determine if AVX is usable.  */
 	  if (CPU_FEATURES_CPU_P (cpu_features, AVX))
 	    {
+	      os_vector_size |= os_ymm;
 	      CPU_FEATURE_SET (cpu_features, AVX);
 	      /* The following features depend on AVX being usable.  */
 	      /* Determine if AVX2 is usable.  */
@@ -166,6 +174,7 @@  update_active (struct cpu_features *cpu_features)
 			 | bit_ZMM16_31_state))
 	      == (bit_Opmask_state | bit_ZMM0_15_state | bit_ZMM16_31_state))
 	    {
+	      os_vector_size |= os_zmm;
 	      /* Determine if AVX512F is usable.  */
 	      if (CPU_FEATURES_CPU_P (cpu_features, AVX512F))
 		{
@@ -210,6 +219,22 @@  update_active (struct cpu_features *cpu_features)
 	    }
 	}
 
+      if (CPU_FEATURES_CPU_P (cpu_features, AVX10)
+	  && cpu_features->basic.max_cpuid >= 0x24)
+	{
+	  __cpuid_count (
+	      0x24, 0, cpu_features->features[CPUID_INDEX_24_ECX_0].cpuid.eax,
+	      cpu_features->features[CPUID_INDEX_24_ECX_0].cpuid.ebx,
+	      cpu_features->features[CPUID_INDEX_24_ECX_0].cpuid.ecx,
+	      cpu_features->features[CPUID_INDEX_24_ECX_0].cpuid.edx);
+	  if (os_vector_size & os_xmm)
+	    CPU_FEATURE_SET_ACTIVE (cpu_features, AVX10_XMM);
+	  if (os_vector_size & os_ymm)
+	    CPU_FEATURE_SET_ACTIVE (cpu_features, AVX10_YMM);
+	  if (os_vector_size & os_zmm)
+	    CPU_FEATURE_SET_ACTIVE (cpu_features, AVX10_ZMM);
+	}
+
       /* Are XTILECFG and XTILEDATA states usable?  */
       if ((xcrlow & (bit_XTILECFG_state | bit_XTILEDATA_state))
 	  == (bit_XTILECFG_state | bit_XTILEDATA_state))
diff --git a/sysdeps/x86/include/cpu-features.h b/sysdeps/x86/include/cpu-features.h
index eb30d342a6..2d7427a6c0 100644
--- a/sysdeps/x86/include/cpu-features.h
+++ b/sysdeps/x86/include/cpu-features.h
@@ -29,7 +29,7 @@ 
 
 enum
 {
-  CPUID_INDEX_MAX = CPUID_INDEX_14_ECX_0 + 1
+  CPUID_INDEX_MAX = CPUID_INDEX_24_ECX_0 + 1
 };
 
 enum
@@ -319,6 +319,7 @@  enum
 #define bit_cpu_AVX_NE_CONVERT	(1u << 5)
 #define bit_cpu_AMX_COMPLEX	(1u << 8)
 #define bit_cpu_PREFETCHI	(1u << 14)
+#define bit_cpu_AVX10		(1u << 19)
 #define bit_cpu_APX_F		(1u << 21)
 
 /* CPUID_INDEX_19.  */
@@ -332,6 +333,13 @@  enum
 /* EBX.  */
 #define bit_cpu_PTWRITE		(1u << 4)
 
+/* CPUID_INDEX_24_ECX_0.  */
+
+/* EBX.  */
+#define bit_cpu_AVX10_XMM		(1u << 16)
+#define bit_cpu_AVX10_YMM		(1u << 17)
+#define bit_cpu_AVX10_ZMM		(1u << 18)
+
 /* CPUID_INDEX_1.  */
 
 /* ECX.  */
@@ -563,6 +571,7 @@  enum
 #define index_cpu_AVX_NE_CONVERT CPUID_INDEX_7_ECX_1
 #define index_cpu_AMX_COMPLEX	CPUID_INDEX_7_ECX_1
 #define index_cpu_PREFETCHI	CPUID_INDEX_7_ECX_1
+#define index_cpu_AVX10		CPUID_INDEX_7_ECX_1
 #define index_cpu_APX_F		CPUID_INDEX_7_ECX_1
 
 /* CPUID_INDEX_19.  */
@@ -576,6 +585,13 @@  enum
 /* EBX.  */
 #define index_cpu_PTWRITE	CPUID_INDEX_14_ECX_0
 
+/* CPUID_INDEX_24_ECX_0.  */
+
+/* EBX.  */
+#define index_cpu_AVX10_XMM	CPUID_INDEX_24_ECX_0
+#define index_cpu_AVX10_YMM	CPUID_INDEX_24_ECX_0
+#define index_cpu_AVX10_ZMM	CPUID_INDEX_24_ECX_0
+
 /* CPUID_INDEX_1.  */
 
 /* ECX.  */
@@ -809,6 +825,7 @@  enum
 #define reg_AVX_NE_CONVERT	edx
 #define reg_AMX_COMPLEX		edx
 #define reg_PREFETCHI		edx
+#define reg_AVX10		edx
 #define reg_APX_F		edx
 
 /* CPUID_INDEX_19.  */
@@ -822,6 +839,14 @@  enum
 /* EBX.  */
 #define reg_PTWRITE		ebx
 
+/* CPUID_INDEX_24_ECX_0.  */
+
+/* EBX.  */
+#define reg_AVX10_XMM		ebx
+#define reg_AVX10_YMM		ebx
+#define reg_AVX10_ZMM		ebx
+
+
 /* PREFERRED_FEATURE_INDEX_1.  First define the bitindex values
    sequentially, then define the bit_arch* and index_arch_* lookup
    constants.  */
diff --git a/sysdeps/x86/sys/platform/x86.h b/sysdeps/x86/sys/platform/x86.h
index 1ea2c5fc0b..fa8c7e158d 100644
--- a/sysdeps/x86/sys/platform/x86.h
+++ b/sysdeps/x86/sys/platform/x86.h
@@ -29,9 +29,45 @@  __BEGIN_DECLS
 extern const struct cpuid_feature *__x86_get_cpuid_feature_leaf (unsigned int)
      __attribute__ ((pure));
 
+static __inline__ unsigned int
+x86_cpu_get_avx10_version_number_from_enum (unsigned int __enum)
+{
+  return __enum - x86_cpu_AVX10_V1 + 1;
+}
+
+static __inline__ _Bool
+x86_cpu_is_index_avx10_version_number (unsigned int __index)
+{
+  return __index >= (unsigned int) x86_cpu_AVX10_V1
+	 && __index <= (unsigned int) x86_cpu_AVX10_V255;
+}
+
+static __inline__ unsigned int
+x86_cpu_get_avx10_info (unsigned int __index)
+{
+  const struct cpuid_feature *__ptr = __x86_get_cpuid_feature_leaf (
+      __index / (8 * sizeof (unsigned int) * 4));
+  unsigned int __reg = __index & (8 * sizeof (unsigned int) * 4 - 1);
+  __reg /= 8 * sizeof (unsigned int);
+
+  return __ptr->cpuid_array[__reg];
+}
+
+/* Get AVX10 version number in byte form.  Must check AVX10 active first. Value
+   is in range [1, 255].  */
+static __inline__ unsigned int
+x86_cpu_get_avx10_version_number (void)
+{
+  return x86_cpu_get_avx10_info (x86_cpu_index_24_ecx_0_ebx) & 0xff;
+}
+
 static __inline__ _Bool
 x86_cpu_present (unsigned int __index)
 {
+  if (x86_cpu_is_index_avx10_version_number (__index))
+    return x86_cpu_get_avx10_version_number ()
+	   >= x86_cpu_get_avx10_version_number_from_enum (__index);
+
   const struct cpuid_feature *__ptr = __x86_get_cpuid_feature_leaf
     (__index / (8 * sizeof (unsigned int) * 4));
   unsigned int __reg
@@ -45,6 +81,10 @@  x86_cpu_present (unsigned int __index)
 static __inline__ _Bool
 x86_cpu_active (unsigned int __index)
 {
+  if (x86_cpu_is_index_avx10_version_number (__index))
+    return x86_cpu_get_avx10_version_number ()
+	   >= x86_cpu_get_avx10_version_number_from_enum (__index);
+
   const struct cpuid_feature *__ptr = __x86_get_cpuid_feature_leaf
     (__index / (8 * sizeof (unsigned int) * 4));
   unsigned int __reg
diff --git a/sysdeps/x86/tst-get-cpu-features.c b/sysdeps/x86/tst-get-cpu-features.c
index b27fa7324a..53e68431f1 100644
--- a/sysdeps/x86/tst-get-cpu-features.c
+++ b/sysdeps/x86/tst-get-cpu-features.c
@@ -219,6 +219,7 @@  do_test (void)
   CHECK_CPU_FEATURE_PRESENT (AVX_NE_CONVERT);
   CHECK_CPU_FEATURE_PRESENT (AMX_COMPLEX);
   CHECK_CPU_FEATURE_PRESENT (PREFETCHI);
+  CHECK_CPU_FEATURE_PRESENT (AVX10);
   CHECK_CPU_FEATURE_PRESENT (APX_F);
   CHECK_CPU_FEATURE_PRESENT (AESKLE);
   CHECK_CPU_FEATURE_PRESENT (WIDE_KL);
@@ -391,11 +392,273 @@  do_test (void)
   CHECK_CPU_FEATURE_ACTIVE (AVX_NE_CONVERT);
   CHECK_CPU_FEATURE_ACTIVE (AMX_COMPLEX);
   CHECK_CPU_FEATURE_ACTIVE (PREFETCHI);
+  CHECK_CPU_FEATURE_ACTIVE (AVX10);
   CHECK_CPU_FEATURE_ACTIVE (APX_F);
   CHECK_CPU_FEATURE_ACTIVE (AESKLE);
   CHECK_CPU_FEATURE_ACTIVE (WIDE_KL);
   CHECK_CPU_FEATURE_ACTIVE (PTWRITE);
 
+  if (CPU_FEATURE_ACTIVE (AVX10))
+    {
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_XMM);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_YMM);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_ZMM);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V1);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V2);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V3);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V4);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V5);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V6);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V7);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V8);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V9);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V10);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V11);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V12);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V13);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V14);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V15);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V16);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V17);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V18);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V19);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V20);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V21);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V22);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V23);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V24);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V25);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V26);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V27);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V28);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V29);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V30);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V31);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V32);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V33);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V34);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V35);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V36);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V37);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V38);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V39);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V40);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V41);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V42);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V43);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V44);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V45);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V46);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V47);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V48);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V49);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V50);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V51);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V52);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V53);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V54);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V55);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V56);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V57);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V58);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V59);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V60);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V61);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V62);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V63);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V64);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V65);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V66);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V67);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V68);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V69);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V70);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V71);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V72);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V73);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V74);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V75);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V76);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V77);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V78);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V79);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V80);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V81);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V82);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V83);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V84);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V85);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V86);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V87);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V88);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V89);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V90);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V91);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V92);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V93);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V94);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V95);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V96);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V97);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V98);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V99);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V100);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V101);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V102);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V103);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V104);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V105);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V106);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V107);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V108);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V109);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V110);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V111);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V112);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V113);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V114);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V115);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V116);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V117);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V118);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V119);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V120);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V121);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V122);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V123);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V124);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V125);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V126);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V127);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V128);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V129);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V130);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V131);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V132);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V133);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V134);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V135);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V136);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V137);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V138);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V139);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V140);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V141);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V142);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V143);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V144);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V145);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V146);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V147);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V148);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V149);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V150);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V151);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V152);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V153);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V154);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V155);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V156);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V157);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V158);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V159);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V160);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V161);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V162);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V163);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V164);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V165);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V166);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V167);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V168);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V169);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V170);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V171);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V172);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V173);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V174);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V175);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V176);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V177);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V178);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V179);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V180);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V181);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V182);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V183);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V184);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V185);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V186);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V187);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V188);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V189);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V190);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V191);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V192);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V193);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V194);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V195);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V196);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V197);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V198);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V199);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V200);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V201);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V202);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V203);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V204);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V205);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V206);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V207);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V208);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V209);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V210);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V211);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V212);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V213);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V214);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V215);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V216);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V217);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V218);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V219);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V220);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V221);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V222);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V223);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V224);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V225);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V226);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V227);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V228);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V229);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V230);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V231);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V232);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V233);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V234);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V235);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V236);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V237);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V238);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V239);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V240);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V241);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V242);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V243);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V244);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V245);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V246);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V247);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V248);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V249);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V250);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V251);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V252);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V253);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V254);
+      CHECK_CPU_FEATURE_ACTIVE (AVX10_V255);
+    }
   return 0;
 }