Fixes for cross-compiling to a different word size
authorSimon Marlow <marlowsd@gmail.com>
Wed, 14 Oct 2009 13:06:12 +0000 (13:06 +0000)
committerSimon Marlow <marlowsd@gmail.com>
Wed, 14 Oct 2009 13:06:12 +0000 (13:06 +0000)
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 <barney_stratford@fastmail.fm> 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
compiler/prelude/PrelRules.lhs
includes/HaskellConstants.hs

index 5cf8adb..aa3cdd5 100644 (file)
@@ -49,6 +49,7 @@ import FastTypes
 import FastString
 import BasicTypes
 import Binary
 import FastString
 import BasicTypes
 import Binary
+import Constants
 
 import Data.Int
 import Data.Ratio
 
 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}
 %*                                                                     *
 %************************************************************************
 \subsection{Literals}
 %*                                                                     *
 %************************************************************************
index 67eb06f..e35d8db 100644 (file)
@@ -45,6 +45,8 @@ import Name           ( Name, nameOccName )
 import Outputable
 import FastString
 import StaticFlags      ( opt_SimplExcessPrecision )
 import Outputable
 import FastString
 import StaticFlags      ( opt_SimplExcessPrecision )
+import Constants
+
 import Data.Bits as Bits
 import Data.Word       ( Word )
 \end{code}
 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
 -- 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
 intResult :: Integer -> Maybe CoreExpr
 intResult result
-  = Just (mkIntVal (toInteger (fromInteger result :: Int)))
+  = Just (mkIntVal (toInteger (fromInteger result :: TargetInt)))
 
 wordResult :: Integer -> Maybe CoreExpr
 wordResult result
 
 wordResult :: Integer -> Maybe CoreExpr
 wordResult result
-  = Just (mkWordVal (toInteger (fromInteger result :: Word)))
+  = Just (mkWordVal (toInteger (fromInteger result :: TargetWord)))
 \end{code}
 
 
 \end{code}
 
 
index 666728c..1c1bb48 100644 (file)
@@ -1,5 +1,7 @@
 
 import Data.Bits (shiftL)
 
 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
 
 -- 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
 
 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
 -- Amount of pointer bits used for semi-tagging constructor closures
 
 tAG_BITS :: Int