<!--
Archs appear in order of significance for blind, de-facto version ordering.

In other words when available, an arch further down will be used. "generic" is
at the top, as a last resort.
-->
<grammar>

<arch name="generic"> <!-- name is required-->
</arch>

<arch name="softfp">
  <flag compiler="gnu">-mfloat-abi=softfp</flag>
  <flag compiler="clang">-mfloat-abi=softfp</flag>
</arch>

<arch name="hardfp">
  <flag compiler="gnu">-mfloat-abi=hard</flag>
  <flag compiler="clang">-mfloat-abi=hard</flag>
</arch>

<arch name="32">
  <flag compiler="gnu">-m32</flag>
  <flag compiler="clang">-m32</flag>
</arch>

<arch name="64">
  <!-- <check name="check_extended_cpuid"> -->
      <!-- <param>0x80000001</param>
  </check> -->
  <!--<check name="cpuid_x86_bit">   checks to see if a bit is set -->
  <!--    <param>3</param>           eax, ebx, ecx, [edx] -->
  <!--    <param>0x80000001</param>  cpuid operation -->
  <!--    <param>29</param>          bit shift -->
  <!-- </check> -->
  <flag compiler="gnu">-m64</flag>
  <flag compiler="clang">-m64</flag>
</arch>

<arch name="popcount">
  <check name="popcnt"></check>
  <flag compiler="gnu">-mpopcnt</flag>
  <flag compiler="clang">-mpopcnt</flag>
  <flag compiler="msvc">/arch:AVX</flag>
</arch>

<arch name="mmx">
  <check name="mmx"></check>
  <flag compiler="gnu">-mmmx</flag>
  <flag compiler="clang">-mmmx</flag>
  <alignment>8</alignment>
</arch>

<arch name="fma">
    <check name="fma3"></check>
    <flag compiler="gnu">-mfma</flag>
    <flag compiler="clang">-mfma</flag>
    <flag compiler="msvc">/arch:AVX2</flag>
    <alignment>32</alignment>
</arch>

<arch name="sse">
  <check name="sse"></check>
  <flag compiler="gnu">-msse</flag>
  <flag compiler="clang">-msse</flag>
  <environment>_MM_SET_FLUSH_ZERO_MODE(_MM_FLUSH_ZERO_ON);</environment>
  <include>xmmintrin.h</include>
  <alignment>16</alignment>
</arch>

<arch name="sse2">
  <check name="sse2"></check>
  <flag compiler="gnu">-msse2</flag>
  <flag compiler="clang">-msse2</flag>
  <alignment>16</alignment>
</arch>

<arch name="orc">
</arch>

<!-- it's here for overrule stuff. -->
<arch name="norc">
</arch>

<arch name="neon">
  <flag compiler="gnu">-funsafe-math-optimizations</flag>
  <flag compiler="clang">-funsafe-math-optimizations</flag>
  <alignment>16</alignment>
  <check name="neon"></check>
</arch>

<arch name="neonv7">
  <flag compiler="gnu">-mfpu=neon</flag>
  <flag compiler="gnu">-funsafe-math-optimizations</flag>
  <flag compiler="clang">-mfpu=neon</flag>
  <flag compiler="clang">-funsafe-math-optimizations</flag>
  <alignment>16</alignment>
  <check name="neon"></check>
</arch>

<arch name="neonv8">
  <flag compiler="gnu">-funsafe-math-optimizations</flag>
  <flag compiler="clang">-funsafe-math-optimizations</flag>
  <alignment>16</alignment>
  <check name="neon"></check>
</arch>

<arch name="sse3">
  <check name="sse3"></check>
  <flag compiler="gnu">-msse3</flag>
  <flag compiler="clang">-msse3</flag>
  <flag compiler="msvc">/arch:AVX</flag>
  <environment>_MM_SET_DENORMALS_ZERO_MODE(_MM_DENORMALS_ZERO_ON);</environment>
  <include>pmmintrin.h</include>
  <alignment>16</alignment>
</arch>

<arch name="ssse3">
  <check name="ssse3"></check>
  <flag compiler="gnu">-mssse3</flag>
  <flag compiler="clang">-mssse3</flag>
  <flag compiler="msvc">/arch:AVX</flag>
  <alignment>16</alignment>
</arch>

<arch name="sse4_a">
  <check name="sse4a"></check>
  <flag compiler="gnu">-msse4a</flag>
  <flag compiler="clang">-msse4a</flag>
  <alignment>16</alignment>
</arch>

<arch name="sse4_1">
  <check name="sse4_1"></check>
  <flag compiler="gnu">-msse4.1</flag>
  <flag compiler="clang">-msse4.1</flag>
  <flag compiler="msvc">/arch:AVX</flag>
  <alignment>16</alignment>
</arch>

<arch name="sse4_2">
  <check name="sse4_2"></check>
  <flag compiler="gnu">-msse4.2</flag>
  <flag compiler="clang">-msse4.2</flag>
  <flag compiler="msvc">/arch:AVX</flag>
  <alignment>16</alignment>
</arch>

<arch name="avx">
  <check name="avx"></check>
  <flag compiler="gnu">-mavx</flag>
  <flag compiler="clang">-mavx</flag>
  <flag compiler="msvc">/arch:AVX</flag>
  <alignment>32</alignment>
</arch>

<arch name="avx2">
    <check name="avx2"></check>
    <flag compiler="gnu">-mavx2</flag>
    <flag compiler="clang">-mavx2</flag>
    <flag compiler="msvc">/arch:AVX2</flag>
    <alignment>32</alignment>
</arch>

<arch name="avx512f">
    <check name="avx512f"></check>
    <flag compiler="gnu">-mavx512f</flag>
    <flag compiler="clang">-mavx512f</flag>
    <flag compiler="msvc">/arch:AVX512F</flag>
    <alignment>64</alignment>
</arch>

<arch name="avx512cd">
    <check name="avx512cd"></check>
    <flag compiler="gnu">-mavx512cd</flag>
    <flag compiler="clang">-mavx512cd</flag>
    <flag compiler="msvc">/arch:AVX512CD</flag>
    <alignment>64</alignment>
</arch>

<arch name="avx512dq">
    <check name="avx512dq"></check>
    <flag compiler="gnu">-mavx512dq</flag>
    <flag compiler="clang">-mavx512dq</flag>
    <flag compiler="msvc">/arch:AVX512DQ</flag>
    <alignment>64</alignment>
</arch>

<arch name="riscv64">
</arch>

<!-->
    tmpl/ currently assumes that every arch.name starting with "rv" requires
    RVV intrinsics
</-->
<!-->
    There is currently no mechanism in RISC-V to append extensions,
    so each arch needs to specify all of them, and the order needs in the
    machine definition needs to be from the fewest to the most extensions.
    Fortunately, this maps quite well to the profiles concept.
</-->
<arch name="rvv">
    <check name="V"></check>
    <flag compiler="gnu">-march=rv64gcv</flag>
    <flag compiler="clang">-march=rv64gcv</flag>
</arch>

<arch name="rvvseg">
    <check name="V"></check>
    <flag compiler="gnu">-march=rv64gcv</flag>
    <flag compiler="clang">-march=rv64gcv</flag>
    <!-->
        It's unclear how performance portable segmented load/stores are, so the
        default rvv implementations avoid using them.
        This is a pseudo arch for separate segmented load/store implementations,
        and is expected to never be used standalone without "rvv".
    </-->
</arch>

<!-->
    google/cpu_features currently doesn't support these extensions and profiles.
</-->
<!--arch name="rva22v">
    <check name="V"></check>
    <check name="B"></check>
    <flag compiler="gnu">-march=rv64gcv_zba_zbb_zbs</flag>
    <flag compiler="clang">-march=rv64gcv_zba_zbb_zbs</flag>
</arch-->

<!--arch name="rva23">
    <check name="rva23"></check>
    <flag compiler="gnu">-march=rva23u64</flag>
    <flag compiler="clang">-march=rva23u64</flag>
</arch-->

</grammar>
