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
11 #include "HsVersions.h"
16 separateByPtrFollowness, isFollowableRep, isFloatingRep,
17 getPrimRepSize, retPrimRepSize,
18 showPrimRep, ppPrimRep,
19 guessPrimRep, decodePrimRep
24 import Pretty -- pretty-printing code
26 #if __GLASGOW_HASKELL__ >= 202
31 #include "../../includes/GhcConstants.h"
34 %************************************************************************
36 \subsection[PrimRep-datatype]{The @PrimRep@ datatype}
38 %************************************************************************
42 = -- These pointer-kinds are all really the same, but we keep
43 -- them separate for documentation purposes.
44 PtrRep -- Pointer to a closure; a ``word''.
45 | CodePtrRep -- Pointer to code
46 | DataPtrRep -- Pointer to data
47 | RetRep -- Pointer to code or data (return vector or code pointer)
48 | CostCentreRep -- Pointer to a cost centre
50 | CharRep -- Machine characters
51 | IntRep -- integers (at least 32 bits)
52 | WordRep -- ditto (but *unsigned*)
53 | AddrRep -- addresses ("C pointers")
55 | DoubleRep -- doubles
57 | ForeignObjRep -- This has to be a special kind because ccall
58 -- generates special code when passing/returning
59 -- one of these. [ADR]
61 | StablePtrRep -- We could replace this with IntRep but maybe
62 -- there's some documentation gain from having
65 | ArrayRep -- Primitive array of Haskell pointers
66 | ByteArrayRep -- Primitive array of bytes (no Haskell pointers)
68 | VoidRep -- Occupies no space at all!
69 -- (Primitive states are mapped onto this)
71 -- Kinds are used in PrimTyCons, which need both Eq and Ord
74 %************************************************************************
76 \subsection[PrimRep-predicates]{Follow-ness, sizes, and such---on @PrimitiveKinds@}
78 %************************************************************************
80 Whether or not the thing is a pointer that the garbage-collector
83 Or, to put it another (less confusing) way, whether the object in
84 question is a heap object.
87 isFollowableRep :: PrimRep -> Bool
89 isFollowableRep PtrRep = True
90 isFollowableRep ArrayRep = True
91 isFollowableRep ByteArrayRep = True
92 -- why is a ForeignObj followable? 4/96 SOF
94 -- A: they're followable because these objects
95 -- should be lugged around by the storage manager
96 -- (==> we need to generate code that identify them as such) -- 3/97 SOF
97 isFollowableRep ForeignObjRep = True
99 isFollowableRep StablePtrRep = False
100 -- StablePtrs aren't followable because they are just indices into a
101 -- table for which explicit allocation/ deallocation is required.
103 isFollowableRep other = False
105 separateByPtrFollowness :: (a -> PrimRep) -> [a] -> ([a], [a])
107 separateByPtrFollowness kind_fun things
108 = sep_things kind_fun things [] []
109 -- accumulating params for follow-able and don't-follow things...
111 sep_things kfun [] bs us = (reverse bs, reverse us)
112 sep_things kfun (t:ts) bs us
113 = if (isFollowableRep . kfun) t then
114 sep_things kfun ts (t:bs) us
116 sep_things kfun ts bs (t:us)
119 @isFloatingRep@ is used to distinguish @Double@ and @Float@ which
120 cause inadvertent numeric conversions if you aren't jolly careful.
121 See codeGen/CgCon:cgTopRhsCon.
124 isFloatingRep :: PrimRep -> Bool
126 isFloatingRep DoubleRep = True
127 isFloatingRep FloatRep = True
128 isFloatingRep other = False
132 getPrimRepSize :: PrimRep -> Int
134 getPrimRepSize DoubleRep = DOUBLE_SIZE -- "words", of course
135 --getPrimRepSize FloatRep = 1
136 --getPrimRepSize CharRep = 1 -- ToDo: count in bytes?
137 --getPrimRepSize ArrayRep = 1 -- Listed specifically for *documentation*
138 --getPrimRepSize ByteArrayRep = 1
139 getPrimRepSize VoidRep = 0
140 getPrimRepSize other = 1
142 retPrimRepSize = getPrimRepSize RetRep
145 %************************************************************************
147 \subsection[PrimRep-instances]{Boring instance decls for @PrimRep@}
149 %************************************************************************
152 instance Outputable PrimRep where
153 ppr sty kind = text (showPrimRep kind)
155 showPrimRep :: PrimRep -> String
156 -- dumping PrimRep tag for unfoldings
157 ppPrimRep :: PrimRep -> Doc
159 guessPrimRep :: String -> PrimRep -- a horrible "inverse" function
160 decodePrimRep :: Char -> PrimRep -- of equal nature
168 CostCentreRep -> 'c' -- Pointer to a cost centre
181 _ -> panic "ppPrimRep")
183 showPrimRep PtrRep = "P_" -- short for StgPtr
185 showPrimRep CodePtrRep = "P_" -- DEATH to StgFunPtr! (94/02/22 WDP)
186 -- but aren't code pointers and function pointers different sizes
187 -- on some machines (eg 80x86)? ADR
188 -- Are you trying to ruin my life, or what? (WDP)
190 showPrimRep DataPtrRep = "D_"
191 showPrimRep RetRep = "StgRetAddr"
192 showPrimRep CostCentreRep = "CostCentre"
193 showPrimRep CharRep = "StgChar"
194 showPrimRep IntRep = "I_" -- short for StgInt
195 showPrimRep WordRep = "W_" -- short for StgWord
196 showPrimRep AddrRep = "StgAddr"
197 showPrimRep FloatRep = "StgFloat"
198 showPrimRep DoubleRep = "StgDouble"
199 showPrimRep ArrayRep = "StgArray" -- see comment below
200 showPrimRep ByteArrayRep = "StgByteArray"
201 showPrimRep StablePtrRep = "StgStablePtr"
202 showPrimRep ForeignObjRep = "StgPtr" -- see comment below
203 showPrimRep VoidRep = "!!VOID_KIND!!"
223 _ -> panic "decodePrimRep"
225 guessPrimRep "D_" = DataPtrRep
226 guessPrimRep "StgRetAddr" = RetRep
227 guessPrimRep "StgChar" = CharRep
228 guessPrimRep "I_" = IntRep
229 guessPrimRep "W_" = WordRep
230 guessPrimRep "StgAddr" = AddrRep
231 guessPrimRep "StgFloat" = FloatRep
232 guessPrimRep "StgDouble" = DoubleRep
233 guessPrimRep "StgArray" = ArrayRep
234 guessPrimRep "StgByteArray" = ByteArrayRep
235 guessPrimRep "StgStablePtr" = StablePtrRep
238 All local C variables of @ArrayRep@ are declared in C as type
239 @StgArray@. The coercion to a more precise C type is done just before
240 indexing (by the relevant C primitive-op macro).
242 Nota Bene. There are three types associated with @ForeignObj@ (MallocPtr++):
245 @StgForeignObjClosure@ is the type of the thing the prim. op @mkForeignObj@ returns.
246 {- old comment for MallocPtr
247 (This typename is hardwired into @ppr_casm_results@ in
252 @StgForeignObj@ is the type of the thing we give the C world.
255 @StgPtr@ is the type of the (pointer to the) heap object which we
256 pass around inside the STG machine.
259 It is really easy to confuse the two. (I'm not sure this choice of
260 type names helps.) [ADR]