2c6bf4006fe66449f91541b9367bac6ed3143056
[ghc-hetmet.git] / ghc / includes / Stg.h
1 /* -----------------------------------------------------------------------------
2  * $Id: Stg.h,v 1.67 2005/02/01 14:14:41 simonmar Exp $
3  *
4  * (c) The GHC Team, 1998-2004
5  *
6  * Top-level include file for everything STG-ish.  
7  *
8  * This file is included *automatically* by all .hc files.
9  *
10  * NOTE: always include Stg.h *before* any other headers, because we
11  * define some register variables which must be done before any inline
12  * functions are defined (some system headers have been known to
13  * define the odd inline function).
14  *
15  * We generally try to keep as little visible as possible when
16  * compiling .hc files.  So for example the definitions of the
17  * InfoTable structs, closure structs and other RTS types are not
18  * visible here.  The compiler knows enough about the representations
19  * of these types to generate code which manipulates them directly
20  * with pointer arithmetic.
21  *
22  * ---------------------------------------------------------------------------*/
23
24 #ifndef STG_H
25 #define STG_H
26
27
28 /* If we include "Stg.h" directly, we're in STG code, and we therefore
29  * get all the global register variables, macros etc. that go along
30  * with that.  If "Stg.h" is included via "Rts.h", we're assumed to
31  * be in vanilla C.
32  */
33 #ifndef IN_STG_CODE
34 # define IN_STG_CODE 1
35 #endif
36
37 #if IN_STG_CODE == 0
38 # define NO_GLOBAL_REG_DECLS    /* don't define fixed registers */
39 #endif
40
41 /* Configuration */
42 #include "ghcconfig.h"
43 #include "RtsConfig.h"
44
45 /* -----------------------------------------------------------------------------
46    Useful definitions
47    -------------------------------------------------------------------------- */
48
49 /*
50  * The C backend like to refer to labels by just mentioning their
51  * names.  Howevver, when a symbol is declared as a variable in C, the
52  * C compiler will implicitly dereference it when it occurs in source.
53  * So we must subvert this behaviour for .hc files by declaring
54  * variables as arrays, which eliminates the implicit dereference.
55  */
56 #if IN_STG_CODE
57 #define RTS_VAR(x) (x)[]
58 #define RTS_DEREF(x) (*(x))
59 #else
60 #define RTS_VAR(x) x
61 #define RTS_DEREF(x) x
62 #endif
63
64 /* bit macros
65  */
66 #define BITS_PER_BYTE 8
67 #define BITS_IN(x) (BITS_PER_BYTE * sizeof(x))
68
69 /*
70  * 'Portable' inlining
71  */
72 #if defined(__GNUC__) || defined( __INTEL_COMPILER)
73 # define INLINE_HEADER static inline
74 # define INLINE_ME inline
75 # define STATIC_INLINE INLINE_HEADER
76 #elif defined(_MSC_VER)
77 # define INLINE_HEADER __inline static
78 # define INLINE_ME __inline
79 # define STATIC_INLINE INLINE_HEADER
80 #else
81 # error "Don't know how to inline functions with your C compiler."
82 #endif
83
84 /*
85  * GCC attributes
86  */
87 #if defined(__GNUC__)
88 #define GNU_ATTRIBUTE(at) __attribute__((at))
89 #else
90 #define GNU_ATTRIBUTE(at)
91 #endif
92
93 #if __GNUC__ >= 3 
94 #define GNUC3_ATTRIBUTE(at) __attribute__((at))
95 #else
96 #define GNUC3_ATTRIBUTE(at)
97 #endif
98
99 #define STG_UNUSED    GNUC3_ATTRIBUTE(__unused__)
100
101 /* -----------------------------------------------------------------------------
102    Global type definitions
103    -------------------------------------------------------------------------- */
104
105 #include "MachDeps.h"
106 #include "StgTypes.h"
107
108 /* -----------------------------------------------------------------------------
109    Shorthand forms
110    -------------------------------------------------------------------------- */
111
112 typedef StgChar         C_;
113 typedef StgWord         W_;
114 typedef StgWord*        P_;
115 typedef P_*             PP_;
116 typedef StgInt          I_;
117 typedef StgAddr         A_;
118 typedef const StgWord*  D_;
119 typedef StgFunPtr       F_;
120 typedef StgByteArray    B_;
121 typedef StgClosurePtr   L_;
122
123 typedef StgInt64        LI_;
124 typedef StgWord64       LW_;
125
126 #define IF_(f)          static F_ GNUC3_ATTRIBUTE(used) f(void) 
127 #define FN_(f)          F_ f(void)
128 #define EF_(f)          extern F_ f(void)
129
130 typedef StgWord StgWordArray[];
131 #define EI_             extern StgWordArray
132 #define II_             static StgWordArray
133
134 /* -----------------------------------------------------------------------------
135    Tail calls
136
137    This needs to be up near the top as the register line on alpha needs
138    to be before all procedures (inline & out-of-line).
139    -------------------------------------------------------------------------- */
140
141 #include "TailCalls.h"
142
143 /* -----------------------------------------------------------------------------
144    Other Stg stuff...
145    -------------------------------------------------------------------------- */
146
147 #include "StgDLL.h"
148 #include "MachRegs.h"
149 #include "Regs.h"
150 #include "StgProf.h"  /* ToDo: separate out RTS-only stuff from here */
151
152 #if IN_STG_CODE
153 /*
154  * This is included later for RTS sources, after definitions of
155  * StgInfoTable, StgClosure and so on. 
156  */
157 #include "StgMiscClosures.h"
158 #endif
159
160 /* RTS external interface */
161 #include "RtsExternal.h"
162
163 /* -----------------------------------------------------------------------------
164    Moving Floats and Doubles
165
166    ASSIGN_FLT is for assigning a float to memory (usually the
167               stack/heap).  The memory address is guaranteed to be
168               StgWord aligned (currently == sizeof(void *)).
169
170    PK_FLT     is for pulling a float out of memory.  The memory is
171               guaranteed to be StgWord aligned.
172    -------------------------------------------------------------------------- */
173
174 INLINE_HEADER void        ASSIGN_FLT (W_ [], StgFloat);
175 INLINE_HEADER StgFloat    PK_FLT     (W_ []);
176
177 #if ALIGNMENT_FLOAT <= ALIGNMENT_LONG
178
179 INLINE_HEADER void     ASSIGN_FLT(W_ p_dest[], StgFloat src) { *(StgFloat *)p_dest = src; }
180 INLINE_HEADER StgFloat PK_FLT    (W_ p_src[])                { return *(StgFloat *)p_src; }
181
182 #else  /* ALIGNMENT_FLOAT > ALIGNMENT_UNSIGNED_INT */
183
184 INLINE_HEADER void ASSIGN_FLT(W_ p_dest[], StgFloat src)
185 {
186     float_thing y;
187     y.f = src;
188     *p_dest = y.fu;
189 }
190
191 INLINE_HEADER StgFloat PK_FLT(W_ p_src[])
192 {
193     float_thing y;
194     y.fu = *p_src;
195     return(y.f);
196 }
197
198 #endif /* ALIGNMENT_FLOAT > ALIGNMENT_LONG */
199
200 #if ALIGNMENT_DOUBLE <= ALIGNMENT_LONG
201
202 INLINE_HEADER void        ASSIGN_DBL (W_ [], StgDouble);
203 INLINE_HEADER StgDouble   PK_DBL     (W_ []);
204
205 INLINE_HEADER void      ASSIGN_DBL(W_ p_dest[], StgDouble src) { *(StgDouble *)p_dest = src; }
206 INLINE_HEADER StgDouble PK_DBL    (W_ p_src[])                 { return *(StgDouble *)p_src; }
207
208 #else   /* ALIGNMENT_DOUBLE > ALIGNMENT_LONG */
209
210 /* Sparc uses two floating point registers to hold a double.  We can
211  * write ASSIGN_DBL and PK_DBL by directly accessing the registers
212  * independently - unfortunately this code isn't writable in C, we
213  * have to use inline assembler.
214  */
215 #if sparc_HOST_ARCH
216
217 #define ASSIGN_DBL(dst0,src) \
218     { StgPtr dst = (StgPtr)(dst0); \
219       __asm__("st %2,%0\n\tst %R2,%1" : "=m" (((P_)(dst))[0]), \
220         "=m" (((P_)(dst))[1]) : "f" (src)); \
221     }
222
223 #define PK_DBL(src0) \
224     ( { StgPtr src = (StgPtr)(src0); \
225         register double d; \
226       __asm__("ld %1,%0\n\tld %2,%R0" : "=f" (d) : \
227         "m" (((P_)(src))[0]), "m" (((P_)(src))[1])); d; \
228     } )
229
230 #else /* ! sparc_HOST_ARCH */
231
232 INLINE_HEADER void        ASSIGN_DBL (W_ [], StgDouble);
233 INLINE_HEADER StgDouble   PK_DBL     (W_ []);
234
235 typedef struct
236   { StgWord dhi;
237     StgWord dlo;
238   } unpacked_double;
239
240 typedef union
241   { StgDouble d;
242     unpacked_double du;
243   } double_thing;
244
245 INLINE_HEADER void ASSIGN_DBL(W_ p_dest[], StgDouble src)
246 {
247     double_thing y;
248     y.d = src;
249     p_dest[0] = y.du.dhi;
250     p_dest[1] = y.du.dlo;
251 }
252
253 /* GCC also works with this version, but it generates
254    the same code as the previous one, and is not ANSI
255
256 #define ASSIGN_DBL( p_dest, src ) \
257         *p_dest = ((double_thing) src).du.dhi; \
258         *(p_dest+1) = ((double_thing) src).du.dlo \
259 */
260
261 INLINE_HEADER StgDouble PK_DBL(W_ p_src[])
262 {
263     double_thing y;
264     y.du.dhi = p_src[0];
265     y.du.dlo = p_src[1];
266     return(y.d);
267 }
268
269 #endif /* ! sparc_HOST_ARCH */
270
271 #endif /* ALIGNMENT_DOUBLE > ALIGNMENT_UNSIGNED_INT */
272
273
274 /* -----------------------------------------------------------------------------
275    Moving 64-bit quantities around
276
277    ASSIGN_Word64      assign an StgWord64/StgInt64 to a memory location
278    PK_Word64          load an StgWord64/StgInt64 from a amemory location
279
280    In both cases the memory location might not be 64-bit aligned.
281    -------------------------------------------------------------------------- */
282
283 #ifdef SUPPORT_LONG_LONGS
284
285 typedef struct
286   { StgWord dhi;
287     StgWord dlo;
288   } unpacked_double_word;
289
290 typedef union
291   { StgInt64 i;
292     unpacked_double_word iu;
293   } int64_thing;
294
295 typedef union
296   { StgWord64 w;
297     unpacked_double_word wu;
298   } word64_thing;
299
300 INLINE_HEADER void ASSIGN_Word64(W_ p_dest[], StgWord64 src)
301 {
302     word64_thing y;
303     y.w = src;
304     p_dest[0] = y.wu.dhi;
305     p_dest[1] = y.wu.dlo;
306 }
307
308 INLINE_HEADER StgWord64 PK_Word64(W_ p_src[])
309 {
310     word64_thing y;
311     y.wu.dhi = p_src[0];
312     y.wu.dlo = p_src[1];
313     return(y.w);
314 }
315
316 INLINE_HEADER void ASSIGN_Int64(W_ p_dest[], StgInt64 src)
317 {
318     int64_thing y;
319     y.i = src;
320     p_dest[0] = y.iu.dhi;
321     p_dest[1] = y.iu.dlo;
322 }
323
324 INLINE_HEADER StgInt64 PK_Int64(W_ p_src[])
325 {
326     int64_thing y;
327     y.iu.dhi = p_src[0];
328     y.iu.dlo = p_src[1];
329     return(y.i);
330 }
331
332 #elif SIZEOF_VOID_P == 8
333
334 INLINE_HEADER void ASSIGN_Word64(W_ p_dest[], StgWord64 src)
335 {
336         p_dest[0] = src;
337 }
338
339 INLINE_HEADER StgWord64 PK_Word64(W_ p_src[])
340 {
341     return p_src[0];
342 }
343
344 INLINE_HEADER void ASSIGN_Int64(W_ p_dest[], StgInt64 src)
345 {
346     p_dest[0] = src;
347 }
348
349 INLINE_HEADER StgInt64 PK_Int64(W_ p_src[])
350 {
351     return p_src[0];
352 }
353
354 #endif
355
356 /* -----------------------------------------------------------------------------
357    Split markers
358    -------------------------------------------------------------------------- */
359
360 #if defined(USE_SPLIT_MARKERS)
361 #if defined(LEADING_UNDERSCORE)
362 #define __STG_SPLIT_MARKER __asm__("\n___stg_split_marker:");
363 #else
364 #define __STG_SPLIT_MARKER __asm__("\n__stg_split_marker:");
365 #endif
366 #else
367 #define __STG_SPLIT_MARKER /* nothing */
368 #endif
369
370 /* -----------------------------------------------------------------------------
371    Integer multiply with overflow
372    -------------------------------------------------------------------------- */
373
374 /* Multiply with overflow checking.
375  *
376  * This is tricky - the usual sign rules for add/subtract don't apply.  
377  *
378  * On 32-bit machines we use gcc's 'long long' types, finding
379  * overflow with some careful bit-twiddling.
380  *
381  * On 64-bit machines where gcc's 'long long' type is also 64-bits,
382  * we use a crude approximation, testing whether either operand is
383  * larger than 32-bits; if neither is, then we go ahead with the
384  * multiplication.
385  *
386  * Return non-zero if there is any possibility that the signed multiply
387  * of a and b might overflow.  Return zero only if you are absolutely sure
388  * that it won't overflow.  If in doubt, return non-zero.
389  */
390
391 #if SIZEOF_VOID_P == 4
392
393 #ifdef WORDS_BIGENDIAN
394 #define RTS_CARRY_IDX__ 0
395 #define RTS_REM_IDX__  1
396 #else
397 #define RTS_CARRY_IDX__ 1
398 #define RTS_REM_IDX__ 0
399 #endif
400
401 typedef union {
402     StgInt64 l;
403     StgInt32 i[2];
404 } long_long_u ;
405
406 #define mulIntMayOflo(a,b)                      \
407 ({                                              \
408   StgInt32 r, c;                                \
409   long_long_u z;                                \
410   z.l = (StgInt64)a * (StgInt64)b;              \
411   r = z.i[RTS_REM_IDX__];                       \
412   c = z.i[RTS_CARRY_IDX__];                     \
413   if (c == 0 || c == -1) {                      \
414     c = ((StgWord)((a^b) ^ r))                  \
415       >> (BITS_IN (I_) - 1);                    \
416   }                                             \
417   c;                                            \
418 })
419
420 /* Careful: the carry calculation above is extremely delicate.  Make sure
421  * you test it thoroughly after changing it.
422  */
423
424 #else
425
426 #define HALF_INT  (((I_)1) << (BITS_IN (I_) / 2))
427
428 #define stg_abs(a) (((I_)(a)) < 0 ? -((I_)(a)) : ((I_)(a)))
429
430 #define mulIntMayOflo(a,b)                      \
431 ({                                              \
432   I_ c;                                         \
433   if (stg_abs(a) >= HALF_INT ||                 \
434       stg_abs(b) >= HALF_INT) {                 \
435     c = 1;                                      \
436   } else {                                      \
437     c = 0;                                      \
438   }                                             \
439   c;                                            \
440 })
441 #endif
442
443 #endif /* STG_H */