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