    {-# LANGUAGE GeneralizedNewtypeDeriving #-}

    -- | Free regs map for x86_64
    module GHC.CmmToAsm.Reg.Linear.X86_64 where

    import GHC.Prelude

    import GHC.CmmToAsm.X86.Regs
    import GHC.Platform.Reg.Class.Unified
    import GHC.Platform.Reg
    import GHC.Platform
    import GHC.Utils.Outputable

    import Data.Word

    newtype FreeRegs = FreeRegs Word64
        deriving (Int -> FreeRegs -> ShowS
    [FreeRegs] -> ShowS
    FreeRegs -> String
    (Int -> FreeRegs -> ShowS)
    -> (FreeRegs -> String) -> ([FreeRegs] -> ShowS) -> Show FreeRegs
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> FreeRegs -> ShowS
    showsPrec :: Int -> FreeRegs -> ShowS
    $cshow :: FreeRegs -> String
    show :: FreeRegs -> String
    $cshowList :: [FreeRegs] -> ShowS
    showList :: [FreeRegs] -> ShowS
    Show,FreeRegs -> SDoc
    (FreeRegs -> SDoc) -> Outputable FreeRegs
    forall a. (a -> SDoc) -> Outputable a
    $cppr :: FreeRegs -> SDoc
    ppr :: FreeRegs -> SDoc
    Outputable)

    noFreeRegs :: FreeRegs
    noFreeRegs :: FreeRegs
    noFreeRegs = Word64 -> FreeRegs
    FreeRegs Word64
    0

    releaseReg :: RealReg -> FreeRegs -> FreeRegs
    releaseReg :: RealReg -> FreeRegs -> FreeRegs
    releaseReg (RealRegSingle Int
    n) (FreeRegs Word64
    f)
            = Word64 -> FreeRegs
    FreeRegs (Word64 -> Int -> Word64
    forall a. (Num a, Bits a) => a -> Int -> a
    setBit Word64
    f Int
    n)

    initFreeRegs :: Platform -> FreeRegs
    initFreeRegs :: Platform -> FreeRegs
    initFreeRegs Platform
    platform
            = (FreeRegs -> RealReg -> FreeRegs)
    -> FreeRegs -> [RealReg] -> FreeRegs
    forall b a. (b -> a -> b) -> b -> [a] -> b
    forall (t :: * -> *) b a.
    Foldable t =>
    (b -> a -> b) -> b -> t a -> b
    foldl' ((RealReg -> FreeRegs -> FreeRegs)
    -> FreeRegs -> RealReg -> FreeRegs
    forall a b c. (a -> b -> c) -> b -> a -> c
    flip RealReg -> FreeRegs -> FreeRegs
    releaseReg) FreeRegs
    noFreeRegs (Platform -> [RealReg]
    allocatableRegs Platform
    platform)

    getFreeRegs :: Platform -> RegClass -> FreeRegs -> [RealReg] -- lazily
    getFreeRegs :: Platform -> RegClass -> FreeRegs -> [RealReg]
    getFreeRegs Platform
    platform RegClass
    cls (FreeRegs Word64
    f) =
      case RegClass
    cls of
        RegClass
    RcInteger ->
          [ Int -> RealReg
    RealRegSingle Int
    i
          | Int
    i <- Platform -> [Int]
    intregnos Platform
    platform
          , Word64 -> Int -> Bool
    forall a. Bits a => a -> Int -> Bool
    testBit Word64
    f Int
    i
          ]
        RegClass
    RcFloatOrVector ->
          [ Int -> RealReg
    RealRegSingle Int
    i
          | Int
    i <- Platform -> [Int]
    xmmregnos Platform
    platform
          , Word64 -> Int -> Bool
    forall a. Bits a => a -> Int -> Bool
    testBit Word64
    f Int
    i
          ]

    allocateReg :: RealReg -> FreeRegs -> FreeRegs
    allocateReg :: RealReg -> FreeRegs -> FreeRegs
    allocateReg (RealRegSingle Int
    r) (FreeRegs Word64
    f)
            = Word64 -> FreeRegs
    FreeRegs (Word64 -> Int -> Word64
    forall a. (Num a, Bits a) => a -> Int -> a
    clearBit Word64
    f Int
    r)