From 79e9cfa32cc3b94428e1199ce550bb62c50bf8e6 Mon Sep 17 00:00:00 2001 From: Simon Marlow Date: Wed, 14 Oct 2009 13:06:12 +0000 Subject: [PATCH] Fixes for cross-compiling to a different word size This patch eliminates a couple of places where we were assuming that the host word size is the same as the target word size. Also a little refactoring: Constants now exports the types TargetInt and TargetWord corresponding to the Int/Word type on the target platform, and I moved the definitions of tARGET_INT_MAX and friends from Literal to Constants. Thanks to Barney Stratford for helping track down the problem and fix it. We now know that GHC can successfully cross-compile from 32-bit to 64-bit. --- compiler/basicTypes/Literal.lhs | 27 +-------------------------- compiler/prelude/PrelRules.lhs | 8 +++++--- includes/HaskellConstants.hs | 22 ++++++++++++++++++++++ 3 files changed, 28 insertions(+), 29 deletions(-) diff --git a/compiler/basicTypes/Literal.lhs b/compiler/basicTypes/Literal.lhs index 5cf8adb..aa3cdd5 100644 --- a/compiler/basicTypes/Literal.lhs +++ b/compiler/basicTypes/Literal.lhs @@ -49,6 +49,7 @@ import FastTypes import FastString import BasicTypes import Binary +import Constants import Data.Int import Data.Ratio @@ -59,32 +60,6 @@ import Data.Char %************************************************************************ %* * -\subsection{Sizes} -%* * -%************************************************************************ - -If we're compiling with GHC (and we're not cross-compiling), then we -know that minBound and maxBound :: Int are the right values for the -target architecture. Otherwise, we assume -2^31 and 2^31-1 -respectively (which will be wrong on a 64-bit machine). - -\begin{code} -tARGET_MIN_INT, tARGET_MAX_INT, tARGET_MAX_WORD :: Integer -#ifdef __GLASGOW_HASKELL__ -tARGET_MIN_INT = toInteger (minBound :: Int) -tARGET_MAX_INT = toInteger (maxBound :: Int) -#else -tARGET_MIN_INT = -2147483648 -tARGET_MAX_INT = 2147483647 -#endif -tARGET_MAX_WORD = (tARGET_MAX_INT * 2) + 1 - -tARGET_MAX_CHAR :: Int -tARGET_MAX_CHAR = 0x10ffff -\end{code} - -%************************************************************************ -%* * \subsection{Literals} %* * %************************************************************************ diff --git a/compiler/prelude/PrelRules.lhs b/compiler/prelude/PrelRules.lhs index 67eb06f..e35d8db 100644 --- a/compiler/prelude/PrelRules.lhs +++ b/compiler/prelude/PrelRules.lhs @@ -45,6 +45,8 @@ import Name ( Name, nameOccName ) import Outputable import FastString import StaticFlags ( opt_SimplExcessPrecision ) +import Constants + import Data.Bits as Bits import Data.Word ( Word ) \end{code} @@ -353,14 +355,14 @@ litEq op_name is_eq -- runtime either, and compilation of completely harmless things like -- ((124076834 :: Word32) + (2147483647 :: Word32)) -- would yield a warning. Instead we simply squash the value into the --- Int range, but not in a way suitable for cross-compiling... :-( +-- *target* Int/Word range. intResult :: Integer -> Maybe CoreExpr intResult result - = Just (mkIntVal (toInteger (fromInteger result :: Int))) + = Just (mkIntVal (toInteger (fromInteger result :: TargetInt))) wordResult :: Integer -> Maybe CoreExpr wordResult result - = Just (mkWordVal (toInteger (fromInteger result :: Word))) + = Just (mkWordVal (toInteger (fromInteger result :: TargetWord))) \end{code} diff --git a/includes/HaskellConstants.hs b/includes/HaskellConstants.hs index 666728c..1c1bb48 100644 --- a/includes/HaskellConstants.hs +++ b/includes/HaskellConstants.hs @@ -1,5 +1,7 @@ import Data.Bits (shiftL) +import Data.Word +import Data.Int -- This magical #include brings in all the everybody-knows-these magic -- constants unfortunately, we need to be *explicit* about which one @@ -135,6 +137,26 @@ wORD_SIZE = SIZEOF_HSWORD wORD_SIZE_IN_BITS :: Int wORD_SIZE_IN_BITS = wORD_SIZE * 8 +-- Define a fixed-range integral type equivalent to the target Int/Word + +#if SIZEOF_HSWORD == 4 +type TargetInt = Int32 +type TargetWord = Word32 +#elif SIZEOF_HSWORD == 8 +type TargetInt = Int64 +type TargetWord = Word64 +#else +#error unknown SIZEOF_HSWORD +#endif + +tARGET_MIN_INT, tARGET_MAX_INT, tARGET_MAX_WORD :: Integer +tARGET_MIN_INT = fromIntegral (minBound :: TargetInt) +tARGET_MAX_INT = fromIntegral (maxBound :: TargetInt) +tARGET_MAX_WORD = fromIntegral (maxBound :: TargetWord) + +tARGET_MAX_CHAR :: Int +tARGET_MAX_CHAR = 0x10ffff + -- Amount of pointer bits used for semi-tagging constructor closures tAG_BITS :: Int -- 1.7.10.4