2 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
4 % $Id: AbsCSyn.lhs,v 1.29 2000/03/23 17:45:17 simonpj Exp $
6 \section[AbstractC]{Abstract C: the last stop before machine code}
8 This ``Abstract C'' data type describes the raw Spineless Tagless
9 machine model at a C-ish level; it is ``abstract'' in that it only
10 includes C-like structures that we happen to need. The conversion of
11 programs from @StgSyntax@ (basically a functional language) to
12 @AbstractC@ (basically imperative C) is the heart of code generation.
13 From @AbstractC@, one may convert to real C (for portability) or to
14 raw assembler/machine code.
24 mkAbstractCs, mkAbsCStmts, mkAlgAltsCSwitch,
33 MagicId(..), node, infoptr,
38 #include "HsVersions.h"
40 import {-# SOURCE #-} ClosureInfo ( ClosureInfo )
43 import Constants ( mAX_Vanilla_REG, mAX_Float_REG,
44 mAX_Double_REG, spRelToInt )
45 import CostCentre ( CostCentre, CostCentreStack )
46 import Literal ( mkMachInt, Literal(..) )
47 import PrimRep ( PrimRep(..) )
48 import PrimOp ( PrimOp, CCall )
49 import Unique ( Unique )
50 import StgSyn ( SRT(..) )
51 import TyCon ( TyCon )
52 import BitSet -- for liveness masks
56 @AbstractC@ is a list of Abstract~C statements, but the data structure
57 is tree-ish, for easier and more efficient putting-together.
63 | AbsCStmts AbstractC AbstractC
65 -- and the individual stmts...
68 A note on @CAssign@: In general, the type associated with an assignment
69 is the type of the lhs. However, when the lhs is a pointer to mixed
70 types (e.g. SpB relative), the type of the assignment is the type of
71 the rhs for float types, or the generic StgWord for all other types.
72 (In particular, a CharRep on the rhs is promoted to IntRep when
73 stored in a mixed type location.)
81 CAddrMode -- Put this in the program counter
82 -- eg `CJump (CReg (VanillaReg PtrRep 1))' puts Ret1 in PC
83 -- Enter can be done by:
84 -- CJump (CVal NodeRel zeroOff)
87 CAddrMode -- Fall through into this routine
88 -- (for the benefit of the native code generators)
89 -- Equivalent to CJump in C land
91 | CReturn -- Perform a return
92 CAddrMode -- Address of a RET_<blah> info table
93 ReturnInfo -- Whether it's a direct or vectored return
96 [(Literal, AbstractC)] -- alternatives
97 AbstractC -- default; if there is no real Abstract C in here
98 -- (e.g., all comments; see function "nonemptyAbsC"),
99 -- then that means the default _cannot_ occur.
100 -- If there is only one alternative & no default code,
101 -- then there is no need to check the tag.
103 -- CSwitch m [(tag,code)] AbsCNop == code
105 | CCodeBlock CLabel AbstractC
106 -- A labelled block of code; this "statement" is not
107 -- executed; rather, the labelled code will be hoisted
108 -- out to the top level (out of line) & it can be
111 | CInitHdr -- to initialise the header of a closure (both fixed/var parts)
113 CAddrMode -- address of the info ptr
114 CAddrMode -- cost centre to place in closure
115 -- CReg CurCostCentre or CC_HDR(R1.p{-Node-})
118 [CAddrMode] -- Results
120 [CAddrMode] -- Arguments
121 [MagicId] -- Potentially volatile/live registers
122 -- (to save/restore around the call/op)
124 -- INVARIANT: When a PrimOp which can cause GC is used, the
125 -- only live data is tidily on the STG stacks or in the STG
126 -- registers (the code generator ensures this).
128 -- Why this? Because if the arguments were arbitrary
129 -- addressing modes, they might be things like (Hp+6) which
130 -- will get utterly spongled by GC.
132 | CSimultaneous -- Perform simultaneously all the statements
133 AbstractC -- in the nested AbstractC. They are only
134 -- allowed to be CAssigns, COpStmts and AbsCNops, so the
135 -- "simultaneous" part just concerns making
136 -- sure that permutations work.
137 -- For example { a := b, b := a }
138 -- needs to go via (at least one) temporary
140 | CCheck -- heap or stack checks, or both.
141 CCheckMacro -- These might include some code to fill in tags
142 [CAddrMode] -- on the stack, so we can't use CMacroStmt below.
145 | CRetDirect -- Direct return
146 !Unique -- for making labels
147 AbstractC -- return code
148 (CLabel,SRT) -- SRT info
149 Liveness -- stack liveness at the return point
151 -- see the notes about these next few; they follow below...
152 | CMacroStmt CStmtMacro [CAddrMode]
153 | CCallProfCtrMacro FAST_STRING [CAddrMode]
154 | CCallProfCCMacro FAST_STRING [CAddrMode]
156 {- The presence of this constructor is a makeshift solution;
157 it being used to work around a gcc-related problem of
158 handling typedefs within statement blocks (or, rather,
159 the inability to do so.)
161 The AbstractC flattener takes care of lifting out these
162 typedefs if needs be (i.e., when generating .hc code and
163 compiling 'foreign import dynamic's)
165 | CCallTypedef Bool {- True => use "typedef"; False => use "extern"-}
166 CCall [CAddrMode] [CAddrMode]
168 -- *** the next three [or so...] are DATA (those above are CODE) ***
171 CLabel -- The (full, not base) label to use for labelling the closure.
173 CAddrMode -- cost centre identifier to place in closure
174 [CAddrMode] -- free vars; ptrs, then non-ptrs.
176 | CSRT CLabel [CLabel] -- SRT declarations: basically an array of
177 -- pointers to static closures.
179 | CBitmap CLabel LivenessMask -- A larger-than-32-bits bitmap.
181 | CClosureInfoAndCode
182 ClosureInfo -- Explains placement and layout of closure
183 AbstractC -- Slow entry point code
185 -- Fast entry point code, if any
186 String -- Closure description; NB we can't get this
187 -- from ClosureInfo, because the latter refers
188 -- to the *right* hand side of a defn, whereas
189 -- the "description" refers to *left* hand side
191 | CRetVector -- A labelled block of static data
194 (CLabel,SRT) -- SRT info
195 Liveness -- stack liveness at the return point
197 | CClosureTbl -- table of constructors for enumerated types
198 TyCon -- which TyCon this table is for
200 | CModuleInitBlock -- module initialisation block
201 CLabel -- label for init block
202 AbstractC -- initialisation code
204 | CCostCentreDecl -- A cost centre *declaration*
205 Bool -- True <=> local => full declaration
206 -- False <=> extern; just say so
209 | CCostCentreStackDecl -- A cost centre stack *declaration*
210 CostCentreStack -- this is the declaration for a
211 -- pre-defined singleton CCS (see
214 | CSplitMarker -- Split into separate object modules here
217 About @CMacroStmt@, etc.: notionally, they all just call some
218 arbitrary C~macro or routine, passing the @CAddrModes@ as arguments.
219 However, we distinguish between various flavours of these things,
220 mostly just to keep things somewhat less wild and wooly.
224 Some {\em essential} bits of the STG execution model are done with C
225 macros. An example is @STK_CHK@, which checks for stack-space
226 overflow. This enumeration type lists all such macros:
229 = ARGS_CHK -- arg satisfaction check
230 | ARGS_CHK_LOAD_NODE -- arg check for top-level functions
231 | UPD_CAF -- update CAF closure with indirection
232 | UPD_BH_UPDATABLE -- eager backholing
233 | UPD_BH_SINGLE_ENTRY -- more eager blackholing
234 | PUSH_UPD_FRAME -- push update frame
235 | PUSH_SEQ_FRAME -- push seq frame
236 | UPDATE_SU_FROM_UPD_FRAME -- pull Su out of the update frame
237 | SET_TAG -- set TagReg if it exists
239 | REGISTER_FOREIGN_EXPORT -- register a foreign exported fun
240 | REGISTER_IMPORT -- register an imported module
242 | GRAN_FETCH -- for GrAnSim only -- HWL
243 | GRAN_RESCHEDULE -- for GrAnSim only -- HWL
244 | GRAN_FETCH_AND_RESCHEDULE -- for GrAnSim only -- HWL
245 | THREAD_CONTEXT_SWITCH -- for GrAnSim only -- HWL
246 | GRAN_YIELD -- for GrAnSim only -- HWL
249 Heap/Stack checks. There are far too many of these.
254 = HP_CHK_NP -- heap/stack checks when
255 | STK_CHK_NP -- node points to the closure
257 | HP_CHK_SEQ_NP -- for 'seq' style case alternatives
259 | HP_CHK -- heap/stack checks when
260 | STK_CHK -- node doesn't point
262 -- case alternative heap checks:
264 | HP_CHK_NOREGS -- no registers live
265 | HP_CHK_UNPT_R1 -- R1 is boxed/unlifted
266 | HP_CHK_UNBX_R1 -- R1 is unboxed
267 | HP_CHK_F1 -- FloatReg1 (only) is live
268 | HP_CHK_D1 -- DblReg1 (only) is live
269 | HP_CHK_L1 -- LngReg1 (only) is live
270 | HP_CHK_UT_ALT -- unboxed tuple return.
272 | HP_CHK_GEN -- generic heap check
275 \item[@CCallProfCtrMacro@:]
276 The @String@ names a macro that, if \tr{#define}d, will bump one/some
277 of the STG-event profiling counters.
279 \item[@CCallProfCCMacro@:]
280 The @String@ names a macro that, if \tr{#define}d, will perform some
281 cost-centre-profiling-related action.
284 %************************************************************************
286 \subsection[CAddrMode]{C addressing modes}
288 %************************************************************************
292 = CVal RegRelative PrimRep
293 -- On RHS of assign: Contents of Magic[n]
294 -- On LHS of assign: location Magic[n]
295 -- (ie at addr Magic+n)
298 -- On RHS of assign: Address of Magic[n]; ie Magic+n
299 -- n=0 gets the Magic location itself
300 -- (NB: n=0 case superceded by CReg)
301 -- On LHS of assign: only sensible if n=0,
302 -- which gives the magic location itself
303 -- (NB: superceded by CReg)
305 | CReg MagicId -- To replace (CAddr MagicId 0)
307 | CTemp !Unique !PrimRep -- Temporary locations
308 -- ``Temporaries'' correspond to local variables in C, and registers in
311 | CLbl CLabel -- Labels in the runtime system, etc.
312 PrimRep -- the kind is so we can generate accurate C decls
314 | CCharLike CAddrMode -- The address of a static char-like closure for
315 -- the specified character. It is guaranteed to be in
318 | CIntLike CAddrMode -- The address of a static int-like closure for the
319 -- specified small integer. It is guaranteed to be in
320 -- the range mIN_INTLIKE..mAX_INTLIKE
324 | CLitLit FAST_STRING -- completely literal literal: just spit this String
328 | CJoinPoint -- This is used as the amode of a let-no-escape-bound
330 VirtualSpOffset -- Sp value after any volatile free vars
331 -- of the rhs have been saved on stack.
332 -- Just before the code for the thing is jumped to,
333 -- Sp will be set to this value,
334 -- and then any stack-passed args pushed,
335 -- then the code for this thing will be entered
337 !PrimRep -- the kind of the result
338 CExprMacro -- the macro to generate a value
339 [CAddrMode] -- and its arguments
342 Various C macros for values which are dependent on the back-end layout.
348 | ARG_TAG -- stack argument tagging
349 | GET_TAG -- get current constructor tag
354 Convenience functions:
357 mkIntCLit :: Int -> CAddrMode
358 mkIntCLit i = CLit (mkMachInt (toInteger i))
360 mkCString :: FAST_STRING -> CAddrMode
361 mkCString s = CLit (MachStr s)
363 mkCCostCentre :: CostCentre -> CAddrMode
364 mkCCostCentre cc = CLbl (mkCC_Label cc) DataPtrRep
366 mkCCostCentreStack :: CostCentreStack -> CAddrMode
367 mkCCostCentreStack ccs = CLbl (mkCCS_Label ccs) DataPtrRep
370 %************************************************************************
372 \subsection[RegRelative]{@RegRelatives@: ???}
374 %************************************************************************
378 = HpRel FAST_INT -- }
379 | SpRel FAST_INT -- }- offsets in StgWords
380 | NodeRel FAST_INT -- }
381 | CIndex CAddrMode CAddrMode PrimRep -- pointer arithmetic :-)
382 -- CIndex a b k === (k*)a[b]
385 = DirectReturn -- Jump directly, if possible
386 | StaticVectoredReturn Int -- Fixed tag, starting at zero
387 | DynamicVectoredReturn CAddrMode -- Dynamic tag given by amode, starting at zero
389 hpRel :: VirtualHeapOffset -- virtual offset of Hp
390 -> VirtualHeapOffset -- virtual offset of The Thing
391 -> RegRelative -- integer offset
392 hpRel IBOX(hp) IBOX(off) = HpRel (hp _SUB_ off)
394 spRel :: VirtualSpOffset -- virtual offset of Sp
395 -> VirtualSpOffset -- virtual offset of The Thing
396 -> RegRelative -- integer offset
397 spRel sp off = SpRel (case spRelToInt sp off of { IBOX(i) -> i })
399 nodeRel :: VirtualHeapOffset
401 nodeRel IBOX(off) = NodeRel off
405 %************************************************************************
407 \subsection[Liveness]{Liveness Masks}
409 %************************************************************************
411 We represent liveness bitmaps as a BitSet (whose internal
412 representation really is a bitmap). These are pinned onto case return
413 vectors to indicate the state of the stack for the garbage collector.
416 type LivenessMask = [BitSet]
418 data Liveness = LvSmall BitSet
422 %************************************************************************
424 \subsection[HeapOffset]{@Heap Offsets@}
426 %************************************************************************
428 This used to be a grotesquely complicated datatype in an attempt to
429 hide the details of header sizes from the compiler itself. Now these
430 constants are imported from the RTS, and we deal in real Ints.
433 type HeapOffset = Int -- ToDo: remove
435 type VirtualHeapOffset = HeapOffset
436 type VirtualSpOffset = Int
438 type HpRelOffset = HeapOffset
439 type SpRelOffset = Int
442 %************************************************************************
444 \subsection[MagicId]{@MagicIds@: registers and such}
446 %************************************************************************
450 = BaseReg -- mentioned only in nativeGen
452 -- Argument and return registers
453 | VanillaReg -- pointers, unboxed ints and chars
455 FAST_INT -- its number (1 .. mAX_Vanilla_REG)
457 | FloatReg -- single-precision floating-point registers
458 FAST_INT -- its number (1 .. mAX_Float_REG)
460 | DoubleReg -- double-precision floating-point registers
461 FAST_INT -- its number (1 .. mAX_Double_REG)
464 | Sp -- Stack ptr; points to last occupied stack location.
465 | Su -- Stack update frame pointer
466 | SpLim -- Stack limit
467 | Hp -- Heap ptr; points to last occupied heap location.
468 | HpLim -- Heap limit register
469 | CurCostCentre -- current cost centre register.
470 | VoidReg -- see "VoidPrim" type; just a placeholder;
471 -- no actual register
472 | LongReg -- long int registers (64-bit, really)
473 PrimRep -- Int64Rep or Word64Rep
474 FAST_INT -- its number (1 .. mAX_Long_REG)
477 node = VanillaReg PtrRep ILIT(1) -- A convenient alias for Node
478 tagreg = VanillaReg WordRep ILIT(2) -- A convenient alias for TagReg
483 We need magical @Eq@ because @VanillaReg@s come in multiple flavors.
486 instance Eq MagicId where
487 reg1 == reg2 = tag reg1 _EQ_ tag reg2
489 tag BaseReg = (ILIT(0) :: FAST_INT)
495 tag CurCostCentre = ILIT(6)
496 tag VoidReg = ILIT(7)
498 tag (VanillaReg _ i) = ILIT(8) _ADD_ i
500 tag (FloatReg i) = ILIT(8) _ADD_ maxv _ADD_ i
501 tag (DoubleReg i) = ILIT(8) _ADD_ maxv _ADD_ maxf _ADD_ i
502 tag (LongReg _ i) = ILIT(8) _ADD_ maxv _ADD_ maxf _ADD_ maxd _ADD_ i
504 maxv = case mAX_Vanilla_REG of { IBOX(x) -> x }
505 maxf = case mAX_Float_REG of { IBOX(x) -> x }
506 maxd = case mAX_Double_REG of { IBOX(x) -> x }
509 Returns True for any register that {\em potentially} dies across
510 C calls (or anything near equivalent). We just say @True@ and
511 let the (machine-specific) registering macros sort things out...
514 isVolatileReg :: MagicId -> Bool
515 isVolatileReg any = True