module LLVM.Extra.ExtensionCheck.X86 ( sse1, sse2, sse3, ssse3, sse41, sse42, avx, avx2, fma3, fma4, amd3dnow, amd3dnowa, aes, ) where import qualified LLVM.Extra.Extension as Ext import qualified System.Cpuid as CPUID import qualified System.Unsafe as Unsafe {- I expect that the cpuid does not suddenly change and thus calling Unsafe.performIO is safe. -} subtarget :: String -> (CPUID.FlagSet CPUID.Feature1C -> CPUID.FlagSet CPUID.Feature1D -> Bool) -> Ext.Subtarget subtarget name q = Ext.Subtarget "x86" name (return $ Unsafe.performIO $ check q) check :: (CPUID.FlagSet CPUID.Feature1C -> CPUID.FlagSet CPUID.Feature1D -> Bool) -> IO Bool check q = fmap (uncurry q) $ CPUID.features -- * target specific extensions sse1 :: Ext.Subtarget sse1 = subtarget "sse" (\_ecx edx -> CPUID.testFlag CPUID.sse edx) sse2 :: Ext.Subtarget sse2 = subtarget "sse2" (\_ecx edx -> CPUID.testFlag CPUID.sse2 edx) sse3 :: Ext.Subtarget sse3 = subtarget "sse3" (\ecx _edx -> CPUID.testFlag CPUID.sse3 ecx) ssse3 :: Ext.Subtarget ssse3 = subtarget "ssse3" (\ecx _edx -> CPUID.testFlag CPUID.ssse3 ecx) sse41 :: Ext.Subtarget sse41 = subtarget "sse41" (\ecx _edx -> CPUID.testFlag CPUID.sse4_1 ecx) sse42 :: Ext.Subtarget sse42 = subtarget "sse42" (\ecx _edx -> CPUID.testFlag CPUID.sse4_2 ecx) avx :: Ext.Subtarget avx = subtarget "avx" (\ecx _edx -> CPUID.testFlag CPUID.avx ecx) avx2 :: Ext.Subtarget avx2 = subtarget "avx2" (\ _ecx _edx -> False) fma3 :: Ext.Subtarget fma3 = subtarget "fma3" (\ ecx _edx -> CPUID.testFlag CPUID.fma ecx) fma4 :: Ext.Subtarget fma4 = subtarget "fma4" (\ _ecx _edx -> False) amd3dnow :: Ext.Subtarget amd3dnow = subtarget "3dnow" (\ _ecx _edx -> False) amd3dnowa :: Ext.Subtarget amd3dnowa = subtarget "3dnowa" (\ _ecx _edx -> False) aes :: Ext.Subtarget aes = subtarget "aesni" (\ _ecx _edx -> False)