{-# 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