/* -----------------------------------------------------------------------------
*
- * (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
-# define _ISOC99_SOURCE
+
// Turn on C99 for .hc code. This gives us the INFINITY and NAN
// constants from math.h, which we occasionally need to use in .hc (#1861)
+# define _ISOC99_SOURCE
+
+// We need _BSD_SOURCE so that math.h defines things like gamma
+// on Linux
+# define _BSD_SOURCE
#endif
#if IN_STG_CODE == 0
/* 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)
* STATIC_INLINE is for inline functions in source files
- * EXTERN_INLINE is for functions that we want to inline sometimes
+ * EXTERN_INLINE is for functions that we want to inline sometimes
+ * (we also compile a static version of the function; see Inlines.c)
*/
#if defined(__GNUC__) || defined( __INTEL_COMPILER)
# define INLINE_ME inline
# define STATIC_INLINE INLINE_HEADER
-# if defined(KEEP_INLINES)
-# define EXTERN_INLINE inline
-# else
-# define EXTERN_INLINE extern inline
-# endif
+// The special "extern inline" behaviour is now only supported by gcc
+// when _GNUC_GNU_INLINE__ is defined, and you have to use
+// __attribute__((gnu_inline)). So when we don't have this, we use
+// ordinary static 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
+# define EXTERN_INLINE extern inline __attribute__((gnu_inline))
+# endif
+#else
+# if defined(KEEP_INLINES)
+# define EXTERN_INLINE
+# else
+# define EXTERN_INLINE INLINE_HEADER
+# endif
+#endif
#elif defined(_MSC_VER)
-------------------------------------------------------------------------- */
#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