2 % (c) The University of Glasgow 2006
3 % (c) The GRASP/AQUA Project, Glasgow University, 1998
5 \section[Literal]{@Literal@: Machine literals (unboxed, of course)}
8 {-# LANGUAGE DeriveDataTypeable #-}
13 Literal(..) -- Exported to ParseIface
15 -- ** Creating Literals
16 , mkMachInt, mkMachWord
17 , mkMachInt64, mkMachWord64
18 , mkMachFloat, mkMachDouble
19 , mkMachChar, mkMachString
21 -- ** Operations on Literals
26 -- ** Predicates on Literals and their contents
27 , litIsDupable, litIsTrivial
28 , inIntRange, inWordRange, tARGET_MAX_INT, inCharRange
33 , word2IntLit, int2WordLit
34 , narrow8IntLit, narrow16IntLit, narrow32IntLit
35 , narrow8WordLit, narrow16WordLit, narrow32WordLit
36 , char2IntLit, int2CharLit
37 , float2IntLit, int2FloatLit, double2IntLit, int2DoubleLit
38 , nullAddrLit, float2DoubleLit, double2FloatLit
56 import Data.Data ( Data, Typeable )
57 import Numeric ( fromRat )
61 %************************************************************************
65 %************************************************************************
68 -- | So-called 'Literal's are one of:
70 -- * An unboxed (/machine/) literal ('MachInt', 'MachFloat', etc.),
71 -- which is presumed to be surrounded by appropriate constructors
72 -- (@Int#@, etc.), so that the overall thing makes sense.
74 -- * The literal derived from the label mentioned in a \"foreign label\"
75 -- declaration ('MachLabel')
78 -- First the primitive guys
79 MachChar Char -- ^ @Char#@ - at least 31 bits. Create with 'mkMachChar'
81 | MachStr FastString -- ^ A string-literal: stored and emitted
82 -- UTF-8 encoded, we'll arrange to decode it
83 -- at runtime. Also emitted with a @'\0'@
84 -- terminator. Create with 'mkMachString'
86 | MachNullAddr -- ^ The @NULL@ pointer, the only pointer value
87 -- that can be represented as a Literal. Create
90 | MachInt Integer -- ^ @Int#@ - at least @WORD_SIZE_IN_BITS@ bits. Create with 'mkMachInt'
91 | MachInt64 Integer -- ^ @Int64#@ - at least 64 bits. Create with 'mkMachInt64'
92 | MachWord Integer -- ^ @Word#@ - at least @WORD_SIZE_IN_BITS@ bits. Create with 'mkMachWord'
93 | MachWord64 Integer -- ^ @Word64#@ - at least 64 bits. Create with 'mkMachWord64'
95 | MachFloat Rational -- ^ @Float#@. Create with 'mkMachFloat'
96 | MachDouble Rational -- ^ @Double#@. Create with 'mkMachDouble'
98 | MachLabel FastString
101 -- ^ A label literal. Parameters:
103 -- 1) The name of the symbol mentioned in the declaration
105 -- 2) The size (in bytes) of the arguments
106 -- the label expects. Only applicable with
107 -- @stdcall@ labels. @Just x@ => @\<x\>@ will
108 -- be appended to label name when emitting assembly.
109 deriving (Data, Typeable)
115 instance Binary Literal where
116 put_ bh (MachChar aa) = do putByte bh 0; put_ bh aa
117 put_ bh (MachStr ab) = do putByte bh 1; put_ bh ab
118 put_ bh (MachNullAddr) = do putByte bh 2
119 put_ bh (MachInt ad) = do putByte bh 3; put_ bh ad
120 put_ bh (MachInt64 ae) = do putByte bh 4; put_ bh ae
121 put_ bh (MachWord af) = do putByte bh 5; put_ bh af
122 put_ bh (MachWord64 ag) = do putByte bh 6; put_ bh ag
123 put_ bh (MachFloat ah) = do putByte bh 7; put_ bh ah
124 put_ bh (MachDouble ai) = do putByte bh 8; put_ bh ai
125 put_ bh (MachLabel aj mb fod)
140 return (MachNullAddr)
146 return (MachInt64 ae)
152 return (MachWord64 ag)
155 return (MachFloat ah)
158 return (MachDouble ai)
163 return (MachLabel aj mb fod)
167 instance Outputable Literal where
170 instance Show Literal where
171 showsPrec p lit = showsPrecSDoc p (ppr lit)
173 instance Eq Literal where
174 a == b = case (a `compare` b) of { EQ -> True; _ -> False }
175 a /= b = case (a `compare` b) of { EQ -> False; _ -> True }
177 instance Ord Literal where
178 a <= b = case (a `compare` b) of { LT -> True; EQ -> True; GT -> False }
179 a < b = case (a `compare` b) of { LT -> True; EQ -> False; GT -> False }
180 a >= b = case (a `compare` b) of { LT -> False; EQ -> True; GT -> True }
181 a > b = case (a `compare` b) of { LT -> False; EQ -> False; GT -> True }
182 compare a b = cmpLit a b
189 -- | Creates a 'Literal' of type @Int#@
190 mkMachInt :: Integer -> Literal
191 mkMachInt x = -- ASSERT2( inIntRange x, integer x )
192 -- Not true: you can write out of range Int# literals
193 -- For example, one can write (intToWord# 0xffff0000) to
194 -- get a particular Word bit-pattern, and there's no other
195 -- convenient way to write such literals, which is why we allow it.
198 -- | Creates a 'Literal' of type @Word#@
199 mkMachWord :: Integer -> Literal
200 mkMachWord x = -- ASSERT2( inWordRange x, integer x )
203 -- | Creates a 'Literal' of type @Int64#@
204 mkMachInt64 :: Integer -> Literal
205 mkMachInt64 x = MachInt64 x
207 -- | Creates a 'Literal' of type @Word64#@
208 mkMachWord64 :: Integer -> Literal
209 mkMachWord64 x = MachWord64 x
211 -- | Creates a 'Literal' of type @Float#@
212 mkMachFloat :: Rational -> Literal
213 mkMachFloat = MachFloat
215 -- | Creates a 'Literal' of type @Double#@
216 mkMachDouble :: Rational -> Literal
217 mkMachDouble = MachDouble
219 -- | Creates a 'Literal' of type @Char#@
220 mkMachChar :: Char -> Literal
221 mkMachChar = MachChar
223 -- | Creates a 'Literal' of type @Addr#@, which is appropriate for passing to
224 -- e.g. some of the \"error\" functions in GHC.Err such as @GHC.Err.runtimeError@
225 mkMachString :: String -> Literal
226 mkMachString s = MachStr (mkFastString s) -- stored UTF-8 encoded
228 inIntRange, inWordRange :: Integer -> Bool
229 inIntRange x = x >= tARGET_MIN_INT && x <= tARGET_MAX_INT
230 inWordRange x = x >= 0 && x <= tARGET_MAX_WORD
232 inCharRange :: Char -> Bool
233 inCharRange c = c >= '\0' && c <= chr tARGET_MAX_CHAR
235 -- | Tests whether the literal represents a zero of whatever type it is
236 isZeroLit :: Literal -> Bool
237 isZeroLit (MachInt 0) = True
238 isZeroLit (MachInt64 0) = True
239 isZeroLit (MachWord 0) = True
240 isZeroLit (MachWord64 0) = True
241 isZeroLit (MachFloat 0) = True
242 isZeroLit (MachDouble 0) = True
249 word2IntLit, int2WordLit,
250 narrow8IntLit, narrow16IntLit, narrow32IntLit,
251 narrow8WordLit, narrow16WordLit, narrow32WordLit,
252 char2IntLit, int2CharLit,
253 float2IntLit, int2FloatLit, double2IntLit, int2DoubleLit,
254 float2DoubleLit, double2FloatLit
255 :: Literal -> Literal
257 word2IntLit (MachWord w)
258 | w > tARGET_MAX_INT = MachInt (w - tARGET_MAX_WORD - 1)
259 | otherwise = MachInt w
261 int2WordLit (MachInt i)
262 | i < 0 = MachWord (1 + tARGET_MAX_WORD + i) -- (-1) ---> tARGET_MAX_WORD
263 | otherwise = MachWord i
265 narrow8IntLit (MachInt i) = MachInt (toInteger (fromInteger i :: Int8))
266 narrow16IntLit (MachInt i) = MachInt (toInteger (fromInteger i :: Int16))
267 narrow32IntLit (MachInt i) = MachInt (toInteger (fromInteger i :: Int32))
268 narrow8WordLit (MachWord w) = MachWord (toInteger (fromInteger w :: Word8))
269 narrow16WordLit (MachWord w) = MachWord (toInteger (fromInteger w :: Word16))
270 narrow32WordLit (MachWord w) = MachWord (toInteger (fromInteger w :: Word32))
272 char2IntLit (MachChar c) = MachInt (toInteger (ord c))
273 int2CharLit (MachInt i) = MachChar (chr (fromInteger i))
275 float2IntLit (MachFloat f) = MachInt (truncate f)
276 int2FloatLit (MachInt i) = MachFloat (fromInteger i)
278 double2IntLit (MachDouble f) = MachInt (truncate f)
279 int2DoubleLit (MachInt i) = MachDouble (fromInteger i)
281 float2DoubleLit (MachFloat f) = MachDouble f
282 double2FloatLit (MachDouble d) = MachFloat d
284 nullAddrLit :: Literal
285 nullAddrLit = MachNullAddr
291 -- | True if there is absolutely no penalty to duplicating the literal.
292 -- False principally of strings
293 litIsTrivial :: Literal -> Bool
294 -- c.f. CoreUtils.exprIsTrivial
295 litIsTrivial (MachStr _) = False
296 litIsTrivial _ = True
298 -- | True if code space does not go bad if we duplicate this literal
299 -- Currently we treat it just like 'litIsTrivial'
300 litIsDupable :: Literal -> Bool
301 -- c.f. CoreUtils.exprIsDupable
302 litIsDupable (MachStr _) = False
303 litIsDupable _ = True
305 litFitsInChar :: Literal -> Bool
306 litFitsInChar (MachInt i)
307 = fromInteger i <= ord minBound
308 && fromInteger i >= ord maxBound
309 litFitsInChar _ = False
315 -- | Find the Haskell 'Type' the literal occupies
316 literalType :: Literal -> Type
317 literalType MachNullAddr = addrPrimTy
318 literalType (MachChar _) = charPrimTy
319 literalType (MachStr _) = addrPrimTy
320 literalType (MachInt _) = intPrimTy
321 literalType (MachWord _) = wordPrimTy
322 literalType (MachInt64 _) = int64PrimTy
323 literalType (MachWord64 _) = word64PrimTy
324 literalType (MachFloat _) = floatPrimTy
325 literalType (MachDouble _) = doublePrimTy
326 literalType (MachLabel _ _ _) = addrPrimTy
328 absentLiteralOf :: TyCon -> Maybe Literal
329 -- Return a literal of the appropriate primtive
330 -- TyCon, to use as a placeholder when it doesn't matter
331 absentLiteralOf tc = lookupUFM absent_lits (tyConName tc)
333 absent_lits :: UniqFM Literal
334 absent_lits = listToUFM [ (addrPrimTyConKey, MachNullAddr)
335 , (charPrimTyConKey, MachChar 'x')
336 , (intPrimTyConKey, MachInt 0)
337 , (int64PrimTyConKey, MachInt64 0)
338 , (floatPrimTyConKey, MachFloat 0)
339 , (doublePrimTyConKey, MachDouble 0)
340 , (wordPrimTyConKey, MachWord 0)
341 , (word64PrimTyConKey, MachWord64 0) ]
348 cmpLit :: Literal -> Literal -> Ordering
349 cmpLit (MachChar a) (MachChar b) = a `compare` b
350 cmpLit (MachStr a) (MachStr b) = a `compare` b
351 cmpLit (MachNullAddr) (MachNullAddr) = EQ
352 cmpLit (MachInt a) (MachInt b) = a `compare` b
353 cmpLit (MachWord a) (MachWord b) = a `compare` b
354 cmpLit (MachInt64 a) (MachInt64 b) = a `compare` b
355 cmpLit (MachWord64 a) (MachWord64 b) = a `compare` b
356 cmpLit (MachFloat a) (MachFloat b) = a `compare` b
357 cmpLit (MachDouble a) (MachDouble b) = a `compare` b
358 cmpLit (MachLabel a _ _) (MachLabel b _ _) = a `compare` b
359 cmpLit lit1 lit2 | litTag lit1 <# litTag lit2 = LT
362 litTag :: Literal -> FastInt
363 litTag (MachChar _) = _ILIT(1)
364 litTag (MachStr _) = _ILIT(2)
365 litTag (MachNullAddr) = _ILIT(3)
366 litTag (MachInt _) = _ILIT(4)
367 litTag (MachWord _) = _ILIT(5)
368 litTag (MachInt64 _) = _ILIT(6)
369 litTag (MachWord64 _) = _ILIT(7)
370 litTag (MachFloat _) = _ILIT(8)
371 litTag (MachDouble _) = _ILIT(9)
372 litTag (MachLabel _ _ _) = _ILIT(10)
377 * MachX (i.e. unboxed) things are printed unadornded (e.g. 3, 'a', "foo")
378 exceptions: MachFloat gets an initial keyword prefix.
381 pprLit :: Literal -> SDoc
382 pprLit (MachChar ch) = pprHsChar ch
383 pprLit (MachStr s) = pprHsString s
384 pprLit (MachInt i) = pprIntVal i
385 pprLit (MachInt64 i) = ptext (sLit "__int64") <+> integer i
386 pprLit (MachWord w) = ptext (sLit "__word") <+> integer w
387 pprLit (MachWord64 w) = ptext (sLit "__word64") <+> integer w
388 pprLit (MachFloat f) = ptext (sLit "__float") <+> float (fromRat f)
389 pprLit (MachDouble d) = double (fromRat d)
390 pprLit (MachNullAddr) = ptext (sLit "__NULL")
391 pprLit (MachLabel l mb fod) = ptext (sLit "__label") <+> b <+> ppr fod
393 Nothing -> pprHsString l
394 Just x -> doubleQuotes (text (unpackFS l ++ '@':show x))
396 pprIntVal :: Integer -> SDoc
397 -- ^ Print negative integers with parens to be sure it's unambiguous
398 pprIntVal i | i < 0 = parens (integer i)
399 | otherwise = integer i
403 %************************************************************************
407 %************************************************************************
409 Hash values should be zero or a positive integer. No negatives please.
410 (They mess up the UniqFM for some reason.)
413 hashLiteral :: Literal -> Int
414 hashLiteral (MachChar c) = ord c + 1000 -- Keep it out of range of common ints
415 hashLiteral (MachStr s) = hashFS s
416 hashLiteral (MachNullAddr) = 0
417 hashLiteral (MachInt i) = hashInteger i
418 hashLiteral (MachInt64 i) = hashInteger i
419 hashLiteral (MachWord i) = hashInteger i
420 hashLiteral (MachWord64 i) = hashInteger i
421 hashLiteral (MachFloat r) = hashRational r
422 hashLiteral (MachDouble r) = hashRational r
423 hashLiteral (MachLabel s _ _) = hashFS s
425 hashRational :: Rational -> Int
426 hashRational r = hashInteger (numerator r)
428 hashInteger :: Integer -> Int
429 hashInteger i = 1 + abs (fromInteger (i `rem` 10000))
430 -- The 1+ is to avoid zero, which is a Bad Number
431 -- since we use * to combine hash values
433 hashFS :: FastString -> Int
434 hashFS s = iBox (uniqueOfFS s)