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

    -- | Native code generator for SPARC architectures
    module GHC.CmmToAsm.SPARC
       ( ncgSPARC
       )
    where

    import GHC.Prelude
    import GHC.Utils.Panic

    import GHC.CmmToAsm.Monad
    import GHC.CmmToAsm.Config
    import GHC.CmmToAsm.Types
    import GHC.CmmToAsm.Instr

    import qualified GHC.CmmToAsm.SPARC.Instr          as SPARC
    import qualified GHC.CmmToAsm.SPARC.Ppr            as SPARC
    import qualified GHC.CmmToAsm.SPARC.CodeGen        as SPARC
    import qualified GHC.CmmToAsm.SPARC.CodeGen.Expand as SPARC
    import qualified GHC.CmmToAsm.SPARC.Regs           as SPARC
    import qualified GHC.CmmToAsm.SPARC.ShortcutJump   as SPARC

    ncgSPARC :: NCGConfig -> NcgImpl RawCmmStatics SPARC.Instr SPARC.JumpDest
    ncgSPARC :: NCGConfig -> NcgImpl RawCmmStatics Instr JumpDest
    ncgSPARC NCGConfig
    config = NcgImpl
       { ncgConfig :: NCGConfig
    ncgConfig                 = NCGConfig
    config
       , cmmTopCodeGen :: RawCmmDecl -> NatM [NatCmmDecl RawCmmStatics Instr]
    cmmTopCodeGen             = RawCmmDecl -> NatM [NatCmmDecl RawCmmStatics Instr]
    SPARC.cmmTopCodeGen
       , generateJumpTableForInstr :: Instr -> Maybe (NatCmmDecl RawCmmStatics Instr)
    generateJumpTableForInstr = Platform -> Instr -> Maybe (NatCmmDecl RawCmmStatics Instr)
    SPARC.generateJumpTableForInstr Platform
    platform
       , getJumpDestBlockId :: JumpDest -> Maybe BlockId
    getJumpDestBlockId        = JumpDest -> Maybe BlockId
    SPARC.getJumpDestBlockId
       , canShortcut :: Instr -> Maybe JumpDest
    canShortcut               = Instr -> Maybe JumpDest
    SPARC.canShortcut
       , shortcutStatics :: (BlockId -> Maybe JumpDest) -> RawCmmStatics -> RawCmmStatics
    shortcutStatics           = (BlockId -> Maybe JumpDest) -> RawCmmStatics -> RawCmmStatics
    SPARC.shortcutStatics
       , shortcutJump :: (BlockId -> Maybe JumpDest) -> Instr -> Instr
    shortcutJump              = (BlockId -> Maybe JumpDest) -> Instr -> Instr
    SPARC.shortcutJump
       , pprNatCmmDecl :: NatCmmDecl RawCmmStatics Instr -> SDoc
    pprNatCmmDecl             = NCGConfig -> NatCmmDecl RawCmmStatics Instr -> SDoc
    SPARC.pprNatCmmDecl NCGConfig
    config
       , maxSpillSlots :: Int
    maxSpillSlots             = NCGConfig -> Int
    SPARC.maxSpillSlots NCGConfig
    config
       , allocatableRegs :: [RealReg]
    allocatableRegs           = [RealReg]
    SPARC.allocatableRegs
       , ncgExpandTop :: [NatCmmDecl RawCmmStatics Instr]
    -> [NatCmmDecl RawCmmStatics Instr]
    ncgExpandTop              = forall a b. (a -> b) -> [a] -> [b]
    map NatCmmDecl RawCmmStatics Instr -> NatCmmDecl RawCmmStatics Instr
    SPARC.expandTop
       , ncgMakeFarBranches :: LabelMap RawCmmStatics
    -> [NatBasicBlock Instr] -> [NatBasicBlock Instr]
    ncgMakeFarBranches        = forall a b. a -> b -> a
    const forall a. a -> a
    id
       , extractUnwindPoints :: [Instr] -> [UnwindPoint]
    extractUnwindPoints       = forall a b. a -> b -> a
    const []
       , invertCondBranches :: Maybe CFG
    -> LabelMap RawCmmStatics
    -> [NatBasicBlock Instr]
    -> [NatBasicBlock Instr]
    invertCondBranches        = \Maybe CFG
    _ LabelMap RawCmmStatics
    _ -> forall a. a -> a
    id
       -- Allocating more stack space for spilling isn't currently supported for the
       -- linear register allocator on SPARC, hence the panic below.
       , ncgAllocMoreStack :: Int
    -> NatCmmDecl RawCmmStatics Instr
    -> UniqSM (NatCmmDecl RawCmmStatics Instr, [(BlockId, BlockId)])
    ncgAllocMoreStack         = forall {a} {p} {a}. Show a => a -> p -> a
    noAllocMoreStack
       }
        where
          platform :: Platform
    platform = NCGConfig -> Platform
    ncgPlatform NCGConfig
    config

          noAllocMoreStack :: a -> p -> a
    noAllocMoreStack a
    amount p
    _
            = forall a. String -> a
    panic forall a b. (a -> b) -> a -> b
    $   String
    "Register allocator: out of stack slots (need " forall a. [a] -> [a] -> [a]
    ++ forall a. Show a => a -> String
    show a
    amount forall a. [a] -> [a] -> [a]
    ++ String
    ")\n"
                  forall a. [a] -> [a] -> [a]
    ++  String
    "   If you are trying to compile SHA1.hs from the crypto library then this\n"
                  forall a. [a] -> [a] -> [a]
    ++  String
    "   is a known limitation in the linear allocator.\n"
                  forall a. [a] -> [a] -> [a]
    ++  String
    "\n"
                  forall a. [a] -> [a] -> [a]
    ++  String
    "   Try enabling the graph colouring allocator with -fregs-graph instead."
                  forall a. [a] -> [a] -> [a]
    ++  String
    "   You can still file a bug report if you like.\n"

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