Stg.h 16.3 KB
Newer Older
1
/* -----------------------------------------------------------------------------
2
 *
3
 * (c) The GHC Team, 1998-2009
4
 *
5
6
7
8
9
 * 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).
10
 *
11
12
13
14
15
16
17
 * We generally try to keep as little visible as possible when
 * compiling .hc files.  So for example the definitions of the
 * InfoTable structs, closure structs and other RTS types are not
 * visible here.  The compiler knows enough about the representations
 * of these types to generate code which manipulates them directly
 * with pointer arithmetic.
 *
18
19
20
21
 * 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:
22
 *   http://ghc.haskell.org/trac/ghc/wiki/Commentary/SourceTree/Includes
23
 *
24
25
26
27
28
 * ---------------------------------------------------------------------------*/

#ifndef STG_H
#define STG_H

Simon Marlow's avatar
Simon Marlow committed
29
30
31
32
33
34
35
36
37
38
/*
 * 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.
39
 */
40
41
#ifndef IN_STG_CODE
# define IN_STG_CODE 1
Ian Lynagh's avatar
Ian Lynagh committed
42

43
44
// 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)
Ian Lynagh's avatar
Ian Lynagh committed
45
# define _ISOC99_SOURCE
Ian Lynagh's avatar
Ian Lynagh committed
46
47
48
49

// We need _BSD_SOURCE so that math.h defines things like gamma
// on Linux
# define _BSD_SOURCE
50

51
52
53
54
55
// On AIX we need _BSD defined, otherwise <math.h> includes <stdlib.h>
# if defined(_AIX)
#  define _BSD 1
# endif

56
57
58
// '_BSD_SOURCE' is deprecated since glibc-2.20
// in favour of '_DEFAULT_SOURCE'
# define _DEFAULT_SOURCE
59
60
#endif

61
62
63
64
#if IN_STG_CODE == 0 || defined(llvm_CC_FLAVOR)
// C compilers that use an LLVM back end (clang or llvm-gcc) do not
// correctly support global register variables so we make sure that
// we do not declare them for these compilers.
65
# define NO_GLOBAL_REG_DECLS    /* don't define fixed registers */
66
67
#endif

68
/* Configuration */
69
#include "ghcconfig.h"
sof's avatar
sof committed
70

71
72
73
74
75
/* 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>

76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
// 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

97
98
99
/* -----------------------------------------------------------------------------
   Useful definitions
   -------------------------------------------------------------------------- */
100

101
/*
Simon Marlow's avatar
Simon Marlow committed
102
 * The C backend likes to refer to labels by just mentioning their
Ian Lynagh's avatar
Ian Lynagh committed
103
 * names.  However, when a symbol is declared as a variable in C, the
104
105
106
 * C compiler will implicitly dereference it when it occurs in source.
 * So we must subvert this behaviour for .hc files by declaring
 * variables as arrays, which eliminates the implicit dereference.
107
 */
108
109
110
#if IN_STG_CODE
#define RTS_VAR(x) (x)[]
#define RTS_DEREF(x) (*(x))
111
#else
112
113
#define RTS_VAR(x) x
#define RTS_DEREF(x) x
114
115
#endif

116
/* bit macros
sof's avatar
sof committed
117
 */
118
119
#define BITS_PER_BYTE 8
#define BITS_IN(x) (BITS_PER_BYTE * sizeof(x))
sof's avatar
sof committed
120

121
122
/* Compute offsets of struct fields
 */
Ian Lynagh's avatar
Ian Lynagh committed
123
#define STG_FIELD_OFFSET(s_type, field) ((StgWord)&(((s_type*)0)->field))
124

sof's avatar
sof committed
125
/*
126
 * 'Portable' inlining:
Simon Marlow's avatar
Simon Marlow committed
127
 * INLINE_HEADER is for inline functions in header files (macros)
128
 * STATIC_INLINE is for inline functions in source files
dterei's avatar
dterei committed
129
 * EXTERN_INLINE is for functions that we want to inline sometimes
130
 * (we also compile a static version of the function; see Inlines.c)
sof's avatar
sof committed
131
 */
132
#if defined(__GNUC__) || defined( __INTEL_COMPILER)
Simon Marlow's avatar
Simon Marlow committed
133

sof's avatar
sof committed
134
135
136
# define INLINE_HEADER static inline
# define INLINE_ME inline
# define STATIC_INLINE INLINE_HEADER
Simon Marlow's avatar
Simon Marlow committed
137

138
139
140
141
142
// 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.
//
143
144
145
146
147
// 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__)
148
149
150
151
152
153
154
155
156
157
158
159
#  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
Simon Marlow's avatar
Simon Marlow committed
160

sof's avatar
sof committed
161
#elif defined(_MSC_VER)
Simon Marlow's avatar
Simon Marlow committed
162

sof's avatar
sof committed
163
164
165
# define INLINE_HEADER __inline static
# define INLINE_ME __inline
# define STATIC_INLINE INLINE_HEADER
Simon Marlow's avatar
Simon Marlow committed
166
167
168
169
170
171
172

# if defined(KEEP_INLINES)
#  define EXTERN_INLINE __inline
# else
#  define EXTERN_INLINE __inline extern
# endif

sof's avatar
sof committed
173
#else
Simon Marlow's avatar
Simon Marlow committed
174

sof's avatar
sof committed
175
# error "Don't know how to inline functions with your C compiler."
Simon Marlow's avatar
Simon Marlow committed
176

sof's avatar
sof committed
177
178
#endif

Simon Marlow's avatar
Simon Marlow committed
179

180
181
182
183
184
185
186
187
188
/*
 * GCC attributes
 */
#if defined(__GNUC__)
#define GNU_ATTRIBUTE(at) __attribute__((at))
#else
#define GNU_ATTRIBUTE(at)
#endif

dterei's avatar
dterei committed
189
#if __GNUC__ >= 3
190
191
192
193
194
#define GNUC3_ATTRIBUTE(at) __attribute__((at))
#else
#define GNUC3_ATTRIBUTE(at)
#endif

Simon Marlow's avatar
Simon Marlow committed
195
196
197
198
199
200
#if __GNUC__ > 4 || __GNUC__ == 4 && __GNUC_MINOR__ >= 3
#define GNUC_ATTR_HOT __attribute__((hot))
#else
#define GNUC_ATTR_HOT /* nothing */
#endif

201
202
#define STG_UNUSED    GNUC3_ATTRIBUTE(__unused__)

203
/* -----------------------------------------------------------------------------
204
   Global type definitions
205
206
   -------------------------------------------------------------------------- */

207
#include "MachDeps.h"
Simon Marlow's avatar
Simon Marlow committed
208
#include "stg/Types.h"
209

210
211
212
213
/* -----------------------------------------------------------------------------
   Shorthand forms
   -------------------------------------------------------------------------- */

dterei's avatar
dterei committed
214
215
216
217
typedef StgChar      C_;
typedef StgWord      W_;
typedef StgWord*  P_;
typedef StgInt    I_;
218
typedef StgWord StgWordArray[];
219
typedef StgFunPtr       F_;
Simon Marlow's avatar
Simon Marlow committed
220

221
222
#define EI_(X)          extern StgWordArray (X) GNU_ATTRIBUTE(aligned (8))
#define II_(X)          static StgWordArray (X) GNU_ATTRIBUTE(aligned (8))
dterei's avatar
dterei committed
223
224
#define IF_(f)    static StgFunPtr GNUC3_ATTRIBUTE(used) f(void)
#define FN_(f)    StgFunPtr f(void)
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
#define EF_(f)    extern StgFunPtr f()   /* See Note [External function prototypes] */

/* Note [External function prototypes]  See Trac #8965
   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The external-function macro EF_(F) used to be defined as
    extern StgFunPtr f(void)
i.e a function of zero arguments.  On most platforms this doesn't
matter very much: calls to these functions put the parameters in the
usual places anyway, and (with the exception of varargs) things just
work.

However, the ELFv2 ABI on ppc64 optimises stack allocation
(http://gcc.gnu.org/ml/gcc-patches/2013-11/msg01149.html): a call to a
function that has a prototype, is not varargs, and receives all parameters
in registers rather than on the stack does not require the caller to
allocate an argument save area.  The incorrect prototypes cause GCC to
believe that all functions declared this way can be called without an
argument save area, but if the callee has sufficiently many arguments then
it will expect that area to be present, and will thus corrupt the caller's
stack.  This happens in particular with calls to runInteractiveProcess in
libraries/process/cbits/runProcess.c, and led to Trac #8965.

The simplest fix appears to be to declare these external functions with an
unspecified argument list rather than a void argument list.  This is no
worse for platforms that don't care either way, and allows a successful
bootstrap of GHC 7.8 on little-endian Linux ppc64 (which uses the ELFv2
ABI).
*/

254

255
256
257
/* -----------------------------------------------------------------------------
   Tail calls
   -------------------------------------------------------------------------- */
258

Simon Marlow's avatar
Simon Marlow committed
259
#define JMP_(cont) return((StgFunPtr)(cont))
260

261
262
263
264
/* -----------------------------------------------------------------------------
   Other Stg stuff...
   -------------------------------------------------------------------------- */

Simon Marlow's avatar
Simon Marlow committed
265
#include "stg/DLL.h"
266
#include "stg/RtsMachRegs.h"
Simon Marlow's avatar
Simon Marlow committed
267
268
#include "stg/Regs.h"
#include "stg/Ticky.h"
Ian Lynagh's avatar
Ian Lynagh committed
269

270
271
272
#if IN_STG_CODE
/*
 * This is included later for RTS sources, after definitions of
dterei's avatar
dterei committed
273
 * StgInfoTable, StgClosure and so on.
274
 */
Simon Marlow's avatar
Simon Marlow committed
275
#include "stg/MiscClosures.h"
276
277
#endif

278
#include "stg/Prim.h" /* ghc-prim fallbacks */
dterei's avatar
dterei committed
279
#include "stg/SMP.h" // write_barrier() inline is required
280

281
/* -----------------------------------------------------------------------------
282
283
284
285
   Moving Floats and Doubles

   ASSIGN_FLT is for assigning a float to memory (usually the
              stack/heap).  The memory address is guaranteed to be
dterei's avatar
dterei committed
286
         StgWord aligned (currently == sizeof(void *)).
287
288
289

   PK_FLT     is for pulling a float out of memory.  The memory is
              guaranteed to be StgWord aligned.
290
291
   -------------------------------------------------------------------------- */

dterei's avatar
dterei committed
292
INLINE_HEADER void     ASSIGN_FLT (W_ [], StgFloat);
293
INLINE_HEADER StgFloat    PK_FLT     (W_ []);
294

Ian Lynagh's avatar
Ian Lynagh committed
295
#if ALIGNMENT_FLOAT <= ALIGNMENT_VOID_P
296

297
298
INLINE_HEADER void     ASSIGN_FLT(W_ p_dest[], StgFloat src) { *(StgFloat *)p_dest = src; }
INLINE_HEADER StgFloat PK_FLT    (W_ p_src[])                { return *(StgFloat *)p_src; }
299

300
#else  /* ALIGNMENT_FLOAT > ALIGNMENT_UNSIGNED_INT */
301

302
303
304
305
306
307
INLINE_HEADER void ASSIGN_FLT(W_ p_dest[], StgFloat src)
{
    float_thing y;
    y.f = src;
    *p_dest = y.fu;
}
308

309
310
311
312
313
314
315
INLINE_HEADER StgFloat PK_FLT(W_ p_src[])
{
    float_thing y;
    y.fu = *p_src;
    return(y.f);
}

Ian Lynagh's avatar
Ian Lynagh committed
316
#endif /* ALIGNMENT_FLOAT > ALIGNMENT_VOID_P */
317

Ian Lynagh's avatar
Ian Lynagh committed
318
#if ALIGNMENT_DOUBLE <= ALIGNMENT_VOID_P
319

dterei's avatar
dterei committed
320
INLINE_HEADER void     ASSIGN_DBL (W_ [], StgDouble);
321
INLINE_HEADER StgDouble   PK_DBL     (W_ []);
322

323
324
INLINE_HEADER void      ASSIGN_DBL(W_ p_dest[], StgDouble src) { *(StgDouble *)p_dest = src; }
INLINE_HEADER StgDouble PK_DBL    (W_ p_src[])                 { return *(StgDouble *)p_src; }
sof's avatar
sof committed
325

Ian Lynagh's avatar
Ian Lynagh committed
326
#else /* ALIGNMENT_DOUBLE > ALIGNMENT_VOID_P */
327
328
329
330
331

/* Sparc uses two floating point registers to hold a double.  We can
 * write ASSIGN_DBL and PK_DBL by directly accessing the registers
 * independently - unfortunately this code isn't writable in C, we
 * have to use inline assembler.
332
 */
333
#if sparc_HOST_ARCH
334
335
336
337

#define ASSIGN_DBL(dst0,src) \
    { StgPtr dst = (StgPtr)(dst0); \
      __asm__("st %2,%0\n\tst %R2,%1" : "=m" (((P_)(dst))[0]), \
dterei's avatar
dterei committed
338
   "=m" (((P_)(dst))[1]) : "f" (src)); \
339
340
341
342
343
344
    }

#define PK_DBL(src0) \
    ( { StgPtr src = (StgPtr)(src0); \
        register double d; \
      __asm__("ld %1,%0\n\tld %2,%R0" : "=f" (d) : \
dterei's avatar
dterei committed
345
   "m" (((P_)(src))[0]), "m" (((P_)(src))[1])); d; \
346
347
    } )

348
#else /* ! sparc_HOST_ARCH */
349

dterei's avatar
dterei committed
350
INLINE_HEADER void     ASSIGN_DBL (W_ [], StgDouble);
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
INLINE_HEADER StgDouble   PK_DBL     (W_ []);

typedef struct
  { StgWord dhi;
    StgWord dlo;
  } unpacked_double;

typedef union
  { StgDouble d;
    unpacked_double du;
  } double_thing;

INLINE_HEADER void ASSIGN_DBL(W_ p_dest[], StgDouble src)
{
    double_thing y;
    y.d = src;
    p_dest[0] = y.du.dhi;
    p_dest[1] = y.du.dlo;
}

/* GCC also works with this version, but it generates
   the same code as the previous one, and is not ANSI

#define ASSIGN_DBL( p_dest, src ) \
dterei's avatar
dterei committed
375
376
   *p_dest = ((double_thing) src).du.dhi; \
   *(p_dest+1) = ((double_thing) src).du.dlo \
377
*/
378

379
380
381
382
383
384
385
INLINE_HEADER StgDouble PK_DBL(W_ p_src[])
{
    double_thing y;
    y.du.dhi = p_src[0];
    y.du.dlo = p_src[1];
    return(y.d);
}
386

387
#endif /* ! sparc_HOST_ARCH */
388

389
#endif /* ALIGNMENT_DOUBLE > ALIGNMENT_UNSIGNED_INT */
390
391


392
393
394
395
396
397
398
399
400
/* -----------------------------------------------------------------------------
   Moving 64-bit quantities around

   ASSIGN_Word64      assign an StgWord64/StgInt64 to a memory location
   PK_Word64          load an StgWord64/StgInt64 from a amemory location

   In both cases the memory location might not be 64-bit aligned.
   -------------------------------------------------------------------------- */

Simon Marlow's avatar
Simon Marlow committed
401
#if SIZEOF_HSWORD == 4
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453

typedef struct
  { StgWord dhi;
    StgWord dlo;
  } unpacked_double_word;

typedef union
  { StgInt64 i;
    unpacked_double_word iu;
  } int64_thing;

typedef union
  { StgWord64 w;
    unpacked_double_word wu;
  } word64_thing;

INLINE_HEADER void ASSIGN_Word64(W_ p_dest[], StgWord64 src)
{
    word64_thing y;
    y.w = src;
    p_dest[0] = y.wu.dhi;
    p_dest[1] = y.wu.dlo;
}

INLINE_HEADER StgWord64 PK_Word64(W_ p_src[])
{
    word64_thing y;
    y.wu.dhi = p_src[0];
    y.wu.dlo = p_src[1];
    return(y.w);
}

INLINE_HEADER void ASSIGN_Int64(W_ p_dest[], StgInt64 src)
{
    int64_thing y;
    y.i = src;
    p_dest[0] = y.iu.dhi;
    p_dest[1] = y.iu.dlo;
}

INLINE_HEADER StgInt64 PK_Int64(W_ p_src[])
{
    int64_thing y;
    y.iu.dhi = p_src[0];
    y.iu.dlo = p_src[1];
    return(y.i);
}

#elif SIZEOF_VOID_P == 8

INLINE_HEADER void ASSIGN_Word64(W_ p_dest[], StgWord64 src)
{
dterei's avatar
dterei committed
454
   p_dest[0] = src;
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
}

INLINE_HEADER StgWord64 PK_Word64(W_ p_src[])
{
    return p_src[0];
}

INLINE_HEADER void ASSIGN_Int64(W_ p_dest[], StgInt64 src)
{
    p_dest[0] = src;
}

INLINE_HEADER StgInt64 PK_Int64(W_ p_src[])
{
    return p_src[0];
}

Simon Marlow's avatar
Simon Marlow committed
472
#endif /* SIZEOF_HSWORD == 4 */
473
474
475
476

/* -----------------------------------------------------------------------------
   Split markers
   -------------------------------------------------------------------------- */
477

478
479
480
481
482
483
484
485
486
487
488
489
490
#if defined(USE_SPLIT_MARKERS)
#if defined(LEADING_UNDERSCORE)
#define __STG_SPLIT_MARKER __asm__("\n___stg_split_marker:");
#else
#define __STG_SPLIT_MARKER __asm__("\n__stg_split_marker:");
#endif
#else
#define __STG_SPLIT_MARKER /* nothing */
#endif

/* -----------------------------------------------------------------------------
   Integer multiply with overflow
   -------------------------------------------------------------------------- */
491

492
493
/* Multiply with overflow checking.
 *
dterei's avatar
dterei committed
494
 * This is tricky - the usual sign rules for add/subtract don't apply.
495
496
497
498
499
500
501
502
503
504
505
506
507
 *
 * On 32-bit machines we use gcc's 'long long' types, finding
 * overflow with some careful bit-twiddling.
 *
 * On 64-bit machines where gcc's 'long long' type is also 64-bits,
 * we use a crude approximation, testing whether either operand is
 * larger than 32-bits; if neither is, then we go ahead with the
 * multiplication.
 *
 * Return non-zero if there is any possibility that the signed multiply
 * of a and b might overflow.  Return zero only if you are absolutely sure
 * that it won't overflow.  If in doubt, return non-zero.
 */
508

509
#if SIZEOF_VOID_P == 4
510

511
512
513
514
515
516
#ifdef WORDS_BIGENDIAN
#define RTS_CARRY_IDX__ 0
#define RTS_REM_IDX__  1
#else
#define RTS_CARRY_IDX__ 1
#define RTS_REM_IDX__ 0
sof's avatar
sof committed
517
518
#endif

519
520
521
522
523
typedef union {
    StgInt64 l;
    StgInt32 i[2];
} long_long_u ;

dterei's avatar
dterei committed
524
#define mulIntMayOflo(a,b)       \
525
({                                              \
dterei's avatar
dterei committed
526
527
528
529
530
531
532
533
534
  StgInt32 r, c;           \
  long_long_u z;           \
  z.l = (StgInt64)a * (StgInt64)b;     \
  r = z.i[RTS_REM_IDX__];        \
  c = z.i[RTS_CARRY_IDX__];         \
  if (c == 0 || c == -1) {       \
    c = ((StgWord)((a^b) ^ r))         \
      >> (BITS_IN (I_) - 1);        \
  }                  \
535
536
537
538
539
540
541
542
543
  c;                                            \
})

/* Careful: the carry calculation above is extremely delicate.  Make sure
 * you test it thoroughly after changing it.
 */

#else

544
/* Approximate version when we don't have long arithmetic (on 64-bit archs) */
545

546
547
548
/* If we have n-bit words then we have n-1 bits after accounting for the
 * sign bit, so we can fit the result of multiplying 2 (n-1)/2-bit numbers */
#define HALF_POS_INT  (((I_)1) << ((BITS_IN (I_) - 1) / 2))
549
#define HALF_NEG_INT  (-HALF_POS_INT)
550

dterei's avatar
dterei committed
551
#define mulIntMayOflo(a,b)       \
552
({                                              \
dterei's avatar
dterei committed
553
  I_ c;              \
554
555
  if ((I_)a <= HALF_NEG_INT || a >= HALF_POS_INT    \
      || (I_)b <= HALF_NEG_INT || b >= HALF_POS_INT) {\
dterei's avatar
dterei committed
556
557
558
559
    c = 1;              \
  } else {              \
    c = 0;              \
  }                  \
560
561
562
  c;                                            \
})
#endif
sof's avatar
sof committed
563

564
#endif /* STG_H */