[project @ 2002-09-17 12:33:08 by simonmar]
[ghc-hetmet.git] / ghc / rts / StgMiscClosures.hc
1 /* -----------------------------------------------------------------------------
2  * $Id: StgMiscClosures.hc,v 1.79 2002/09/17 12:33:08 simonmar Exp $
3  *
4  * (c) The GHC Team, 1998-2000
5  *
6  * Entry code for various built-in closure types.
7  *
8  * ---------------------------------------------------------------------------*/
9
10 #include "Stg.h"
11 #include "Rts.h"
12 #include "RtsUtils.h"
13 #include "RtsFlags.h"
14 #include "StgMiscClosures.h"
15 #include "Storage.h"
16 #include "StoragePriv.h"
17 #include "Profiling.h"
18 #include "Prelude.h"
19 #include "Schedule.h"
20 #include "SMP.h"
21 #if defined(GRAN) || defined(PAR)
22 # include "GranSimRts.h"      /* for DumpRawGranEvent */
23 # include "StgRun.h"    /* for StgReturn and register saving */
24 #endif
25
26 #ifdef HAVE_STDLIB_H
27 #include <stdlib.h>
28 #endif
29
30 /* ToDo: make the printing of panics more win32-friendly, i.e.,
31  *       pop up some lovely message boxes (as well).
32  */
33 #define DUMP_ERRMSG(msg) STGCALL2(fprintf,stderr,msg)
34
35 /*
36   Template for the entry code of non-enterable closures.
37 */
38
39 #define NON_ENTERABLE_ENTRY_CODE(type)          \
40 STGFUN(stg_##type##_entry)                      \
41 {                                               \
42   FB_                                           \
43     barf(#type " object entered!\n");           \
44   FE_                                           \
45 }
46
47
48 /* -----------------------------------------------------------------------------
49    Support for the bytecode interpreter.
50    -------------------------------------------------------------------------- */
51
52 /* 9 bits of return code for constructors created by the interpreter. */
53 FN_(stg_interp_constr_entry) 
54
55   /* R1 points at the constructor */
56   FB_ 
57     /* STGCALL2(fprintf,stderr,"stg_interp_constr_entry (direct return)!\n"); */
58     /* Pointless, since SET_TAG doesn't do anything */
59     SET_TAG( GET_TAG(GET_INFO(R1.cl))); 
60     JMP_(ENTRY_CODE((P_)(*Sp))); 
61   FE_ 
62 }
63
64 FN_(stg_interp_constr1_entry) { FB_ JMP_(RET_VEC((P_)(*Sp),0)); FE_ }
65 FN_(stg_interp_constr2_entry) { FB_ JMP_(RET_VEC((P_)(*Sp),1)); FE_ }
66 FN_(stg_interp_constr3_entry) { FB_ JMP_(RET_VEC((P_)(*Sp),2)); FE_ }
67 FN_(stg_interp_constr4_entry) { FB_ JMP_(RET_VEC((P_)(*Sp),3)); FE_ }
68 FN_(stg_interp_constr5_entry) { FB_ JMP_(RET_VEC((P_)(*Sp),4)); FE_ }
69 FN_(stg_interp_constr6_entry) { FB_ JMP_(RET_VEC((P_)(*Sp),5)); FE_ }
70 FN_(stg_interp_constr7_entry) { FB_ JMP_(RET_VEC((P_)(*Sp),6)); FE_ }
71 FN_(stg_interp_constr8_entry) { FB_ JMP_(RET_VEC((P_)(*Sp),7)); FE_ }
72  
73 /* Some info tables to be used when compiled code returns a value to
74    the interpreter, i.e. the interpreter pushes one of these onto the
75    stack before entering a value.  What the code does is to
76    impedance-match the compiled return convention (in R1p/R1n/F1/D1 etc) to
77    the interpreter's convention (returned value is on top of stack),
78    and then cause the scheduler to enter the interpreter.
79
80    On entry, the stack (growing down) looks like this:
81
82       ptr to BCO holding return continuation
83       ptr to one of these info tables.
84  
85    The info table code, both direct and vectored, must:
86       * push R1/F1/D1 on the stack, and its tag if necessary
87       * push the BCO (so it's now on the stack twice)
88       * Yield, ie, go to the scheduler.
89
90    Scheduler examines the t.o.s, discovers it is a BCO, and proceeds
91    directly to the bytecode interpreter.  That pops the top element
92    (the BCO, containing the return continuation), and interprets it.
93    Net result: return continuation gets interpreted, with the
94    following stack:
95
96       ptr to this BCO
97       ptr to the info table just jumped thru
98       return value
99
100    which is just what we want -- the "standard" return layout for the
101    interpreter.  Hurrah!
102
103    Don't ask me how unboxed tuple returns are supposed to work.  We
104    haven't got a good story about that yet.
105 */
106
107 /* When the returned value is in R1 and it is a pointer, so doesn't
108    need tagging ... */
109 #define STG_CtoI_RET_R1p_Template(label)        \
110    IFN_(label)                          \
111    {                                    \
112       StgPtr bco;                       \
113       FB_                               \
114       bco = ((StgPtr*)Sp)[1];           \
115       Sp -= 1;                          \
116       ((StgPtr*)Sp)[0] = R1.p;          \
117       Sp -= 1;                          \
118       ((StgPtr*)Sp)[0] = bco;           \
119       JMP_(stg_yield_to_interpreter);   \
120       FE_                               \
121    }
122
123 STG_CtoI_RET_R1p_Template(stg_ctoi_ret_R1p_entry);
124 STG_CtoI_RET_R1p_Template(stg_ctoi_ret_R1p_0_entry);
125 STG_CtoI_RET_R1p_Template(stg_ctoi_ret_R1p_1_entry);
126 STG_CtoI_RET_R1p_Template(stg_ctoi_ret_R1p_2_entry);
127 STG_CtoI_RET_R1p_Template(stg_ctoi_ret_R1p_3_entry);
128 STG_CtoI_RET_R1p_Template(stg_ctoi_ret_R1p_4_entry);
129 STG_CtoI_RET_R1p_Template(stg_ctoi_ret_R1p_5_entry);
130 STG_CtoI_RET_R1p_Template(stg_ctoi_ret_R1p_6_entry);
131 STG_CtoI_RET_R1p_Template(stg_ctoi_ret_R1p_7_entry);
132
133 VEC_POLY_INFO_TABLE(stg_ctoi_ret_R1p,0, NULL/*srt*/, 0/*srt_off*/, 0/*srt_len*/, RET_BCO,, EF_);
134
135
136
137 /* When the returned value is in R1 and it isn't a pointer. */
138 #define STG_CtoI_RET_R1n_Template(label)        \
139    IFN_(label)                          \
140    {                                    \
141       StgPtr bco;                       \
142       FB_                               \
143       bco = ((StgPtr*)Sp)[1];           \
144       Sp -= 1;                          \
145       ((StgPtr*)Sp)[0] = (StgPtr)R1.i;  \
146       Sp -= 1;                          \
147       ((StgPtr*)Sp)[0] = (StgPtr)1; /* tag */   \
148       Sp -= 1;                          \
149       ((StgPtr*)Sp)[0] = bco;           \
150       JMP_(stg_yield_to_interpreter);   \
151       FE_                               \
152    }
153
154 STG_CtoI_RET_R1n_Template(stg_ctoi_ret_R1n_entry);
155 STG_CtoI_RET_R1n_Template(stg_ctoi_ret_R1n_0_entry);
156 STG_CtoI_RET_R1n_Template(stg_ctoi_ret_R1n_1_entry);
157 STG_CtoI_RET_R1n_Template(stg_ctoi_ret_R1n_2_entry);
158 STG_CtoI_RET_R1n_Template(stg_ctoi_ret_R1n_3_entry);
159 STG_CtoI_RET_R1n_Template(stg_ctoi_ret_R1n_4_entry);
160 STG_CtoI_RET_R1n_Template(stg_ctoi_ret_R1n_5_entry);
161 STG_CtoI_RET_R1n_Template(stg_ctoi_ret_R1n_6_entry);
162 STG_CtoI_RET_R1n_Template(stg_ctoi_ret_R1n_7_entry);
163
164 VEC_POLY_INFO_TABLE(stg_ctoi_ret_R1n,0, NULL/*srt*/, 0/*srt_off*/, 0/*srt_len*/, RET_BCO,, EF_);
165
166
167
168 /* When the returned value is in F1 ... */
169 #define STG_CtoI_RET_F1_Template(label)         \
170    IFN_(label)                          \
171    {                                    \
172       StgPtr bco;                       \
173       FB_                               \
174       bco = ((StgPtr*)Sp)[1];           \
175       Sp -= sizeofW(StgFloat);          \
176       ASSIGN_FLT((W_*)Sp, F1);          \
177       Sp -= 1;                          \
178       ((StgPtr*)Sp)[0] = (StgPtr)sizeofW(StgFloat); \
179       Sp -= 1;                          \
180       ((StgPtr*)Sp)[0] = bco;           \
181       JMP_(stg_yield_to_interpreter);   \
182       FE_                               \
183    }
184
185 STG_CtoI_RET_F1_Template(stg_ctoi_ret_F1_entry);
186 STG_CtoI_RET_F1_Template(stg_ctoi_ret_F1_0_entry);
187 STG_CtoI_RET_F1_Template(stg_ctoi_ret_F1_1_entry);
188 STG_CtoI_RET_F1_Template(stg_ctoi_ret_F1_2_entry);
189 STG_CtoI_RET_F1_Template(stg_ctoi_ret_F1_3_entry);
190 STG_CtoI_RET_F1_Template(stg_ctoi_ret_F1_4_entry);
191 STG_CtoI_RET_F1_Template(stg_ctoi_ret_F1_5_entry);
192 STG_CtoI_RET_F1_Template(stg_ctoi_ret_F1_6_entry);
193 STG_CtoI_RET_F1_Template(stg_ctoi_ret_F1_7_entry);
194
195 VEC_POLY_INFO_TABLE(stg_ctoi_ret_F1,0, NULL/*srt*/, 0/*srt_off*/, 0/*srt_len*/, RET_BCO,, EF_);
196
197
198 /* When the returned value is in D1 ... */
199 #define STG_CtoI_RET_D1_Template(label)         \
200    IFN_(label)                          \
201    {                                    \
202       StgPtr bco;                       \
203       FB_                               \
204       bco = ((StgPtr*)Sp)[1];           \
205       Sp -= sizeofW(StgDouble);         \
206       ASSIGN_DBL((W_*)Sp, D1);          \
207       Sp -= 1;                          \
208       ((StgPtr*)Sp)[0] = (StgPtr)sizeofW(StgDouble); \
209       Sp -= 1;                          \
210       ((StgPtr*)Sp)[0] = bco;           \
211       JMP_(stg_yield_to_interpreter);   \
212       FE_                               \
213    }
214
215 STG_CtoI_RET_D1_Template(stg_ctoi_ret_D1_entry);
216 STG_CtoI_RET_D1_Template(stg_ctoi_ret_D1_0_entry);
217 STG_CtoI_RET_D1_Template(stg_ctoi_ret_D1_1_entry);
218 STG_CtoI_RET_D1_Template(stg_ctoi_ret_D1_2_entry);
219 STG_CtoI_RET_D1_Template(stg_ctoi_ret_D1_3_entry);
220 STG_CtoI_RET_D1_Template(stg_ctoi_ret_D1_4_entry);
221 STG_CtoI_RET_D1_Template(stg_ctoi_ret_D1_5_entry);
222 STG_CtoI_RET_D1_Template(stg_ctoi_ret_D1_6_entry);
223 STG_CtoI_RET_D1_Template(stg_ctoi_ret_D1_7_entry);
224
225 VEC_POLY_INFO_TABLE(stg_ctoi_ret_D1,0, NULL/*srt*/, 0/*srt_off*/, 0/*srt_len*/, RET_BCO,, EF_);
226
227
228 /* When the returned value a VoidRep ... */
229 #define STG_CtoI_RET_V_Template(label)  \
230    IFN_(label)                          \
231    {                                    \
232       StgPtr bco;                       \
233       FB_                               \
234       bco = ((StgPtr*)Sp)[1];           \
235       Sp -= 1;                          \
236       ((StgPtr*)Sp)[0] = 0; /* VoidRep tag */ \
237       Sp -= 1;                          \
238       ((StgPtr*)Sp)[0] = bco;           \
239       JMP_(stg_yield_to_interpreter);   \
240       FE_                               \
241    }
242
243 STG_CtoI_RET_V_Template(stg_ctoi_ret_V_entry);
244 STG_CtoI_RET_V_Template(stg_ctoi_ret_V_0_entry);
245 STG_CtoI_RET_V_Template(stg_ctoi_ret_V_1_entry);
246 STG_CtoI_RET_V_Template(stg_ctoi_ret_V_2_entry);
247 STG_CtoI_RET_V_Template(stg_ctoi_ret_V_3_entry);
248 STG_CtoI_RET_V_Template(stg_ctoi_ret_V_4_entry);
249 STG_CtoI_RET_V_Template(stg_ctoi_ret_V_5_entry);
250 STG_CtoI_RET_V_Template(stg_ctoi_ret_V_6_entry);
251 STG_CtoI_RET_V_Template(stg_ctoi_ret_V_7_entry);
252
253 VEC_POLY_INFO_TABLE(stg_ctoi_ret_V,0, NULL/*srt*/, 0/*srt_off*/, 0/*srt_len*/, RET_BCO,, EF_);
254
255
256 /* The other way round: when the interpreter returns a value to
257    compiled code.  The stack looks like this:
258
259       return info table (pushed by compiled code)
260       return value (pushed by interpreter)
261
262    If the value is ptr-rep'd, the interpreter simply returns to the
263    scheduler, instructing it to ThreadEnterGHC.
264
265    Otherwise (unboxed return value), we replace the top stack word,
266    which must be the tag, with stg_gc_unbx_r1_info (or f1_info or d1_info),
267    and return to the scheduler, instructing it to ThreadRunGHC.
268
269    No supporting code needed!
270 */
271
272
273 /* Entering a BCO.  Heave it on the stack and defer to the
274    scheduler. */
275 INFO_TABLE(stg_BCO_info,stg_BCO_entry,4,0,BCO,,EF_,"BCO","BCO");
276 STGFUN(stg_BCO_entry) {
277   FB_
278     Sp -= 1;
279     Sp[0] = R1.w;
280     JMP_(stg_yield_to_interpreter);
281   FE_
282 }
283
284
285 /* -----------------------------------------------------------------------------
286    Entry code for an indirection.
287    -------------------------------------------------------------------------- */
288
289 INFO_TABLE(stg_IND_info,stg_IND_entry,1,0,IND,,EF_,"IND","IND");
290 STGFUN(stg_IND_entry)
291 {
292     FB_
293     TICK_ENT_DYN_IND(Node);     /* tick */
294     R1.p = (P_) ((StgInd*)R1.p)->indirectee;
295     TICK_ENT_VIA_NODE();
296     JMP_(GET_ENTRY(R1.cl));
297     FE_
298 }
299
300 INFO_TABLE(stg_IND_STATIC_info,stg_IND_STATIC_entry,1,0,IND_STATIC,,EF_,"IND_STATIC","IND_STATIC");
301 STGFUN(stg_IND_STATIC_entry)
302 {
303     FB_
304     TICK_ENT_STATIC_IND(Node);  /* tick */
305     R1.p = (P_) ((StgIndStatic*)R1.p)->indirectee;
306     TICK_ENT_VIA_NODE();
307     JMP_(GET_ENTRY(R1.cl));
308     FE_
309 }
310
311 INFO_TABLE(stg_IND_PERM_info,stg_IND_PERM_entry,1,1,IND_PERM,,EF_,"IND_PERM","IND_PERM");
312 STGFUN(stg_IND_PERM_entry)
313 {
314     FB_
315     /* Don't add INDs to granularity cost */
316     /* Dont: TICK_ENT_STATIC_IND(Node); for ticky-ticky; this ind is here only to help profiling */
317
318 #if defined(TICKY_TICKY) && !defined(PROFILING)
319     /* TICKY_TICKY && !PROFILING means PERM_IND *replaces* an IND, rather than being extra  */
320     TICK_ENT_PERM_IND(R1.p); /* tick */
321 #endif
322
323     LDV_ENTER((StgInd *)R1.p);
324
325     /* Enter PAP cost centre -- lexical scoping only */
326     ENTER_CCS_PAP_CL(R1.cl);
327
328     /* For ticky-ticky, change the perm_ind to a normal ind on first
329      * entry, so the number of ent_perm_inds is the number of *thunks*
330      * entered again, not the number of subsequent entries.
331      *
332      * Since this screws up cost centres, we die if profiling and
333      * ticky_ticky are on at the same time.  KSW 1999-01.
334      */
335
336 #ifdef TICKY_TICKY
337 #  ifdef PROFILING
338 #    error Profiling and ticky-ticky do not mix at present!
339 #  endif  /* PROFILING */
340     SET_INFO((StgInd*)R1.p,&stg_IND_info);
341 #endif /* TICKY_TICKY */
342
343     R1.p = (P_) ((StgInd*)R1.p)->indirectee;
344
345     /* Dont: TICK_ENT_VIA_NODE(); for ticky-ticky; as above */
346
347 #if defined(TICKY_TICKY) && !defined(PROFILING)
348     TICK_ENT_VIA_NODE();
349 #endif
350
351     JMP_(GET_ENTRY(R1.cl));
352     FE_
353 }  
354
355 INFO_TABLE(stg_IND_OLDGEN_info,stg_IND_OLDGEN_entry,1,1,IND_OLDGEN,,EF_,"IND_OLDGEN","IND_OLDGEN");
356 STGFUN(stg_IND_OLDGEN_entry)
357 {
358     FB_
359     TICK_ENT_STATIC_IND(Node);  /* tick */
360     R1.p = (P_) ((StgInd*)R1.p)->indirectee;
361     TICK_ENT_VIA_NODE();
362     JMP_(GET_ENTRY(R1.cl));
363     FE_
364 }
365
366 INFO_TABLE(stg_IND_OLDGEN_PERM_info,stg_IND_OLDGEN_PERM_entry,1,1,IND_OLDGEN_PERM,,EF_,"IND_OLDGEN_PERM","IND_OLDGEN_PERM");
367 STGFUN(stg_IND_OLDGEN_PERM_entry)
368 {
369     FB_
370     /* Dont: TICK_ENT_STATIC_IND(Node); for ticky-ticky; this ind is here only to help profiling */
371
372 #if defined(TICKY_TICKY) && !defined(PROFILING)
373     /* TICKY_TICKY && !PROFILING means PERM_IND *replaces* an IND, rather than being extra  */
374     TICK_ENT_PERM_IND(R1.p); /* tick */
375 #endif
376
377     LDV_ENTER((StgInd *)R1.p);
378
379     /* Enter PAP cost centre -- lexical scoping only */
380     ENTER_CCS_PAP_CL(R1.cl);
381
382     /* see comment in IND_PERM */
383 #ifdef TICKY_TICKY
384 #  ifdef PROFILING
385 #    error Profiling and ticky-ticky do not mix at present!
386 #  endif  /* PROFILING */
387     SET_INFO((StgInd*)R1.p,&stg_IND_OLDGEN_info);
388 #endif /* TICKY_TICKY */
389
390     R1.p = (P_) ((StgInd*)R1.p)->indirectee;
391     TICK_ENT_VIA_NODE();
392     JMP_(GET_ENTRY(R1.cl));
393     FE_
394 }
395
396 /* -----------------------------------------------------------------------------
397    Entry code for a black hole.
398
399    Entering a black hole normally causes a cyclic data dependency, but
400    in the concurrent world, black holes are synchronization points,
401    and they are turned into blocking queues when there are threads
402    waiting for the evaluation of the closure to finish.
403    -------------------------------------------------------------------------- */
404
405 /* Note: a BLACKHOLE and BLACKHOLE_BQ must be big enough to be
406  * overwritten with an indirection/evacuee/catch.  Thus we claim it
407  * has 1 non-pointer word of payload (in addition to the pointer word
408  * for the blocking queue in a BQ), which should be big enough for an
409  * old-generation indirection. 
410  */
411
412 INFO_TABLE(stg_BLACKHOLE_info, stg_BLACKHOLE_entry,0,2,BLACKHOLE,,EF_,"BLACKHOLE","BLACKHOLE");
413 STGFUN(stg_BLACKHOLE_entry)
414 {
415   FB_
416 #if defined(GRAN)
417     /* Before overwriting TSO_LINK */
418     STGCALL3(GranSimBlock,CurrentTSO,CurrentProc,(StgClosure *)R1.p /*Node*/);
419 #endif
420
421 #ifdef SMP
422     {
423       bdescr *bd = Bdescr(R1.p);
424       if (bd->u.back != (bdescr *)BaseReg) {
425         if (bd->gen_no >= 1 || bd->step->no >= 1) {
426           CMPXCHG(R1.cl->header.info, &stg_BLACKHOLE_info, &stg_WHITEHOLE_info);
427         } else {
428           EXTFUN_RTS(stg_gc_enter_1_hponly);
429           JMP_(stg_gc_enter_1_hponly);
430         }
431       }
432     }
433 #endif
434     TICK_ENT_BH();
435
436     // Actually this is not necessary because R1.p is about to be destroyed.
437     LDV_ENTER((StgClosure *)R1.p);
438
439     /* Put ourselves on the blocking queue for this black hole */
440 #if defined(GRAN) || defined(PAR)
441     // in fact, only difference is the type of the end-of-queue marker!
442     CurrentTSO->link = END_BQ_QUEUE;
443     ((StgBlockingQueue *)R1.p)->blocking_queue = (StgBlockingQueueElement *)CurrentTSO;
444 #else
445     CurrentTSO->link = END_TSO_QUEUE;
446     ((StgBlockingQueue *)R1.p)->blocking_queue = CurrentTSO;
447 #endif
448     // jot down why and on what closure we are blocked
449     CurrentTSO->why_blocked = BlockedOnBlackHole;
450     CurrentTSO->block_info.closure = R1.cl;
451
452     /* Change the BLACKHOLE into a BLACKHOLE_BQ */
453 #ifdef PROFILING
454
455     // The size remains the same, so we call LDV_recordDead() - no need to fill slop.
456     LDV_recordDead((StgClosure *)R1.p, BLACKHOLE_sizeW());
457 #endif
458     // 
459     // Todo: maybe use SET_HDR() and remove LDV_recordCreate()?
460     // 
461     ((StgBlockingQueue *)R1.p)->header.info = &stg_BLACKHOLE_BQ_info;
462 #ifdef PROFILING
463     LDV_recordCreate((StgClosure *)R1.p);
464 #endif
465
466     // closure is mutable since something has just been added to its BQ
467     recordMutable((StgMutClosure *)R1.cl);
468
469     // PAR: dumping of event now done in blockThread -- HWL
470
471     // stg_gen_block is too heavyweight, use a specialised one
472     BLOCK_NP(1);
473   FE_
474 }
475
476 INFO_TABLE(stg_BLACKHOLE_BQ_info, stg_BLACKHOLE_BQ_entry,1,1,BLACKHOLE_BQ,,EF_,"BLACKHOLE","BLACKHOLE");
477 STGFUN(stg_BLACKHOLE_BQ_entry)
478 {
479   FB_
480 #if defined(GRAN)
481     /* Before overwriting TSO_LINK */
482     STGCALL3(GranSimBlock,CurrentTSO,CurrentProc,(StgClosure *)R1.p /*Node*/);
483 #endif
484
485 #ifdef SMP
486     {
487       bdescr *bd = Bdescr(R1.p);
488       if (bd->u.back != (bdescr *)BaseReg) {
489         if (bd->gen_no >= 1 || bd->step->no >= 1) {
490           CMPXCHG(R1.cl->header.info, &stg_BLACKHOLE_info, &stg_WHITEHOLE_info);
491         } else {
492           EXTFUN_RTS(stg_gc_enter_1_hponly);
493           JMP_(stg_gc_enter_1_hponly);
494         }
495       }
496     }
497 #endif
498
499     TICK_ENT_BH();
500     LDV_ENTER((StgClosure *)R1.p);
501
502     /* Put ourselves on the blocking queue for this black hole */
503     CurrentTSO->link = ((StgBlockingQueue *)R1.p)->blocking_queue;
504     ((StgBlockingQueue *)R1.p)->blocking_queue = CurrentTSO;
505     /* jot down why and on what closure we are blocked */
506     CurrentTSO->why_blocked = BlockedOnBlackHole;
507     CurrentTSO->block_info.closure = R1.cl;
508 #ifdef SMP
509     ((StgBlockingQueue *)R1.p)->header.info = &stg_BLACKHOLE_BQ_info;
510 #endif
511
512     /* PAR: dumping of event now done in blockThread -- HWL */
513
514     /* stg_gen_block is too heavyweight, use a specialised one */
515     BLOCK_NP(1);
516   FE_
517 }
518
519 /*
520    Revertible black holes are needed in the parallel world, to handle
521    negative acknowledgements of messages containing updatable closures.
522    The idea is that when the original message is transmitted, the closure
523    is turned into a revertible black hole...an object which acts like a
524    black hole when local threads try to enter it, but which can be reverted
525    back to the original closure if necessary.
526
527    It's actually a lot like a blocking queue (BQ) entry, because revertible
528    black holes are initially set up with an empty blocking queue.
529 */
530
531 #if defined(PAR) || defined(GRAN)
532
533 INFO_TABLE(stg_RBH_info, stg_RBH_entry,1,1,RBH,,EF_,"RBH","RBH");
534 STGFUN(stg_RBH_entry)
535 {
536   FB_
537 # if defined(GRAN)
538     /* mainly statistics gathering for GranSim simulation */
539     STGCALL3(GranSimBlock,CurrentTSO,CurrentProc,(StgClosure *)R1.p /*Node*/);
540 # endif
541
542     /* exactly the same as a BLACKHOLE_BQ_entry -- HWL */
543     /* Put ourselves on the blocking queue for this black hole */
544     CurrentTSO->link = ((StgBlockingQueue *)R1.p)->blocking_queue;
545     ((StgBlockingQueue *)R1.p)->blocking_queue = CurrentTSO;
546     /* jot down why and on what closure we are blocked */
547     CurrentTSO->why_blocked = BlockedOnBlackHole;
548     CurrentTSO->block_info.closure = R1.cl;
549
550     /* PAR: dumping of event now done in blockThread -- HWL */
551
552     /* stg_gen_block is too heavyweight, use a specialised one */
553     BLOCK_NP(1); 
554   FE_
555 }
556
557 INFO_TABLE(stg_RBH_Save_0_info, stg_RBH_Save_0_entry,0,2,CONSTR,,EF_,"RBH_Save_0","RBH_Save_0");
558 NON_ENTERABLE_ENTRY_CODE(RBH_Save_0);
559
560 INFO_TABLE(stg_RBH_Save_1_info, stg_RBH_Save_1_entry,1,1,CONSTR,,EF_,"RBH_Save_1","RBH_Save_1");
561 NON_ENTERABLE_ENTRY_CODE(RBH_Save_1);
562
563 INFO_TABLE(stg_RBH_Save_2_info, stg_RBH_Save_2_entry,2,0,CONSTR,,EF_,"RBH_Save_2","RBH_Save_2");
564 NON_ENTERABLE_ENTRY_CODE(RBH_Save_2);
565 #endif /* defined(PAR) || defined(GRAN) */
566
567 /* identical to BLACKHOLEs except for the infotag */
568 INFO_TABLE(stg_CAF_BLACKHOLE_info, stg_CAF_BLACKHOLE_entry,0,2,CAF_BLACKHOLE,,EF_,"CAF_BLACKHOLE","CAF_BLACKHOLE");
569 STGFUN(stg_CAF_BLACKHOLE_entry)
570 {
571   FB_
572 #if defined(GRAN)
573     /* mainly statistics gathering for GranSim simulation */
574     STGCALL3(GranSimBlock,CurrentTSO,CurrentProc,(StgClosure *)R1.p /*Node*/);
575 #endif
576
577 #ifdef SMP
578     {
579       bdescr *bd = Bdescr(R1.p);
580       if (bd->u.back != (bdescr *)BaseReg) {
581         if (bd->gen_no >= 1 || bd->step->no >= 1) {
582           CMPXCHG(R1.cl->header.info, &stg_CAF_BLACKHOLE_info, &stg_WHITEHOLE_info);
583         } else {
584           EXTFUN_RTS(stg_gc_enter_1_hponly);
585           JMP_(stg_gc_enter_1_hponly);
586         }
587       }
588     }
589 #endif
590
591     TICK_ENT_BH();
592     LDV_ENTER((StgClosure *)R1.p);
593
594     // Put ourselves on the blocking queue for this black hole
595 #if defined(GRAN) || defined(PAR)
596     // in fact, only difference is the type of the end-of-queue marker!
597     CurrentTSO->link = END_BQ_QUEUE;
598     ((StgBlockingQueue *)R1.p)->blocking_queue = (StgBlockingQueueElement *)CurrentTSO;
599 #else
600     CurrentTSO->link = END_TSO_QUEUE;
601     ((StgBlockingQueue *)R1.p)->blocking_queue = CurrentTSO;
602 #endif
603     // jot down why and on what closure we are blocked
604     CurrentTSO->why_blocked = BlockedOnBlackHole;
605     CurrentTSO->block_info.closure = R1.cl;
606
607     // Change the CAF_BLACKHOLE into a BLACKHOLE_BQ_STATIC
608     ((StgBlockingQueue *)R1.p)->header.info = &stg_BLACKHOLE_BQ_info;
609
610     // closure is mutable since something has just been added to its BQ
611     recordMutable((StgMutClosure *)R1.cl);
612
613     // PAR: dumping of event now done in blockThread -- HWL
614
615     // stg_gen_block is too heavyweight, use a specialised one
616     BLOCK_NP(1);
617   FE_
618 }
619
620 #ifdef TICKY_TICKY
621 INFO_TABLE(stg_SE_BLACKHOLE_info, stg_SE_BLACKHOLE_entry,0,2,SE_BLACKHOLE,,EF_,"SE_BLACKHOLE","SE_BLACKHOLE");
622 STGFUN(stg_SE_BLACKHOLE_entry)
623 {
624   FB_
625     STGCALL3(fprintf,stderr,"SE_BLACKHOLE at %p entered!\n",R1.p);
626     STGCALL1(shutdownHaskellAndExit,EXIT_FAILURE);
627   FE_
628 }
629
630 INFO_TABLE(stg_SE_CAF_BLACKHOLE_info, SE_CAF_BLACKHOLE_entry,0,2,SE_CAF_BLACKHOLE,,EF_,"CAF_BLACKHOLE","CAF_BLACKHOLE");
631 STGFUN(stg_SE_CAF_BLACKHOLE_entry)
632 {
633   FB_
634     STGCALL3(fprintf,stderr,"SE_CAF_BLACKHOLE at %p entered!\n",R1.p);
635     STGCALL1(shutdownHaskellAndExit,EXIT_FAILURE);
636   FE_
637 }
638 #endif
639
640 #ifdef SMP
641 INFO_TABLE(stg_WHITEHOLE_info, stg_WHITEHOLE_entry,0,2,CONSTR_NOCAF_STATIC,,EF_,"WHITEHOLE","WHITEHOLE");
642 STGFUN(stg_WHITEHOLE_entry)
643 {
644   FB_
645      JMP_(GET_ENTRY(R1.cl));
646   FE_
647 }
648 #endif
649
650 /* -----------------------------------------------------------------------------
651    Some static info tables for things that don't get entered, and
652    therefore don't need entry code (i.e. boxed but unpointed objects)
653    NON_ENTERABLE_ENTRY_CODE now defined at the beginning of the file
654    -------------------------------------------------------------------------- */
655
656 INFO_TABLE(stg_TSO_info, stg_TSO_entry, 0,0,TSO,,EF_,"TSO","TSO");
657 NON_ENTERABLE_ENTRY_CODE(TSO);
658
659 /* -----------------------------------------------------------------------------
660    Evacuees are left behind by the garbage collector.  Any attempt to enter
661    one is a real bug.
662    -------------------------------------------------------------------------- */
663
664 INFO_TABLE(stg_EVACUATED_info,stg_EVACUATED_entry,1,0,EVACUATED,,EF_,"EVACUATED","EVACUATED");
665 NON_ENTERABLE_ENTRY_CODE(EVACUATED);
666
667 /* -----------------------------------------------------------------------------
668    Weak pointers
669
670    Live weak pointers have a special closure type.  Dead ones are just
671    nullary constructors (although they live on the heap - we overwrite
672    live weak pointers with dead ones).
673    -------------------------------------------------------------------------- */
674
675 INFO_TABLE(stg_WEAK_info,stg_WEAK_entry,0,4,WEAK,,EF_,"WEAK","WEAK");
676 NON_ENTERABLE_ENTRY_CODE(WEAK);
677
678 // It's important when turning an existing WEAK into a DEAD_WEAK
679 // (which is what finalizeWeak# does) that we don't lose the link
680 // field and break the linked list of weak pointers.  Hence, we give
681 // DEAD_WEAK 4 non-pointer fields, the same as WEAK.
682
683 INFO_TABLE_CONSTR(stg_DEAD_WEAK_info,stg_DEAD_WEAK_entry,0,4,0,CONSTR,,EF_,"DEAD_WEAK","DEAD_WEAK");
684 NON_ENTERABLE_ENTRY_CODE(DEAD_WEAK);
685
686 /* -----------------------------------------------------------------------------
687    NO_FINALIZER
688
689    This is a static nullary constructor (like []) that we use to mark an empty
690    finalizer in a weak pointer object.
691    -------------------------------------------------------------------------- */
692
693 INFO_TABLE_CONSTR(stg_NO_FINALIZER_info,stg_NO_FINALIZER_entry,0,0,0,CONSTR_NOCAF_STATIC,,EF_,"NO_FINALIZER","NO_FINALIZER");
694 NON_ENTERABLE_ENTRY_CODE(NO_FINALIZER);
695
696 SET_STATIC_HDR(stg_NO_FINALIZER_closure,stg_NO_FINALIZER_info,0/*CC*/,,EI_)
697 , /*payload*/{} };
698
699 /* -----------------------------------------------------------------------------
700    Foreign Objects are unlifted and therefore never entered.
701    -------------------------------------------------------------------------- */
702
703 INFO_TABLE(stg_FOREIGN_info,stg_FOREIGN_entry,0,1,FOREIGN,,EF_,"FOREIGN","FOREIGN");
704 NON_ENTERABLE_ENTRY_CODE(FOREIGN);
705
706 /* -----------------------------------------------------------------------------
707    Stable Names are unlifted too.
708    -------------------------------------------------------------------------- */
709
710 INFO_TABLE(stg_STABLE_NAME_info,stg_STABLE_NAME_entry,0,1,STABLE_NAME,,EF_,"STABLE_NAME","STABLE_NAME");
711 NON_ENTERABLE_ENTRY_CODE(STABLE_NAME);
712
713 /* -----------------------------------------------------------------------------
714    MVars
715
716    There are two kinds of these: full and empty.  We need an info table
717    and entry code for each type.
718    -------------------------------------------------------------------------- */
719
720 INFO_TABLE(stg_FULL_MVAR_info,stg_FULL_MVAR_entry,4,0,MVAR,,EF_,"MVAR","MVAR");
721 NON_ENTERABLE_ENTRY_CODE(FULL_MVAR);
722
723 INFO_TABLE(stg_EMPTY_MVAR_info,stg_EMPTY_MVAR_entry,4,0,MVAR,,EF_,"MVAR","MVAR");
724 NON_ENTERABLE_ENTRY_CODE(EMPTY_MVAR);
725
726 /* -----------------------------------------------------------------------------
727    END_TSO_QUEUE
728
729    This is a static nullary constructor (like []) that we use to mark the
730    end of a linked TSO queue.
731    -------------------------------------------------------------------------- */
732
733 INFO_TABLE_CONSTR(stg_END_TSO_QUEUE_info,stg_END_TSO_QUEUE_entry,0,0,0,CONSTR_NOCAF_STATIC,,EF_,"END_TSO_QUEUE","END_TSO_QUEUE");
734 NON_ENTERABLE_ENTRY_CODE(END_TSO_QUEUE);
735
736 SET_STATIC_HDR(stg_END_TSO_QUEUE_closure,stg_END_TSO_QUEUE_info,0/*CC*/,,EI_)
737 , /*payload*/{} };
738
739 /* -----------------------------------------------------------------------------
740    Mutable lists
741
742    Mutable lists (used by the garbage collector) consist of a chain of
743    StgMutClosures connected through their mut_link fields, ending in
744    an END_MUT_LIST closure.
745    -------------------------------------------------------------------------- */
746
747 INFO_TABLE_CONSTR(stg_END_MUT_LIST_info,stg_END_MUT_LIST_entry,0,0,0,CONSTR_NOCAF_STATIC,,EF_,"END_MUT_LIST","END_MUT_LIST");
748 NON_ENTERABLE_ENTRY_CODE(END_MUT_LIST);
749
750 SET_STATIC_HDR(stg_END_MUT_LIST_closure,stg_END_MUT_LIST_info,0/*CC*/,,EI_)
751 , /*payload*/{} };
752
753 INFO_TABLE(stg_MUT_CONS_info, stg_MUT_CONS_entry, 1, 1, MUT_CONS, , EF_, "MUT_CONS", "MUT_CONS");
754 NON_ENTERABLE_ENTRY_CODE(MUT_CONS);
755
756 /* -----------------------------------------------------------------------------
757    Exception lists
758    -------------------------------------------------------------------------- */
759
760 INFO_TABLE_CONSTR(stg_END_EXCEPTION_LIST_info,stg_END_EXCEPTION_LIST_entry,0,0,0,CONSTR_NOCAF_STATIC,,EF_,"END_EXCEPTION_LIST","END_EXCEPTION_LIST");
761 NON_ENTERABLE_ENTRY_CODE(END_EXCEPTION_LIST);
762
763 SET_STATIC_HDR(stg_END_EXCEPTION_LIST_closure,stg_END_EXCEPTION_LIST_info,0/*CC*/,,EI_)
764 , /*payload*/{} };
765
766 INFO_TABLE(stg_EXCEPTION_CONS_info, stg_EXCEPTION_CONS_entry, 1, 1, CONSTR, , EF_, "EXCEPTION_CONS", "EXCEPTION_CONS");
767 NON_ENTERABLE_ENTRY_CODE(EXCEPTION_CONS);
768
769 /* -----------------------------------------------------------------------------
770    Arrays
771
772    These come in two basic flavours: arrays of data (StgArrWords) and arrays of
773    pointers (StgArrPtrs).  They all have a similar layout:
774
775         ___________________________
776         | Info | No. of | data....
777         |  Ptr | Words  |
778         ---------------------------
779
780    These are *unpointed* objects: i.e. they cannot be entered.
781
782    -------------------------------------------------------------------------- */
783
784 #define ArrayInfo(type)                                 \
785 INFO_TABLE(stg_##type##_info, stg_##type##_entry, 0, 0, type, , EF_,"" # type "","" # type "");
786
787 ArrayInfo(ARR_WORDS);
788 NON_ENTERABLE_ENTRY_CODE(ARR_WORDS);
789 ArrayInfo(MUT_ARR_PTRS);
790 NON_ENTERABLE_ENTRY_CODE(MUT_ARR_PTRS);
791 ArrayInfo(MUT_ARR_PTRS_FROZEN);
792 NON_ENTERABLE_ENTRY_CODE(MUT_ARR_PTRS_FROZEN);
793
794 #undef ArrayInfo
795
796 /* -----------------------------------------------------------------------------
797    Mutable Variables
798    -------------------------------------------------------------------------- */
799
800 INFO_TABLE(stg_MUT_VAR_info, stg_MUT_VAR_entry, 1, 1, MUT_VAR, , EF_, "MUT_VAR", "MUT_VAR");
801 NON_ENTERABLE_ENTRY_CODE(MUT_VAR);
802
803 /* -----------------------------------------------------------------------------
804    Standard Error Entry.
805
806    This is used for filling in vector-table entries that can never happen,
807    for instance.
808    -------------------------------------------------------------------------- */
809 /* No longer used; we use NULL, because a) it never happens, right? and b)
810    Windows doesn't like DLL entry points being used as static initialisers
811 STGFUN(stg_error_entry)                                                 \
812 {                                                                       \
813   FB_                                                                   \
814     DUMP_ERRMSG("fatal: stg_error_entry");                              \
815     STGCALL1(shutdownHaskellAndExit, EXIT_FAILURE);                     \
816     return NULL;                                                        \
817   FE_                                                                   \
818 }
819 */
820 /* -----------------------------------------------------------------------------
821    Dummy return closure
822  
823    Entering this closure will just return to the address on the top of the
824    stack.  Useful for getting a thread in a canonical form where we can
825    just enter the top stack word to start the thread.  (see deleteThread)
826  * -------------------------------------------------------------------------- */
827
828 INFO_TABLE(stg_dummy_ret_info, stg_dummy_ret_entry, 0, 0, CONSTR_NOCAF_STATIC, , EF_, "DUMMY_RET", "DUMMY_RET");
829 STGFUN(stg_dummy_ret_entry)
830 {
831   W_ ret_addr;
832   FB_
833   ret_addr = Sp[0];
834   Sp++;
835   JMP_(ENTRY_CODE(ret_addr));
836   FE_
837 }
838 SET_STATIC_HDR(stg_dummy_ret_closure,stg_dummy_ret_info,CCS_DONT_CARE,,EI_)
839 , /*payload*/{} };
840
841 /* -----------------------------------------------------------------------------
842     Strict IO application - performing an IO action and entering its result.
843     
844     rts_evalIO() lets you perform Haskell IO actions from outside of Haskell-land,
845     returning back to you their result. Want this result to be evaluated to WHNF
846     by that time, so that we can easily get at the int/char/whatever using the
847     various get{Ty} functions provided by the RTS API.
848
849     forceIO takes care of this, performing the IO action and entering the
850     results that comes back.
851
852  * -------------------------------------------------------------------------- */
853
854 #ifdef REG_R1
855 INFO_TABLE_SRT_BITMAP(stg_forceIO_ret_info,stg_forceIO_ret_entry,0,0,0,0,RET_SMALL,,EF_,0,0);
856 STGFUN(stg_forceIO_ret_entry)
857 {
858   FB_
859   Sp++;
860   Sp -= sizeofW(StgSeqFrame);
861   PUSH_SEQ_FRAME(Sp);
862   JMP_(GET_ENTRY(R1.cl));
863 }
864 #else
865 INFO_TABLE_SRT_BITMAP(stg_forceIO_ret_info,stg_forceIO_ret_entry,0,0,0,0,RET_SMALL,,EF_,0,0);
866 STGFUN(stg_forceIO_ret_entry)
867 {
868   StgClosure *rval;
869   FB_
870   rval = (StgClosure *)Sp[0];
871   Sp += 2;
872   Sp -= sizeofW(StgSeqFrame);
873   PUSH_SEQ_FRAME(Sp);
874   R1.cl = rval;
875   JMP_(GET_ENTRY(R1.cl));
876 }
877 #endif
878
879 INFO_TABLE(stg_forceIO_info,stg_forceIO_entry,1,0,FUN_STATIC,,EF_,"FORCE_IO","FORCE_IO");
880 FN_(stg_forceIO_entry)
881 {
882   FB_
883   /* Sp[0] contains the IO action we want to perform */
884   R1.p  = (P_)Sp[0];
885   /* Replace it with the return continuation that enters the result. */
886   Sp[0] = (W_)&stg_forceIO_ret_info;
887   Sp--;
888   /* Push the RealWorld# tag and enter */
889   Sp[0] =(W_)REALWORLD_TAG;
890   JMP_(GET_ENTRY(R1.cl));
891   FE_
892 }
893 SET_STATIC_HDR(stg_forceIO_closure,stg_forceIO_info,CCS_DONT_CARE,,EI_)
894 , /*payload*/{} };
895
896
897 /* -----------------------------------------------------------------------------
898    CHARLIKE and INTLIKE closures.  
899
900    These are static representations of Chars and small Ints, so that
901    we can remove dynamic Chars and Ints during garbage collection and
902    replace them with references to the static objects.
903    -------------------------------------------------------------------------- */
904
905 #if defined(INTERPRETER) || defined(ENABLE_WIN32_DLL_SUPPORT)
906 /*
907  * When sticking the RTS in a DLL, we delay populating the
908  * Charlike and Intlike tables until load-time, which is only
909  * when we've got the real addresses to the C# and I# closures.
910  *
911  */
912 static INFO_TBL_CONST StgInfoTable czh_static_info;
913 static INFO_TBL_CONST StgInfoTable izh_static_info;
914 #define Char_hash_static_info czh_static_info
915 #define Int_hash_static_info izh_static_info
916 #else
917 #define Char_hash_static_info GHCziBase_Czh_static_info
918 #define Int_hash_static_info GHCziBase_Izh_static_info
919 #endif
920
921 #define CHARLIKE_HDR(n)                                         \
922         {                                                       \
923           STATIC_HDR(Char_hash_static_info, /* C# */            \
924                          CCS_DONT_CARE),                        \
925           data : n                                              \
926         }
927                                              
928 #define INTLIKE_HDR(n)                                          \
929         {                                                       \
930           STATIC_HDR(Int_hash_static_info,  /* I# */            \
931                          CCS_DONT_CARE),                        \
932           data : n                                              \
933         }
934
935 /* put these in the *data* section, since the garbage collector relies
936  * on the fact that static closures live in the data section.
937  */
938
939 /* end the name with _closure, to convince the mangler this is a closure */
940
941 StgIntCharlikeClosure stg_CHARLIKE_closure[] = {
942     CHARLIKE_HDR(0),
943     CHARLIKE_HDR(1),
944     CHARLIKE_HDR(2),
945     CHARLIKE_HDR(3),
946     CHARLIKE_HDR(4),
947     CHARLIKE_HDR(5),
948     CHARLIKE_HDR(6),
949     CHARLIKE_HDR(7),
950     CHARLIKE_HDR(8),
951     CHARLIKE_HDR(9),
952     CHARLIKE_HDR(10),
953     CHARLIKE_HDR(11),
954     CHARLIKE_HDR(12),
955     CHARLIKE_HDR(13),
956     CHARLIKE_HDR(14),
957     CHARLIKE_HDR(15),
958     CHARLIKE_HDR(16),
959     CHARLIKE_HDR(17),
960     CHARLIKE_HDR(18),
961     CHARLIKE_HDR(19),
962     CHARLIKE_HDR(20),
963     CHARLIKE_HDR(21),
964     CHARLIKE_HDR(22),
965     CHARLIKE_HDR(23),
966     CHARLIKE_HDR(24),
967     CHARLIKE_HDR(25),
968     CHARLIKE_HDR(26),
969     CHARLIKE_HDR(27),
970     CHARLIKE_HDR(28),
971     CHARLIKE_HDR(29),
972     CHARLIKE_HDR(30),
973     CHARLIKE_HDR(31),
974     CHARLIKE_HDR(32),
975     CHARLIKE_HDR(33),
976     CHARLIKE_HDR(34),
977     CHARLIKE_HDR(35),
978     CHARLIKE_HDR(36),
979     CHARLIKE_HDR(37),
980     CHARLIKE_HDR(38),
981     CHARLIKE_HDR(39),
982     CHARLIKE_HDR(40),
983     CHARLIKE_HDR(41),
984     CHARLIKE_HDR(42),
985     CHARLIKE_HDR(43),
986     CHARLIKE_HDR(44),
987     CHARLIKE_HDR(45),
988     CHARLIKE_HDR(46),
989     CHARLIKE_HDR(47),
990     CHARLIKE_HDR(48),
991     CHARLIKE_HDR(49),
992     CHARLIKE_HDR(50),
993     CHARLIKE_HDR(51),
994     CHARLIKE_HDR(52),
995     CHARLIKE_HDR(53),
996     CHARLIKE_HDR(54),
997     CHARLIKE_HDR(55),
998     CHARLIKE_HDR(56),
999     CHARLIKE_HDR(57),
1000     CHARLIKE_HDR(58),
1001     CHARLIKE_HDR(59),
1002     CHARLIKE_HDR(60),
1003     CHARLIKE_HDR(61),
1004     CHARLIKE_HDR(62),
1005     CHARLIKE_HDR(63),
1006     CHARLIKE_HDR(64),
1007     CHARLIKE_HDR(65),
1008     CHARLIKE_HDR(66),
1009     CHARLIKE_HDR(67),
1010     CHARLIKE_HDR(68),
1011     CHARLIKE_HDR(69),
1012     CHARLIKE_HDR(70),
1013     CHARLIKE_HDR(71),
1014     CHARLIKE_HDR(72),
1015     CHARLIKE_HDR(73),
1016     CHARLIKE_HDR(74),
1017     CHARLIKE_HDR(75),
1018     CHARLIKE_HDR(76),
1019     CHARLIKE_HDR(77),
1020     CHARLIKE_HDR(78),
1021     CHARLIKE_HDR(79),
1022     CHARLIKE_HDR(80),
1023     CHARLIKE_HDR(81),
1024     CHARLIKE_HDR(82),
1025     CHARLIKE_HDR(83),
1026     CHARLIKE_HDR(84),
1027     CHARLIKE_HDR(85),
1028     CHARLIKE_HDR(86),
1029     CHARLIKE_HDR(87),
1030     CHARLIKE_HDR(88),
1031     CHARLIKE_HDR(89),
1032     CHARLIKE_HDR(90),
1033     CHARLIKE_HDR(91),
1034     CHARLIKE_HDR(92),
1035     CHARLIKE_HDR(93),
1036     CHARLIKE_HDR(94),
1037     CHARLIKE_HDR(95),
1038     CHARLIKE_HDR(96),
1039     CHARLIKE_HDR(97),
1040     CHARLIKE_HDR(98),
1041     CHARLIKE_HDR(99),
1042     CHARLIKE_HDR(100),
1043     CHARLIKE_HDR(101),
1044     CHARLIKE_HDR(102),
1045     CHARLIKE_HDR(103),
1046     CHARLIKE_HDR(104),
1047     CHARLIKE_HDR(105),
1048     CHARLIKE_HDR(106),
1049     CHARLIKE_HDR(107),
1050     CHARLIKE_HDR(108),
1051     CHARLIKE_HDR(109),
1052     CHARLIKE_HDR(110),
1053     CHARLIKE_HDR(111),
1054     CHARLIKE_HDR(112),
1055     CHARLIKE_HDR(113),
1056     CHARLIKE_HDR(114),
1057     CHARLIKE_HDR(115),
1058     CHARLIKE_HDR(116),
1059     CHARLIKE_HDR(117),
1060     CHARLIKE_HDR(118),
1061     CHARLIKE_HDR(119),
1062     CHARLIKE_HDR(120),
1063     CHARLIKE_HDR(121),
1064     CHARLIKE_HDR(122),
1065     CHARLIKE_HDR(123),
1066     CHARLIKE_HDR(124),
1067     CHARLIKE_HDR(125),
1068     CHARLIKE_HDR(126),
1069     CHARLIKE_HDR(127),
1070     CHARLIKE_HDR(128),
1071     CHARLIKE_HDR(129),
1072     CHARLIKE_HDR(130),
1073     CHARLIKE_HDR(131),
1074     CHARLIKE_HDR(132),
1075     CHARLIKE_HDR(133),
1076     CHARLIKE_HDR(134),
1077     CHARLIKE_HDR(135),
1078     CHARLIKE_HDR(136),
1079     CHARLIKE_HDR(137),
1080     CHARLIKE_HDR(138),
1081     CHARLIKE_HDR(139),
1082     CHARLIKE_HDR(140),
1083     CHARLIKE_HDR(141),
1084     CHARLIKE_HDR(142),
1085     CHARLIKE_HDR(143),
1086     CHARLIKE_HDR(144),
1087     CHARLIKE_HDR(145),
1088     CHARLIKE_HDR(146),
1089     CHARLIKE_HDR(147),
1090     CHARLIKE_HDR(148),
1091     CHARLIKE_HDR(149),
1092     CHARLIKE_HDR(150),
1093     CHARLIKE_HDR(151),
1094     CHARLIKE_HDR(152),
1095     CHARLIKE_HDR(153),
1096     CHARLIKE_HDR(154),
1097     CHARLIKE_HDR(155),
1098     CHARLIKE_HDR(156),
1099     CHARLIKE_HDR(157),
1100     CHARLIKE_HDR(158),
1101     CHARLIKE_HDR(159),
1102     CHARLIKE_HDR(160),
1103     CHARLIKE_HDR(161),
1104     CHARLIKE_HDR(162),
1105     CHARLIKE_HDR(163),
1106     CHARLIKE_HDR(164),
1107     CHARLIKE_HDR(165),
1108     CHARLIKE_HDR(166),
1109     CHARLIKE_HDR(167),
1110     CHARLIKE_HDR(168),
1111     CHARLIKE_HDR(169),
1112     CHARLIKE_HDR(170),
1113     CHARLIKE_HDR(171),
1114     CHARLIKE_HDR(172),
1115     CHARLIKE_HDR(173),
1116     CHARLIKE_HDR(174),
1117     CHARLIKE_HDR(175),
1118     CHARLIKE_HDR(176),
1119     CHARLIKE_HDR(177),
1120     CHARLIKE_HDR(178),
1121     CHARLIKE_HDR(179),
1122     CHARLIKE_HDR(180),
1123     CHARLIKE_HDR(181),
1124     CHARLIKE_HDR(182),
1125     CHARLIKE_HDR(183),
1126     CHARLIKE_HDR(184),
1127     CHARLIKE_HDR(185),
1128     CHARLIKE_HDR(186),
1129     CHARLIKE_HDR(187),
1130     CHARLIKE_HDR(188),
1131     CHARLIKE_HDR(189),
1132     CHARLIKE_HDR(190),
1133     CHARLIKE_HDR(191),
1134     CHARLIKE_HDR(192),
1135     CHARLIKE_HDR(193),
1136     CHARLIKE_HDR(194),
1137     CHARLIKE_HDR(195),
1138     CHARLIKE_HDR(196),
1139     CHARLIKE_HDR(197),
1140     CHARLIKE_HDR(198),
1141     CHARLIKE_HDR(199),
1142     CHARLIKE_HDR(200),
1143     CHARLIKE_HDR(201),
1144     CHARLIKE_HDR(202),
1145     CHARLIKE_HDR(203),
1146     CHARLIKE_HDR(204),
1147     CHARLIKE_HDR(205),
1148     CHARLIKE_HDR(206),
1149     CHARLIKE_HDR(207),
1150     CHARLIKE_HDR(208),
1151     CHARLIKE_HDR(209),
1152     CHARLIKE_HDR(210),
1153     CHARLIKE_HDR(211),
1154     CHARLIKE_HDR(212),
1155     CHARLIKE_HDR(213),
1156     CHARLIKE_HDR(214),
1157     CHARLIKE_HDR(215),
1158     CHARLIKE_HDR(216),
1159     CHARLIKE_HDR(217),
1160     CHARLIKE_HDR(218),
1161     CHARLIKE_HDR(219),
1162     CHARLIKE_HDR(220),
1163     CHARLIKE_HDR(221),
1164     CHARLIKE_HDR(222),
1165     CHARLIKE_HDR(223),
1166     CHARLIKE_HDR(224),
1167     CHARLIKE_HDR(225),
1168     CHARLIKE_HDR(226),
1169     CHARLIKE_HDR(227),
1170     CHARLIKE_HDR(228),
1171     CHARLIKE_HDR(229),
1172     CHARLIKE_HDR(230),
1173     CHARLIKE_HDR(231),
1174     CHARLIKE_HDR(232),
1175     CHARLIKE_HDR(233),
1176     CHARLIKE_HDR(234),
1177     CHARLIKE_HDR(235),
1178     CHARLIKE_HDR(236),
1179     CHARLIKE_HDR(237),
1180     CHARLIKE_HDR(238),
1181     CHARLIKE_HDR(239),
1182     CHARLIKE_HDR(240),
1183     CHARLIKE_HDR(241),
1184     CHARLIKE_HDR(242),
1185     CHARLIKE_HDR(243),
1186     CHARLIKE_HDR(244),
1187     CHARLIKE_HDR(245),
1188     CHARLIKE_HDR(246),
1189     CHARLIKE_HDR(247),
1190     CHARLIKE_HDR(248),
1191     CHARLIKE_HDR(249),
1192     CHARLIKE_HDR(250),
1193     CHARLIKE_HDR(251),
1194     CHARLIKE_HDR(252),
1195     CHARLIKE_HDR(253),
1196     CHARLIKE_HDR(254),
1197     CHARLIKE_HDR(255)
1198 };
1199
1200 StgIntCharlikeClosure stg_INTLIKE_closure[] = {
1201     INTLIKE_HDR(-16),   /* MIN_INTLIKE == -16 */
1202     INTLIKE_HDR(-15),
1203     INTLIKE_HDR(-14),
1204     INTLIKE_HDR(-13),
1205     INTLIKE_HDR(-12),
1206     INTLIKE_HDR(-11),
1207     INTLIKE_HDR(-10),
1208     INTLIKE_HDR(-9),
1209     INTLIKE_HDR(-8),
1210     INTLIKE_HDR(-7),
1211     INTLIKE_HDR(-6),
1212     INTLIKE_HDR(-5),
1213     INTLIKE_HDR(-4),
1214     INTLIKE_HDR(-3),
1215     INTLIKE_HDR(-2),
1216     INTLIKE_HDR(-1),
1217     INTLIKE_HDR(0),
1218     INTLIKE_HDR(1),
1219     INTLIKE_HDR(2),
1220     INTLIKE_HDR(3),
1221     INTLIKE_HDR(4),
1222     INTLIKE_HDR(5),
1223     INTLIKE_HDR(6),
1224     INTLIKE_HDR(7),
1225     INTLIKE_HDR(8),
1226     INTLIKE_HDR(9),
1227     INTLIKE_HDR(10),
1228     INTLIKE_HDR(11),
1229     INTLIKE_HDR(12),
1230     INTLIKE_HDR(13),
1231     INTLIKE_HDR(14),
1232     INTLIKE_HDR(15),
1233     INTLIKE_HDR(16)     /* MAX_INTLIKE == 16 */
1234 };