Add support for 256-bit-wide vectors.
[ghc.git] / includes / Cmm.h
1 /* -----------------------------------------------------------------------------
2 *
3 * (c) The University of Glasgow 2004-2013
4 *
5 * This file is included at the top of all .cmm source files (and
6 * *only* .cmm files). It defines a collection of useful macros for
7 * making .cmm code a bit less error-prone to write, and a bit easier
8 * on the eye for the reader.
9 *
10 * For the syntax of .cmm files, see the parser in ghc/compiler/cmm/CmmParse.y.
11 *
12 * Accessing fields of structures defined in the RTS header files is
13 * done via automatically-generated macros in DerivedConstants.h. For
14 * example, where previously we used
15 *
16 * CurrentTSO->what_next = x
17 *
18 * in C-- we now use
19 *
20 * StgTSO_what_next(CurrentTSO) = x
21 *
22 * where the StgTSO_what_next() macro is automatically generated by
23 * mkDerivedConstants.c. If you need to access a field that doesn't
24 * already have a macro, edit that file (it's pretty self-explanatory).
25 *
26 * -------------------------------------------------------------------------- */
27
28 #ifndef CMM_H
29 #define CMM_H
30
31 /*
32 * In files that are included into both C and C-- (and perhaps
33 * Haskell) sources, we sometimes need to conditionally compile bits
34 * depending on the language. CMINUSMINUS==1 in .cmm sources:
35 */
36 #define CMINUSMINUS 1
37
38 #include "ghcconfig.h"
39
40 /* -----------------------------------------------------------------------------
41 Types
42
43 The following synonyms for C-- types are declared here:
44
45 I8, I16, I32, I64 MachRep-style names for convenience
46
47 W_ is shorthand for the word type (== StgWord)
48 F_ shorthand for float (F_ == StgFloat == C's float)
49 D_ shorthand for double (D_ == StgDouble == C's double)
50
51 CInt has the same size as an int in C on this platform
52 CLong has the same size as a long in C on this platform
53
54 --------------------------------------------------------------------------- */
55
56 #define I8 bits8
57 #define I16 bits16
58 #define I32 bits32
59 #define I64 bits64
60 #define P_ gcptr
61
62 #if SIZEOF_VOID_P == 4
63 #define W_ bits32
64 /* Maybe it's better to include MachDeps.h */
65 #define TAG_BITS 2
66 #elif SIZEOF_VOID_P == 8
67 #define W_ bits64
68 /* Maybe it's better to include MachDeps.h */
69 #define TAG_BITS 3
70 #else
71 #error Unknown word size
72 #endif
73
74 /*
75 * The RTS must sometimes UNTAG a pointer before dereferencing it.
76 * See the wiki page Commentary/Rts/HaskellExecution/PointerTagging
77 */
78 #define TAG_MASK ((1 << TAG_BITS) - 1)
79 #define UNTAG(p) (p & ~TAG_MASK)
80 #define GETTAG(p) (p & TAG_MASK)
81
82 #if SIZEOF_INT == 4
83 #define CInt bits32
84 #elif SIZEOF_INT == 8
85 #define CInt bits64
86 #else
87 #error Unknown int size
88 #endif
89
90 #if SIZEOF_LONG == 4
91 #define CLong bits32
92 #elif SIZEOF_LONG == 8
93 #define CLong bits64
94 #else
95 #error Unknown long size
96 #endif
97
98 #define F_ float32
99 #define D_ float64
100 #define L_ bits64
101 #define V16_ bits128
102 #define V32_ bits256
103
104 #define SIZEOF_StgDouble 8
105 #define SIZEOF_StgWord64 8
106
107 /* -----------------------------------------------------------------------------
108 Misc useful stuff
109 -------------------------------------------------------------------------- */
110
111 #define ccall foreign "C"
112
113 #define NULL (0::W_)
114
115 #define STRING(name,str) \
116 section "rodata" { \
117 name : bits8[] str; \
118 } \
119
120 #ifdef TABLES_NEXT_TO_CODE
121 #define RET_LBL(f) f##_info
122 #else
123 #define RET_LBL(f) f##_ret
124 #endif
125
126 #ifdef TABLES_NEXT_TO_CODE
127 #define ENTRY_LBL(f) f##_info
128 #else
129 #define ENTRY_LBL(f) f##_entry
130 #endif
131
132 /* -----------------------------------------------------------------------------
133 Byte/word macros
134
135 Everything in C-- is in byte offsets (well, most things). We use
136 some macros to allow us to express offsets in words and to try to
137 avoid byte/word confusion.
138 -------------------------------------------------------------------------- */
139
140 #define SIZEOF_W SIZEOF_VOID_P
141 #define W_MASK (SIZEOF_W-1)
142
143 #if SIZEOF_W == 4
144 #define W_SHIFT 2
145 #elif SIZEOF_W == 8
146 #define W_SHIFT 3
147 #endif
148
149 /* Converting quantities of words to bytes */
150 #define WDS(n) ((n)*SIZEOF_W)
151
152 /*
153 * Converting quantities of bytes to words
154 * NB. these work on *unsigned* values only
155 */
156 #define BYTES_TO_WDS(n) ((n) / SIZEOF_W)
157 #define ROUNDUP_BYTES_TO_WDS(n) (((n) + SIZEOF_W - 1) / SIZEOF_W)
158
159 /* TO_W_(n) converts n to W_ type from a smaller type */
160 #if SIZEOF_W == 4
161 #define TO_W_(x) %sx32(x)
162 #define HALF_W_(x) %lobits16(x)
163 #elif SIZEOF_W == 8
164 #define TO_W_(x) %sx64(x)
165 #define HALF_W_(x) %lobits32(x)
166 #endif
167
168 #if SIZEOF_INT == 4 && SIZEOF_W == 8
169 #define W_TO_INT(x) %lobits32(x)
170 #elif SIZEOF_INT == SIZEOF_W
171 #define W_TO_INT(x) (x)
172 #endif
173
174 #if SIZEOF_LONG == 4 && SIZEOF_W == 8
175 #define W_TO_LONG(x) %lobits32(x)
176 #elif SIZEOF_LONG == SIZEOF_W
177 #define W_TO_LONG(x) (x)
178 #endif
179
180 /* -----------------------------------------------------------------------------
181 Heap/stack access, and adjusting the heap/stack pointers.
182 -------------------------------------------------------------------------- */
183
184 #define Sp(n) W_[Sp + WDS(n)]
185 #define Hp(n) W_[Hp + WDS(n)]
186
187 #define Sp_adj(n) Sp = Sp + WDS(n) /* pronounced "spadge" */
188 #define Hp_adj(n) Hp = Hp + WDS(n)
189
190 /* -----------------------------------------------------------------------------
191 Assertions and Debuggery
192 -------------------------------------------------------------------------- */
193
194 #ifdef DEBUG
195 #define ASSERT(predicate) \
196 if (predicate) { \
197 /*null*/; \
198 } else { \
199 foreign "C" _assertFail(NULL, __LINE__) never returns; \
200 }
201 #else
202 #define ASSERT(p) /* nothing */
203 #endif
204
205 #ifdef DEBUG
206 #define DEBUG_ONLY(s) s
207 #else
208 #define DEBUG_ONLY(s) /* nothing */
209 #endif
210
211 /*
212 * The IF_DEBUG macro is useful for debug messages that depend on one
213 * of the RTS debug options. For example:
214 *
215 * IF_DEBUG(RtsFlags_DebugFlags_apply,
216 * foreign "C" fprintf(stderr, stg_ap_0_ret_str));
217 *
218 * Note the syntax is slightly different to the C version of this macro.
219 */
220 #ifdef DEBUG
221 #define IF_DEBUG(c,s) if (RtsFlags_DebugFlags_##c(RtsFlags) != 0::I32) { s; }
222 #else
223 #define IF_DEBUG(c,s) /* nothing */
224 #endif
225
226 /* -----------------------------------------------------------------------------
227 Entering
228
229 It isn't safe to "enter" every closure. Functions in particular
230 have no entry code as such; their entry point contains the code to
231 apply the function.
232
233 ToDo: range should end in N_CLOSURE_TYPES-1, not N_CLOSURE_TYPES,
234 but switch doesn't allow us to use exprs there yet.
235
236 If R1 points to a tagged object it points either to
237 * A constructor.
238 * A function with arity <= TAG_MASK.
239 In both cases the right thing to do is to return.
240 Note: it is rather lucky that we can use the tag bits to do this
241 for both objects. Maybe it points to a brittle design?
242
243 Indirections can contain tagged pointers, so their tag is checked.
244 -------------------------------------------------------------------------- */
245
246 #ifdef PROFILING
247
248 // When profiling, we cannot shortcut ENTER() by checking the tag,
249 // because LDV profiling relies on entering closures to mark them as
250 // "used".
251
252 #define LOAD_INFO(ret,x) \
253 info = %INFO_PTR(UNTAG(x));
254
255 #define UNTAG_IF_PROF(x) UNTAG(x)
256
257 #else
258
259 #define LOAD_INFO(ret,x) \
260 if (GETTAG(x) != 0) { \
261 ret(x); \
262 } \
263 info = %INFO_PTR(x);
264
265 #define UNTAG_IF_PROF(x) (x) /* already untagged */
266
267 #endif
268
269 // We need two versions of ENTER():
270 // - ENTER(x) takes the closure as an argument and uses return(),
271 // for use in civilized code where the stack is handled by GHC
272 //
273 // - ENTER_NOSTACK() where the closure is in R1, and returns are
274 // explicit jumps, for use when we are doing the stack management
275 // ourselves.
276
277 #define ENTER(x) ENTER_(return,x)
278 #define ENTER_R1() ENTER_(RET_R1,R1)
279
280 #define RET_R1(x) jump %ENTRY_CODE(Sp(0)) [R1]
281
282 #define ENTER_(ret,x) \
283 again: \
284 W_ info; \
285 LOAD_INFO(ret,x) \
286 switch [INVALID_OBJECT .. N_CLOSURE_TYPES] \
287 (TO_W_( %INFO_TYPE(%STD_INFO(info)) )) { \
288 case \
289 IND, \
290 IND_PERM, \
291 IND_STATIC: \
292 { \
293 x = StgInd_indirectee(x); \
294 goto again; \
295 } \
296 case \
297 FUN, \
298 FUN_1_0, \
299 FUN_0_1, \
300 FUN_2_0, \
301 FUN_1_1, \
302 FUN_0_2, \
303 FUN_STATIC, \
304 BCO, \
305 PAP: \
306 { \
307 ret(x); \
308 } \
309 default: \
310 { \
311 x = UNTAG_IF_PROF(x); \
312 jump %ENTRY_CODE(info) (x); \
313 } \
314 }
315
316 // The FUN cases almost never happen: a pointer to a non-static FUN
317 // should always be tagged. This unfortunately isn't true for the
318 // interpreter right now, which leaves untagged FUNs on the stack.
319
320 /* -----------------------------------------------------------------------------
321 Constants.
322 -------------------------------------------------------------------------- */
323
324 #include "rts/Constants.h"
325 #include "DerivedConstants.h"
326 #include "rts/storage/ClosureTypes.h"
327 #include "rts/storage/FunTypes.h"
328 #include "rts/storage/SMPClosureOps.h"
329 #include "rts/OSThreads.h"
330
331 /*
332 * Need MachRegs, because some of the RTS code is conditionally
333 * compiled based on REG_R1, REG_R2, etc.
334 */
335 #include "stg/RtsMachRegs.h"
336
337 #include "rts/prof/LDV.h"
338
339 #undef BLOCK_SIZE
340 #undef MBLOCK_SIZE
341 #include "rts/storage/Block.h" /* For Bdescr() */
342
343
344 #define MyCapability() (BaseReg - OFFSET_Capability_r)
345
346 /* -------------------------------------------------------------------------
347 Info tables
348 ------------------------------------------------------------------------- */
349
350 #if defined(PROFILING)
351 #define PROF_HDR_FIELDS(w_,hdr1,hdr2) \
352 w_ hdr1, \
353 w_ hdr2,
354 #else
355 #define PROF_HDR_FIELDS(w_,hdr1,hdr2) /* nothing */
356 #endif
357
358 /* -------------------------------------------------------------------------
359 Allocation and garbage collection
360 ------------------------------------------------------------------------- */
361
362 /*
363 * ALLOC_PRIM is for allocating memory on the heap for a primitive
364 * object. It is used all over PrimOps.cmm.
365 *
366 * We make the simplifying assumption that the "admin" part of a
367 * primitive closure is just the header when calculating sizes for
368 * ticky-ticky. It's not clear whether eg. the size field of an array
369 * should be counted as "admin", or the various fields of a BCO.
370 */
371 #define ALLOC_PRIM(bytes) \
372 HP_CHK_GEN_TICKY(bytes); \
373 TICK_ALLOC_PRIM(SIZEOF_StgHeader,bytes-SIZEOF_StgHeader,0); \
374 CCCS_ALLOC(bytes);
375
376 #define HEAP_CHECK(bytes,failure) \
377 TICK_BUMP(HEAP_CHK_ctr); \
378 Hp = Hp + (bytes); \
379 if (Hp > HpLim) { HpAlloc = (bytes); failure; } \
380 TICK_ALLOC_HEAP_NOCTR(bytes);
381
382 #define ALLOC_PRIM_WITH_CUSTOM_FAILURE(bytes,failure) \
383 HEAP_CHECK(bytes,failure) \
384 TICK_ALLOC_PRIM(SIZEOF_StgHeader,bytes-SIZEOF_StgHeader,0); \
385 CCCS_ALLOC(bytes);
386
387 #define ALLOC_PRIM_(bytes,fun) \
388 ALLOC_PRIM_WITH_CUSTOM_FAILURE(bytes,GC_PRIM(fun));
389
390 #define ALLOC_PRIM_P(bytes,fun,arg) \
391 ALLOC_PRIM_WITH_CUSTOM_FAILURE(bytes,GC_PRIM_P(fun,arg));
392
393 #define ALLOC_PRIM_N(bytes,fun,arg) \
394 ALLOC_PRIM_WITH_CUSTOM_FAILURE(bytes,GC_PRIM_N(fun,arg));
395
396 /* CCS_ALLOC wants the size in words, because ccs->mem_alloc is in words */
397 #define CCCS_ALLOC(__alloc) CCS_ALLOC(BYTES_TO_WDS(__alloc), CCCS)
398
399 #define HP_CHK_GEN_TICKY(bytes) \
400 HP_CHK_GEN(bytes); \
401 TICK_ALLOC_HEAP_NOCTR(bytes);
402
403 #define HP_CHK_P(bytes, fun, arg) \
404 HEAP_CHECK(bytes, GC_PRIM_P(fun,arg))
405
406 // TODO I'm not seeing where ALLOC_P_TICKY is used; can it be removed?
407 // -NSF March 2013
408 #define ALLOC_P_TICKY(bytes, fun, arg) \
409 HP_CHK_P(bytes); \
410 TICK_ALLOC_HEAP_NOCTR(bytes);
411
412 #define CHECK_GC() \
413 (bdescr_link(CurrentNursery) == NULL || \
414 generation_n_new_large_words(W_[g0]) >= TO_W_(CLong[large_alloc_lim]))
415
416 // allocate() allocates from the nursery, so we check to see
417 // whether the nursery is nearly empty in any function that uses
418 // allocate() - this includes many of the primops.
419 //
420 // HACK alert: the __L__ stuff is here to coax the common-block
421 // eliminator into commoning up the call stg_gc_noregs() with the same
422 // code that gets generated by a STK_CHK_GEN() in the same proc. We
423 // also need an if (0) { goto __L__; } so that the __L__ label isn't
424 // optimised away by the control-flow optimiser prior to common-block
425 // elimination (it will be optimised away later).
426 //
427 // This saves some code in gmp-wrappers.cmm where we have lots of
428 // MAYBE_GC() in the same proc as STK_CHK_GEN().
429 //
430 #define MAYBE_GC(retry) \
431 if (CHECK_GC()) { \
432 HpAlloc = 0; \
433 goto __L__; \
434 __L__: \
435 call stg_gc_noregs(); \
436 goto retry; \
437 } \
438 if (0) { goto __L__; }
439
440 #define GC_PRIM(fun) \
441 R9 = fun; \
442 jump stg_gc_prim();
443
444 #define GC_PRIM_N(fun,arg) \
445 R9 = fun; \
446 jump stg_gc_prim_n(arg);
447
448 #define GC_PRIM_P(fun,arg) \
449 R9 = fun; \
450 jump stg_gc_prim_p(arg);
451
452 #define GC_PRIM_PP(fun,arg1,arg2) \
453 R9 = fun; \
454 jump stg_gc_prim_pp(arg1,arg2);
455
456 #define MAYBE_GC_(fun) \
457 if (CHECK_GC()) { \
458 HpAlloc = 0; \
459 GC_PRIM(fun) \
460 }
461
462 #define MAYBE_GC_N(fun,arg) \
463 if (CHECK_GC()) { \
464 HpAlloc = 0; \
465 GC_PRIM_N(fun,arg) \
466 }
467
468 #define MAYBE_GC_P(fun,arg) \
469 if (CHECK_GC()) { \
470 HpAlloc = 0; \
471 GC_PRIM_P(fun,arg) \
472 }
473
474 #define MAYBE_GC_PP(fun,arg1,arg2) \
475 if (CHECK_GC()) { \
476 HpAlloc = 0; \
477 GC_PRIM_PP(fun,arg1,arg2) \
478 }
479
480 #define STK_CHK(n, fun) \
481 TICK_BUMP(STK_CHK_ctr); \
482 if (Sp - (n) < SpLim) { \
483 GC_PRIM(fun) \
484 }
485
486 #define STK_CHK_P(n, fun, arg) \
487 if (Sp - (n) < SpLim) { \
488 GC_PRIM_P(fun,arg) \
489 }
490
491 #define STK_CHK_PP(n, fun, arg1, arg2) \
492 if (Sp - (n) < SpLim) { \
493 GC_PRIM_PP(fun,arg1,arg2) \
494 }
495
496 #define STK_CHK_ENTER(n, closure) \
497 if (Sp - (n) < SpLim) { \
498 jump __stg_gc_enter_1(closure); \
499 }
500
501 // A funky heap check used by AutoApply.cmm
502
503 #define HP_CHK_NP_ASSIGN_SP0(size,f) \
504 HEAP_CHECK(size, Sp(0) = f; jump __stg_gc_enter_1 [R1];)
505
506 /* -----------------------------------------------------------------------------
507 Closure headers
508 -------------------------------------------------------------------------- */
509
510 /*
511 * This is really ugly, since we don't do the rest of StgHeader this
512 * way. The problem is that values from DerivedConstants.h cannot be
513 * dependent on the way (SMP, PROF etc.). For SIZEOF_StgHeader we get
514 * the value from GHC, but it seems like too much trouble to do that
515 * for StgThunkHeader.
516 */
517 #define SIZEOF_StgThunkHeader SIZEOF_StgHeader+SIZEOF_StgSMPThunkHeader
518
519 #define StgThunk_payload(__ptr__,__ix__) \
520 W_[__ptr__+SIZEOF_StgThunkHeader+ WDS(__ix__)]
521
522 /* -----------------------------------------------------------------------------
523 Closures
524 -------------------------------------------------------------------------- */
525
526 /* The offset of the payload of an array */
527 #define BYTE_ARR_CTS(arr) ((arr) + SIZEOF_StgArrWords)
528
529 /* The number of words allocated in an array payload */
530 #define BYTE_ARR_WDS(arr) ROUNDUP_BYTES_TO_WDS(StgArrWords_bytes(arr))
531
532 /* Getting/setting the info pointer of a closure */
533 #define SET_INFO(p,info) StgHeader_info(p) = info
534 #define GET_INFO(p) StgHeader_info(p)
535
536 /* Determine the size of an ordinary closure from its info table */
537 #define sizeW_fromITBL(itbl) \
538 SIZEOF_StgHeader + WDS(%INFO_PTRS(itbl)) + WDS(%INFO_NPTRS(itbl))
539
540 /* NB. duplicated from InfoTables.h! */
541 #define BITMAP_SIZE(bitmap) ((bitmap) & BITMAP_SIZE_MASK)
542 #define BITMAP_BITS(bitmap) ((bitmap) >> BITMAP_BITS_SHIFT)
543
544 /* Debugging macros */
545 #define LOOKS_LIKE_INFO_PTR(p) \
546 ((p) != NULL && \
547 LOOKS_LIKE_INFO_PTR_NOT_NULL(p))
548
549 #define LOOKS_LIKE_INFO_PTR_NOT_NULL(p) \
550 ( (TO_W_(%INFO_TYPE(%STD_INFO(p))) != INVALID_OBJECT) && \
551 (TO_W_(%INFO_TYPE(%STD_INFO(p))) < N_CLOSURE_TYPES))
552
553 #define LOOKS_LIKE_CLOSURE_PTR(p) (LOOKS_LIKE_INFO_PTR(GET_INFO(UNTAG(p))))
554
555 /*
556 * The layout of the StgFunInfoExtra part of an info table changes
557 * depending on TABLES_NEXT_TO_CODE. So we define field access
558 * macros which use the appropriate version here:
559 */
560 #ifdef TABLES_NEXT_TO_CODE
561 /*
562 * when TABLES_NEXT_TO_CODE, slow_apply is stored as an offset
563 * instead of the normal pointer.
564 */
565
566 #define StgFunInfoExtra_slow_apply(fun_info) \
567 (TO_W_(StgFunInfoExtraRev_slow_apply_offset(fun_info)) \
568 + (fun_info) + SIZEOF_StgFunInfoExtraRev + SIZEOF_StgInfoTable)
569
570 #define StgFunInfoExtra_fun_type(i) StgFunInfoExtraRev_fun_type(i)
571 #define StgFunInfoExtra_arity(i) StgFunInfoExtraRev_arity(i)
572 #define StgFunInfoExtra_bitmap(i) StgFunInfoExtraRev_bitmap(i)
573 #else
574 #define StgFunInfoExtra_slow_apply(i) StgFunInfoExtraFwd_slow_apply(i)
575 #define StgFunInfoExtra_fun_type(i) StgFunInfoExtraFwd_fun_type(i)
576 #define StgFunInfoExtra_arity(i) StgFunInfoExtraFwd_arity(i)
577 #define StgFunInfoExtra_bitmap(i) StgFunInfoExtraFwd_bitmap(i)
578 #endif
579
580 #define mutArrCardMask ((1 << MUT_ARR_PTRS_CARD_BITS) - 1)
581 #define mutArrPtrCardDown(i) ((i) >> MUT_ARR_PTRS_CARD_BITS)
582 #define mutArrPtrCardUp(i) (((i) + mutArrCardMask) >> MUT_ARR_PTRS_CARD_BITS)
583 #define mutArrPtrsCardWords(n) ROUNDUP_BYTES_TO_WDS(mutArrPtrCardUp(n))
584
585 #if defined(PROFILING) || (!defined(THREADED_RTS) && defined(DEBUG))
586 #define OVERWRITING_CLOSURE(c) foreign "C" overwritingClosure(c "ptr")
587 #else
588 #define OVERWRITING_CLOSURE(c) /* nothing */
589 #endif
590
591 #ifdef THREADED_RTS
592 #define prim_write_barrier prim %write_barrier()
593 #else
594 #define prim_write_barrier /* nothing */
595 #endif
596
597 /* -----------------------------------------------------------------------------
598 Ticky macros
599 -------------------------------------------------------------------------- */
600
601 #ifdef TICKY_TICKY
602 #define TICK_BUMP_BY(ctr,n) CLong[ctr] = CLong[ctr] + n
603 #else
604 #define TICK_BUMP_BY(ctr,n) /* nothing */
605 #endif
606
607 #define TICK_BUMP(ctr) TICK_BUMP_BY(ctr,1)
608
609 #define TICK_ENT_DYN_IND() TICK_BUMP(ENT_DYN_IND_ctr)
610 #define TICK_ENT_DYN_THK() TICK_BUMP(ENT_DYN_THK_ctr)
611 #define TICK_ENT_VIA_NODE() TICK_BUMP(ENT_VIA_NODE_ctr)
612 #define TICK_ENT_STATIC_IND() TICK_BUMP(ENT_STATIC_IND_ctr)
613 #define TICK_ENT_PERM_IND() TICK_BUMP(ENT_PERM_IND_ctr)
614 #define TICK_ENT_PAP() TICK_BUMP(ENT_PAP_ctr)
615 #define TICK_ENT_AP() TICK_BUMP(ENT_AP_ctr)
616 #define TICK_ENT_AP_STACK() TICK_BUMP(ENT_AP_STACK_ctr)
617 #define TICK_ENT_BH() TICK_BUMP(ENT_BH_ctr)
618 #define TICK_ENT_LNE() TICK_BUMP(ENT_LNE_ctr)
619 #define TICK_UNKNOWN_CALL() TICK_BUMP(UNKNOWN_CALL_ctr)
620 #define TICK_UPDF_PUSHED() TICK_BUMP(UPDF_PUSHED_ctr)
621 #define TICK_CATCHF_PUSHED() TICK_BUMP(CATCHF_PUSHED_ctr)
622 #define TICK_UPDF_OMITTED() TICK_BUMP(UPDF_OMITTED_ctr)
623 #define TICK_UPD_NEW_IND() TICK_BUMP(UPD_NEW_IND_ctr)
624 #define TICK_UPD_NEW_PERM_IND() TICK_BUMP(UPD_NEW_PERM_IND_ctr)
625 #define TICK_UPD_OLD_IND() TICK_BUMP(UPD_OLD_IND_ctr)
626 #define TICK_UPD_OLD_PERM_IND() TICK_BUMP(UPD_OLD_PERM_IND_ctr)
627
628 #define TICK_SLOW_CALL_FUN_TOO_FEW() TICK_BUMP(SLOW_CALL_FUN_TOO_FEW_ctr)
629 #define TICK_SLOW_CALL_FUN_CORRECT() TICK_BUMP(SLOW_CALL_FUN_CORRECT_ctr)
630 #define TICK_SLOW_CALL_FUN_TOO_MANY() TICK_BUMP(SLOW_CALL_FUN_TOO_MANY_ctr)
631 #define TICK_SLOW_CALL_PAP_TOO_FEW() TICK_BUMP(SLOW_CALL_PAP_TOO_FEW_ctr)
632 #define TICK_SLOW_CALL_PAP_CORRECT() TICK_BUMP(SLOW_CALL_PAP_CORRECT_ctr)
633 #define TICK_SLOW_CALL_PAP_TOO_MANY() TICK_BUMP(SLOW_CALL_PAP_TOO_MANY_ctr)
634
635 #define TICK_SLOW_CALL_fast_v16() TICK_BUMP(SLOW_CALL_fast_v16_ctr)
636 #define TICK_SLOW_CALL_fast_v() TICK_BUMP(SLOW_CALL_fast_v_ctr)
637 #define TICK_SLOW_CALL_fast_p() TICK_BUMP(SLOW_CALL_fast_p_ctr)
638 #define TICK_SLOW_CALL_fast_pv() TICK_BUMP(SLOW_CALL_fast_pv_ctr)
639 #define TICK_SLOW_CALL_fast_pp() TICK_BUMP(SLOW_CALL_fast_pp_ctr)
640 #define TICK_SLOW_CALL_fast_ppv() TICK_BUMP(SLOW_CALL_fast_ppv_ctr)
641 #define TICK_SLOW_CALL_fast_ppp() TICK_BUMP(SLOW_CALL_fast_ppp_ctr)
642 #define TICK_SLOW_CALL_fast_pppv() TICK_BUMP(SLOW_CALL_fast_pppv_ctr)
643 #define TICK_SLOW_CALL_fast_pppp() TICK_BUMP(SLOW_CALL_fast_pppp_ctr)
644 #define TICK_SLOW_CALL_fast_ppppp() TICK_BUMP(SLOW_CALL_fast_ppppp_ctr)
645 #define TICK_SLOW_CALL_fast_pppppp() TICK_BUMP(SLOW_CALL_fast_pppppp_ctr)
646 #define TICK_VERY_SLOW_CALL() TICK_BUMP(VERY_SLOW_CALL_ctr)
647
648 /* NOTE: TICK_HISTO_BY and TICK_HISTO
649 currently have no effect.
650 The old code for it didn't typecheck and I
651 just commented it out to get ticky to work.
652 - krc 1/2007 */
653
654 #define TICK_HISTO_BY(histo,n,i) /* nothing */
655
656 #define TICK_HISTO(histo,n) TICK_HISTO_BY(histo,n,1)
657
658 /* An unboxed tuple with n components. */
659 #define TICK_RET_UNBOXED_TUP(n) \
660 TICK_BUMP(RET_UNBOXED_TUP_ctr++); \
661 TICK_HISTO(RET_UNBOXED_TUP,n)
662
663 /*
664 * A slow call with n arguments. In the unevald case, this call has
665 * already been counted once, so don't count it again.
666 */
667 #define TICK_SLOW_CALL(n) \
668 TICK_BUMP(SLOW_CALL_ctr); \
669 TICK_HISTO(SLOW_CALL,n)
670
671 /*
672 * This slow call was found to be to an unevaluated function; undo the
673 * ticks we did in TICK_SLOW_CALL.
674 */
675 #define TICK_SLOW_CALL_UNEVALD(n) \
676 TICK_BUMP(SLOW_CALL_UNEVALD_ctr); \
677 TICK_BUMP_BY(SLOW_CALL_ctr,-1); \
678 TICK_HISTO_BY(SLOW_CALL,n,-1);
679
680 /* Updating a closure with a new CON */
681 #define TICK_UPD_CON_IN_NEW(n) \
682 TICK_BUMP(UPD_CON_IN_NEW_ctr); \
683 TICK_HISTO(UPD_CON_IN_NEW,n)
684
685 #define TICK_ALLOC_HEAP_NOCTR(bytes) \
686 TICK_BUMP(ALLOC_RTS_ctr); \
687 TICK_BUMP_BY(ALLOC_RTS_tot,bytes)
688
689 /* -----------------------------------------------------------------------------
690 Saving and restoring STG registers
691
692 STG registers must be saved around a C call, just in case the STG
693 register is mapped to a caller-saves machine register. Normally we
694 don't need to worry about this the code generator has already
695 loaded any live STG registers into variables for us, but in
696 hand-written low-level Cmm code where we don't know which registers
697 are live, we might have to save them all.
698 -------------------------------------------------------------------------- */
699
700 #define SAVE_STGREGS \
701 W_ r1, r2, r3, r4, r5, r6, r7, r8; \
702 F_ f1, f2, f3, f4, f5, f6; \
703 D_ d1, d2, d3, d4, d5, d6; \
704 L_ l1; \
705 \
706 r1 = R1; \
707 r2 = R2; \
708 r3 = R3; \
709 r4 = R4; \
710 r5 = R5; \
711 r6 = R6; \
712 r7 = R7; \
713 r8 = R8; \
714 \
715 f1 = F1; \
716 f2 = F2; \
717 f3 = F3; \
718 f4 = F4; \
719 f5 = F5; \
720 f6 = F6; \
721 \
722 d1 = D1; \
723 d2 = D2; \
724 d3 = D3; \
725 d4 = D4; \
726 d5 = D5; \
727 d6 = D6; \
728 \
729 l1 = L1;
730
731
732 #define RESTORE_STGREGS \
733 R1 = r1; \
734 R2 = r2; \
735 R3 = r3; \
736 R4 = r4; \
737 R5 = r5; \
738 R6 = r6; \
739 R7 = r7; \
740 R8 = r8; \
741 \
742 F1 = f1; \
743 F2 = f2; \
744 F3 = f3; \
745 F4 = f4; \
746 F5 = f5; \
747 F6 = f6; \
748 \
749 D1 = d1; \
750 D2 = d2; \
751 D3 = d3; \
752 D4 = d4; \
753 D5 = d5; \
754 D6 = d6; \
755 \
756 L1 = l1;
757
758 /* -----------------------------------------------------------------------------
759 Misc junk
760 -------------------------------------------------------------------------- */
761
762 #define NO_TREC stg_NO_TREC_closure
763 #define END_TSO_QUEUE stg_END_TSO_QUEUE_closure
764 #define STM_AWOKEN stg_STM_AWOKEN_closure
765 #define END_INVARIANT_CHECK_QUEUE stg_END_INVARIANT_CHECK_QUEUE_closure
766
767 #define recordMutableCap(p, gen) \
768 W_ __bd; \
769 W_ mut_list; \
770 mut_list = Capability_mut_lists(MyCapability()) + WDS(gen); \
771 __bd = W_[mut_list]; \
772 if (bdescr_free(__bd) >= bdescr_start(__bd) + BLOCK_SIZE) { \
773 W_ __new_bd; \
774 ("ptr" __new_bd) = foreign "C" allocBlock_lock(); \
775 bdescr_link(__new_bd) = __bd; \
776 __bd = __new_bd; \
777 W_[mut_list] = __bd; \
778 } \
779 W_ free; \
780 free = bdescr_free(__bd); \
781 W_[free] = p; \
782 bdescr_free(__bd) = free + WDS(1);
783
784 #define recordMutable(p) \
785 P_ __p; \
786 W_ __bd; \
787 W_ __gen; \
788 __p = p; \
789 __bd = Bdescr(__p); \
790 __gen = TO_W_(bdescr_gen_no(__bd)); \
791 if (__gen > 0) { recordMutableCap(__p, __gen); }
792
793 #endif /* CMM_H */