2 % (c) The GRASP Project, Glasgow University, 1992-1996
4 \section[PrimRep]{Primitive machine-level kinds of things.}
6 At various places in the back end, we want to be to tag things with a
7 ``primitive kind''---i.e., the machine-manipulable implementation
14 , separateByPtrFollowness
19 , getPrimRepSizeInBytes
28 #include "HsVersions.h"
34 -- NOTE: we have to reach out and grab this header file
35 -- in our current source/build tree, and not the one supplied
36 -- by whoever's compiling us.
37 #include "../../includes/GhcConstants.h"
40 %************************************************************************
42 \subsection[PrimRep-datatype]{The @PrimRep@ datatype}
44 %************************************************************************
48 = -- These pointer-kinds are all really the same, but we keep
49 -- them separate for documentation purposes.
50 PtrRep -- Pointer to a closure; a ``word''.
51 | CodePtrRep -- Pointer to code
52 | DataPtrRep -- Pointer to data
53 | RetRep -- Pointer to code or data (return vector or code pointer)
54 | CostCentreRep -- Pointer to a cost centre
56 | CharRep -- Machine characters
57 | IntRep -- integers (at least 32 bits)
58 | WordRep -- ditto (but *unsigned*)
59 | AddrRep -- addresses ("C pointers")
61 | DoubleRep -- doubles
62 | Word64Rep -- guaranteed to be 64 bits (no more, no less.)
63 | Int64Rep -- guaranteed to be 64 bits (no more, no less.)
65 | ForeignObjRep -- This has to be a special kind because ccall
66 -- generates special code when passing/returning
67 -- one of these. [ADR]
69 | StablePtrRep -- We could replace this with IntRep but maybe
70 -- there's some documentation gain from having
73 | ArrayRep -- Primitive array of Haskell pointers
74 | ByteArrayRep -- Primitive array of bytes (no Haskell pointers)
76 | VoidRep -- Occupies no space at all!
77 -- (Primitive states are mapped onto this)
79 -- Kinds are used in PrimTyCons, which need both Eq and Ord
82 %************************************************************************
84 \subsection[PrimRep-predicates]{Follow-ness, sizes, and such---on @PrimitiveKinds@}
86 %************************************************************************
88 Whether or not the thing is a pointer that the garbage-collector
89 should follow. Or, to put it another (less confusing) way, whether
90 the object in question is a heap object.
92 Depending on the outcome, this predicate determines what stack
93 the pointer/object possibly will have to be saved onto, and the
94 computation of GC liveness info.
97 isFollowableRep :: PrimRep -> Bool
99 isFollowableRep PtrRep = True
100 isFollowableRep ArrayRep = True
101 isFollowableRep ByteArrayRep = True
102 -- why is a ForeignObj followable? 4/96 SOF
104 -- A: they're followable because these objects
105 -- should be lugged around by the storage manager
106 -- (==> registers containing them are live) -- 3/97 SOF
107 isFollowableRep ForeignObjRep = True
109 isFollowableRep StablePtrRep = False
110 -- StablePtrs aren't followable because they are just indices into a
111 -- table for which explicit allocation/ deallocation is required.
113 isFollowableRep other = False
115 separateByPtrFollowness :: (a -> PrimRep) -> [a] -> ([a], [a])
117 separateByPtrFollowness kind_fun things
118 = sep_things kind_fun things [] []
119 -- accumulating params for follow-able and don't-follow things...
121 sep_things kfun [] bs us = (reverse bs, reverse us)
122 sep_things kfun (t:ts) bs us
123 = if (isFollowableRep . kfun) t then
124 sep_things kfun ts (t:bs) us
126 sep_things kfun ts bs (t:us)
129 @isFloatingRep@ is used to distinguish @Double@ and @Float@ which
130 cause inadvertent numeric conversions if you aren't jolly careful.
131 See codeGen/CgCon:cgTopRhsCon.
134 isFloatingRep :: PrimRep -> Bool
136 isFloatingRep DoubleRep = True
137 isFloatingRep FloatRep = True
138 isFloatingRep other = False
143 is64BitRep :: PrimRep -> Bool
145 is64BitRep Int64Rep = True
146 is64BitRep Word64Rep = True
147 is64BitRep other = False
154 getPrimRepSize :: PrimRep -> Int
156 getPrimRepSize DoubleRep = DOUBLE_SIZE -- "words", of course
157 getPrimRepSize Word64Rep = WORD64_SIZE
158 getPrimRepSize Int64Rep = INT64_SIZE
159 --getPrimRepSize FloatRep = 1
160 --getPrimRepSize CharRep = 1 -- ToDo: count in bytes?
161 --getPrimRepSize ArrayRep = 1 -- Listed specifically for *documentation*
162 --getPrimRepSize ByteArrayRep = 1
163 getPrimRepSize VoidRep = 0
164 getPrimRepSize other = 1
166 retPrimRepSize = getPrimRepSize RetRep
168 -- size in bytes, ToDo: cpp in the right vals.
169 -- (used in some settings to figure out how many bytes
170 -- we have to push onto the stack when calling external
171 -- entry points (e.g., stdcalling on win32))
172 getPrimRepSizeInBytes :: PrimRep -> Int
173 getPrimRepSizeInBytes pr =
186 _ -> panic "getPrimRepSize: ouch - this wasn't supposed to happen!"
190 %************************************************************************
192 \subsection[PrimRep-instances]{Boring instance decls for @PrimRep@}
194 %************************************************************************
197 instance Outputable PrimRep where
198 ppr kind = text (showPrimRep kind)
200 showPrimRep :: PrimRep -> String
201 showPrimRepToUser :: PrimRep -> String
202 -- dumping PrimRep tag for unfoldings
203 ppPrimRep :: PrimRep -> SDoc
205 guessPrimRep :: String -> PrimRep -- a horrible "inverse" function
206 decodePrimRep :: Char -> PrimRep -- of equal nature
214 CostCentreRep -> 'c' -- Pointer to a cost centre
229 _ -> panic "ppPrimRep")
231 showPrimRep PtrRep = "P_" -- short for StgPtr
233 showPrimRep CodePtrRep = "P_" -- DEATH to StgFunPtr! (94/02/22 WDP)
234 -- but aren't code pointers and function pointers different sizes
235 -- on some machines (eg 80x86)? ADR
236 -- Are you trying to ruin my life, or what? (WDP)
238 showPrimRep DataPtrRep = "D_"
239 showPrimRep RetRep = "StgRetAddr"
240 showPrimRep CostCentreRep = "CostCentre"
241 showPrimRep CharRep = "StgChar"
242 showPrimRep IntRep = "I_" -- short for StgInt
243 showPrimRep WordRep = "W_" -- short for StgWord
244 showPrimRep Int64Rep = "LI_" -- short for StgLongInt
245 showPrimRep Word64Rep = "LW_" -- short for StgLongWord
246 showPrimRep AddrRep = "StgAddr"
247 showPrimRep FloatRep = "StgFloat"
248 showPrimRep DoubleRep = "StgDouble"
249 showPrimRep ArrayRep = "StgArray" -- see comment below
250 showPrimRep ByteArrayRep = "StgByteArray"
251 showPrimRep StablePtrRep = "StgStablePtr"
252 showPrimRep ForeignObjRep = "StgPtr" -- see comment below
253 showPrimRep VoidRep = "!!VOID_KIND!!"
255 showPrimRepToUser pr =
260 Int64Rep -> "StgInt64"
261 Word64Rep -> "StgWord64"
263 FloatRep -> "StgFloat"
264 DoubleRep -> "StgDouble"
265 ArrayRep -> "StgArray"
266 ByteArrayRep -> "StgByteArray"
267 StablePtrRep -> "StgStablePtr"
268 ForeignObjRep -> "StgPtr"
269 _ -> panic ("showPrimRepToUser: " ++ showPrimRep pr)
292 _ -> panic "decodePrimRep"
294 guessPrimRep "D_" = DataPtrRep
295 guessPrimRep "StgRetAddr" = RetRep
296 guessPrimRep "StgChar" = CharRep
297 guessPrimRep "I_" = IntRep
298 guessPrimRep "LI_" = Int64Rep
299 guessPrimRep "W_" = WordRep
300 guessPrimRep "LW_" = Word64Rep
301 guessPrimRep "StgAddr" = AddrRep
302 guessPrimRep "StgFloat" = FloatRep
303 guessPrimRep "StgDouble" = DoubleRep
304 guessPrimRep "StgArray" = ArrayRep
305 guessPrimRep "StgByteArray" = ByteArrayRep
306 guessPrimRep "StgStablePtr" = StablePtrRep
309 All local C variables of @ArrayRep@ are declared in C as type
310 @StgArray@. The coercion to a more precise C type is done just before
311 indexing (by the relevant C primitive-op macro).
313 Nota Bene. There are three types associated with @ForeignObj@ (MallocPtr++):
316 @StgForeignObjClosure@ is the type of the thing the prim. op @mkForeignObj@ returns.
317 {- old comment for MallocPtr
318 (This typename is hardwired into @ppr_casm_results@ in
323 @StgForeignObj@ is the type of the thing we give the C world.
326 @StgPtr@ is the type of the (pointer to the) heap object which we
327 pass around inside the STG machine.
330 It is really easy to confuse the two. (I'm not sure this choice of
331 type names helps.) [ADR]