[project @ 2004-08-13 10:45:16 by simonmar]
[ghc-hetmet.git] / ghc / compiler / absCSyn / AbsCSyn.lhs
index 05972fa..3c8a470 100644 (file)
@@ -1,5 +1,7 @@
 %
-% (c) The GRASP/AQUA Project, Glasgow University, 1992-1996
+% (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
+%
+% $Id: AbsCSyn.lhs,v 1.56 2003/11/17 14:47:53 simonmar Exp $
 %
 \section[AbstractC]{Abstract C: the last stop before machine code}
 
@@ -12,57 +14,32 @@ From @AbstractC@, one may convert to real C (for portability) or to
 raw assembler/machine code.
 
 \begin{code}
-module AbsCSyn {- (
-       -- export everything
-       AbstractC(..),
-       CStmtMacro(..),
-       CExprMacro(..),
-       CAddrMode(..),
-       ReturnInfo(..),
-       mkAbstractCs, mkAbsCStmts, mkAlgAltsCSwitch,
-       mkIntCLit,
-       mkAbsCStmtList,
-       mkCCostCentre,
-
-       -- RegRelatives
-       RegRelative(..),
-
-       -- registers
-       MagicId(..), node, infoptr,
-       isVolatileReg, noLiveRegsMask, mkLiveRegsMask,
-       CostRes(Cost)
-    )-} where
+module AbsCSyn where   -- export everything
 
 #include "HsVersions.h"
 
 import {-# SOURCE #-} ClosureInfo ( ClosureInfo )
-import {-# SOURCE #-} CLabel     ( CLabel )
-
-#if  ! OMIT_NATIVE_CODEGEN
-import {-# SOURCE #-} MachMisc
-#endif
 
+import CLabel
 import Constants       ( mAX_Vanilla_REG, mAX_Float_REG,
-                         mAX_Double_REG, lIVENESS_R1, lIVENESS_R2,
-                         lIVENESS_R3, lIVENESS_R4, lIVENESS_R5,
-                         lIVENESS_R6, lIVENESS_R7, lIVENESS_R8
-                       )
-import HeapOffs                ( VirtualSpAOffset, VirtualSpBOffset,
-                         VirtualHeapOffset, HeapOffset
-                       )
-import CostCentre       ( CostCentre )
-import Literal         ( mkMachInt, Literal )
-import PrimRep         ( isFollowableRep, PrimRep(..) )
-import PrimOp           ( PrimOp )
+                         mAX_Double_REG, spRelToInt )
+import CostCentre       ( CostCentre, CostCentreStack )
+import Literal         ( mkMachInt, Literal(..) )
+import ForeignCall     ( CCallSpec )
+import PrimRep         ( PrimRep(..) )
+import MachOp          ( MachOp(..) )
 import Unique           ( Unique )
-
+import StgSyn          ( StgOp )
+import TyCon           ( TyCon )
+import Bitmap          ( Bitmap, mAX_SMALL_BITMAP_SIZE )
+import SMRep           ( StgWord, StgHalfWord )
+import FastTypes
+import FastString
 \end{code}
 
 @AbstractC@ is a list of Abstract~C statements, but the data structure
 is tree-ish, for easier and more efficient putting-together.
 \begin{code}
-absCNop = AbsCNop
-
 data AbstractC
   = AbsCNop
   | AbsCStmts          AbstractC AbstractC
@@ -79,8 +56,8 @@ stored in a mixed type location.)
 
 \begin{code}
   | CAssign
-       CAddrMode       -- target
-       CAddrMode       -- source
+       !CAddrMode      -- target
+       !CAddrMode      -- source
 
   | CJump
        CAddrMode       -- Put this in the program counter
@@ -93,11 +70,11 @@ stored in a mixed type location.)
                        -- (for the benefit of the native code generators)
                        -- Equivalent to CJump in C land
 
-  | CReturn            -- This used to be RetVecRegRel
-       CAddrMode       -- Any base address mode
-       ReturnInfo      -- How to get the return address from the base address
+  | CReturn            -- Perform a return
+       CAddrMode       -- Address of a RET_<blah> info table
+       ReturnInfo      -- Whether it's a direct or vectored return
 
-  | CSwitch CAddrMode
+  | CSwitch !CAddrMode
        [(Literal, AbstractC)]  -- alternatives
        AbstractC               -- default; if there is no real Abstract C in here
                                -- (e.g., all comments; see function "nonemptyAbsC"),
@@ -108,7 +85,6 @@ stored in a mixed type location.)
                                --  CSwitch m [(tag,code)] AbsCNop == code
 
   | CCodeBlock CLabel AbstractC
-                       -- [amode analog: CLabelledCode]
                        -- A labelled block of code; this "statement" is not
                        -- executed; rather, the labelled code will be hoisted
                        -- out to the top level (out of line) & it can be
@@ -116,16 +92,34 @@ stored in a mixed type location.)
 
   | CInitHdr           -- to initialise the header of a closure (both fixed/var parts)
        ClosureInfo
-       RegRelative     -- address of the info ptr
-       CAddrMode       -- cost centre to place in closure
+       CAddrMode       -- address of the info ptr
+       !CAddrMode      -- cost centre to place in closure
                        --   CReg CurCostCentre or CC_HDR(R1.p{-Node-})
-       Bool            -- inplace update or allocate
+       Int             -- size of closure, for profiling
+
+  -- NEW CASES FOR EXPANDED PRIMOPS
+
+  | CMachOpStmt                        -- Machine-level operation
+       CAddrMode               -- result
+       MachOp
+       [CAddrMode]             -- Arguments
+        (Maybe [MagicId])      -- list of regs which need to be preserved
+       -- across the primop.  This is allowed to be Nothing only if
+       -- machOpIsDefinitelyInline returns True.  And that in turn may
+       -- only return True if we are absolutely sure that the mach op
+       -- can be done inline on all platforms.  
+
+  | CSequential                -- Do the nested AbstractCs sequentially.
+       [AbstractC]     -- In particular, as far as the AbsCUtils.doSimultaneously
+                       -- is concerned, these stmts are to be treated as atomic
+                       -- and are not to be reordered.
+
+  -- end of NEW CASES FOR EXPANDED PRIMOPS
 
   | COpStmt
        [CAddrMode]     -- Results
-       PrimOp
+       StgOp
        [CAddrMode]     -- Arguments
-       Int             -- Live registers (may be obtainable from volatility? ADR)
        [MagicId]       -- Potentially volatile/live registers
                        -- (to save/restore around the call/op)
 
@@ -145,10 +139,21 @@ stored in a mixed type location.)
                        -- For example { a := b, b := a }
                        --      needs to go via (at least one) temporary
 
+  | CCheck             -- heap or stack checks, or both.  
+       CCheckMacro     -- These might include some code to fill in tags 
+       [CAddrMode]     -- on the stack, so we can't use CMacroStmt below.
+       AbstractC
+
+  | CRetDirect                 -- Direct return
+        !Unique                        -- for making labels
+       AbstractC               -- return code
+       C_SRT                   -- SRT info
+       Liveness                -- stack liveness at the return point
+
   -- see the notes about these next few; they follow below...
   | CMacroStmt         CStmtMacro      [CAddrMode]
-  | CCallProfCtrMacro  FAST_STRING     [CAddrMode]
-  | CCallProfCCMacro   FAST_STRING     [CAddrMode]
+  | CCallProfCtrMacro  FastString      [CAddrMode]
+  | CCallProfCCMacro   FastString      [CAddrMode]
 
     {- The presence of this constructor is a makeshift solution;
        it being used to work around a gcc-related problem of
@@ -159,57 +164,69 @@ stored in a mixed type location.)
        typedefs if needs be (i.e., when generating .hc code and
        compiling 'foreign import dynamic's)
     -}
-  | CCallTypedef        PrimOp{-CCallOp-} [CAddrMode] [CAddrMode]
+  | CCallTypedef Bool {- True => use "typedef"; False => use "extern"-}
+                CCallSpec Unique [CAddrMode] [CAddrMode]
 
   -- *** the next three [or so...] are DATA (those above are CODE) ***
 
   | CStaticClosure
-       CLabel  -- The (full, not base) label to use for labelling the closure.
-       ClosureInfo
-       CAddrMode       -- cost centre identifier to place in closure
-       [CAddrMode]     -- free vars; ptrs, then non-ptrs
-
+       CLabel                  -- The closure's label
+       ClosureInfo             -- Todo: maybe info_lbl & closure_lbl instead?
+       CAddrMode               -- cost centre identifier to place in closure
+       [CAddrMode]             -- free vars; ptrs, then non-ptrs.
+
+  | CSRT CLabel [CLabel]       -- SRT declarations: basically an array of 
+                               -- pointers to static closures.
+  
+  | CBitmap Liveness           -- A "large" bitmap to be emitted
+
+  | CSRTDesc                   -- A "large" SRT descriptor (one that doesn't
+                               -- fit into the half-word bitmap in the itbl).
+       !CLabel                 -- Label for this SRT descriptor
+       !CLabel                 -- Pointer to the SRT
+       !Int                    -- Offset within the SRT
+       !Int                    -- Length
+       !Bitmap                 -- Bitmap
 
   | CClosureInfoAndCode
-       ClosureInfo     -- Explains placement and layout of closure
-       AbstractC       -- Slow entry point code
-       (Maybe AbstractC)
-                       -- Fast entry point code, if any
-       CAddrMode       -- Address of update code; Nothing => should never be used
-                       -- (which is the case for all except constructors)
-       String          -- Closure description; NB we can't get this from
-                       -- ClosureInfo, because the latter refers to the *right* hand
-                       -- side of a defn, whereas the "description" refers to *left*
-                       -- hand side
-       Int             -- Liveness info; this is here because it is
-                       -- easy to produce w/in the CgMonad; hard
-                       -- thereafter.  (WDP 95/11)
-
-  | CRetVector                 -- Return vector with "holes"
-                               -- (Nothings) for the default
-       CLabel                  -- vector-table label
-       [Maybe CAddrMode]
-       AbstractC               -- (and what to put in a "hole" [when Nothing])
-
-  | CRetUnVector       -- Direct return
-       CLabel          -- unvector-table label
-       CAddrMode       -- return code
-
-  | CFlatRetVector     -- A labelled block of static data
-       CLabel          -- This is the flattened version of CRetVector
+       ClosureInfo             -- Explains placement and layout of closure
+       AbstractC               -- Entry point code
+
+  | CRetVector                 -- A labelled block of static data
+       CLabel
        [CAddrMode]
+       C_SRT                   -- SRT info
+       Liveness                -- stack liveness at the return point
 
-  | CCostCentreDecl    -- A cost centre *declaration*
-       Bool            -- True  <=> local => full declaration
-                       -- False <=> extern; just say so
+  | CClosureTbl                -- table of constructors for enumerated types
+       TyCon                   -- which TyCon this table is for
+
+  | CModuleInitBlock           -- module initialisation block
+       CLabel                  -- "plain" label for init block
+       CLabel                  -- label for init block (with ver + way info)
+       AbstractC               -- initialisation code
+
+  | CCostCentreDecl            -- A cost centre *declaration*
+       Bool                    -- True  <=> local => full declaration
+                               -- False <=> extern; just say so
        CostCentre
 
-  | CClosureUpdInfo
-       AbstractC       -- InRegs Info Table (CClosureInfoTable)
-                       --                    ^^^^^^^^^^^^^^^^^
-                       --                                out of date -- HWL
+  | CCostCentreStackDecl       -- A cost centre stack *declaration*
+       CostCentreStack         -- this is the declaration for a
+                               -- pre-defined singleton CCS (see 
+                               -- CostCentre.lhs)
+
+  | CSplitMarker               -- Split into separate object modules here
 
-  | CSplitMarker       -- Split into separate object modules here
+-- C_SRT is what StgSyn.SRT gets translated to... 
+-- we add a label for the table, and expect only the 'offset/length' form
+
+data C_SRT = NoC_SRT
+          | C_SRT !CLabel !Int{-offset-} !StgHalfWord{-bitmap or escape-}
+
+needsSRT :: C_SRT -> Bool
+needsSRT NoC_SRT       = False
+needsSRT (C_SRT _ _ _) = True
 \end{code}
 
 About @CMacroStmt@, etc.: notionally, they all just call some
@@ -224,27 +241,49 @@ macros.  An example is @STK_CHK@, which checks for stack-space
 overflow.  This enumeration type lists all such macros:
 \begin{code}
 data CStmtMacro
-  = ARGS_CHK_A_LOAD_NODE
-  | ARGS_CHK_A
-  | ARGS_CHK_B_LOAD_NODE
-  | ARGS_CHK_B
-  | HEAP_CHK
-  | STK_CHK
-  | UPD_CAF
-  | UPD_IND
-  | UPD_INPLACE_NOPTRS
-  | UPD_INPLACE_PTRS
-  | UPD_BH_UPDATABLE
-  | UPD_BH_SINGLE_ENTRY
-  | PUSH_STD_UPD_FRAME
-  | POP_STD_UPD_FRAME
-  | SET_TAG
+  = UPD_CAF                            -- update CAF closure with indirection
+  | UPD_BH_UPDATABLE                   -- eager backholing
+  | UPD_BH_SINGLE_ENTRY                        -- more eager blackholing
+  | PUSH_UPD_FRAME                     -- push update frame
+  | SET_TAG                            -- set TagReg if it exists
+      -- dataToTag# primop -- *only* used in unregisterised builds.
+      -- (see AbsCUtils.dsCOpStmt)
+  | DATA_TO_TAGZH
+
+  | REGISTER_FOREIGN_EXPORT            -- register a foreign exported fun
+  | REGISTER_IMPORT                    -- register an imported module
+  | REGISTER_DIMPORT                    -- register an imported module from
+                                        -- another DLL
+
   | GRAN_FETCH                 -- for GrAnSim only  -- HWL
   | GRAN_RESCHEDULE            -- for GrAnSim only  -- HWL
   | GRAN_FETCH_AND_RESCHEDULE  -- for GrAnSim only  -- HWL
   | THREAD_CONTEXT_SWITCH      -- for GrAnSim only  -- HWL
   | GRAN_YIELD                 -- for GrAnSim only  -- HWL 
-  deriving Text
+\end{code}
+
+Heap/Stack checks.  There are far too many of these.
+
+\begin{code}
+data CCheckMacro
+
+  = HP_CHK_NP                          -- heap/stack checks when
+  | STK_CHK_NP                         -- node points to the closure
+  | HP_STK_CHK_NP
+
+  | HP_CHK_FUN                         -- heap/stack checks when
+  | STK_CHK_FUN                                -- node doesn't point
+  | HP_STK_CHK_FUN
+                                       -- case alternative heap checks:
+
+  | HP_CHK_NOREGS                      --   no registers live
+  | HP_CHK_UNPT_R1                     --   R1 is boxed/unlifted
+  | HP_CHK_UNBX_R1                     --   R1 is unboxed
+  | HP_CHK_F1                          --   FloatReg1 (only) is live 
+  | HP_CHK_D1                          --   DblReg1   (only) is live
+  | HP_CHK_L1                          --   LngReg1   (only) is live
+
+  | HP_CHK_UNBX_TUPLE                  -- unboxed tuple heap check
 \end{code}
 
 \item[@CCallProfCtrMacro@:]
@@ -256,47 +295,12 @@ The @String@ names a macro that, if \tr{#define}d, will perform some
 cost-centre-profiling-related action.
 \end{description}
 
-HERE ARE SOME OLD NOTES ABOUT HEAP-CHK ENTRY POINTS:
-
-\item[@CCallStgC@:]
-Some parts of the system, {\em notably the storage manager}, are
-implemented by C~routines that must know something about the internals
-of the STG world, e.g., where the heap-pointer is.  (The
-``C-as-assembler'' documents describes this stuff in detail.)
-
-This is quite a tricky business, especially with ``optimised~C,'' so
-we keep close tabs on these fellows.  This enumeration type lists all
-such ``STG~C'' routines:
-
-HERE ARE SOME *OLD* NOTES ABOUT HEAP-CHK ENTRY POINTS:
-
-Heap overflow invokes the garbage collector (of your choice :-), and
-we have different entry points, to tell the GC the exact configuration
-before it.
-\begin{description}
-\item[Branch of a boxed case:]
-The @Node@ register points off to somewhere legitimate, the @TagReg@
-holds the tag, and the @RetReg@ points to the code for the
-alterative which should be resumed. (ToDo: update)
-
-\item[Branch of an unboxed case:]
-The @Node@ register points nowhere of any particular interest, a
-kind-specific register (@IntReg@, @FloatReg@, etc.) holds the unboxed
-value, and the @RetReg@ points to the code for the alternative
-which should be resumed. (ToDo: update)
-
-\item[Closure entry:]
-The @Node@ register points to the closure, and the @RetReg@ points
-to the code to be resumed. (ToDo: update)
-\end{description}
-
 %************************************************************************
 %*                                                                     *
 \subsection[CAddrMode]{C addressing modes}
 %*                                                                     *
 %************************************************************************
 
-Addressing modes: these have @PrimitiveKinds@ pinned on them.
 \begin{code}
 data CAddrMode
   = CVal  RegRelative PrimRep
@@ -312,71 +316,41 @@ data CAddrMode
                        --      which gives the magic location itself
                        --      (NB: superceded by CReg)
 
-  | CReg MagicId       -- To replace (CAddr MagicId 0)
+             -- JRS 2002-02-05: CAddr is really scummy and should be fixed.
+             -- The effect is that the semantics of CAddr depend on what the
+             -- contained RegRelative is; it is decidely non-orthogonal.
 
-  | CTableEntry            -- CVal should be generalized to allow this
-               CAddrMode   -- Base
-               CAddrMode   -- Offset
-               PrimRep    -- For casting
+  | CReg MagicId       -- To replace (CAddr MagicId 0)
 
-  | CTemp Unique PrimRep       -- Temporary locations
+  | CTemp !Unique !PrimRep     -- Temporary locations
        -- ``Temporaries'' correspond to local variables in C, and registers in
        -- native code.
 
   | CLbl    CLabel     -- Labels in the runtime system, etc.
-                       -- See comment under CLabelledData about (String,Name)
            PrimRep     -- the kind is so we can generate accurate C decls
 
-  | CUnVecLbl          -- A choice of labels left up to the back end
-             CLabel    -- direct
-             CLabel    -- vectored
-
   | CCharLike CAddrMode        -- The address of a static char-like closure for
                        -- the specified character.  It is guaranteed to be in
-                       -- the range 0..255.
+                       -- the range mIN_CHARLIKE..mAX_CHARLIKE
 
   | CIntLike CAddrMode -- The address of a static int-like closure for the
-                       -- specified small integer.  It is guaranteed to be in the
-                       -- range mIN_INTLIKE..mAX_INTLIKE
+                       -- specified small integer.  It is guaranteed to be in
+                       -- the range mIN_INTLIKE..mAX_INTLIKE
 
-  | CString FAST_STRING        -- The address of the null-terminated string
   | CLit    Literal
-  | CLitLit FAST_STRING        -- completely literal literal: just spit this String
-                       -- into the C output
-           PrimRep
-
-  | COffset HeapOffset -- A literal constant, not an offset *from* anything!
-                       -- ToDo: this should really be CLitOffset
-
-  | CCode AbstractC    -- Some code.  Used mainly for return addresses.
-
-  | CLabelledCode CLabel AbstractC  -- Almost defunct? (ToDo?) --JSM
-                       -- Some code that must have a particular label
-                       -- (which is jumpable to)
-
-  | CJoinPoint         -- This is used as the amode of a let-no-escape-bound variable
-       VirtualSpAOffset        -- SpA and SpB values after any volatile free vars
-       VirtualSpBOffset        -- of the rhs have been saved on stack.
-                               -- Just before the code for the thing is jumped to,
-                               -- SpA/B will be set to these values,
-                               -- and then any stack-passed args pushed,
-                               -- then the code for this thing will be entered
 
+  | CJoinPoint         -- This is used as the amode of a let-no-escape-bound
+                       -- variable.
+       VirtualSpOffset   -- Sp value after any volatile free vars
+                         -- of the rhs have been saved on stack.
+                         -- Just before the code for the thing is jumped to,
+                         -- Sp will be set to this value,
+                         -- and then any stack-passed args pushed,
+                         -- then the code for this thing will be entered
   | CMacroExpr
-       PrimRep         -- the kind of the result
+       !PrimRep        -- the kind of the result
        CExprMacro      -- the macro to generate a value
        [CAddrMode]     -- and its arguments
-
-  | CCostCentre                -- If Bool is True ==> it to be printed as a String,
-       CostCentre      -- (*not* as a C identifier or some such).
-       Bool            -- (It's not just the double-quotes on either side;
-                       -- spaces and other funny characters will have been
-                       -- fiddled in the non-String variant.)
-
-mkCCostCentre cc
-  = --ASSERT(not (currentOrSubsumedCosts cc))
-    --FALSE: We do put subsumedCC in static closures
-    CCostCentre cc False
 \end{code}
 
 Various C macros for values which are dependent on the back-end layout.
@@ -384,18 +358,32 @@ Various C macros for values which are dependent on the back-end layout.
 \begin{code}
 
 data CExprMacro
-  = INFO_PTR
-  | ENTRY_CODE
-  | INFO_TAG
-  | EVAL_TAG
-  deriving(Text)
-
+  = ENTRY_CODE
+  | ARG_TAG                            -- stack argument tagging
+  | GET_TAG                            -- get current constructor tag
+  | CCS_HDR
+  | BYTE_ARR_CTS               -- used when passing a ByteArray# to a ccall
+  | PTRS_ARR_CTS               -- similarly for an Array#
+  | ForeignObj_CLOSURE_DATA    -- and again for a ForeignObj#
 \end{code}
 
-A tiny convenience:
+Convenience functions:
+
 \begin{code}
 mkIntCLit :: Int -> CAddrMode
 mkIntCLit i = CLit (mkMachInt (toInteger i))
+
+mkWordCLit :: StgWord -> CAddrMode
+mkWordCLit wd = CLit (MachWord (fromIntegral wd))
+
+mkCString :: FastString -> CAddrMode
+mkCString s = CLit (MachStr s)
+
+mkCCostCentre :: CostCentre -> CAddrMode
+mkCCostCentre cc = CLbl (mkCC_Label cc) DataPtrRep
+
+mkCCostCentreStack :: CostCentreStack -> CAddrMode
+mkCCostCentreStack ccs = CLbl (mkCCS_Label ccs) DataPtrRep
 \end{code}
 
 %************************************************************************
@@ -406,171 +394,147 @@ mkIntCLit i = CLit (mkMachInt (toInteger i))
 
 \begin{code}
 data RegRelative
-  = HpRel       VirtualHeapOffset      -- virtual offset of Hp
-                VirtualHeapOffset      -- virtual offset of The Thing
-  | SpARel      VirtualSpAOffset       -- virtual offset of SpA
-                VirtualSpAOffset       -- virtual offset of The Thing
-  | SpBRel      VirtualSpBOffset       -- virtual offset of SpB
-                VirtualSpBOffset       -- virtual offset of The Thing
-  | NodeRel     VirtualHeapOffset
+  = HpRel      FastInt -- }
+  | SpRel      FastInt -- }- offsets in StgWords
+  | NodeRel    FastInt -- }
+  | CIndex     CAddrMode CAddrMode PrimRep     -- pointer arithmetic :-)
+                                               -- CIndex a b k === (k*)a[b]
 
 data ReturnInfo
   = DirectReturn                       -- Jump directly, if possible
   | StaticVectoredReturn Int           -- Fixed tag, starting at zero
   | DynamicVectoredReturn CAddrMode    -- Dynamic tag given by amode, starting at zero
+
+hpRel :: VirtualHeapOffset     -- virtual offset of Hp
+      -> VirtualHeapOffset     -- virtual offset of The Thing
+      -> RegRelative           -- integer offset
+hpRel hp off = HpRel (iUnbox (hp - off))
+
+spRel :: VirtualSpOffset       -- virtual offset of Sp
+      -> VirtualSpOffset       -- virtual offset of The Thing
+      -> RegRelative           -- integer offset
+spRel sp off = SpRel (iUnbox (spRelToInt sp off))
+
+nodeRel :: VirtualHeapOffset
+        -> RegRelative
+nodeRel off = NodeRel (iUnbox off)
+
 \end{code}
 
 %************************************************************************
 %*                                                                     *
-\subsection[MagicId]{@MagicIds@: registers and such}
+\subsection[Liveness]{Liveness Masks}
 %*                                                                     *
 %************************************************************************
 
-Much of what happens in Abstract-C is in terms of ``magic'' locations,
-such as the stack pointer, heap pointer, etc.  If possible, these will
-be held in registers.
+We represent liveness bitmaps as a BitSet (whose internal
+representation really is a bitmap).  These are pinned onto case return
+vectors to indicate the state of the stack for the garbage collector.
 
-Here are some notes about what's active when:
-\begin{description}
-\item[Always active:]
-       Hp, HpLim, SpA, SpB, SuA, SuB
+In the compiled program, liveness bitmaps that fit inside a single
+word (StgWord) are stored as a single word, while larger bitmaps are
+stored as a pointer to an array of words. 
 
-\item[Entry set:]
-       ArgPtr1 (= Node)...
+\begin{code}
+data Liveness = Liveness CLabel !Int Bitmap
 
-\item[Return set:]
-Ptr regs: RetPtr1 (= Node), RetPtr2...
-Int/char regs:  RetData1 (= TagReg = IntReg), RetData2...
-Float regs: RetFloat1, ...
-Double regs: RetDouble1, ...
-\end{description}
+maybeLargeBitmap :: Liveness -> AbstractC
+maybeLargeBitmap liveness@(Liveness _ size _)
+  | size <= mAX_SMALL_BITMAP_SIZE = AbsCNop
+  | otherwise                     = CBitmap liveness
+\end{code}
+
+%************************************************************************
+%*                                                                     *
+\subsection[HeapOffset]{@Heap Offsets@}
+%*                                                                     *
+%************************************************************************
+
+This used to be a grotesquely complicated datatype in an attempt to
+hide the details of header sizes from the compiler itself.  Now these
+constants are imported from the RTS, and we deal in real Ints.
+
+\begin{code}
+type HeapOffset = Int                  -- ToDo: remove
+
+type VirtualHeapOffset = HeapOffset
+type VirtualSpOffset   = Int
+\end{code}
+
+%************************************************************************
+%*                                                                     *
+\subsection[MagicId]{@MagicIds@: registers and such}
+%*                                                                     *
+%************************************************************************
 
 \begin{code}
 data MagicId
   = BaseReg    -- mentioned only in nativeGen
 
-  | StkOReg    -- mentioned only in nativeGen
-
   -- Argument and return registers
   | VanillaReg         -- pointers, unboxed ints and chars
-       PrimRep         -- PtrRep, IntRep, CharRep, StablePtrRep or ForeignObjRep
-                       --      (in case we need to distinguish)
-       FAST_INT        -- its number (1 .. mAX_Vanilla_REG)
-
-  | FloatReg   -- single-precision floating-point registers
-       FAST_INT        -- its number (1 .. mAX_Float_REG)
-
-  | DoubleReg  -- double-precision floating-point registers
-       FAST_INT        -- its number (1 .. mAX_Double_REG)
-
+       PrimRep
+       FastInt -- its number (1 .. mAX_Vanilla_REG)
+
+  | FloatReg           -- single-precision floating-point registers
+       FastInt -- its number (1 .. mAX_Float_REG)
+
+  | DoubleReg          -- double-precision floating-point registers
+       FastInt -- its number (1 .. mAX_Double_REG)
+
+  -- STG registers
+  | Sp                 -- Stack ptr; points to last occupied stack location.
+  | SpLim              -- Stack limit
+  | Hp                 -- Heap ptr; points to last occupied heap location.
+  | HpLim              -- Heap limit register
+  | CurCostCentre      -- current cost centre register.
+  | VoidReg            -- see "VoidPrim" type; just a placeholder; 
+                       --   no actual register
   | LongReg            -- long int registers (64-bit, really)
        PrimRep         -- Int64Rep or Word64Rep
-       FAST_INT        -- its number (1 .. mAX_Long_REG)
-
-  | TagReg     -- to return constructor tags; as almost all returns are vectored,
-               -- this is rarely used.
-
-  | RetReg     -- topmost return address from the B stack
-
-  | SpA                -- Stack ptr; points to last occupied stack location.
-               -- Stack grows downward.
-  | SuA        -- mentioned only in nativeGen
-
-  | SpB                -- Basic values, return addresses and update frames.
-               -- Grows upward.
-  | SuB                -- mentioned only in nativeGen
-
-  | Hp         -- Heap ptr; points to last occupied heap location.
-               -- Free space at lower addresses.
-
-  | HpLim      -- Heap limit register: mentioned only in nativeGen
-
-  | LivenessReg        -- (parallel only) used when we need to record explicitly
-               -- what registers are live
-
-  | StdUpdRetVecReg    -- mentioned only in nativeGen
-  | StkStubReg         -- register holding STK_STUB_closure (for stubbing dead stack slots)
+       FastInt -- its number (1 .. mAX_Long_REG)
 
-  | CurCostCentre -- current cost centre register.
+  | CurrentTSO         -- pointer to current thread's TSO
+  | CurrentNursery     -- pointer to allocation area
+  | HpAlloc            -- allocation count for heap check failure
 
-  | VoidReg -- see "VoidPrim" type; just a placeholder; no actual register
 
-node   = VanillaReg PtrRep     ILIT(1) -- A convenient alias for Node
-infoptr = VanillaReg DataPtrRep ILIT(2) -- An alias for InfoPtr
+node   = VanillaReg PtrRep     (_ILIT 1) -- A convenient alias for Node
+tagreg  = VanillaReg WordRep    (_ILIT 2) -- A convenient alias for TagReg
 
---------------------
-noLiveRegsMask :: Int  -- Mask indicating nothing live
-noLiveRegsMask = 0
-
-mkLiveRegsMask
-       :: [MagicId]    -- Candidate live regs; depends what they have in them
-       -> Int
-
-mkLiveRegsMask regs
-  = foldl do_reg noLiveRegsMask regs
-  where
-    do_reg acc (VanillaReg kind reg_no)
-      | isFollowableRep kind
-      = acc + (reg_tbl !! IBOX(reg_no _SUB_ ILIT(1)))
-
-    do_reg acc anything_else = acc
-
-    reg_tbl -- ToDo: mk Array!
-      = [lIVENESS_R1, lIVENESS_R2, lIVENESS_R3, lIVENESS_R4,
-        lIVENESS_R5, lIVENESS_R6, lIVENESS_R7, lIVENESS_R8]
+nodeReg = CReg node
 \end{code}
 
 We need magical @Eq@ because @VanillaReg@s come in multiple flavors.
 
 \begin{code}
 instance Eq MagicId where
-    reg1 == reg2 = tag reg1 _EQ_ tag reg2
+    reg1 == reg2 = tag reg1 ==# tag reg2
      where
-       tag BaseReg          = (ILIT(0) :: FAST_INT)
-       tag StkOReg          = ILIT(1)
-       tag TagReg           = ILIT(2)
-       tag RetReg           = ILIT(3)
-       tag SpA              = ILIT(4)
-       tag SuA              = ILIT(5)
-       tag SpB              = ILIT(6)
-       tag SuB              = ILIT(7)
-       tag Hp               = ILIT(8)
-       tag HpLim            = ILIT(9)
-       tag LivenessReg      = ILIT(10)
-       tag StdUpdRetVecReg  = ILIT(12)
-       tag StkStubReg       = ILIT(13)
-       tag CurCostCentre    = ILIT(14)
-       tag VoidReg          = ILIT(15)
-
-       tag reg =
-          ILIT(15) _ADD_ (
-         case reg of
-           VanillaReg _ i -> i
-           FloatReg i     -> maxv _ADD_ i
-           DoubleReg i    -> maxv _ADD_ maxf _ADD_ i
-           LongReg _ i    -> maxv _ADD_ maxf _ADD_ maxd _ADD_ i
-         )
-         where
-           maxv = case mAX_Vanilla_REG of { IBOX(x) -> x }
-           maxf = case mAX_Float_REG   of { IBOX(x) -> x }
-           maxd = case mAX_Double_REG of { IBOX(x) -> x }
+       tag BaseReg          = (_ILIT(0) :: FastInt)
+       tag Sp               = _ILIT(1)
+       tag SpLim            = _ILIT(3)
+       tag Hp               = _ILIT(4)
+       tag HpLim            = _ILIT(5)
+       tag CurCostCentre    = _ILIT(6)
+       tag VoidReg          = _ILIT(7)
+
+       tag (VanillaReg _ i) = _ILIT(8) +# i
+
+       tag (FloatReg i)  = _ILIT(8) +# maxv +# i
+       tag (DoubleReg i) = _ILIT(8) +# maxv +# maxf +# i
+       tag (LongReg _ i) = _ILIT(8) +# maxv +# maxf +# maxd +# i
+
+        maxv = iUnbox mAX_Vanilla_REG
+        maxf = iUnbox mAX_Float_REG
+        maxd = iUnbox mAX_Double_REG
 \end{code}
 
 Returns True for any register that {\em potentially} dies across
 C calls (or anything near equivalent).  We just say @True@ and
 let the (machine-specific) registering macros sort things out...
+
 \begin{code}
 isVolatileReg :: MagicId -> Bool
-
 isVolatileReg any = True
---isVolatileReg (FloatReg _)   = True
---isVolatileReg (DoubleReg _)  = True
 \end{code}
-
-%************************************************************************
-%*                                                                     *
-\subsection[AbsCSyn-printing]{Pretty-printing Abstract~C}
-%*                                                                     *
-%************************************************************************
-
-It's in \tr{PprAbsC.lhs}.