    {-# LANGUAGE LambdaCase #-}
    module GHC.Platform.Reg.Class
      ( RegClass (..), RegArch(..), registerArch )
    where

    import GHC.Prelude

    import GHC.Types.Unique
    import GHC.Builtin.Uniques ( mkRegClassUnique )
    import GHC.Platform.ArchOS
    import GHC.Utils.Outputable ( Outputable(ppr), text )

    -- | The class of a register.
    --      Used in the register allocator.
    --      We treat all registers in a class as being interchangeable.
    --
    newtype RegClass = RegClass Int
      deriving ( RegClass -> RegClass -> Bool
    (RegClass -> RegClass -> Bool)
    -> (RegClass -> RegClass -> Bool) -> Eq RegClass
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: RegClass -> RegClass -> Bool
    == :: RegClass -> RegClass -> Bool
    $c/= :: RegClass -> RegClass -> Bool
    /= :: RegClass -> RegClass -> Bool
    Eq, Eq RegClass
    Eq RegClass =>
    (RegClass -> RegClass -> Ordering)
    -> (RegClass -> RegClass -> Bool)
    -> (RegClass -> RegClass -> Bool)
    -> (RegClass -> RegClass -> Bool)
    -> (RegClass -> RegClass -> Bool)
    -> (RegClass -> RegClass -> RegClass)
    -> (RegClass -> RegClass -> RegClass)
    -> Ord RegClass
    RegClass -> RegClass -> Bool
    RegClass -> RegClass -> Ordering
    RegClass -> RegClass -> RegClass
    forall a.
    Eq a =>
    (a -> a -> Ordering)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> a)
    -> (a -> a -> a)
    -> Ord a
    $ccompare :: RegClass -> RegClass -> Ordering
    compare :: RegClass -> RegClass -> Ordering
    $c< :: RegClass -> RegClass -> Bool
    < :: RegClass -> RegClass -> Bool
    $c<= :: RegClass -> RegClass -> Bool
    <= :: RegClass -> RegClass -> Bool
    $c> :: RegClass -> RegClass -> Bool
    > :: RegClass -> RegClass -> Bool
    $c>= :: RegClass -> RegClass -> Bool
    >= :: RegClass -> RegClass -> Bool
    $cmax :: RegClass -> RegClass -> RegClass
    max :: RegClass -> RegClass -> RegClass
    $cmin :: RegClass -> RegClass -> RegClass
    min :: RegClass -> RegClass -> RegClass
    Ord, Int -> RegClass -> ShowS
    [RegClass] -> ShowS
    RegClass -> String
    (Int -> RegClass -> ShowS)
    -> (RegClass -> String) -> ([RegClass] -> ShowS) -> Show RegClass
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> RegClass -> ShowS
    showsPrec :: Int -> RegClass -> ShowS
    $cshow :: RegClass -> String
    show :: RegClass -> String
    $cshowList :: [RegClass] -> ShowS
    showList :: [RegClass] -> ShowS
    Show )

    instance Uniquable RegClass where
      getUnique :: RegClass -> Unique
    getUnique ( RegClass Int
    i ) = Int -> Unique
    mkRegClassUnique Int
    i

    -- | This instance is just used for the graph colouring register allocator.
    -- Prefer using either 'GHC.Platform.Reg.Class.Separate.pprRegClass'
    -- or 'GHC.Platform.Reg.Class.Unified.pprRegClass', which is more informative.
    instance Outputable RegClass where
      ppr :: RegClass -> SDoc
    ppr (RegClass Int
    i) = Int -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr Int
    i

    -- | The register architecture of a given machine.
    data RegArch
      -- | Floating-point and vector registers are unified (e.g. X86, AArch64).
      = Unified
      -- | Floating-point and vector registers are separate (e.g. RISC-V).
      | Separate
      -- | No vector registers.
      | NoVectors
      deriving ( RegArch -> RegArch -> Bool
    (RegArch -> RegArch -> Bool)
    -> (RegArch -> RegArch -> Bool) -> Eq RegArch
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: RegArch -> RegArch -> Bool
    == :: RegArch -> RegArch -> Bool
    $c/= :: RegArch -> RegArch -> Bool
    /= :: RegArch -> RegArch -> Bool
    Eq, Eq RegArch
    Eq RegArch =>
    (RegArch -> RegArch -> Ordering)
    -> (RegArch -> RegArch -> Bool)
    -> (RegArch -> RegArch -> Bool)
    -> (RegArch -> RegArch -> Bool)
    -> (RegArch -> RegArch -> Bool)
    -> (RegArch -> RegArch -> RegArch)
    -> (RegArch -> RegArch -> RegArch)
    -> Ord RegArch
    RegArch -> RegArch -> Bool
    RegArch -> RegArch -> Ordering
    RegArch -> RegArch -> RegArch
    forall a.
    Eq a =>
    (a -> a -> Ordering)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> a)
    -> (a -> a -> a)
    -> Ord a
    $ccompare :: RegArch -> RegArch -> Ordering
    compare :: RegArch -> RegArch -> Ordering
    $c< :: RegArch -> RegArch -> Bool
    < :: RegArch -> RegArch -> Bool
    $c<= :: RegArch -> RegArch -> Bool
    <= :: RegArch -> RegArch -> Bool
    $c> :: RegArch -> RegArch -> Bool
    > :: RegArch -> RegArch -> Bool
    $c>= :: RegArch -> RegArch -> Bool
    >= :: RegArch -> RegArch -> Bool
    $cmax :: RegArch -> RegArch -> RegArch
    max :: RegArch -> RegArch -> RegArch
    $cmin :: RegArch -> RegArch -> RegArch
    min :: RegArch -> RegArch -> RegArch
    Ord, Int -> RegArch -> ShowS
    [RegArch] -> ShowS
    RegArch -> String
    (Int -> RegArch -> ShowS)
    -> (RegArch -> String) -> ([RegArch] -> ShowS) -> Show RegArch
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> RegArch -> ShowS
    showsPrec :: Int -> RegArch -> ShowS
    $cshow :: RegArch -> String
    show :: RegArch -> String
    $cshowList :: [RegArch] -> ShowS
    showList :: [RegArch] -> ShowS
    Show )

    instance Outputable RegArch where
      ppr :: RegArch -> SDoc
    ppr RegArch
    regArch = String -> SDoc
    forall doc. IsLine doc => String -> doc
    text (RegArch -> String
    forall a. Show a => a -> String
    show RegArch
    regArch)

    -- | What is the register architecture of the given architecture?
    registerArch :: Arch -> RegArch
    registerArch :: Arch -> RegArch
    registerArch Arch
    arch =
      case Arch
    arch of
        Arch
    ArchX86       -> RegArch
    Unified
        Arch
    ArchX86_64    -> RegArch
    Unified
        Arch
    ArchPPC       -> RegArch
    Unified
        ArchPPC_64 {} -> RegArch
    Unified
        Arch
    ArchAArch64   -> RegArch
    Unified
        -- Support for vector registers not yet implemented for RISC-V
        -- see panic in `getFreeRegs`.
        --ArchRISCV64   -> Separate
        Arch
    ArchRISCV64   -> RegArch
    NoVectors
        Arch
    _             -> RegArch
    NoVectors