%
% (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
%
-% $Id: AbsCSyn.lhs,v 1.41 2001/12/05 17:35:12 sewardj Exp $
+% $Id: AbsCSyn.lhs,v 1.55 2003/07/28 16:05:30 simonmar Exp $
%
\section[AbstractC]{Abstract C: the last stop before machine code}
raw assembler/machine code.
\begin{code}
-module AbsCSyn {- (
- -- export everything
- AbstractC(..),
- C_SRT(..)
- CStmtMacro(..),
- CExprMacro(..),
- CAddrMode(..),
- ReturnInfo(..),
- mkAbstractCs, mkAbsCStmts, mkAlgAltsCSwitch,
- mkIntCLit,
- mkAbsCStmtList,
- mkCCostCentre,
-
- -- RegRelatives
- RegRelative(..),
-
- -- registers
- MagicId(..), node, infoptr,
- isVolatileReg,
- CostRes(Cost)
- )-} where
+module AbsCSyn where -- export everything
#include "HsVersions.h"
import Unique ( Unique )
import StgSyn ( StgOp )
import TyCon ( TyCon )
-import BitSet -- for liveness masks
-import Maybes ( Maybe012(..) )
+import Bitmap ( Bitmap, mAX_SMALL_BITMAP_SIZE )
+import SMRep ( StgWord, StgHalfWord )
import FastTypes
-
-import Outputable
+import FastString
\end{code}
@AbstractC@ is a list of Abstract~C statements, but the data structure
| CInitHdr -- to initialise the header of a closure (both fixed/var parts)
ClosureInfo
CAddrMode -- address of the info ptr
- CAddrMode -- cost centre to place in closure
+ !CAddrMode -- cost centre to place in closure
-- CReg CurCostCentre or CC_HDR(R1.p{-Node-})
Int -- size of closure, for profiling
-- NEW CASES FOR EXPANDED PRIMOPS
| CMachOpStmt -- Machine-level operation
- (Maybe012 CAddrMode) -- 0, 1 or 2 results
+ CAddrMode -- result
MachOp
[CAddrMode] -- Arguments
(Maybe [MagicId]) -- list of regs which need to be preserved
-- 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
-- *** 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
+ 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 CLabel LivenessMask -- A bitmap to be emitted if and only if
- -- it is larger than a target machine word.
+ | 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
- 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
+ AbstractC -- Entry point code
| CRetVector -- A labelled block of static data
CLabel
TyCon -- which TyCon this table is for
| CModuleInitBlock -- module initialisation block
- CLabel -- label for init block
+ CLabel -- "plain" label for init block
+ CLabel -- label for init block (with ver + way info)
AbstractC -- initialisation code
| CCostCentreDecl -- A cost centre *declaration*
-- we add a label for the table, and expect only the 'offset/length' form
data C_SRT = NoC_SRT
- | C_SRT CLabel !Int{-offset-} !Int{-length-}
+ | C_SRT !CLabel !Int{-offset-} !StgHalfWord{-bitmap or escape-}
needsSRT :: C_SRT -> Bool
needsSRT NoC_SRT = False
overflow. This enumeration type lists all such macros:
\begin{code}
data CStmtMacro
- = ARGS_CHK -- arg satisfaction check
- | ARGS_CHK_LOAD_NODE -- arg check for top-level functions
- | UPD_CAF -- update CAF closure with indirection
+ = 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
- | PUSH_SEQ_FRAME -- push seq frame
- | UPDATE_SU_FROM_UPD_FRAME -- pull Su out of the 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
= HP_CHK_NP -- heap/stack checks when
| STK_CHK_NP -- node points to the closure
| HP_STK_CHK_NP
- | HP_CHK_SEQ_NP -- for 'seq' style case alternatives
- | HP_CHK -- heap/stack checks when
- | STK_CHK -- node doesn't point
- | HP_STK_CHK
+ | 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_F1 -- FloatReg1 (only) is live
| HP_CHK_D1 -- DblReg1 (only) is live
| HP_CHK_L1 -- LngReg1 (only) is live
- | HP_CHK_UT_ALT -- unboxed tuple return.
- | HP_CHK_GEN -- generic heap check
+ | HP_CHK_UNBX_TUPLE -- unboxed tuple heap check
\end{code}
\item[@CCallProfCtrMacro@:]
-- which gives the magic location itself
-- (NB: superceded by CReg)
+ -- 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.
+
| CReg MagicId -- To replace (CAddr MagicId 0)
| CTemp !Unique !PrimRep -- Temporary locations
!PrimRep -- the kind of the result
CExprMacro -- the macro to generate a value
[CAddrMode] -- and its arguments
-
- | CMem PrimRep -- A value :: PrimRep, in memory, at the
- CAddrMode -- specified address
\end{code}
Various C macros for values which are dependent on the back-end layout.
= ENTRY_CODE
| ARG_TAG -- stack argument tagging
| GET_TAG -- get current constructor tag
- | UPD_FRAME_UPDATEE
| 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}
Convenience functions:
mkIntCLit :: Int -> CAddrMode
mkIntCLit i = CLit (mkMachInt (toInteger i))
-mkCString :: FAST_STRING -> CAddrMode
+mkWordCLit :: StgWord -> CAddrMode
+mkWordCLit wd = CLit (MachWord (fromIntegral wd))
+
+mkCString :: FastString -> CAddrMode
mkCString s = CLit (MachStr s)
mkCCostCentre :: CostCentre -> CAddrMode
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. When we compile via C
-(especially when we bootstrap via HC files), we generate identical C
-code regardless of whether words are 32- or 64-bit on the target
-machine, by postponing the decision of how to store each liveness
-bitmap to C compilation time (or rather, C preprocessing time).
+stored as a pointer to an array of words.
\begin{code}
-type LivenessMask = [BitSet]
+data Liveness = Liveness CLabel !Int Bitmap
-data Liveness = Liveness CLabel LivenessMask
+maybeLargeBitmap :: Liveness -> AbstractC
+maybeLargeBitmap liveness@(Liveness _ size _)
+ | size <= mAX_SMALL_BITMAP_SIZE = AbsCNop
+ | otherwise = CBitmap liveness
\end{code}
%************************************************************************
-- STG registers
| Sp -- Stack ptr; points to last occupied stack location.
- | Su -- Stack update frame pointer
| SpLim -- Stack limit
| Hp -- Heap ptr; points to last occupied heap location.
| HpLim -- Heap limit register
where
tag BaseReg = (_ILIT(0) :: FastInt)
tag Sp = _ILIT(1)
- tag Su = _ILIT(2)
tag SpLim = _ILIT(3)
tag Hp = _ILIT(4)
tag HpLim = _ILIT(5)