module GHC.CmmToAsm.AArch64.Regs where
import GHC.Prelude
import GHC.Platform.Reg
import GHC.Platform.Reg.Class
import GHC.CmmToAsm.Format
import GHC.Cmm
import GHC.Cmm.CLabel ( CLabel )
import GHC.Types.Unique
import GHC.Platform.Regs
import GHC.Utils.Outputable
import GHC.Utils.Panic
import GHC.Platform
allMachRegNos :: [RegNo]
allMachRegNos = [0..31] ++ [32..63]
allocatableRegs :: Platform -> [RealReg]
allocatableRegs platform
= let isFree i = freeReg platform i
in map RealRegSingle $ filter isFree allMachRegNos
allGpArgRegs :: [Reg]
allGpArgRegs = map regSingle [0..7]
allFpArgRegs :: [Reg]
allFpArgRegs = map regSingle [32..39]
data AddrMode
= AddrRegReg Reg Reg
| AddrRegImm Reg Imm
| AddrReg Reg
deriving (Eq, Show)
data Imm
= ImmInt Int
| ImmInteger Integer
| ImmCLbl CLabel
| ImmLit SDoc
| ImmIndex CLabel Int
| ImmFloat Rational
| ImmDouble Rational
| ImmConstantSum Imm Imm
| ImmConstantDiff Imm Imm
deriving (Eq, Show)
instance Show SDoc where
show = showPprUnsafe . ppr
instance Eq SDoc where
lhs == rhs = show lhs == show rhs
strImmLit :: String -> Imm
strImmLit s = ImmLit (text s)
litToImm :: CmmLit -> Imm
litToImm (CmmInt i w) = ImmInteger (narrowS w i)
litToImm (CmmFloat f W32) = ImmFloat f
litToImm (CmmFloat f W64) = ImmDouble f
litToImm (CmmLabel l) = ImmCLbl l
litToImm (CmmLabelOff l off) = ImmIndex l off
litToImm (CmmLabelDiffOff l1 l2 off _)
= ImmConstantSum
(ImmConstantDiff (ImmCLbl l1) (ImmCLbl l2))
(ImmInt off)
litToImm _ = panic "AArch64.Regs.litToImm: no match"
virtualRegSqueeze :: RegClass -> VirtualReg -> Int
virtualRegSqueeze cls vr
= case cls of
RcInteger
-> case vr of
VirtualRegI{} -> 1
VirtualRegHi{} -> 1
_other -> 0
RcDouble
-> case vr of
VirtualRegD{} -> 1
VirtualRegF{} -> 0
_other -> 0
_other -> 0
realRegSqueeze :: RegClass -> RealReg -> Int
realRegSqueeze cls rr
= case cls of
RcInteger
-> case rr of
RealRegSingle regNo
| regNo < 32 -> 1
| otherwise -> 0
RealRegPair{} -> 0
RcDouble
-> case rr of
RealRegSingle regNo
| regNo < 32 -> 0
| otherwise -> 1
RealRegPair{} -> 0
_other -> 0
mkVirtualReg :: Unique -> Format -> VirtualReg
mkVirtualReg u format
| not (isFloatFormat format) = VirtualRegI u
| otherwise
= case format of
FF32 -> VirtualRegD u
FF64 -> VirtualRegD u
_ -> panic "AArch64.mkVirtualReg"
classOfRealReg :: RealReg -> RegClass
classOfRealReg (RealRegSingle i)
| i < 32 = RcInteger
| otherwise = RcDouble
classOfRealReg (RealRegPair{})
= panic "regClass(ppr): no reg pairs on this architecture"
regDotColor :: RealReg -> SDoc
regDotColor reg
= case classOfRealReg reg of
RcInteger -> text "blue"
RcFloat -> text "red"
RcDouble -> text "green"