%************************************************************************ %* * \section[GhcConstants]{Constants known by C code {\em and} by the compiler (hsc)} %* * %************************************************************************ Multi-slurp protection (start): \begin{code} #ifndef GHCCONSTANTS_H #define GHCCONSTANTS_H #ifndef PLATFORM_H #include "platform.h" #endif \end{code} % BECAUSE THIS FILE IS INCLUDED INTO HASKELL FILES, THERE MUST BE NO C % COMMENTS IN THE ``CODE'' BITS. This file defines constants that are common to diverse parts of the Glasgow Haskell compilation system. For example, both the compiler proper and some magic runtime-system bits need to know the minimum size of an updatable closure. %************************************************************************ %* * \subsection[updatable-closure-size]{Size of Updatable Closures} %* * %************************************************************************ We define the minimum size for updatable closures. This must be at least 2, to allow for cons cells and linked indirections. All updates will be performed on closures of this size. For non-updatable closures the minimum size is 1 to allow for a forwarding pointer. \begin{code} #define MIN_UPD_SIZE 2 #define MIN_NONUPD_SIZE 1 \end{code} ToDo: @MIN_STATIC_NONUPD_SIZE@ ??? %************************************************************************ %* * \subsection[double-etc-size]{Sizes of various types} %* * %************************************************************************ The size of an StgDouble, in StgWords. \begin{code} #if alpha_TARGET_ARCH #define DOUBLE_SIZE 1 #else #define DOUBLE_SIZE 2 #endif \end{code} Sizes of gmp objects, in StgWords \begin{code} #define MP_STRUCT_SIZE 3 #define MIN_MP_INT_SIZE 16 \end{code} %************************************************************************ %* * \subsection[spec-closure-constraints]{What can be declared as a @SPEC@ closure} %* * %************************************************************************ The following define what closure layouts can be declared as @SPEC@ closures. \begin{code} #define MAX_SPEC_ALL_PTRS 12 #define MAX_SPEC_ALL_NONPTRS 5 #define MAX_SPEC_OTHER_SIZE 3 \end{code} The highest-numbered selectee field that we can do magic on (i.e., do the selection at GC time): \begin{code} #define MAX_SPEC_SELECTEE_SIZE 12 \end{code} %************************************************************************ %* * \subsection[stg-reg-counts]{How many STG registers are there} %* * %************************************************************************ \begin{code} #define MAX_VANILLA_REG 8 #define MAX_FLOAT_REG 4 #define MAX_DOUBLE_REG 2 \end{code} %************************************************************************ %* * \subsection[vectored-return]{What number of data type cases can use vectored returns} %* * %************************************************************************ @MAX_VECTORED_RTN@ defines the largest number of constructors that a data type can have and still use a vectored return. \begin{code} #define MAX_VECTORED_RTN 8 \end{code} %************************************************************************ %* * \subsection[intlike-range]{Range of int-like closures} %* * %************************************************************************ Range of built-in table of static small int-like closures. \begin{code} #define MAX_INTLIKE (16) #define MIN_INTLIKE (-16) \end{code} %************************************************************************ %* * \subsection[update-frame-size]{Update frame size} %* * %************************************************************************ The update frames are described in \tr{SMupdate.lh}. All the compiler needs to ``know'' is the size of the different frames. First we define update frame sizes for the compiler. These may vary at runtime depending what type of code is being generated so we also define the parts which can be put together. **************************************************************** *** NB: These update-frame sizes INCLUDE the return address. *** **************************************************************** The update frame sizes when cost centres are not being used are: \begin{code} #define NOSCC_STD_UF_SIZE 4 #define NOSCC_CON_UF_SIZE 2 \end{code} If cost-centres are being used we have to add to the above sizes: \begin{code} #define SCC_STD_UF_SIZE 5 #define SCC_CON_UF_SIZE 3 \end{code} If we are compiling C code the use of cost centres is determined at compile time so we use conditional macro definitions. \begin{code} #if defined(PROFILING) #define STD_UF_SIZE SCC_STD_UF_SIZE #define CON_UF_SIZE SCC_CON_UF_SIZE #else #define STD_UF_SIZE NOSCC_STD_UF_SIZE #define CON_UF_SIZE NOSCC_CON_UF_SIZE #endif \end{code} Sorry. but we can't comment these if's and else's ! Offsets relative to a pointer to the top word (return address) of frame... Notes: (1)~GC looks at the @UF_RET@ word to determine frame type. (2) GC requires that @UF_SUB@ be the same offset in all frames, no matter what. \begin{code} #define UF_RET 0 #define UF_SUB 1 #define UF_SUA 2 #define UF_UPDATEE 3 #define UF_COST_CENTRE 4 \end{code} %************************************************************************ %* * \subsection[semi-tagging-constants]{Constants for semi-tagging} %* * %************************************************************************ Tags for indirection nodes and ``other'' (probably unevaluated) nodes; normal-form values of algebraic data types will have tags 0, 1, ... @INFO_IND_TAG@ is different from @INFO_OTHER_TAG@ just so we can count how often we bang into indirection nodes; that's all. (WDP 95/11) \begin{code} #define INFO_OTHER_TAG (-1) #define INFO_IND_TAG (-2) #define INFO_FIRST_TAG 0 \end{code} %************************************************************************ %* * \subsection[liveness-masks]{Liveness masks for calling GC} %* * %************************************************************************ We often have to tell the RTS (usually: garbage-collector) what STG registers have ``followable'' pointers in them. We used to just say {\em how many} there were; but this doesn't work in a semi-tagged world---part of the point of semi-tagging is to avoid loading up registers needlessly; but if you don't load a register and then you tell the GC that it has followable contents.... So we use a {\em liveness mask} (one word) instead. This is probably neater anyway. The layout is: \begin{verbatim} -------------------------- ... | Rn | ... | R2 | R1 | -------------------------- \end{verbatim} The \tr{LIVENESS_} macros are used both in Haskell and C. The \tr{IS_LIVE_} macros (``is this register live according to this mask?'') are used only in C [obviously]. \begin{code} #define NO_LIVENESS 0 #define LIVENESS_R1 1 #define LIVENESS_R2 2 #define LIVENESS_R3 4 #define LIVENESS_R4 8 #define LIVENESS_R5 16 #define LIVENESS_R6 32 #define LIVENESS_R7 64 #define LIVENESS_R8 128 #define IS_LIVE_R1(mask) (((mask) & LIVENESS_R1) != 0) #define IS_LIVE_R2(mask) (((mask) & LIVENESS_R2) != 0) #define IS_LIVE_R3(mask) (((mask) & LIVENESS_R3) != 0) #define IS_LIVE_R4(mask) (((mask) & LIVENESS_R4) != 0) #define IS_LIVE_R5(mask) (((mask) & LIVENESS_R5) != 0) #define IS_LIVE_R6(mask) (((mask) & LIVENESS_R6) != 0) #define IS_LIVE_R7(mask) (((mask) & LIVENESS_R7) != 0) #define IS_LIVE_R8(mask) (((mask) & LIVENESS_R8) != 0) \end{code} Some extra stuff will probably be needed for ``shift bits off the end and stop when zero,'' which would be quicker. Later. Multi-slurp protection (end-of-file): \begin{code} #endif \end{code}