    {-# OPTIONS_GHC -fno-warn-orphans #-}

    -- | Native code generator for AArch64 architectures
    module GHC.CmmToAsm.AArch64
       ( ncgAArch64 )
    where

    import GHC.Prelude

    import GHC.CmmToAsm.Instr
    import GHC.CmmToAsm.Monad
    import GHC.CmmToAsm.Config
    import GHC.CmmToAsm.Types
    import GHC.Utils.Outputable (ftext)

    import qualified GHC.CmmToAsm.AArch64.Instr   as AArch64
    import qualified GHC.CmmToAsm.AArch64.Ppr     as AArch64
    import qualified GHC.CmmToAsm.AArch64.CodeGen as AArch64
    import qualified GHC.CmmToAsm.AArch64.Regs    as AArch64
    import qualified GHC.CmmToAsm.AArch64.RegInfo as AArch64

    ncgAArch64 :: NCGConfig -> NcgImpl RawCmmStatics AArch64.Instr AArch64.JumpDest
    ncgAArch64 :: NCGConfig -> NcgImpl RawCmmStatics Instr JumpDest
    ncgAArch64 NCGConfig
    config
     = NcgImpl {
            ncgConfig :: NCGConfig
    ncgConfig                 = NCGConfig
    config
           ,cmmTopCodeGen :: RawCmmDecl -> NatM [NatCmmDecl RawCmmStatics Instr]
    cmmTopCodeGen             = RawCmmDecl -> NatM [NatCmmDecl RawCmmStatics Instr]
    AArch64.cmmTopCodeGen
           ,generateJumpTableForInstr :: Instr -> Maybe (NatCmmDecl RawCmmStatics Instr)
    generateJumpTableForInstr = NCGConfig -> Instr -> Maybe (NatCmmDecl RawCmmStatics Instr)
    AArch64.generateJumpTableForInstr NCGConfig
    config
           ,getJumpDestBlockId :: JumpDest -> Maybe BlockId
    getJumpDestBlockId        = JumpDest -> Maybe BlockId
    AArch64.getJumpDestBlockId
           ,canShortcut :: Instr -> Maybe JumpDest
    canShortcut               = Instr -> Maybe JumpDest
    AArch64.canShortcut
           ,shortcutStatics :: (BlockId -> Maybe JumpDest) -> RawCmmStatics -> RawCmmStatics
    shortcutStatics           = (BlockId -> Maybe JumpDest) -> RawCmmStatics -> RawCmmStatics
    AArch64.shortcutStatics
           ,shortcutJump :: (BlockId -> Maybe JumpDest) -> Instr -> Instr
    shortcutJump              = (BlockId -> Maybe JumpDest) -> Instr -> Instr
    AArch64.shortcutJump
           ,pprNatCmmDeclS :: NatCmmDecl RawCmmStatics Instr -> SDoc
    pprNatCmmDeclS            = NCGConfig -> NatCmmDecl RawCmmStatics Instr -> SDoc
    forall doc.
    IsDoc doc =>
    NCGConfig -> NatCmmDecl RawCmmStatics Instr -> doc
    AArch64.pprNatCmmDecl NCGConfig
    config
           ,pprNatCmmDeclH :: NatCmmDecl RawCmmStatics Instr -> HDoc
    pprNatCmmDeclH            = NCGConfig -> NatCmmDecl RawCmmStatics Instr -> HDoc
    forall doc.
    IsDoc doc =>
    NCGConfig -> NatCmmDecl RawCmmStatics Instr -> doc
    AArch64.pprNatCmmDecl NCGConfig
    config
           ,maxSpillSlots :: Int
    maxSpillSlots             = NCGConfig -> Int
    AArch64.maxSpillSlots NCGConfig
    config
           ,allocatableRegs :: [RealReg]
    allocatableRegs           = Platform -> [RealReg]
    AArch64.allocatableRegs Platform
    platform
           ,ncgAllocMoreStack :: Int
    -> NatCmmDecl RawCmmStatics Instr
    -> UniqSM (NatCmmDecl RawCmmStatics Instr, [(BlockId, BlockId)])
    ncgAllocMoreStack         = Platform
    -> Int
    -> NatCmmDecl RawCmmStatics Instr
    -> UniqSM (NatCmmDecl RawCmmStatics Instr, [(BlockId, BlockId)])
    forall statics.
    Platform
    -> Int
    -> NatCmmDecl statics Instr
    -> UniqSM (NatCmmDecl statics Instr, [(BlockId, BlockId)])
    AArch64.allocMoreStack Platform
    platform
           ,ncgMakeFarBranches :: Platform
    -> LabelMap RawCmmStatics
    -> [NatBasicBlock Instr]
    -> UniqSM [NatBasicBlock Instr]
    ncgMakeFarBranches        = Platform
    -> LabelMap RawCmmStatics
    -> [NatBasicBlock Instr]
    -> UniqSM [NatBasicBlock Instr]
    AArch64.makeFarBranches
           ,extractUnwindPoints :: [Instr] -> [UnwindPoint]
    extractUnwindPoints       = [UnwindPoint] -> [Instr] -> [UnwindPoint]
    forall a b. a -> b -> a
    const []
           ,invertCondBranches :: Maybe CFG
    -> LabelMap RawCmmStatics
    -> [NatBasicBlock Instr]
    -> [NatBasicBlock Instr]
    invertCondBranches        = \Maybe CFG
    _ LabelMap RawCmmStatics
    _ [NatBasicBlock Instr]
    blocks -> [NatBasicBlock Instr]
    blocks
      }
        where
          platform :: Platform
    platform = NCGConfig -> Platform
    ncgPlatform NCGConfig
    config

    -- | Instruction instance for aarch64
    instance Instruction AArch64.Instr where
            regUsageOfInstr :: Platform -> Instr -> RegUsage
    regUsageOfInstr         = Platform -> Instr -> RegUsage
    AArch64.regUsageOfInstr
            patchRegsOfInstr :: Instr -> (Reg -> Reg) -> Instr
    patchRegsOfInstr        = Instr -> (Reg -> Reg) -> Instr
    AArch64.patchRegsOfInstr
            isJumpishInstr :: Instr -> Bool
    isJumpishInstr          = Instr -> Bool
    AArch64.isJumpishInstr
            jumpDestsOfInstr :: Instr -> [BlockId]
    jumpDestsOfInstr        = Instr -> [BlockId]
    AArch64.jumpDestsOfInstr
            patchJumpInstr :: Instr -> (BlockId -> BlockId) -> Instr
    patchJumpInstr          = Instr -> (BlockId -> BlockId) -> Instr
    AArch64.patchJumpInstr
            mkSpillInstr :: NCGConfig -> Reg -> Int -> Int -> [Instr]
    mkSpillInstr            = HasCallStack => NCGConfig -> Reg -> Int -> Int -> [Instr]
    NCGConfig -> Reg -> Int -> Int -> [Instr]
    AArch64.mkSpillInstr
            mkLoadInstr :: NCGConfig -> Reg -> Int -> Int -> [Instr]
    mkLoadInstr             = NCGConfig -> Reg -> Int -> Int -> [Instr]
    AArch64.mkLoadInstr
            takeDeltaInstr :: Instr -> Maybe Int
    takeDeltaInstr          = Instr -> Maybe Int
    AArch64.takeDeltaInstr
            isMetaInstr :: Instr -> Bool
    isMetaInstr             = Instr -> Bool
    AArch64.isMetaInstr
            mkRegRegMoveInstr :: Platform -> Reg -> Reg -> Instr
    mkRegRegMoveInstr Platform
    _     = Reg -> Reg -> Instr
    AArch64.mkRegRegMoveInstr
            takeRegRegMoveInstr :: Instr -> Maybe (Reg, Reg)
    takeRegRegMoveInstr     = Instr -> Maybe (Reg, Reg)
    AArch64.takeRegRegMoveInstr
            mkJumpInstr :: BlockId -> [Instr]
    mkJumpInstr             = BlockId -> [Instr]
    AArch64.mkJumpInstr
            mkStackAllocInstr :: Platform -> Int -> [Instr]
    mkStackAllocInstr       = Platform -> Int -> [Instr]
    AArch64.mkStackAllocInstr
            mkStackDeallocInstr :: Platform -> Int -> [Instr]
    mkStackDeallocInstr     = Platform -> Int -> [Instr]
    AArch64.mkStackDeallocInstr
            mkComment :: FastString -> [Instr]
    mkComment               = Instr -> [Instr]
    forall a. a -> [a]
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure (Instr -> [Instr])
    -> (FastString -> Instr) -> FastString -> [Instr]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . SDoc -> Instr
    AArch64.COMMENT (SDoc -> Instr) -> (FastString -> SDoc) -> FastString -> Instr
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . FastString -> SDoc
    forall doc. IsLine doc => FastString -> doc
    ftext
            pprInstr :: Platform -> Instr -> SDoc
    pprInstr                = Platform -> Instr -> SDoc
    forall doc. IsDoc doc => Platform -> Instr -> doc
    AArch64.pprInstr