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, isFollowableRep, isFloatingRep,
15 getPrimRepSize, retPrimRepSize,
16 showPrimRep, ppPrimRep,
17 guessPrimRep, decodePrimRep
20 #include "HsVersions.h"
26 #include "../../includes/GhcConstants.h"
29 %************************************************************************
31 \subsection[PrimRep-datatype]{The @PrimRep@ datatype}
33 %************************************************************************
37 = -- These pointer-kinds are all really the same, but we keep
38 -- them separate for documentation purposes.
39 PtrRep -- Pointer to a closure; a ``word''.
40 | CodePtrRep -- Pointer to code
41 | DataPtrRep -- Pointer to data
42 | RetRep -- Pointer to code or data (return vector or code pointer)
43 | CostCentreRep -- Pointer to a cost centre
45 | CharRep -- Machine characters
46 | IntRep -- integers (at least 32 bits)
47 | WordRep -- ditto (but *unsigned*)
48 | AddrRep -- addresses ("C pointers")
50 | DoubleRep -- doubles
52 | ForeignObjRep -- This has to be a special kind because ccall
53 -- generates special code when passing/returning
54 -- one of these. [ADR]
56 | StablePtrRep -- We could replace this with IntRep but maybe
57 -- there's some documentation gain from having
60 | ArrayRep -- Primitive array of Haskell pointers
61 | ByteArrayRep -- Primitive array of bytes (no Haskell pointers)
63 | VoidRep -- Occupies no space at all!
64 -- (Primitive states are mapped onto this)
66 -- Kinds are used in PrimTyCons, which need both Eq and Ord
69 %************************************************************************
71 \subsection[PrimRep-predicates]{Follow-ness, sizes, and such---on @PrimitiveKinds@}
73 %************************************************************************
75 Whether or not the thing is a pointer that the garbage-collector
76 should follow. Or, to put it another (less confusing) way, whether
77 the object in question is a heap object.
79 Depending on the outcome, this predicate determines what stack
80 the pointer/object possibly will have to be saved onto, and the
81 computation of GC liveness info.
84 isFollowableRep :: PrimRep -> Bool
86 isFollowableRep PtrRep = True
87 isFollowableRep ArrayRep = True
88 isFollowableRep ByteArrayRep = True
89 -- why is a ForeignObj followable? 4/96 SOF
91 -- A: they're followable because these objects
92 -- should be lugged around by the storage manager
93 -- (==> registers containing them are live) -- 3/97 SOF
94 isFollowableRep ForeignObjRep = True
96 isFollowableRep StablePtrRep = False
97 -- StablePtrs aren't followable because they are just indices into a
98 -- table for which explicit allocation/ deallocation is required.
100 isFollowableRep other = False
102 separateByPtrFollowness :: (a -> PrimRep) -> [a] -> ([a], [a])
104 separateByPtrFollowness kind_fun things
105 = sep_things kind_fun things [] []
106 -- accumulating params for follow-able and don't-follow things...
108 sep_things kfun [] bs us = (reverse bs, reverse us)
109 sep_things kfun (t:ts) bs us
110 = if (isFollowableRep . kfun) t then
111 sep_things kfun ts (t:bs) us
113 sep_things kfun ts bs (t:us)
116 @isFloatingRep@ is used to distinguish @Double@ and @Float@ which
117 cause inadvertent numeric conversions if you aren't jolly careful.
118 See codeGen/CgCon:cgTopRhsCon.
121 isFloatingRep :: PrimRep -> Bool
123 isFloatingRep DoubleRep = True
124 isFloatingRep FloatRep = True
125 isFloatingRep other = False
129 getPrimRepSize :: PrimRep -> Int
131 getPrimRepSize DoubleRep = DOUBLE_SIZE -- "words", of course
132 --getPrimRepSize FloatRep = 1
133 --getPrimRepSize CharRep = 1 -- ToDo: count in bytes?
134 --getPrimRepSize ArrayRep = 1 -- Listed specifically for *documentation*
135 --getPrimRepSize ByteArrayRep = 1
136 getPrimRepSize VoidRep = 0
137 getPrimRepSize other = 1
139 retPrimRepSize = getPrimRepSize RetRep
142 %************************************************************************
144 \subsection[PrimRep-instances]{Boring instance decls for @PrimRep@}
146 %************************************************************************
149 instance Outputable PrimRep where
150 ppr kind = text (showPrimRep kind)
152 showPrimRep :: PrimRep -> String
153 -- dumping PrimRep tag for unfoldings
154 ppPrimRep :: PrimRep -> SDoc
156 guessPrimRep :: String -> PrimRep -- a horrible "inverse" function
157 decodePrimRep :: Char -> PrimRep -- of equal nature
165 CostCentreRep -> 'c' -- Pointer to a cost centre
178 _ -> panic "ppPrimRep")
180 showPrimRep PtrRep = "P_" -- short for StgPtr
182 showPrimRep CodePtrRep = "P_" -- DEATH to StgFunPtr! (94/02/22 WDP)
183 -- but aren't code pointers and function pointers different sizes
184 -- on some machines (eg 80x86)? ADR
185 -- Are you trying to ruin my life, or what? (WDP)
187 showPrimRep DataPtrRep = "D_"
188 showPrimRep RetRep = "StgRetAddr"
189 showPrimRep CostCentreRep = "CostCentre"
190 showPrimRep CharRep = "StgChar"
191 showPrimRep IntRep = "I_" -- short for StgInt
192 showPrimRep WordRep = "W_" -- short for StgWord
193 showPrimRep AddrRep = "StgAddr"
194 showPrimRep FloatRep = "StgFloat"
195 showPrimRep DoubleRep = "StgDouble"
196 showPrimRep ArrayRep = "StgArray" -- see comment below
197 showPrimRep ByteArrayRep = "StgByteArray"
198 showPrimRep StablePtrRep = "StgStablePtr"
199 showPrimRep ForeignObjRep = "StgPtr" -- see comment below
200 showPrimRep VoidRep = "!!VOID_KIND!!"
220 _ -> panic "decodePrimRep"
222 guessPrimRep "D_" = DataPtrRep
223 guessPrimRep "StgRetAddr" = RetRep
224 guessPrimRep "StgChar" = CharRep
225 guessPrimRep "I_" = IntRep
226 guessPrimRep "W_" = WordRep
227 guessPrimRep "StgAddr" = AddrRep
228 guessPrimRep "StgFloat" = FloatRep
229 guessPrimRep "StgDouble" = DoubleRep
230 guessPrimRep "StgArray" = ArrayRep
231 guessPrimRep "StgByteArray" = ByteArrayRep
232 guessPrimRep "StgStablePtr" = StablePtrRep
235 All local C variables of @ArrayRep@ are declared in C as type
236 @StgArray@. The coercion to a more precise C type is done just before
237 indexing (by the relevant C primitive-op macro).
239 Nota Bene. There are three types associated with @ForeignObj@ (MallocPtr++):
242 @StgForeignObjClosure@ is the type of the thing the prim. op @mkForeignObj@ returns.
243 {- old comment for MallocPtr
244 (This typename is hardwired into @ppr_casm_results@ in
249 @StgForeignObj@ is the type of the thing we give the C world.
252 @StgPtr@ is the type of the (pointer to the) heap object which we
253 pass around inside the STG machine.
256 It is really easy to confuse the two. (I'm not sure this choice of
257 type names helps.) [ADR]