summaryrefslogtreecommitdiff
path: root/compiler/GHC/Platform.hs
diff options
context:
space:
mode:
authorSylvain Henry <sylvain@haskus.fr>2020-07-21 19:15:59 +0200
committerMarge Bot <ben+marge-bot@smart-cactus.org>2020-07-25 00:45:08 -0400
commit7721b923d53fb9eb93f80bb93b4c3bd976c05b4c (patch)
treeedc61b1ed9885e442c7327460052f10d1ca589fa /compiler/GHC/Platform.hs
parent73145d57f961c73b5853da7881d6a21e48e05909 (diff)
downloadhaskell-7721b923d53fb9eb93f80bb93b4c3bd976c05b4c.tar.gz
Move GHC.Platform into the compiler
Previously it was in ghc-boot so that ghc-pkg could use it. However it wasn't necessary because ghc-pkg only uses a subset of it: reading target arch and OS from the settings file. This is now done via GHC.Platform.ArchOS (was called PlatformMini before).
Diffstat (limited to 'compiler/GHC/Platform.hs')
-rw-r--r--compiler/GHC/Platform.hs216
1 files changed, 216 insertions, 0 deletions
diff --git a/compiler/GHC/Platform.hs b/compiler/GHC/Platform.hs
new file mode 100644
index 0000000000..56a18e9c88
--- /dev/null
+++ b/compiler/GHC/Platform.hs
@@ -0,0 +1,216 @@
+{-# LANGUAGE ScopedTypeVariables #-}
+
+-- | Platform description
+module GHC.Platform
+ ( Platform (..)
+ , PlatformWordSize(..)
+ , PlatformConstants(..)
+ , platformArch
+ , platformOS
+ , ArchOS(..)
+ , Arch(..)
+ , OS(..)
+ , ArmISA(..)
+ , ArmISAExt(..)
+ , ArmABI(..)
+ , PPC_64ABI(..)
+ , ByteOrder(..)
+ , target32Bit
+ , isARM
+ , osElfTarget
+ , osMachOTarget
+ , osSubsectionsViaSymbols
+ , platformUsesFrameworks
+ , platformWordSizeInBytes
+ , platformWordSizeInBits
+ , platformMinInt
+ , platformMaxInt
+ , platformMaxWord
+ , platformInIntRange
+ , platformInWordRange
+ , PlatformMisc(..)
+ , SseVersion (..)
+ , BmiVersion (..)
+ )
+where
+
+import Prelude -- See Note [Why do we import Prelude here?]
+
+import Data.Word
+import Data.Int
+
+import GHC.Read
+import GHC.ByteOrder (ByteOrder(..))
+import GHC.Platform.Constants
+import GHC.Platform.ArchOS
+
+-- | Platform description
+--
+-- This is used to describe platforms so that we can generate code for them.
+data Platform = Platform
+ { platformArchOS :: !ArchOS -- ^ Architecture and OS
+ , platformWordSize :: !PlatformWordSize -- ^ Word size
+ , platformByteOrder :: !ByteOrder -- ^ Byte order (endianness)
+ , platformUnregisterised :: !Bool
+ , platformHasGnuNonexecStack :: !Bool
+ , platformHasIdentDirective :: !Bool
+ , platformHasSubsectionsViaSymbols :: !Bool
+ , platformIsCrossCompiling :: !Bool
+ , platformLeadingUnderscore :: !Bool -- ^ Symbols need underscore prefix
+ , platformTablesNextToCode :: !Bool
+ -- ^ Determines whether we will be compiling info tables that reside just
+ -- before the entry code, or with an indirection to the entry code. See
+ -- TABLES_NEXT_TO_CODE in includes/rts/storage/InfoTables.h.
+ , platformConstants :: !PlatformConstants
+ -- ^ Constants such as structure offsets, type sizes, etc.
+ }
+ deriving (Read, Show, Eq)
+
+data PlatformWordSize
+ = PW4 -- ^ A 32-bit platform
+ | PW8 -- ^ A 64-bit platform
+ deriving (Eq)
+
+instance Show PlatformWordSize where
+ show PW4 = "4"
+ show PW8 = "8"
+
+instance Read PlatformWordSize where
+ readPrec = do
+ i :: Int <- readPrec
+ case i of
+ 4 -> return PW4
+ 8 -> return PW8
+ other -> fail ("Invalid PlatformWordSize: " ++ show other)
+
+platformWordSizeInBytes :: Platform -> Int
+platformWordSizeInBytes p =
+ case platformWordSize p of
+ PW4 -> 4
+ PW8 -> 8
+
+platformWordSizeInBits :: Platform -> Int
+platformWordSizeInBits p = platformWordSizeInBytes p * 8
+
+-- | Platform architecture
+platformArch :: Platform -> Arch
+platformArch platform = case platformArchOS platform of
+ ArchOS arch _ -> arch
+
+-- | Platform OS
+platformOS :: Platform -> OS
+platformOS platform = case platformArchOS platform of
+ ArchOS _ os -> os
+
+isARM :: Arch -> Bool
+isARM (ArchARM {}) = True
+isARM ArchARM64 = True
+isARM _ = False
+
+-- | This predicate tells us whether the platform is 32-bit.
+target32Bit :: Platform -> Bool
+target32Bit p =
+ case platformWordSize p of
+ PW4 -> True
+ PW8 -> False
+
+-- | This predicate tells us whether the OS supports ELF-like shared libraries.
+osElfTarget :: OS -> Bool
+osElfTarget OSLinux = True
+osElfTarget OSFreeBSD = True
+osElfTarget OSDragonFly = True
+osElfTarget OSOpenBSD = True
+osElfTarget OSNetBSD = True
+osElfTarget OSSolaris2 = True
+osElfTarget OSDarwin = False
+osElfTarget OSMinGW32 = False
+osElfTarget OSKFreeBSD = True
+osElfTarget OSHaiku = True
+osElfTarget OSQNXNTO = False
+osElfTarget OSAIX = False
+osElfTarget OSHurd = True
+osElfTarget OSUnknown = False
+ -- Defaulting to False is safe; it means don't rely on any
+ -- ELF-specific functionality. It is important to have a default for
+ -- portability, otherwise we have to answer this question for every
+ -- new platform we compile on (even unreg).
+
+-- | This predicate tells us whether the OS support Mach-O shared libraries.
+osMachOTarget :: OS -> Bool
+osMachOTarget OSDarwin = True
+osMachOTarget _ = False
+
+osUsesFrameworks :: OS -> Bool
+osUsesFrameworks OSDarwin = True
+osUsesFrameworks _ = False
+
+platformUsesFrameworks :: Platform -> Bool
+platformUsesFrameworks = osUsesFrameworks . platformOS
+
+osSubsectionsViaSymbols :: OS -> Bool
+osSubsectionsViaSymbols OSDarwin = True
+osSubsectionsViaSymbols _ = False
+
+-- | Minimum representable Int value for the given platform
+platformMinInt :: Platform -> Integer
+platformMinInt p = case platformWordSize p of
+ PW4 -> toInteger (minBound :: Int32)
+ PW8 -> toInteger (minBound :: Int64)
+
+-- | Maximum representable Int value for the given platform
+platformMaxInt :: Platform -> Integer
+platformMaxInt p = case platformWordSize p of
+ PW4 -> toInteger (maxBound :: Int32)
+ PW8 -> toInteger (maxBound :: Int64)
+
+-- | Maximum representable Word value for the given platform
+platformMaxWord :: Platform -> Integer
+platformMaxWord p = case platformWordSize p of
+ PW4 -> toInteger (maxBound :: Word32)
+ PW8 -> toInteger (maxBound :: Word64)
+
+-- | Test if the given Integer is representable with a platform Int
+platformInIntRange :: Platform -> Integer -> Bool
+platformInIntRange platform x = x >= platformMinInt platform && x <= platformMaxInt platform
+
+-- | Test if the given Integer is representable with a platform Word
+platformInWordRange :: Platform -> Integer -> Bool
+platformInWordRange platform x = x >= 0 && x <= platformMaxWord platform
+
+
+--------------------------------------------------
+-- Instruction sets
+--------------------------------------------------
+
+-- | x86 SSE instructions
+data SseVersion
+ = SSE1
+ | SSE2
+ | SSE3
+ | SSE4
+ | SSE42
+ deriving (Eq, Ord)
+
+-- | x86 BMI (bit manipulation) instructions
+data BmiVersion
+ = BMI1
+ | BMI2
+ deriving (Eq, Ord)
+
+
+-- | Platform-specific settings formerly hard-coded in Config.hs.
+--
+-- These should probably be all be triaged whether they can be computed from
+-- other settings or belong in another another place (like 'Platform' above).
+data PlatformMisc = PlatformMisc
+ { -- TODO Recalculate string from richer info?
+ platformMisc_targetPlatformString :: String
+ , platformMisc_ghcWithInterpreter :: Bool
+ , platformMisc_ghcWithSMP :: Bool
+ , platformMisc_ghcRTSWays :: String
+ , platformMisc_libFFI :: Bool
+ , platformMisc_ghcThreaded :: Bool
+ , platformMisc_ghcDebugged :: Bool
+ , platformMisc_ghcRtsWithLibdw :: Bool
+ , platformMisc_llvmTarget :: String
+ }