2 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
4 % $Id: AbsCSyn.lhs,v 1.25 1999/10/31 15:35:32 sof 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 )
42 #if ! OMIT_NATIVE_CODEGEN
43 import {-# SOURCE #-} MachMisc
47 import Constants ( mAX_Vanilla_REG, mAX_Float_REG,
48 mAX_Double_REG, spRelToInt )
49 import CostCentre ( CostCentre, CostCentreStack )
50 import Const ( mkMachInt, Literal(..) )
51 import PrimRep ( PrimRep(..) )
52 import PrimOp ( PrimOp )
53 import Unique ( Unique )
54 import StgSyn ( SRT(..) )
55 import TyCon ( TyCon )
56 import BitSet -- for liveness masks
60 @AbstractC@ is a list of Abstract~C statements, but the data structure
61 is tree-ish, for easier and more efficient putting-together.
67 | AbsCStmts AbstractC AbstractC
69 -- and the individual stmts...
72 A note on @CAssign@: In general, the type associated with an assignment
73 is the type of the lhs. However, when the lhs is a pointer to mixed
74 types (e.g. SpB relative), the type of the assignment is the type of
75 the rhs for float types, or the generic StgWord for all other types.
76 (In particular, a CharRep on the rhs is promoted to IntRep when
77 stored in a mixed type location.)
85 CAddrMode -- Put this in the program counter
86 -- eg `CJump (CReg (VanillaReg PtrRep 1))' puts Ret1 in PC
87 -- Enter can be done by:
88 -- CJump (CVal NodeRel zeroOff)
91 CAddrMode -- Fall through into this routine
92 -- (for the benefit of the native code generators)
93 -- Equivalent to CJump in C land
95 | CReturn -- Perform a return
96 CAddrMode -- Address of a RET_<blah> info table
97 ReturnInfo -- Whether it's a direct or vectored return
100 [(Literal, AbstractC)] -- alternatives
101 AbstractC -- default; if there is no real Abstract C in here
102 -- (e.g., all comments; see function "nonemptyAbsC"),
103 -- then that means the default _cannot_ occur.
104 -- If there is only one alternative & no default code,
105 -- then there is no need to check the tag.
107 -- CSwitch m [(tag,code)] AbsCNop == code
109 | CCodeBlock CLabel AbstractC
110 -- A labelled block of code; this "statement" is not
111 -- executed; rather, the labelled code will be hoisted
112 -- out to the top level (out of line) & it can be
115 | CInitHdr -- to initialise the header of a closure (both fixed/var parts)
117 CAddrMode -- address of the info ptr
118 CAddrMode -- cost centre to place in closure
119 -- CReg CurCostCentre or CC_HDR(R1.p{-Node-})
122 [CAddrMode] -- Results
124 [CAddrMode] -- Arguments
125 [MagicId] -- Potentially volatile/live registers
126 -- (to save/restore around the call/op)
128 -- INVARIANT: When a PrimOp which can cause GC is used, the
129 -- only live data is tidily on the STG stacks or in the STG
130 -- registers (the code generator ensures this).
132 -- Why this? Because if the arguments were arbitrary
133 -- addressing modes, they might be things like (Hp+6) which
134 -- will get utterly spongled by GC.
136 | CSimultaneous -- Perform simultaneously all the statements
137 AbstractC -- in the nested AbstractC. They are only
138 -- allowed to be CAssigns, COpStmts and AbsCNops, so the
139 -- "simultaneous" part just concerns making
140 -- sure that permutations work.
141 -- For example { a := b, b := a }
142 -- needs to go via (at least one) temporary
144 | CCheck -- heap or stack checks, or both.
145 CCheckMacro -- These might include some code to fill in tags
146 [CAddrMode] -- on the stack, so we can't use CMacroStmt below.
149 | CRetDirect -- Direct return
150 !Unique -- for making labels
151 AbstractC -- return code
152 (CLabel,SRT) -- SRT info
153 Liveness -- stack liveness at the return point
155 -- see the notes about these next few; they follow below...
156 | CMacroStmt CStmtMacro [CAddrMode]
157 | CCallProfCtrMacro FAST_STRING [CAddrMode]
158 | CCallProfCCMacro FAST_STRING [CAddrMode]
160 {- The presence of this constructor is a makeshift solution;
161 it being used to work around a gcc-related problem of
162 handling typedefs within statement blocks (or, rather,
163 the inability to do so.)
165 The AbstractC flattener takes care of lifting out these
166 typedefs if needs be (i.e., when generating .hc code and
167 compiling 'foreign import dynamic's)
169 | CCallTypedef Bool {- True => use "typedef"; False => use "extern"-}
170 PrimOp{-CCallOp-} [CAddrMode] [CAddrMode]
172 -- *** the next three [or so...] are DATA (those above are CODE) ***
175 CLabel -- The (full, not base) label to use for labelling the closure.
177 CAddrMode -- cost centre identifier to place in closure
178 [CAddrMode] -- free vars; ptrs, then non-ptrs.
180 | CSRT CLabel [CLabel] -- SRT declarations: basically an array of
181 -- pointers to static closures.
183 | CBitmap CLabel LivenessMask -- A larger-than-32-bits bitmap.
185 | CClosureInfoAndCode
186 ClosureInfo -- Explains placement and layout of closure
187 AbstractC -- Slow entry point code
189 -- Fast entry point code, if any
190 String -- Closure description; NB we can't get this
191 -- from ClosureInfo, because the latter refers
192 -- to the *right* hand side of a defn, whereas
193 -- the "description" refers to *left* hand side
195 | CRetVector -- A labelled block of static data
198 (CLabel,SRT) -- SRT info
199 Liveness -- stack liveness at the return point
201 | CClosureTbl -- table of constructors for enumerated types
202 TyCon -- which TyCon this table is for
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
238 | GRAN_FETCH -- for GrAnSim only -- HWL
239 | GRAN_RESCHEDULE -- for GrAnSim only -- HWL
240 | GRAN_FETCH_AND_RESCHEDULE -- for GrAnSim only -- HWL
241 | THREAD_CONTEXT_SWITCH -- for GrAnSim only -- HWL
242 | GRAN_YIELD -- for GrAnSim only -- HWL
245 Heap/Stack checks. There are far too many of these.
250 = HP_CHK_NP -- heap/stack checks when
251 | STK_CHK_NP -- node points to the closure
253 | HP_CHK_SEQ_NP -- for 'seq' style case alternatives
255 | HP_CHK -- heap/stack checks when
256 | STK_CHK -- node doesn't point
258 -- case alternative heap checks:
260 | HP_CHK_NOREGS -- no registers live
261 | HP_CHK_UNPT_R1 -- R1 is boxed/unlifted
262 | HP_CHK_UNBX_R1 -- R1 is unboxed
263 | HP_CHK_F1 -- FloatReg1 (only) is live
264 | HP_CHK_D1 -- DblReg1 (only) is live
265 | HP_CHK_L1 -- LngReg1 (only) is live
266 | HP_CHK_UT_ALT -- unboxed tuple return.
268 | HP_CHK_GEN -- generic heap check
271 \item[@CCallProfCtrMacro@:]
272 The @String@ names a macro that, if \tr{#define}d, will bump one/some
273 of the STG-event profiling counters.
275 \item[@CCallProfCCMacro@:]
276 The @String@ names a macro that, if \tr{#define}d, will perform some
277 cost-centre-profiling-related action.
280 %************************************************************************
282 \subsection[CAddrMode]{C addressing modes}
284 %************************************************************************
288 = CVal RegRelative PrimRep
289 -- On RHS of assign: Contents of Magic[n]
290 -- On LHS of assign: location Magic[n]
291 -- (ie at addr Magic+n)
294 -- On RHS of assign: Address of Magic[n]; ie Magic+n
295 -- n=0 gets the Magic location itself
296 -- (NB: n=0 case superceded by CReg)
297 -- On LHS of assign: only sensible if n=0,
298 -- which gives the magic location itself
299 -- (NB: superceded by CReg)
301 | CReg MagicId -- To replace (CAddr MagicId 0)
303 | CTemp !Unique !PrimRep -- Temporary locations
304 -- ``Temporaries'' correspond to local variables in C, and registers in
307 | CLbl CLabel -- Labels in the runtime system, etc.
308 PrimRep -- the kind is so we can generate accurate C decls
310 | CCharLike CAddrMode -- The address of a static char-like closure for
311 -- the specified character. It is guaranteed to be in
314 | CIntLike CAddrMode -- The address of a static int-like closure for the
315 -- specified small integer. It is guaranteed to be in
316 -- the range mIN_INTLIKE..mAX_INTLIKE
320 | CLitLit FAST_STRING -- completely literal literal: just spit this String
324 | CJoinPoint -- This is used as the amode of a let-no-escape-bound
326 VirtualSpOffset -- Sp value after any volatile free vars
327 -- of the rhs have been saved on stack.
328 -- Just before the code for the thing is jumped to,
329 -- Sp will be set to this value,
330 -- and then any stack-passed args pushed,
331 -- then the code for this thing will be entered
333 !PrimRep -- the kind of the result
334 CExprMacro -- the macro to generate a value
335 [CAddrMode] -- and its arguments
338 Various C macros for values which are dependent on the back-end layout.
344 | ARG_TAG -- stack argument tagging
345 | GET_TAG -- get current constructor tag
350 Convenience functions:
353 mkIntCLit :: Int -> CAddrMode
354 mkIntCLit i = CLit (mkMachInt (toInteger i))
356 mkCString :: FAST_STRING -> CAddrMode
357 mkCString s = CLit (MachStr s)
359 mkCCostCentre :: CostCentre -> CAddrMode
360 mkCCostCentre cc = CLbl (mkCC_Label cc) DataPtrRep
362 mkCCostCentreStack :: CostCentreStack -> CAddrMode
363 mkCCostCentreStack ccs = CLbl (mkCCS_Label ccs) DataPtrRep
366 %************************************************************************
368 \subsection[RegRelative]{@RegRelatives@: ???}
370 %************************************************************************
374 = HpRel FAST_INT -- }
375 | SpRel FAST_INT -- }- offsets in StgWords
376 | NodeRel FAST_INT -- }
377 | CIndex CAddrMode CAddrMode PrimRep -- pointer arithmetic :-)
378 -- CIndex a b k === (k*)a[b]
381 = DirectReturn -- Jump directly, if possible
382 | StaticVectoredReturn Int -- Fixed tag, starting at zero
383 | DynamicVectoredReturn CAddrMode -- Dynamic tag given by amode, starting at zero
385 hpRel :: VirtualHeapOffset -- virtual offset of Hp
386 -> VirtualHeapOffset -- virtual offset of The Thing
387 -> RegRelative -- integer offset
388 hpRel IBOX(hp) IBOX(off) = HpRel (hp _SUB_ off)
390 spRel :: VirtualSpOffset -- virtual offset of Sp
391 -> VirtualSpOffset -- virtual offset of The Thing
392 -> RegRelative -- integer offset
393 spRel sp off = SpRel (case spRelToInt sp off of { IBOX(i) -> i })
395 nodeRel :: VirtualHeapOffset
397 nodeRel IBOX(off) = NodeRel off
401 %************************************************************************
403 \subsection[Liveness]{Liveness Masks}
405 %************************************************************************
407 We represent liveness bitmaps as a BitSet (whose internal
408 representation really is a bitmap). These are pinned onto case return
409 vectors to indicate the state of the stack for the garbage collector.
412 type LivenessMask = [BitSet]
414 data Liveness = LvSmall BitSet
418 %************************************************************************
420 \subsection[HeapOffset]{@Heap Offsets@}
422 %************************************************************************
424 This used to be a grotesquely complicated datatype in an attempt to
425 hide the details of header sizes from the compiler itself. Now these
426 constants are imported from the RTS, and we deal in real Ints.
429 type HeapOffset = Int -- ToDo: remove
431 type VirtualHeapOffset = HeapOffset
432 type VirtualSpOffset = Int
434 type HpRelOffset = HeapOffset
435 type SpRelOffset = Int
438 %************************************************************************
440 \subsection[MagicId]{@MagicIds@: registers and such}
442 %************************************************************************
446 = BaseReg -- mentioned only in nativeGen
448 -- Argument and return registers
449 | VanillaReg -- pointers, unboxed ints and chars
451 FAST_INT -- its number (1 .. mAX_Vanilla_REG)
453 | FloatReg -- single-precision floating-point registers
454 FAST_INT -- its number (1 .. mAX_Float_REG)
456 | DoubleReg -- double-precision floating-point registers
457 FAST_INT -- its number (1 .. mAX_Double_REG)
460 | Sp -- Stack ptr; points to last occupied stack location.
461 | Su -- Stack update frame pointer
462 | SpLim -- Stack limit
463 | Hp -- Heap ptr; points to last occupied heap location.
464 | HpLim -- Heap limit register
465 | CurCostCentre -- current cost centre register.
466 | VoidReg -- see "VoidPrim" type; just a placeholder;
467 -- no actual register
468 | LongReg -- long int registers (64-bit, really)
469 PrimRep -- Int64Rep or Word64Rep
470 FAST_INT -- its number (1 .. mAX_Long_REG)
473 node = VanillaReg PtrRep ILIT(1) -- A convenient alias for Node
474 tagreg = VanillaReg WordRep ILIT(2) -- A convenient alias for TagReg
478 We need magical @Eq@ because @VanillaReg@s come in multiple flavors.
481 instance Eq MagicId where
482 reg1 == reg2 = tag reg1 _EQ_ tag reg2
484 tag BaseReg = (ILIT(0) :: FAST_INT)
490 tag CurCostCentre = ILIT(6)
491 tag VoidReg = ILIT(7)
493 tag (VanillaReg _ i) = ILIT(8) _ADD_ i
495 tag (FloatReg i) = ILIT(8) _ADD_ maxv _ADD_ i
496 tag (DoubleReg i) = ILIT(8) _ADD_ maxv _ADD_ maxf _ADD_ i
497 tag (LongReg _ i) = ILIT(8) _ADD_ maxv _ADD_ maxf _ADD_ maxd _ADD_ i
499 maxv = case mAX_Vanilla_REG of { IBOX(x) -> x }
500 maxf = case mAX_Float_REG of { IBOX(x) -> x }
501 maxd = case mAX_Double_REG of { IBOX(x) -> x }
504 Returns True for any register that {\em potentially} dies across
505 C calls (or anything near equivalent). We just say @True@ and
506 let the (machine-specific) registering macros sort things out...
509 isVolatileReg :: MagicId -> Bool
510 isVolatileReg any = True