module LLVM.Extra.ExtensionCheck.X86 (
sse1, sse2, sse3, ssse3, sse41, sse42,
) where
import qualified LLVM.Extra.Extension as Ext
import Data.Word (Word32, )
import Data.Bits (testBit, )
import System.Cpuid (cpuid, )
import System.IO.Unsafe (unsafePerformIO, )
subtarget :: String -> (Word32 -> Word32 -> Bool) -> Ext.Subtarget
subtarget name q =
Ext.Subtarget "x86" name
(return $ unsafePerformIO $ check q)
check :: (Word32 -> Word32 -> Bool) -> IO Bool
check q = do
(high, _, _, _) <- cpuid 0
let featureId = 1
if featureId>high
then return False
else do
(_,_,ecx,edx) <- cpuid featureId
return (q ecx edx)
sse1 :: Ext.Subtarget
sse1 = subtarget "sse" (\_ecx edx -> testBit edx 25)
sse2 :: Ext.Subtarget
sse2 = subtarget "sse2" (\_ecx edx -> testBit edx 26)
sse3 :: Ext.Subtarget
sse3 = subtarget "sse3" (\ecx _edx -> testBit ecx 0)
ssse3 :: Ext.Subtarget
ssse3 = subtarget "ssse3" (\ecx _edx -> testBit ecx 9)
sse41 :: Ext.Subtarget
sse41 = subtarget "sse41" (\ecx _edx -> testBit ecx 19)
sse42 :: Ext.Subtarget
sse42 = subtarget "sse42" (\ecx _edx -> testBit ecx 20)