{-# 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
-> UniqDSM (NatCmmDecl RawCmmStatics Instr, [(BlockId, BlockId)])
ncgAllocMoreStack         = Platform
-> Int
-> NatCmmDecl RawCmmStatics Instr
-> UniqDSM (NatCmmDecl RawCmmStatics Instr, [(BlockId, BlockId)])
forall statics.
Platform
-> Int
-> NatCmmDecl statics Instr
-> UniqDSM (NatCmmDecl statics Instr, [(BlockId, BlockId)])
AArch64.allocMoreStack Platform
platform
       ,ncgMakeFarBranches :: Platform
-> LabelMap RawCmmStatics
-> [NatBasicBlock Instr]
-> UniqDSM [NatBasicBlock Instr]
ncgMakeFarBranches        = Platform
-> LabelMap RawCmmStatics
-> [NatBasicBlock Instr]
-> UniqDSM [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 :: HasDebugCallStack => Platform -> Instr -> (Reg -> Reg) -> Instr
patchRegsOfInstr Platform
_      = Instr -> (Reg -> Reg) -> Instr
AArch64.patchRegsOfInstr
        isJumpishInstr :: Instr -> Bool
isJumpishInstr          = Instr -> Bool
AArch64.isJumpishInstr
        jumpDestsOfInstr :: Instr -> [BlockId]
jumpDestsOfInstr        = Instr -> [BlockId]
AArch64.jumpDestsOfInstr
        canFallthroughTo :: Instr -> BlockId -> Bool
canFallthroughTo        = Instr -> BlockId -> Bool
AArch64.canFallthroughTo
        patchJumpInstr :: Instr -> (BlockId -> BlockId) -> Instr
patchJumpInstr          = Instr -> (BlockId -> BlockId) -> Instr
AArch64.patchJumpInstr
        mkSpillInstr :: HasDebugCallStack =>
NCGConfig -> RegWithFormat -> Int -> Int -> [Instr]
mkSpillInstr            = HasCallStack => NCGConfig -> RegWithFormat -> Int -> Int -> [Instr]
NCGConfig -> RegWithFormat -> Int -> Int -> [Instr]
AArch64.mkSpillInstr
        mkLoadInstr :: HasDebugCallStack =>
NCGConfig -> RegWithFormat -> Int -> Int -> [Instr]
mkLoadInstr             = NCGConfig -> RegWithFormat -> Int -> Int -> [Instr]
AArch64.mkLoadInstr
        takeDeltaInstr :: Instr -> Maybe Int
takeDeltaInstr          = Instr -> Maybe Int
AArch64.takeDeltaInstr
        isMetaInstr :: Instr -> Bool
isMetaInstr             = Instr -> Bool
AArch64.isMetaInstr
        mkRegRegMoveInstr :: HasDebugCallStack => NCGConfig -> Format -> Reg -> Reg -> Instr
mkRegRegMoveInstr NCGConfig
_     = Format -> Reg -> Reg -> Instr
AArch64.mkRegRegMoveInstr
        takeRegRegMoveInstr :: Platform -> Instr -> Maybe (Reg, Reg)
takeRegRegMoveInstr Platform
_   = 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