/* -----------------------------------------------------------------------------
*
- * (c) The GHC Team, 1998-2004
+ * (c) The GHC Team, 1998-2009
*
- * Top-level include file for everything STG-ish.
- *
- * This file is included *automatically* by all .hc files.
- *
- * NOTE: always include Stg.h *before* any other headers, because we
- * define some register variables which must be done before any inline
- * functions are defined (some system headers have been known to
- * define the odd inline function).
+ * Top-level include file for everything required when compiling .hc
+ * code. NOTE: in .hc files, Stg.h must be included *before* any
+ * other headers, because we define some register variables which must
+ * be done before any inline functions are defined (some system
+ * headers have been known to define the odd inline function).
*
* We generally try to keep as little visible as possible when
* compiling .hc files. So for example the definitions of the
* of these types to generate code which manipulates them directly
* with pointer arithmetic.
*
+ * In ordinary C code, do not #include this file directly: #include
+ * "Rts.h" instead.
+ *
+ * To understand the structure of the RTS headers, see the wiki:
+ * http://hackage.haskell.org/trac/ghc/wiki/Commentary/SourceTree/Includes
+ *
* ---------------------------------------------------------------------------*/
#ifndef STG_H
#define STG_H
-
-/* If we include "Stg.h" directly, we're in STG code, and we therefore
- * get all the global register variables, macros etc. that go along
- * with that. If "Stg.h" is included via "Rts.h", we're assumed to
- * be in vanilla C.
+/*
+ * If we are compiling a .hc file, then we want all the register
+ * variables. This is the what happens if you #include "Stg.h" first:
+ * we assume this is a .hc file, and set IN_STG_CODE==1, which later
+ * causes the register variables to be enabled in stg/Regs.h.
+ *
+ * If instead "Rts.h" is included first, then we are compiling a
+ * vanilla C file. Everything from Stg.h is provided, except that
+ * IN_STG_CODE is not defined, and the register variables will not be
+ * active.
*/
#ifndef IN_STG_CODE
# define IN_STG_CODE 1
// constants from math.h, which we occasionally need to use in .hc (#1861)
# define _ISOC99_SOURCE
-// Turning on _ISOC99_SOURCE means S_ISSOCK gets defined on Linux
+// We need _BSD_SOURCE so that math.h defines things like gamma
+// on Linux
# define _BSD_SOURCE
#endif
/* Configuration */
#include "ghcconfig.h"
-#include "RtsConfig.h"
/* The code generator calls the math functions directly in .hc code.
NB. after configuration stuff above, because this sets #defines
that depend on config info, such as __USE_FILE_OFFSET64 */
#include <math.h>
+// On Solaris, we don't get the INFINITY and NAN constants unless we
+// #define _STDC_C99, and we can't do that unless we also use -std=c99,
+// because _STDC_C99 causes the headers to use C99 syntax (e.g. restrict).
+// We aren't ready for -std=c99 yet, so define INFINITY/NAN by hand using
+// the gcc builtins.
+#if !defined(INFINITY)
+#if defined(__GNUC__)
+#define INFINITY __builtin_inf()
+#else
+#error No definition for INFINITY
+#endif
+#endif
+
+#if !defined(NAN)
+#if defined(__GNUC__)
+#define NAN __builtin_nan("")
+#else
+#error No definition for NAN
+#endif
+#endif
+
/* -----------------------------------------------------------------------------
Useful definitions
-------------------------------------------------------------------------- */
/*
- * The C backend like to refer to labels by just mentioning their
+ * The C backend likes to refer to labels by just mentioning their
* names. Howevver, when a symbol is declared as a variable in C, the
* C compiler will implicitly dereference it when it occurs in source.
* So we must subvert this behaviour for .hc files by declaring
#define BITS_PER_BYTE 8
#define BITS_IN(x) (BITS_PER_BYTE * sizeof(x))
+/* Compute offsets of struct fields
+ */
+#define STG_FIELD_OFFSET(s_type, field) ((StgWord)&(((s_type*)0)->field))
+
/*
* 'Portable' inlining:
* INLINE_HEADER is for inline functions in header files (macros)
// __attribute__((gnu_inline)). So when we don't have this, we use
// ordinary static inline.
//
-#if defined(__GNUC_GNU_INLINE__)
+// Apple's gcc defines __GNUC_GNU_INLINE__ without providing
+// gnu_inline, so we exclude MacOS X and fall through to the safe
+// version.
+//
+#if defined(__GNUC_GNU_INLINE__) && !defined(__APPLE__)
# if defined(KEEP_INLINES)
# define EXTERN_INLINE inline
# else
-------------------------------------------------------------------------- */
#include "MachDeps.h"
-#include "StgTypes.h"
+#include "stg/Types.h"
/* -----------------------------------------------------------------------------
Shorthand forms
typedef StgChar C_;
typedef StgWord W_;
typedef StgWord* P_;
-typedef P_* PP_;
typedef StgInt I_;
-typedef StgAddr A_;
-typedef const StgWord* D_;
+typedef StgWord StgWordArray[];
typedef StgFunPtr F_;
-typedef StgByteArray B_;
-typedef StgClosurePtr L_;
-typedef StgInt64 LI_;
-typedef StgWord64 LW_;
-
-#define IF_(f) static F_ GNUC3_ATTRIBUTE(used) f(void)
-#define FN_(f) F_ f(void)
-#define EF_(f) extern F_ f(void)
-
-typedef StgWord StgWordArray[];
#define EI_(X) extern StgWordArray (X) GNU_ATTRIBUTE(aligned (8))
#define II_(X) static StgWordArray (X) GNU_ATTRIBUTE(aligned (8))
+#define IF_(f) static StgFunPtr GNUC3_ATTRIBUTE(used) f(void)
+#define FN_(f) StgFunPtr f(void)
+#define EF_(f) extern StgFunPtr f(void)
/* -----------------------------------------------------------------------------
Tail calls
to be before all procedures (inline & out-of-line).
-------------------------------------------------------------------------- */
-#include "TailCalls.h"
+#include "stg/TailCalls.h"
/* -----------------------------------------------------------------------------
Other Stg stuff...
-------------------------------------------------------------------------- */
-#include "StgDLL.h"
-#include "MachRegs.h"
-#include "Regs.h"
-
-#ifdef TICKY_TICKY
-#include "TickyCounters.h"
-#endif
+#include "stg/DLL.h"
+#include "stg/MachRegs.h"
+#include "stg/Regs.h"
+#include "stg/Ticky.h"
#if IN_STG_CODE
/*
* This is included later for RTS sources, after definitions of
* StgInfoTable, StgClosure and so on.
*/
-#include "StgMiscClosures.h"
+#include "stg/MiscClosures.h"
#endif
-#include "SMP.h" // write_barrier() inline is required
+#include "stg/SMP.h" // write_barrier() inline is required
/* -----------------------------------------------------------------------------
Moving Floats and Doubles
In both cases the memory location might not be 64-bit aligned.
-------------------------------------------------------------------------- */
-#ifdef SUPPORT_LONG_LONGS
+#if SIZEOF_HSWORD == 4
typedef struct
{ StgWord dhi;
return p_src[0];
}
-#endif
+#endif /* SIZEOF_HSWORD == 4 */
/* -----------------------------------------------------------------------------
Split markers