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

    -- | Native code generator for x86 and x86-64 architectures
    module GHC.CmmToAsm.X86
       ( ncgX86_64
       , ncgX86
       )
    where

    import GHC.Prelude

    import GHC.CmmToAsm.Instr
    import GHC.CmmToAsm.Monad
    import GHC.CmmToAsm.Config
    import GHC.CmmToAsm.Types
    import GHC.Types.Basic (Alignment)

    import qualified GHC.CmmToAsm.X86.Instr   as X86
    import qualified GHC.CmmToAsm.X86.Ppr     as X86
    import qualified GHC.CmmToAsm.X86.CodeGen as X86
    import qualified GHC.CmmToAsm.X86.Regs    as X86

    ncgX86 :: NCGConfig -> NcgImpl (Alignment, RawCmmStatics) X86.Instr X86.JumpDest
    ncgX86 :: NCGConfig -> NcgImpl (Alignment, RawCmmStatics) Instr JumpDest
    ncgX86 = NCGConfig -> NcgImpl (Alignment, RawCmmStatics) Instr JumpDest
    ncgX86_64

    ncgX86_64 :: NCGConfig -> NcgImpl (Alignment, RawCmmStatics) X86.Instr X86.JumpDest
    ncgX86_64 :: NCGConfig -> NcgImpl (Alignment, RawCmmStatics) Instr JumpDest
    ncgX86_64 NCGConfig
    config = NcgImpl
       { ncgConfig :: NCGConfig
    ncgConfig                 = NCGConfig
    config
       , cmmTopCodeGen :: RawCmmDecl -> NatM [NatCmmDecl (Alignment, RawCmmStatics) Instr]
    cmmTopCodeGen             = RawCmmDecl -> NatM [NatCmmDecl (Alignment, RawCmmStatics) Instr]
    X86.cmmTopCodeGen
       , generateJumpTableForInstr :: Instr -> Maybe (NatCmmDecl (Alignment, RawCmmStatics) Instr)
    generateJumpTableForInstr = NCGConfig
    -> Instr -> Maybe (NatCmmDecl (Alignment, RawCmmStatics) Instr)
    X86.generateJumpTableForInstr NCGConfig
    config
       , getJumpDestBlockId :: JumpDest -> Maybe BlockId
    getJumpDestBlockId        = JumpDest -> Maybe BlockId
    X86.getJumpDestBlockId
       , canShortcut :: Instr -> Maybe JumpDest
    canShortcut               = Instr -> Maybe JumpDest
    X86.canShortcut
       , shortcutStatics :: (BlockId -> Maybe JumpDest)
    -> (Alignment, RawCmmStatics) -> (Alignment, RawCmmStatics)
    shortcutStatics           = (BlockId -> Maybe JumpDest)
    -> (Alignment, RawCmmStatics) -> (Alignment, RawCmmStatics)
    X86.shortcutStatics
       , shortcutJump :: (BlockId -> Maybe JumpDest) -> Instr -> Instr
    shortcutJump              = (BlockId -> Maybe JumpDest) -> Instr -> Instr
    X86.shortcutJump
       , pprNatCmmDecl :: NatCmmDecl (Alignment, RawCmmStatics) Instr -> SDoc
    pprNatCmmDecl             = NCGConfig -> NatCmmDecl (Alignment, RawCmmStatics) Instr -> SDoc
    X86.pprNatCmmDecl NCGConfig
    config
       , maxSpillSlots :: Int
    maxSpillSlots             = NCGConfig -> Int
    X86.maxSpillSlots NCGConfig
    config
       , allocatableRegs :: [RealReg]
    allocatableRegs           = Platform -> [RealReg]
    X86.allocatableRegs Platform
    platform
       , ncgAllocMoreStack :: Int
    -> NatCmmDecl (Alignment, RawCmmStatics) Instr
    -> UniqSM
         (NatCmmDecl (Alignment, RawCmmStatics) Instr, [(BlockId, BlockId)])
    ncgAllocMoreStack         = Platform
    -> Int
    -> NatCmmDecl (Alignment, RawCmmStatics) Instr
    -> UniqSM
         (NatCmmDecl (Alignment, RawCmmStatics) Instr, [(BlockId, BlockId)])
    forall statics.
    Platform
    -> Int
    -> NatCmmDecl statics Instr
    -> UniqSM (NatCmmDecl statics Instr, [(BlockId, BlockId)])
    X86.allocMoreStack Platform
    platform
       , ncgExpandTop :: [NatCmmDecl (Alignment, RawCmmStatics) Instr]
    -> [NatCmmDecl (Alignment, RawCmmStatics) Instr]
    ncgExpandTop              = [NatCmmDecl (Alignment, RawCmmStatics) Instr]
    -> [NatCmmDecl (Alignment, RawCmmStatics) Instr]
    forall a. a -> a
    id
       , ncgMakeFarBranches :: LabelMap RawCmmStatics
    -> [NatBasicBlock Instr] -> [NatBasicBlock Instr]
    ncgMakeFarBranches        = ([NatBasicBlock Instr] -> [NatBasicBlock Instr])
    -> LabelMap RawCmmStatics
    -> [NatBasicBlock Instr]
    -> [NatBasicBlock Instr]
    forall a b. a -> b -> a
    const [NatBasicBlock Instr] -> [NatBasicBlock Instr]
    forall a. a -> a
    id
       , extractUnwindPoints :: [Instr] -> [UnwindPoint]
    extractUnwindPoints       = [Instr] -> [UnwindPoint]
    X86.extractUnwindPoints
       , invertCondBranches :: Maybe CFG
    -> LabelMap RawCmmStatics
    -> [NatBasicBlock Instr]
    -> [NatBasicBlock Instr]
    invertCondBranches        = Maybe CFG
    -> LabelMap RawCmmStatics
    -> [NatBasicBlock Instr]
    -> [NatBasicBlock Instr]
    forall a.
    Maybe CFG
    -> LabelMap a -> [NatBasicBlock Instr] -> [NatBasicBlock Instr]
    X86.invertCondBranches
       }
        where
          platform :: Platform
    platform = NCGConfig -> Platform
    ncgPlatform NCGConfig
    config

    -- | Instruction instance for x86 instruction set.
    instance Instruction X86.Instr where
       regUsageOfInstr :: Platform -> Instr -> RegUsage
    regUsageOfInstr         = Platform -> Instr -> RegUsage
    X86.regUsageOfInstr
       patchRegsOfInstr :: Instr -> (Reg -> Reg) -> Instr
    patchRegsOfInstr        = Instr -> (Reg -> Reg) -> Instr
    X86.patchRegsOfInstr
       isJumpishInstr :: Instr -> Bool
    isJumpishInstr          = Instr -> Bool
    X86.isJumpishInstr
       jumpDestsOfInstr :: Instr -> [BlockId]
    jumpDestsOfInstr        = Instr -> [BlockId]
    X86.jumpDestsOfInstr
       patchJumpInstr :: Instr -> (BlockId -> BlockId) -> Instr
    patchJumpInstr          = Instr -> (BlockId -> BlockId) -> Instr
    X86.patchJumpInstr
       mkSpillInstr :: NCGConfig -> Reg -> Int -> Int -> [Instr]
    mkSpillInstr            = NCGConfig -> Reg -> Int -> Int -> [Instr]
    X86.mkSpillInstr
       mkLoadInstr :: NCGConfig -> Reg -> Int -> Int -> [Instr]
    mkLoadInstr             = NCGConfig -> Reg -> Int -> Int -> [Instr]
    X86.mkLoadInstr
       takeDeltaInstr :: Instr -> Maybe Int
    takeDeltaInstr          = Instr -> Maybe Int
    X86.takeDeltaInstr
       isMetaInstr :: Instr -> Bool
    isMetaInstr             = Instr -> Bool
    X86.isMetaInstr
       mkRegRegMoveInstr :: Platform -> Reg -> Reg -> Instr
    mkRegRegMoveInstr       = Platform -> Reg -> Reg -> Instr
    X86.mkRegRegMoveInstr
       takeRegRegMoveInstr :: Instr -> Maybe (Reg, Reg)
    takeRegRegMoveInstr     = Instr -> Maybe (Reg, Reg)
    X86.takeRegRegMoveInstr
       mkJumpInstr :: BlockId -> [Instr]
    mkJumpInstr             = BlockId -> [Instr]
    X86.mkJumpInstr
       mkStackAllocInstr :: Platform -> Int -> [Instr]
    mkStackAllocInstr       = Platform -> Int -> [Instr]
    X86.mkStackAllocInstr
       mkStackDeallocInstr :: Platform -> Int -> [Instr]
    mkStackDeallocInstr     = Platform -> Int -> [Instr]
    X86.mkStackDeallocInstr
       pprInstr :: Platform -> Instr -> SDoc
    pprInstr                = Platform -> Instr -> SDoc
    X86.pprInstr
       mkComment :: SDoc -> [Instr]
    mkComment               = [Instr] -> SDoc -> [Instr]
    forall a b. a -> b -> a
    const []