cpu-features-0.1.0.0: src/System/CPUFeatures/X86/Bool.hs
{-# LANGUAGE CPP #-}
{-# LANGUAGE MagicHash #-}
{-# LANGUAGE UnliftedFFITypes #-}
{- |
Description: Detect x86 features at runtime
This module provides the basic interface to detect CPU features.
The availability is indicated by a boolean variable (@b\<FEATRUE NAME\>@).
-}
module System.CPUFeatures.X86.Bool
(bAESNI
,bAMX_BF16
,bAMX_FP16
,bAMX_INT8
,bAMX_TILE
,bAVX
,bAVX_VNNI
,bAVX10_1
,bAVX10_2
,bAVX2
,bAVX512_BF16
,bAVX512_BITALG
,bAVX512_FP16
,bAVX512_IFMA
,bAVX512_VBMI
,bAVX512_VBMI2
,bAVX512_VNNI
,bAVX512_VPOPCNTDQ
,bAVX512BW
,bAVX512CD
,bAVX512DQ
,bAVX512F
,bAVX512VL
,bBMI1
,bBMI2
,bF16C
,bFMA
,bGFNI
,bPCLMULQDQ
,bPOPCNT
,bRDRAND
,bSHA
,bSSE3
,bSSE4_1
,bSSE4_2
,bSSSE3
,bVAES
,bVPCLMULQDQ
,mAVX10
) where
#if defined(x86_64_HOST_ARCH) || defined(i386_HOST_ARCH)
import System.CPUFeatures.X86.Cpuid
import Data.Bits
-- import Data.Maybe (isJust)
#if defined(darwin_HOST_OS)
import GHC.Exts (Addr#)
#endif
#endif
bAESNI :: Bool
bAMX_BF16 :: Bool
bAMX_FP16 :: Bool
bAMX_INT8 :: Bool
bAMX_TILE :: Bool
bAVX :: Bool
bAVX_VNNI :: Bool
bAVX10_1 :: Bool
bAVX10_2 :: Bool
bAVX2 :: Bool
bAVX512_BF16 :: Bool
bAVX512_BITALG :: Bool
bAVX512_FP16 :: Bool
bAVX512_IFMA :: Bool
bAVX512_VBMI :: Bool
bAVX512_VBMI2 :: Bool
bAVX512_VNNI :: Bool
bAVX512_VPOPCNTDQ :: Bool
bAVX512BW :: Bool
bAVX512CD :: Bool
bAVX512DQ :: Bool
bAVX512F :: Bool
bAVX512VL :: Bool
bBMI1 :: Bool
bBMI2 :: Bool
bF16C :: Bool
bFMA :: Bool
bGFNI :: Bool
bPCLMULQDQ :: Bool
bPOPCNT :: Bool
bRDRAND :: Bool
bSHA :: Bool
bSSE3 :: Bool
bSSE4_1 :: Bool
bSSE4_2 :: Bool
bSSSE3 :: Bool
bVAES :: Bool
bVPCLMULQDQ :: Bool
mAVX10 :: Maybe Int
#if defined(x86_64_HOST_ARCH) || defined(i386_HOST_ARCH)
{-# NOINLINE cpuid_01 #-}
cpuid_01 :: CpuidResult
cpuid_01 = cpuid 0x1 0
{-# NOINLINE cpuid_07_0 #-}
cpuid_07_0 :: CpuidResult
cpuid_07_0 = cpuid 0x7 0
{-# NOINLINE cpuid_07_1 #-}
cpuid_07_1 :: CpuidResult
cpuid_07_1 = cpuid 0x7 1
{-# NOINLINE cpuid_24_0 #-}
cpuid_24_0 :: CpuidResult
cpuid_24_0 = cpuid 0x24 0
-- May be used by future AVX10
-- {-# NOINLINE cpuid_24_1 #-}
-- cpuid_24_1 :: CpuidResult
-- cpuid_24_1 = cpuid 0x24 1
#if defined(darwin_HOST_OS)
foreign import ccall unsafe hs_cpu_features_sysctl :: Addr# -> Bool
#endif
{-# NOINLINE mAVX10 #-}
mAVX10 | testBit (edx cpuid_07_1) 19
, testBit (ecx cpuid_01) 27 -- OSXSAVE
, (xgetbv 0 .&. 0xe6) == 0xe6 -- opmask, upper ZMM[0-15], ZMM[16-31], XMM, YMM
, testBit (ebx cpuid_24_0) 17 -- AVX10/256
= let !version = fromIntegral (ebx cpuid_24_0 .&. 0xff)
in Just version
| otherwise = Nothing
bAESNI = testBit (ecx cpuid_01) 25
bAMX_BF16 = testBit (edx cpuid_07_0) 22
bAMX_FP16 = testBit (eax cpuid_07_1) 21
bAMX_INT8 = testBit (edx cpuid_07_0) 25
bAMX_TILE = testBit (edx cpuid_07_0) 24
{-# NOINLINE bAVX #-}
bAVX = (ecx cpuid_01 .&. (bit 27 .|. bit 28)) == bit 27 .|. bit 28 && (xgetbv 0 .&. 6) == 6 -- bit 27: OSXSAVE, bit 28: AVX
bAVX_VNNI = testBit (eax cpuid_07_1) 4
bAVX10_1 = mAVX10 >= Just 1
bAVX10_2 = mAVX10 >= Just 2
-- bAVX10_VL256 = isJust mAVX10 -- mAVX10 checks for VL256
-- bAVX10_VL512 = isJust mAVX10 && testBit (ebx cpuid_24_0) 18
bAVX2 = bAVX && testBit (ebx cpuid_07_0) 5
bAVX512_BF16 = bAVX512F && testBit (eax cpuid_07_1) 5
bAVX512_BITALG = bAVX512F && testBit (ecx cpuid_07_0) 12
bAVX512_FP16 = bAVX512F && testBit (edx cpuid_07_0) 23
bAVX512_IFMA = bAVX512F && testBit (ebx cpuid_07_0) 21
bAVX512_VBMI = bAVX512F && testBit (ecx cpuid_07_0) 1
bAVX512_VBMI2 = bAVX512F && testBit (ecx cpuid_07_0) 6
bAVX512_VNNI = bAVX512F && testBit (ecx cpuid_07_0) 11
-- bAVX512_VP2INTERSECT = bAVX512F && testBit (edx cpuid_07_0) 8
bAVX512_VPOPCNTDQ = bAVX512F && testBit (ecx cpuid_07_0) 14
bAVX512BW = bAVX512F && testBit (ebx cpuid_07_0) 30
bAVX512CD = bAVX512F && testBit (ebx cpuid_07_0) 28
bAVX512DQ = bAVX512F && testBit (ebx cpuid_07_0) 17
{-# NOINLINE bAVX512F #-}
#if defined(darwin_HOST_OS)
bAVX512F = hs_cpu_features_sysctl "hw.optional.avx512f"# -- AVX-512 support on macOS is on-demand, that is, XCR0 is cleared by default.
#else
bAVX512F = testBit (ecx cpuid_01) 27 && (xgetbv 0 .&. 0xe6) == 0xe6 && testBit (ebx cpuid_07_0) 16 -- CPUID.1:ECX[bit 27]: OSXSAVE
#endif
bAVX512VL = testBit (ebx cpuid_07_0) 31
bBMI1 = testBit (ebx cpuid_07_0) 3
bBMI2 = testBit (ebx cpuid_07_0) 8
bF16C = bAVX && testBit (ecx cpuid_01) 29
bFMA = bAVX && testBit (ecx cpuid_01) 12
bGFNI = testBit (ecx cpuid_07_0) 8
bPCLMULQDQ = testBit (ecx cpuid_01) 1
bPOPCNT = testBit (ecx cpuid_01) 23
bRDRAND = testBit (ecx cpuid_01) 30
bSHA = testBit (ebx cpuid_07_0) 29
bSSE3 = testBit (ecx cpuid_01) 0
bSSE4_1 = testBit (ecx cpuid_01) 19
bSSE4_2 = testBit (ecx cpuid_01) 20
bSSSE3 = testBit (ecx cpuid_01) 9
bVAES = testBit (ecx cpuid_07_0) 9
bVPCLMULQDQ = testBit (ecx cpuid_07_0) 10
#else
{-# INLINE bAESNI #-}
bAESNI = False
{-# INLINE bAMX_BF16 #-}
bAMX_BF16 = False
{-# INLINE bAMX_FP16 #-}
bAMX_FP16 = False
{-# INLINE bAMX_INT8 #-}
bAMX_INT8 = False
{-# INLINE bAMX_TILE #-}
bAMX_TILE = False
{-# INLINE bAVX #-}
bAVX = False
{-# INLINE bAVX_VNNI #-}
bAVX_VNNI = False
{-# INLINE bAVX10_1 #-}
bAVX10_1 = False
{-# INLINE bAVX10_2 #-}
bAVX10_2 = False
{-# INLINE bAVX2 #-}
bAVX2 = False
{-# INLINE bAVX512_BF16 #-}
bAVX512_BF16 = False
{-# INLINE bAVX512_BITALG #-}
bAVX512_BITALG = False
{-# INLINE bAVX512_FP16 #-}
bAVX512_FP16 = False
{-# INLINE bAVX512_IFMA #-}
bAVX512_IFMA = False
{-# INLINE bAVX512_VBMI #-}
bAVX512_VBMI = False
{-# INLINE bAVX512_VBMI2 #-}
bAVX512_VBMI2 = False
{-# INLINE bAVX512_VNNI #-}
bAVX512_VNNI = False
{-# INLINE bAVX512_VPOPCNTDQ #-}
bAVX512_VPOPCNTDQ = False
{-# INLINE bAVX512BW #-}
bAVX512BW = False
{-# INLINE bAVX512CD #-}
bAVX512CD = False
{-# INLINE bAVX512DQ #-}
bAVX512DQ = False
{-# INLINE bAVX512F #-}
bAVX512F = False
{-# INLINE bAVX512VL #-}
bAVX512VL = False
{-# INLINE bBMI1 #-}
bBMI1 = False
{-# INLINE bBMI2 #-}
bBMI2 = False
{-# INLINE bF16C #-}
bF16C = False
{-# INLINE bFMA #-}
bFMA = False
{-# INLINE bGFNI #-}
bGFNI = False
{-# INLINE bPCLMULQDQ #-}
bPCLMULQDQ = False
{-# INLINE bPOPCNT #-}
bPOPCNT = False
{-# INLINE bRDRAND #-}
bRDRAND = False
{-# INLINE bSHA #-}
bSHA = False
{-# INLINE bSSE3 #-}
bSSE3 = False
{-# INLINE bSSE4_1 #-}
bSSE4_1 = False
{-# INLINE bSSE4_2 #-}
bSSE4_2 = False
{-# INLINE bSSSE3 #-}
bSSSE3 = False
{-# INLINE bVAES #-}
bVAES = False
{-# INLINE bVPCLMULQDQ #-}
bVPCLMULQDQ = False
{-# INLINE mAVX10 #-}
mAVX10 = Nothing
#endif