    -- | Native code generator configuration
    module GHC.CmmToAsm.Config
       ( NCGConfig(..)
       , ncgWordWidth
       , ncgSpillPreallocSize
       , platformWordWidth
       )
    where

    import GHC.Prelude
    import GHC.Platform
    import GHC.Cmm.Type (Width(..))
    import GHC.CmmToAsm.CFG.Weight
    import GHC.Unit.Module (Module)
    import GHC.Utils.Outputable

    -- | Native code generator configuration
    data NCGConfig = NCGConfig
       { NCGConfig -> Platform
    ncgPlatform              :: !Platform        -- ^ Target platform
       , NCGConfig -> SDocContext
    ncgAsmContext            :: !SDocContext     -- ^ Context for ASM code generation
       , NCGConfig -> Module
    ncgThisModule            :: !Module          -- ^ The name of the module we are currently compiling
       , NCGConfig -> Maybe Int
    ncgProcAlignment         :: !(Maybe Int)     -- ^ Mandatory proc alignment
       , NCGConfig -> Bool
    ncgExternalDynamicRefs   :: !Bool            -- ^ Generate code to link against dynamic libraries
       , NCGConfig -> Bool
    ncgPIC                   :: !Bool            -- ^ Enable Position-Independent Code
       , NCGConfig -> Word
    ncgInlineThresholdMemcpy :: !Word            -- ^ If inlining `memcpy` produces less than this threshold (in pseudo-instruction unit), do it
       , NCGConfig -> Word
    ncgInlineThresholdMemset :: !Word            -- ^ Ditto for `memset`
       , NCGConfig -> Bool
    ncgSplitSections         :: !Bool            -- ^ Split sections
       , NCGConfig -> Bool
    ncgRegsIterative         :: !Bool
       , NCGConfig -> Bool
    ncgRegsGraph             :: !Bool
       , NCGConfig -> Bool
    ncgAsmLinting            :: !Bool            -- ^ Perform ASM linting pass
       , NCGConfig -> Bool
    ncgDoConstantFolding     :: !Bool            -- ^ Perform CMM constant folding
       , NCGConfig -> Maybe SseVersion
    ncgSseVersion            :: Maybe SseVersion -- ^ (x86) SSE instructions
       , NCGConfig -> Bool
    ncgAvxEnabled            :: !Bool
       , NCGConfig -> Bool
    ncgAvx2Enabled           :: !Bool
       , NCGConfig -> Bool
    ncgAvx512fEnabled        :: !Bool
       , NCGConfig -> Maybe BmiVersion
    ncgBmiVersion            :: Maybe BmiVersion -- ^ (x86) BMI instructions
       , NCGConfig -> Bool
    ncgDumpRegAllocStages    :: !Bool
       , NCGConfig -> Bool
    ncgDumpAsmStats          :: !Bool
       , NCGConfig -> Bool
    ncgDumpAsmConflicts      :: !Bool
       , NCGConfig -> Weights
    ncgCfgWeights            :: !Weights         -- ^ CFG edge weights
       , NCGConfig -> Bool
    ncgCfgBlockLayout        :: !Bool            -- ^ Use CFG based block layout algorithm
       , NCGConfig -> Bool
    ncgCfgWeightlessLayout   :: !Bool            -- ^ Layout based on last instruction per block.
       , NCGConfig -> Bool
    ncgDwarfEnabled          :: !Bool            -- ^ Enable Dwarf generation
       , NCGConfig -> Bool
    ncgDwarfUnwindings       :: !Bool            -- ^ Enable unwindings
       , NCGConfig -> Bool
    ncgDwarfStripBlockInfo   :: !Bool            -- ^ Strip out block information from generated Dwarf
       , NCGConfig -> Bool
    ncgExposeInternalSymbols :: !Bool            -- ^ Expose symbol table entries for internal symbols
       , NCGConfig -> Bool
    ncgDwarfSourceNotes      :: !Bool            -- ^ Enable GHC-specific source note DIEs
       , NCGConfig -> Bool
    ncgCmmStaticPred         :: !Bool            -- ^ Enable static control-flow prediction
       , NCGConfig -> Bool
    ncgEnableShortcutting    :: !Bool            -- ^ Enable shortcutting (don't jump to blocks only containing a jump)
       , NCGConfig -> Bool
    ncgEnableInterModuleFarJumps:: !Bool            -- ^ Use far-jumps for cross-module jumps.
       , NCGConfig -> Bool
    ncgComputeUnwinding      :: !Bool            -- ^ Compute block unwinding tables
       , NCGConfig -> Bool
    ncgEnableDeadCodeElimination :: !Bool        -- ^ Whether to enable the dead-code elimination
       }

    -- | Return Word size
    ncgWordWidth :: NCGConfig -> Width
    ncgWordWidth :: NCGConfig -> Width
    ncgWordWidth NCGConfig
    config = Platform -> Width
    platformWordWidth (NCGConfig -> Platform
    ncgPlatform NCGConfig
    config)

    -- | Size in bytes of the pre-allocated spill space on the C stack
    ncgSpillPreallocSize :: NCGConfig -> Int
    ncgSpillPreallocSize :: NCGConfig -> Int
    ncgSpillPreallocSize NCGConfig
    config = PlatformConstants -> Int
    pc_RESERVED_C_STACK_BYTES (Platform -> PlatformConstants
    platformConstants (NCGConfig -> Platform
    ncgPlatform NCGConfig
    config))

    -- | Return Word size
    platformWordWidth :: Platform -> Width
    platformWordWidth :: Platform -> Width
    platformWordWidth Platform
    platform = case Platform -> PlatformWordSize
    platformWordSize Platform
    platform of
       PlatformWordSize
    PW4 -> Width
    W32
       PlatformWordSize
    PW8 -> Width
    W64