module GHC.Platform.Reg (
RegNo,
Reg(..),
regPair,
regSingle,
realRegSingle,
isRealReg, takeRealReg,
isVirtualReg, takeVirtualReg,
VirtualReg(..),
renameVirtualReg,
classOfVirtualReg,
getHiVirtualRegFromLo,
getHiVRegFromLo,
RealReg(..),
regNosOfRealReg,
realRegsAlias,
liftPatchFnToRegReg
)
where
import GHC.Prelude
import GHC.Utils.Outputable
import GHC.Utils.Panic
import GHC.Types.Unique
import GHC.Builtin.Uniques
import GHC.Platform.Reg.Class
import Data.List (intersect)
type RegNo
= Int
data VirtualReg
= VirtualRegI !Unique
| VirtualRegHi !Unique
| VirtualRegF !Unique
| VirtualRegD !Unique
deriving (Eq, Show)
instance Ord VirtualReg where
compare (VirtualRegI a) (VirtualRegI b) = nonDetCmpUnique a b
compare (VirtualRegHi a) (VirtualRegHi b) = nonDetCmpUnique a b
compare (VirtualRegF a) (VirtualRegF b) = nonDetCmpUnique a b
compare (VirtualRegD a) (VirtualRegD b) = nonDetCmpUnique a b
compare VirtualRegI{} _ = LT
compare _ VirtualRegI{} = GT
compare VirtualRegHi{} _ = LT
compare _ VirtualRegHi{} = GT
compare VirtualRegF{} _ = LT
compare _ VirtualRegF{} = GT
instance Uniquable VirtualReg where
getUnique reg
= case reg of
VirtualRegI u -> u
VirtualRegHi u -> u
VirtualRegF u -> u
VirtualRegD u -> u
instance Outputable VirtualReg where
ppr reg
= case reg of
VirtualRegI u -> text "%vI_" <> pprUniqueAlways u
VirtualRegHi u -> text "%vHi_" <> pprUniqueAlways u
VirtualRegF u -> text "%vFloat_" <> pprUniqueAlways u
VirtualRegD u -> text "%vDouble_" <> pprUniqueAlways u
renameVirtualReg :: Unique -> VirtualReg -> VirtualReg
renameVirtualReg u r
= case r of
VirtualRegI _ -> VirtualRegI u
VirtualRegHi _ -> VirtualRegHi u
VirtualRegF _ -> VirtualRegF u
VirtualRegD _ -> VirtualRegD u
classOfVirtualReg :: VirtualReg -> RegClass
classOfVirtualReg vr
= case vr of
VirtualRegI{} -> RcInteger
VirtualRegHi{} -> RcInteger
VirtualRegF{} -> RcFloat
VirtualRegD{} -> RcDouble
getHiVirtualRegFromLo :: VirtualReg -> VirtualReg
getHiVirtualRegFromLo reg
= case reg of
VirtualRegI u -> VirtualRegHi (newTagUnique u 'H')
_ -> panic "Reg.getHiVirtualRegFromLo"
getHiVRegFromLo :: Reg -> Reg
getHiVRegFromLo reg
= case reg of
RegVirtual vr -> RegVirtual (getHiVirtualRegFromLo vr)
RegReal _ -> panic "Reg.getHiVRegFromLo"
data RealReg
= RealRegSingle !RegNo
| RealRegPair !RegNo !RegNo
deriving (Eq, Show, Ord)
instance Uniquable RealReg where
getUnique reg
= case reg of
RealRegSingle i -> mkRegSingleUnique i
RealRegPair r1 r2 -> mkRegPairUnique (r1 * 65536 + r2)
instance Outputable RealReg where
ppr reg
= case reg of
RealRegSingle i -> text "%r" <> int i
RealRegPair r1 r2 -> text "%r(" <> int r1
<> vbar <> int r2 <> text ")"
regNosOfRealReg :: RealReg -> [RegNo]
regNosOfRealReg rr
= case rr of
RealRegSingle r1 -> [r1]
RealRegPair r1 r2 -> [r1, r2]
realRegsAlias :: RealReg -> RealReg -> Bool
realRegsAlias rr1 rr2
= not $ null $ intersect (regNosOfRealReg rr1) (regNosOfRealReg rr2)
data Reg
= RegVirtual !VirtualReg
| RegReal !RealReg
deriving (Eq, Ord)
regSingle :: RegNo -> Reg
regSingle regNo = RegReal (realRegSingle regNo)
realRegSingle :: RegNo -> RealReg
realRegSingle regNo = RealRegSingle regNo
regPair :: RegNo -> RegNo -> Reg
regPair regNo1 regNo2 = RegReal $ RealRegPair regNo1 regNo2
instance Uniquable Reg where
getUnique reg
= case reg of
RegVirtual vr -> getUnique vr
RegReal rr -> getUnique rr
instance Outputable Reg where
ppr reg
= case reg of
RegVirtual vr -> ppr vr
RegReal rr -> ppr rr
isRealReg :: Reg -> Bool
isRealReg reg
= case reg of
RegReal _ -> True
RegVirtual _ -> False
takeRealReg :: Reg -> Maybe RealReg
takeRealReg reg
= case reg of
RegReal rr -> Just rr
_ -> Nothing
isVirtualReg :: Reg -> Bool
isVirtualReg reg
= case reg of
RegReal _ -> False
RegVirtual _ -> True
takeVirtualReg :: Reg -> Maybe VirtualReg
takeVirtualReg reg
= case reg of
RegReal _ -> Nothing
RegVirtual vr -> Just vr
liftPatchFnToRegReg :: (VirtualReg -> RealReg) -> (Reg -> Reg)
liftPatchFnToRegReg patchF reg
= case reg of
RegVirtual vr -> RegReal (patchF vr)
RegReal _ -> reg