[project @ 2000-01-14 11:45:21 by hwloidl]
[ghc-hetmet.git] / ghc / rts / StgMiscClosures.hc
1 /* -----------------------------------------------------------------------------
2  * $Id: StgMiscClosures.hc,v 1.32 2000/01/14 11:45:21 hwloidl Exp $
3  *
4  * (c) The GHC Team, 1998-1999
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 "ProfRts.h"
18 #include "SMP.h"
19 #if defined(GRAN) || defined(PAR)
20 # include "GranSimRts.h"      /* for DumpRawGranEvent */
21 # include "StgRun.h"    /* for StgReturn and register saving */
22 #endif
23
24 #ifdef HAVE_STDIO_H
25 #include <stdio.h>
26 #endif
27
28 /* ToDo: make the printing of panics more Win32-friendly, i.e.,
29  *       pop up some lovely message boxes (as well).
30  */
31 #define DUMP_ERRMSG(msg) STGCALL2(fprintf,stderr,msg)
32
33 /*
34   Template for the entry code of non-enterable closures.
35 */
36
37 #define NON_ENTERABLE_ENTRY_CODE(type)                                  \
38 STGFUN(type##_entry)                                                    \
39 {                                                                       \
40   FB_                                                                   \
41     DUMP_ERRMSG(#type " object entered!\n");                            \
42     STGCALL1(shutdownHaskellAndExit, EXIT_FAILURE);                     \
43   FE_                                                                   \
44 }
45
46 /* -----------------------------------------------------------------------------
47    Entry code for an indirection.
48
49    This code assumes R1 is in a register for now.
50    -------------------------------------------------------------------------- */
51
52 INFO_TABLE(IND_info,IND_entry,1,0,IND,,EF_,0,0);
53 STGFUN(IND_entry)
54 {
55     FB_
56     TICK_ENT_IND(Node); /* tick */
57
58     R1.p = (P_) ((StgInd*)R1.p)->indirectee;
59     TICK_ENT_VIA_NODE();
60     JMP_(ENTRY_CODE(*R1.p));
61     FE_
62 }
63
64 INFO_TABLE(IND_STATIC_info,IND_STATIC_entry,1,0,IND_STATIC,,EF_,0,0);
65 STGFUN(IND_STATIC_entry)
66 {
67     FB_
68     TICK_ENT_IND(Node); /* tick */
69   
70     R1.p = (P_) ((StgIndStatic*)R1.p)->indirectee;
71     TICK_ENT_VIA_NODE();
72     JMP_(ENTRY_CODE(*R1.p));
73     FE_
74 }
75
76 INFO_TABLE(IND_PERM_info,IND_PERM_entry,1,1,IND_PERM,,EF_,0,0);
77 STGFUN(IND_PERM_entry)
78 {
79     FB_
80     /* Don't add INDs to granularity cost */
81     /* Dont: TICK_ENT_IND(Node); for ticky-ticky; this ind is here only to help profiling */
82
83 #if defined(TICKY_TICKY) && !defined(PROFILING)
84     /* TICKY_TICKY && !PROFILING means PERM_IND *replaces* an IND, rather than being extra  */
85     TICK_ENT_PERM_IND(R1.p); /* tick */
86 #endif
87
88     /* Enter PAP cost centre -- lexical scoping only */
89     ENTER_CCS_PAP_CL(R1.cl);
90
91     /* For ticky-ticky, change the perm_ind to a normal ind on first
92      * entry, so the number of ent_perm_inds is the number of *thunks*
93      * entered again, not the number of subsequent entries.
94      *
95      * Since this screws up cost centres, we die if profiling and
96      * ticky_ticky are on at the same time.  KSW 1999-01.
97      */
98
99 #ifdef TICKY_TICKY
100 #  ifdef PROFILING
101 #    error Profiling and ticky-ticky do not mix at present!
102 #  endif  /* PROFILING */
103     SET_INFO((StgInd*)R1.p,&IND_info);
104 #endif /* TICKY_TICKY */
105
106     R1.p = (P_) ((StgInd*)R1.p)->indirectee;
107
108     /* Dont: TICK_ENT_VIA_NODE(); for ticky-ticky; as above */
109
110 #if defined(TICKY_TICKY) && !defined(PROFILING)
111     TICK_ENT_VIA_NODE();
112 #endif
113
114     JMP_(ENTRY_CODE(*R1.p));
115     FE_
116 }  
117
118 INFO_TABLE(IND_OLDGEN_info,IND_OLDGEN_entry,1,1,IND_OLDGEN,,EF_,0,0);
119 STGFUN(IND_OLDGEN_entry)
120 {
121     FB_
122     TICK_ENT_IND(Node); /* tick */
123   
124     R1.p = (P_) ((StgInd*)R1.p)->indirectee;
125     TICK_ENT_VIA_NODE();
126     JMP_(ENTRY_CODE(*R1.p));
127     FE_
128 }
129
130 INFO_TABLE(IND_OLDGEN_PERM_info,IND_OLDGEN_PERM_entry,1,1,IND_OLDGEN_PERM,,EF_,0,0);
131 STGFUN(IND_OLDGEN_PERM_entry)
132 {
133     FB_
134     /* Dont: TICK_ENT_IND(Node); for ticky-ticky; this ind is here only to help profiling */
135
136 #if defined(TICKY_TICKY) && !defined(PROFILING)
137     /* TICKY_TICKY && !PROFILING means PERM_IND *replaces* an IND, rather than being extra  */
138     TICK_ENT_PERM_IND(R1.p); /* tick */
139 #endif
140   
141     /* Enter PAP cost centre -- lexical scoping only */
142     ENTER_CCS_PAP_CL(R1.cl);
143
144     /* see comment in IND_PERM */
145 #ifdef TICKY_TICKY
146 #  ifdef PROFILING
147 #    error Profiling and ticky-ticky do not mix at present!
148 #  endif  /* PROFILING */
149     SET_INFO((StgInd*)R1.p,&IND_OLDGEN_info);
150 #endif /* TICKY_TICKY */
151
152     R1.p = (P_) ((StgInd*)R1.p)->indirectee;
153     TICK_ENT_VIA_NODE();
154     JMP_(ENTRY_CODE(*R1.p));
155     FE_
156 }
157
158 /* -----------------------------------------------------------------------------
159    Entry code for CAFs
160
161    This code assumes R1 is in a register for now.
162    -------------------------------------------------------------------------- */
163
164 INFO_TABLE(CAF_UNENTERED_info,CAF_UNENTERED_entry,1,3,CAF_UNENTERED,,EF_,0,0);
165 STGFUN(CAF_UNENTERED_entry)
166 {
167     FB_
168     /* ToDo: implement directly in GHC */
169     Sp -= 1;
170     Sp[0] = R1.w;
171     JMP_(stg_yield_to_Hugs);
172     FE_
173 }
174
175 /* 0,4 is entirely bogus; _do not_ rely on this info */
176 INFO_TABLE(CAF_ENTERED_info,CAF_ENTERED_entry,0,4,CAF_ENTERED,,EF_,0,0);
177 STGFUN(CAF_ENTERED_entry)
178 {
179     FB_
180     R1.p = (P_) ((StgCAF*)R1.p)->value; /* just a fancy indirection */
181     TICK_ENT_VIA_NODE();
182     JMP_(GET_ENTRY(R1.cl));
183     FE_
184 }
185
186 /* -----------------------------------------------------------------------------
187    Entry code for a black hole.
188
189    Entering a black hole normally causes a cyclic data dependency, but
190    in the concurrent world, black holes are synchronization points,
191    and they are turned into blocking queues when there are threads
192    waiting for the evaluation of the closure to finish.
193    -------------------------------------------------------------------------- */
194
195 /* Note: a BLACKHOLE and BLACKHOLE_BQ must be big enough to be
196  * overwritten with an indirection/evacuee/catch.  Thus we claim it
197  * has 1 non-pointer word of payload (in addition to the pointer word
198  * for the blocking queue in a BQ), which should be big enough for an
199  * old-generation indirection. 
200  */
201
202 INFO_TABLE(BLACKHOLE_info, BLACKHOLE_entry,0,2,BLACKHOLE,,EF_,0,0);
203 STGFUN(BLACKHOLE_entry)
204 {
205   FB_
206 #if defined(GRAN)
207     /* Before overwriting TSO_LINK */
208     STGCALL3(GranSimBlock,CurrentTSO,CurrentProc,(StgClosure *)R1.p /*Node*/);
209 #endif
210
211 #ifdef SMP
212     CMPXCHG(R1.cl->header.info, &BLACKHOLE_info, &WHITEHOLE_info);
213 #endif
214
215     TICK_ENT_BH();
216
217     /* Put ourselves on the blocking queue for this black hole */
218 #if defined(GRAN) || defined(PAR)
219     /* in fact, only difference is the type of the end-of-queue marker! */
220     CurrentTSO->link = END_BQ_QUEUE;
221     ((StgBlockingQueue *)R1.p)->blocking_queue = (StgBlockingQueueElement *)CurrentTSO;
222 #else
223     CurrentTSO->link = END_TSO_QUEUE;
224     ((StgBlockingQueue *)R1.p)->blocking_queue = CurrentTSO;
225 #endif
226     /* jot down why and on what closure we are blocked */
227     CurrentTSO->why_blocked = BlockedOnBlackHole;
228     CurrentTSO->block_info.closure = R1.cl;
229     /* closure is mutable since something has just been added to its BQ */
230     recordMutable((StgMutClosure *)R1.cl);
231     /* Change the BLACKHOLE into a BLACKHOLE_BQ */
232     ((StgBlockingQueue *)R1.p)->header.info = &BLACKHOLE_BQ_info;
233
234 #if defined(PAR)
235     /* Save the Thread State here, before calling RTS routines below! */
236     SAVE_THREAD_STATE(1);
237
238     /* if collecting stats update the execution time etc */
239     if (RtsFlags.ParFlags.ParStats.Full) {
240       /* Note that CURRENT_TIME may perform an unsafe call */
241       //rtsTime now = CURRENT_TIME; /* Now */
242       CurrentTSO->par.exectime += CURRENT_TIME - CurrentTSO->par.blockedat;
243       CurrentTSO->par.blockcount++;
244       CurrentTSO->par.blockedat = CURRENT_TIME;
245       DumpRawGranEvent(CURRENT_PROC, thisPE,
246                        GR_BLOCK, CurrentTSO, (StgClosure *)R1.p, 0);
247     }
248
249     THREAD_RETURN(1);  /* back to the scheduler */  
250 #else
251     /* stg_gen_block is too heavyweight, use a specialised one */
252     BLOCK_NP(1);
253 #endif
254
255   FE_
256 }
257
258 INFO_TABLE(BLACKHOLE_BQ_info, BLACKHOLE_BQ_entry,1,1,BLACKHOLE_BQ,,EF_,0,0);
259 STGFUN(BLACKHOLE_BQ_entry)
260 {
261   FB_
262 #if defined(GRAN)
263     /* Before overwriting TSO_LINK */
264     STGCALL3(GranSimBlock,CurrentTSO,CurrentProc,(StgClosure *)R1.p /*Node*/);
265 #endif
266
267 #ifdef SMP
268     CMPXCHG(R1.cl->header.info, &BLACKHOLE_BQ_info, &WHITEHOLE_info);
269 #endif
270
271     TICK_ENT_BH();
272
273     /* Put ourselves on the blocking queue for this black hole */
274     CurrentTSO->link = ((StgBlockingQueue *)R1.p)->blocking_queue;
275     ((StgBlockingQueue *)R1.p)->blocking_queue = CurrentTSO;
276     /* jot down why and on what closure we are blocked */
277     CurrentTSO->why_blocked = BlockedOnBlackHole;
278     CurrentTSO->block_info.closure = R1.cl;
279 #ifdef SMP
280     ((StgBlockingQueue *)R1.p)->header.info = &BLACKHOLE_BQ_info;
281 #endif
282
283 #if defined(PAR)
284     /* Save the Thread State here, before calling RTS routines below! */
285     SAVE_THREAD_STATE(1);
286
287     /* if collecting stats update the execution time etc */
288     if (RtsFlags.ParFlags.ParStats.Full) {
289       /* Note that CURRENT_TIME may perform an unsafe call */
290       //rtsTime now = CURRENT_TIME; /* Now */
291       CurrentTSO->par.exectime += CURRENT_TIME - CurrentTSO->par.blockedat;
292       CurrentTSO->par.blockcount++;
293       CurrentTSO->par.blockedat = CURRENT_TIME;
294       DumpRawGranEvent(CURRENT_PROC, thisPE,
295                        GR_BLOCK, CurrentTSO, (StgClosure *)R1.p, 0);
296     }
297
298     THREAD_RETURN(1);  /* back to the scheduler */  
299 #else
300     /* stg_gen_block is too heavyweight, use a specialised one */
301     BLOCK_NP(1);
302 #endif
303   FE_
304 }
305
306 /*
307    Revertible black holes are needed in the parallel world, to handle
308    negative acknowledgements of messages containing updatable closures.
309    The idea is that when the original message is transmitted, the closure
310    is turned into a revertible black hole...an object which acts like a
311    black hole when local threads try to enter it, but which can be reverted
312    back to the original closure if necessary.
313
314    It's actually a lot like a blocking queue (BQ) entry, because revertible
315    black holes are initially set up with an empty blocking queue.
316 */
317
318 #if defined(PAR) || defined(GRAN)
319
320 INFO_TABLE(RBH_info, RBH_entry,1,1,RBH,,EF_,0,0);
321 STGFUN(RBH_entry)
322 {
323   FB_
324 # if defined(GRAN)
325     /* mainly statistics gathering for GranSim simulation */
326     STGCALL3(GranSimBlock,CurrentTSO,CurrentProc,(StgClosure *)R1.p /*Node*/);
327 # endif
328
329     /* exactly the same as a BLACKHOLE_BQ_entry -- HWL */
330     /* Put ourselves on the blocking queue for this black hole */
331     CurrentTSO->link = ((StgBlockingQueue *)R1.p)->blocking_queue;
332     ((StgBlockingQueue *)R1.p)->blocking_queue = CurrentTSO;
333     /* jot down why and on what closure we are blocked */
334     CurrentTSO->why_blocked = BlockedOnBlackHole;
335     CurrentTSO->block_info.closure = R1.cl;
336
337 #if defined(PAR)
338     /* Save the Thread State here, before calling RTS routines below! */
339     SAVE_THREAD_STATE(1);
340
341     /* if collecting stats update the execution time etc */
342     if (RtsFlags.ParFlags.ParStats.Full) {
343       /* Note that CURRENT_TIME may perform an unsafe call */
344       //rtsTime now = CURRENT_TIME; /* Now */
345       CurrentTSO->par.exectime += CURRENT_TIME - CurrentTSO->par.blockedat;
346       CurrentTSO->par.blockcount++;
347       CurrentTSO->par.blockedat = CURRENT_TIME;
348       DumpRawGranEvent(CURRENT_PROC, thisPE,
349                        GR_BLOCK, CurrentTSO, (StgClosure *)R1.p, 0);
350     }
351
352     THREAD_RETURN(1);  /* back to the scheduler */  
353 #else
354     /* saves thread state and leaves thread in ThreadEnterGHC state; */
355     /* stg_gen_block is too heavyweight, use a specialised one */
356     BLOCK_NP(1); 
357 #endif
358
359   FE_
360 }
361
362 INFO_TABLE(RBH_Save_0_info, RBH_Save_0_entry,0,2,CONSTR,,EF_,0,0);
363 NON_ENTERABLE_ENTRY_CODE(RBH_Save_0);
364
365 INFO_TABLE(RBH_Save_1_info, RBH_Save_1_entry,1,1,CONSTR,,EF_,0,0);
366 NON_ENTERABLE_ENTRY_CODE(RBH_Save_1);
367
368 INFO_TABLE(RBH_Save_2_info, RBH_Save_2_entry,2,0,CONSTR,,EF_,0,0);
369 NON_ENTERABLE_ENTRY_CODE(RBH_Save_2);
370 #endif /* defined(PAR) || defined(GRAN) */
371
372 /* identical to BLACKHOLEs except for the infotag */
373 INFO_TABLE(CAF_BLACKHOLE_info, CAF_BLACKHOLE_entry,0,2,CAF_BLACKHOLE,,EF_,0,0);
374 STGFUN(CAF_BLACKHOLE_entry)
375 {
376   FB_
377 #if defined(GRAN)
378     /* mainly statistics gathering for GranSim simulation */
379     STGCALL3(GranSimBlock,CurrentTSO,CurrentProc,(StgClosure *)R1.p /*Node*/);
380 #endif
381
382 #ifdef SMP
383     CMPXCHG(R1.cl->header.info, &CAF_BLACKHOLE_info, &WHITEHOLE_info);
384 #endif
385
386     TICK_ENT_BH();
387
388     /* Put ourselves on the blocking queue for this black hole */
389 #if defined(GRAN) || defined(PAR)
390     /* in fact, only difference is the type of the end-of-queue marker! */
391     CurrentTSO->link = END_BQ_QUEUE;
392     ((StgBlockingQueue *)R1.p)->blocking_queue = (StgBlockingQueueElement *)CurrentTSO;
393 #else
394     CurrentTSO->link = END_TSO_QUEUE;
395     ((StgBlockingQueue *)R1.p)->blocking_queue = CurrentTSO;
396 #endif
397     /* jot down why and on what closure we are blocked */
398     CurrentTSO->why_blocked = BlockedOnBlackHole;
399     CurrentTSO->block_info.closure = R1.cl;
400     /* closure is mutable since something has just been added to its BQ */
401     recordMutable((StgMutClosure *)R1.cl);
402     /* Change the CAF_BLACKHOLE into a BLACKHOLE_BQ */
403     ((StgBlockingQueue *)R1.p)->header.info = &BLACKHOLE_BQ_info;
404
405 #if defined(PAR)
406     /* Save the Thread State here, before calling RTS routines below! */
407     SAVE_THREAD_STATE(1);
408
409     /* if collecting stats update the execution time etc */
410     if (RtsFlags.ParFlags.ParStats.Full) {
411       /* Note that CURRENT_TIME may perform an unsafe call */
412       //rtsTime now = CURRENT_TIME; /* Now */
413       CurrentTSO->par.exectime += CURRENT_TIME - CurrentTSO->par.blockedat;
414       CurrentTSO->par.blockcount++;
415       CurrentTSO->par.blockedat = CURRENT_TIME;
416       DumpRawGranEvent(CURRENT_PROC, thisPE,
417                        GR_BLOCK, CurrentTSO, (StgClosure *)R1.p, 0);
418     }
419
420     THREAD_RETURN(1);  /* back to the scheduler */  
421 #else
422     /* stg_gen_block is too heavyweight, use a specialised one */
423     BLOCK_NP(1);
424 #endif
425
426   FE_
427 }
428
429 #ifdef TICKY_TICKY
430 INFO_TABLE(SE_BLACKHOLE_info, SE_BLACKHOLE_entry,0,2,SE_BLACKHOLE,,EF_,0,0);
431 STGFUN(SE_BLACKHOLE_entry)
432 {
433   FB_
434     STGCALL3(fprintf,stderr,"SE_BLACKHOLE at %p entered!\n",R1.p);
435     STGCALL1(shutdownHaskellAndExit,EXIT_FAILURE);
436   FE_
437 }
438
439 INFO_TABLE(SE_CAF_BLACKHOLE_info, SE_CAF_BLACKHOLE_entry,0,2,SE_CAF_BLACKHOLE,,EF_,0,0);
440 STGFUN(SE_CAF_BLACKHOLE_entry)
441 {
442   FB_
443     STGCALL3(fprintf,stderr,"SE_CAF_BLACKHOLE at %p entered!\n",R1.p);
444     STGCALL1(shutdownHaskellAndExit,EXIT_FAILURE);
445   FE_
446 }
447 #endif
448
449 #ifdef SMP
450 INFO_TABLE(WHITEHOLE_info, WHITEHOLE_entry,0,2,CONSTR_NOCAF_STATIC,,EF_,0,0);
451 STGFUN(WHITEHOLE_entry)
452 {
453   FB_
454      JMP_(GET_ENTRY(R1.cl));
455   FE_
456 }
457 #endif
458
459 /* -----------------------------------------------------------------------------
460    The code for a BCO returns to the scheduler
461    -------------------------------------------------------------------------- */
462 INFO_TABLE(BCO_info,BCO_entry,0,0,BCO,,EF_,0,0);
463 EF_(BCO_entry) {                                
464   FB_   
465     Sp -= 1;
466     Sp[0] = R1.w;
467     JMP_(stg_yield_to_Hugs);
468   FE_                                                           
469 }
470
471 /* -----------------------------------------------------------------------------
472    Some static info tables for things that don't get entered, and
473    therefore don't need entry code (i.e. boxed but unpointed objects)
474    NON_ENTERABLE_ENTRY_CODE now defined at the beginning of the file
475    -------------------------------------------------------------------------- */
476
477 INFO_TABLE(TSO_info, TSO_entry, 0,0,TSO,,EF_,0,0);
478 NON_ENTERABLE_ENTRY_CODE(TSO);
479
480 /* -----------------------------------------------------------------------------
481    Evacuees are left behind by the garbage collector.  Any attempt to enter
482    one is a real bug.
483    -------------------------------------------------------------------------- */
484
485 INFO_TABLE(EVACUATED_info,EVACUATED_entry,1,0,EVACUATED,,EF_,0,0);
486 NON_ENTERABLE_ENTRY_CODE(EVACUATED);
487
488 /* -----------------------------------------------------------------------------
489    Weak pointers
490
491    Live weak pointers have a special closure type.  Dead ones are just
492    nullary constructors (although they live on the heap - we overwrite
493    live weak pointers with dead ones).
494    -------------------------------------------------------------------------- */
495
496 INFO_TABLE(WEAK_info,WEAK_entry,0,4,WEAK,,EF_,0,0);
497 NON_ENTERABLE_ENTRY_CODE(WEAK);
498
499 INFO_TABLE_CONSTR(DEAD_WEAK_info,DEAD_WEAK_entry,0,1,0,CONSTR,,EF_,0,0);
500 NON_ENTERABLE_ENTRY_CODE(DEAD_WEAK);
501
502 /* -----------------------------------------------------------------------------
503    NO_FINALIZER
504
505    This is a static nullary constructor (like []) that we use to mark an empty
506    finalizer in a weak pointer object.
507    -------------------------------------------------------------------------- */
508
509 INFO_TABLE_CONSTR(NO_FINALIZER_info,NO_FINALIZER_entry,0,0,0,CONSTR_NOCAF_STATIC,,EF_,0,0);
510 NON_ENTERABLE_ENTRY_CODE(NO_FINALIZER);
511
512 SET_STATIC_HDR(NO_FINALIZER_closure,NO_FINALIZER_info,0/*CC*/,,EI_)
513 , /*payload*/{} };
514
515 /* -----------------------------------------------------------------------------
516    Foreign Objects are unlifted and therefore never entered.
517    -------------------------------------------------------------------------- */
518
519 INFO_TABLE(FOREIGN_info,FOREIGN_entry,0,1,FOREIGN,,EF_,0,0);
520 NON_ENTERABLE_ENTRY_CODE(FOREIGN);
521
522 /* -----------------------------------------------------------------------------
523    Stable Names are unlifted too.
524    -------------------------------------------------------------------------- */
525
526 INFO_TABLE(STABLE_NAME_info,STABLE_NAME_entry,0,1,STABLE_NAME,,EF_,0,0);
527 NON_ENTERABLE_ENTRY_CODE(STABLE_NAME);
528
529 /* -----------------------------------------------------------------------------
530    MVars
531
532    There are two kinds of these: full and empty.  We need an info table
533    and entry code for each type.
534    -------------------------------------------------------------------------- */
535
536 INFO_TABLE(FULL_MVAR_info,FULL_MVAR_entry,4,0,MVAR,,EF_,0,0);
537 NON_ENTERABLE_ENTRY_CODE(FULL_MVAR);
538
539 INFO_TABLE(EMPTY_MVAR_info,EMPTY_MVAR_entry,4,0,MVAR,,EF_,0,0);
540 NON_ENTERABLE_ENTRY_CODE(EMPTY_MVAR);
541
542 /* -----------------------------------------------------------------------------
543    END_TSO_QUEUE
544
545    This is a static nullary constructor (like []) that we use to mark the
546    end of a linked TSO queue.
547    -------------------------------------------------------------------------- */
548
549 INFO_TABLE_CONSTR(END_TSO_QUEUE_info,END_TSO_QUEUE_entry,0,0,0,CONSTR_NOCAF_STATIC,,EF_,0,0);
550 NON_ENTERABLE_ENTRY_CODE(END_TSO_QUEUE);
551
552 SET_STATIC_HDR(END_TSO_QUEUE_closure,END_TSO_QUEUE_info,0/*CC*/,,EI_)
553 , /*payload*/{} };
554
555 /* -----------------------------------------------------------------------------
556    Mutable lists
557
558    Mutable lists (used by the garbage collector) consist of a chain of
559    StgMutClosures connected through their mut_link fields, ending in
560    an END_MUT_LIST closure.
561    -------------------------------------------------------------------------- */
562
563 INFO_TABLE_CONSTR(END_MUT_LIST_info,END_MUT_LIST_entry,0,0,0,CONSTR_NOCAF_STATIC,,EF_,0,0);
564 NON_ENTERABLE_ENTRY_CODE(END_MUT_LIST);
565
566 SET_STATIC_HDR(END_MUT_LIST_closure,END_MUT_LIST_info,0/*CC*/,,EI_)
567 , /*payload*/{} };
568
569 INFO_TABLE(MUT_CONS_info, MUT_CONS_entry, 1, 1, MUT_VAR, , EF_, 0, 0);
570 NON_ENTERABLE_ENTRY_CODE(MUT_CONS);
571
572 /* -----------------------------------------------------------------------------
573    Exception lists
574    -------------------------------------------------------------------------- */
575
576 INFO_TABLE_CONSTR(END_EXCEPTION_LIST_info,END_EXCEPTION_LIST_entry,0,0,0,CONSTR_NOCAF_STATIC,,EF_,0,0);
577 NON_ENTERABLE_ENTRY_CODE(END_EXCEPTION_LIST);
578
579 SET_STATIC_HDR(END_EXCEPTION_LIST_closure,END_EXCEPTION_LIST_info,0/*CC*/,,EI_)
580 , /*payload*/{} };
581
582 INFO_TABLE(EXCEPTION_CONS_info, EXCEPTION_CONS_entry, 1, 1, CONSTR, , EF_, 0, 0);
583 NON_ENTERABLE_ENTRY_CODE(EXCEPTION_CONS);
584
585 /* -----------------------------------------------------------------------------
586    Arrays
587
588    These come in two basic flavours: arrays of data (StgArrWords) and arrays of
589    pointers (StgArrPtrs).  They all have a similar layout:
590
591         ___________________________
592         | Info | No. of | data....
593         |  Ptr | Words  |
594         ---------------------------
595
596    These are *unpointed* objects: i.e. they cannot be entered.
597
598    -------------------------------------------------------------------------- */
599
600 #define ArrayInfo(type)                                 \
601 INFO_TABLE(type##_info, type##_entry, 0, 0, type, , EF_,0,0);
602
603 ArrayInfo(ARR_WORDS);
604 NON_ENTERABLE_ENTRY_CODE(ARR_WORDS);
605 ArrayInfo(MUT_ARR_PTRS);
606 NON_ENTERABLE_ENTRY_CODE(MUT_ARR_PTRS);
607 ArrayInfo(MUT_ARR_PTRS_FROZEN);
608 NON_ENTERABLE_ENTRY_CODE(MUT_ARR_PTRS_FROZEN);
609
610 #undef ArrayInfo
611
612 /* -----------------------------------------------------------------------------
613    Mutable Variables
614    -------------------------------------------------------------------------- */
615
616 INFO_TABLE(MUT_VAR_info, MUT_VAR_entry, 1, 1, MUT_VAR, , EF_, 0, 0);
617 NON_ENTERABLE_ENTRY_CODE(MUT_VAR);
618
619 /* -----------------------------------------------------------------------------
620    Standard Error Entry.
621
622    This is used for filling in vector-table entries that can never happen,
623    for instance.
624    -------------------------------------------------------------------------- */
625
626 STGFUN(stg_error_entry)                                                 \
627 {                                                                       \
628   FB_                                                                   \
629     DUMP_ERRMSG("fatal: stg_error_entry");                              \
630     STGCALL1(shutdownHaskellAndExit, EXIT_FAILURE);                     \
631   FE_                                                                   \
632 }
633
634 /* -----------------------------------------------------------------------------
635    Dummy return closure
636  
637    Entering this closure will just return to the address on the top of the
638    stack.  Useful for getting a thread in a canonical form where we can
639    just enter the top stack word to start the thread.  (see deleteThread)
640  * -------------------------------------------------------------------------- */
641
642 INFO_TABLE(dummy_ret_info, dummy_ret_entry, 0, 0, CONSTR_NOCAF_STATIC, , EF_, 0, 0);
643 FN_(dummy_ret_entry)
644 {
645   W_ ret_addr;
646   FB_
647   ret_addr = Sp[0];
648   Sp++;
649   JMP_(ENTRY_CODE(ret_addr));
650   FE_
651 }
652 SET_STATIC_HDR(dummy_ret_closure,dummy_ret_info,CCS_DONTZuCARE,,EI_)
653 , /*payload*/{} };
654
655 /* -----------------------------------------------------------------------------
656     Strict IO application - performing an IO action and entering its result.
657     
658     rts_evalIO() lets you perform Haskell IO actions from outside of Haskell-land,
659     returning back to you their result. Want this result to be evaluated to WHNF
660     by that time, so that we can easily get at the int/char/whatever using the
661     various get{Ty} functions provided by the RTS API.
662
663     forceIO takes care of this, performing the IO action and entering the
664     results that comes back.
665
666  * -------------------------------------------------------------------------- */
667
668 INFO_TABLE_SRT_BITMAP(forceIO_ret_info,forceIO_ret_entry,0,0,0,0,RET_SMALL,,EF_,0,0);
669 FN_(forceIO_ret_entry)
670 {
671   FB_
672   Sp++;
673   Sp -= sizeofW(StgSeqFrame);
674   PUSH_SEQ_FRAME(Sp);
675   JMP_(GET_ENTRY(R1.cl));
676 }
677
678
679 INFO_TABLE(forceIO_info,forceIO_entry,1,0,FUN,,EF_,0,0);
680 FN_(forceIO_entry)
681 {
682   FB_
683   /* Sp[0] contains the IO action we want to perform */
684   R1.p  = (P_)Sp[0];
685   /* Replace it with the return continuation that enters the result. */
686   Sp[0] = (W_)&forceIO_ret_info;
687   Sp--;
688   /* Push the RealWorld# tag and enter */
689   Sp[0] =(W_)REALWORLD_TAG;
690   JMP_(GET_ENTRY(R1.cl));
691   FE_
692 }
693 SET_STATIC_HDR(forceIO_closure,forceIO_info,CCS_DONTZuCARE,,EI_)
694 , /*payload*/{} };
695
696
697 /* -----------------------------------------------------------------------------
698    Standard Infotables (for use in interpreter)
699    -------------------------------------------------------------------------- */
700
701 #ifdef INTERPRETER
702
703 STGFUN(Hugs_CONSTR_entry)
704 {
705     /* R1 points at the constructor */
706     JMP_(ENTRY_CODE(((StgPtr*)Sp)[0]));
707 }
708
709 #define RET_BCO_ENTRY_TEMPLATE(label)   \
710    IFN_(label)                          \
711    {                                    \
712       FB_                               \
713       Sp -= 1;                          \
714       ((StgPtr*)Sp)[0] = R1.p;          \
715       JMP_(stg_yield_to_Hugs);          \
716       FE_                               \
717    }
718
719 RET_BCO_ENTRY_TEMPLATE(ret_bco_entry  );
720 RET_BCO_ENTRY_TEMPLATE(ret_bco_0_entry);
721 RET_BCO_ENTRY_TEMPLATE(ret_bco_1_entry);
722 RET_BCO_ENTRY_TEMPLATE(ret_bco_2_entry);
723 RET_BCO_ENTRY_TEMPLATE(ret_bco_3_entry);
724 RET_BCO_ENTRY_TEMPLATE(ret_bco_4_entry);
725 RET_BCO_ENTRY_TEMPLATE(ret_bco_5_entry);
726 RET_BCO_ENTRY_TEMPLATE(ret_bco_6_entry);
727 RET_BCO_ENTRY_TEMPLATE(ret_bco_7_entry);
728
729 VEC_POLY_INFO_TABLE(ret_bco,0, NULL/*srt*/, 0/*srt_off*/, 0/*srt_len*/, RET_BCO,, EF_);
730
731 #endif /* INTERPRETER */
732
733 #ifndef COMPILER
734
735 INFO_TABLE_CONSTR(Czh_con_info,Hugs_CONSTR_entry,0,sizeofW(StgChar),0,CONSTR,,EF_,0,0);
736 INFO_TABLE_CONSTR(Izh_con_info,Hugs_CONSTR_entry,0,sizeofW(StgInt),0,CONSTR,,EF_,0,0);
737 INFO_TABLE_CONSTR(I64zh_con_info,Hugs_CONSTR_entry,0,sizeofW(StgInt64),0,CONSTR,,EF_,0,0);
738 INFO_TABLE_CONSTR(Fzh_con_info,Hugs_CONSTR_entry,0,sizeofW(StgFloat),0,CONSTR,,EF_,0,0);
739 INFO_TABLE_CONSTR(Dzh_con_info,Hugs_CONSTR_entry,0,sizeofW(StgDouble),0,CONSTR,,EF_,0,0);
740 INFO_TABLE_CONSTR(Azh_con_info,Hugs_CONSTR_entry,0,sizeofW(StgAddr),0,CONSTR,,EF_,0,0);
741 INFO_TABLE_CONSTR(Wzh_con_info,Hugs_CONSTR_entry,0,sizeofW(StgWord),0,CONSTR,,EF_,0,0);
742 INFO_TABLE_CONSTR(StablePtr_con_info,Hugs_CONSTR_entry,0,sizeofW(StgStablePtr),0,CONSTR,,EF_,0,0);
743
744 /* These might seem redundant but {I,C}zh_static_info are used in
745  * {INT,CHAR}LIKE and the rest are used in RtsAPI.c
746  */
747 INFO_TABLE_CONSTR(Czh_static_info,Hugs_CONSTR_entry,0,sizeofW(StgChar),0,CONSTR_NOCAF_STATIC,,EF_,0,0);
748 INFO_TABLE_CONSTR(Izh_static_info,Hugs_CONSTR_entry,0,sizeofW(StgInt),0,CONSTR_NOCAF_STATIC,,EF_,0,0);
749 INFO_TABLE_CONSTR(I64zh_static_info,Hugs_CONSTR_entry,0,sizeofW(StgInt64),0,CONSTR_NOCAF_STATIC,,EF_,0,0);
750 INFO_TABLE_CONSTR(Fzh_static_info,Hugs_CONSTR_entry,0,sizeofW(StgFloat),0,CONSTR_NOCAF_STATIC,,EF_,0,0);
751 INFO_TABLE_CONSTR(Dzh_static_info,Hugs_CONSTR_entry,0,sizeofW(StgDouble),0,CONSTR_NOCAF_STATIC,,EF_,0,0);
752 INFO_TABLE_CONSTR(Azh_static_info,Hugs_CONSTR_entry,0,sizeofW(StgAddr),0,CONSTR_NOCAF_STATIC,,EF_,0,0);
753 INFO_TABLE_CONSTR(Wzh_static_info,Hugs_CONSTR_entry,0,sizeofW(StgWord),0,CONSTR_NOCAF_STATIC,,EF_,0,0);
754 INFO_TABLE_CONSTR(StablePtr_static_info,Hugs_CONSTR_entry,0,sizeofW(StgStablePtr),0,CONSTR_NOCAF_STATIC,,EF_,0,0);
755
756 #endif /* !defined(COMPILER) */
757
758 /* -----------------------------------------------------------------------------
759    CHARLIKE and INTLIKE closures.  
760
761    These are static representations of Chars and small Ints, so that
762    we can remove dynamic Chars and Ints during garbage collection and
763    replace them with references to the static objects.
764    -------------------------------------------------------------------------- */
765
766 #ifdef ENABLE_WIN32_DLL_SUPPORT
767 /*
768  * When sticking the RTS in a DLL, we delay populating the
769  * Charlike and Intlike tables until load-time, which is only
770  * when we've got the real addresses to the C# and I# closures.
771  *
772  */
773 static INFO_TBL_CONST StgInfoTable czh_static_info;
774 static INFO_TBL_CONST StgInfoTable izh_static_info;
775 #define Char_hash_static_info czh_static_info
776 #define Int_hash_static_info izh_static_info
777 #else
778 #define Char_hash_static_info Czh_static_info
779 #define Int_hash_static_info Izh_static_info
780 #endif
781
782 #define CHARLIKE_HDR(n)                                         \
783         {                                                       \
784           STATIC_HDR(Char_hash_static_info, /* C# */            \
785                          CCS_DONTZuCARE),                       \
786           data : n                                              \
787         }
788                                              
789 #define INTLIKE_HDR(n)                                          \
790         {                                                       \
791           STATIC_HDR(Int_hash_static_info,  /* I# */            \
792                          CCS_DONTZuCARE),                       \
793           data : n                                              \
794         }
795
796 /* put these in the *data* section, since the garbage collector relies
797  * on the fact that static closures live in the data section.
798  */
799
800 /* end the name with _closure, to convince the mangler this is a closure */
801
802 StgIntCharlikeClosure CHARLIKE_closure[] = {
803     CHARLIKE_HDR(0),
804     CHARLIKE_HDR(1),
805     CHARLIKE_HDR(2),
806     CHARLIKE_HDR(3),
807     CHARLIKE_HDR(4),
808     CHARLIKE_HDR(5),
809     CHARLIKE_HDR(6),
810     CHARLIKE_HDR(7),
811     CHARLIKE_HDR(8),
812     CHARLIKE_HDR(9),
813     CHARLIKE_HDR(10),
814     CHARLIKE_HDR(11),
815     CHARLIKE_HDR(12),
816     CHARLIKE_HDR(13),
817     CHARLIKE_HDR(14),
818     CHARLIKE_HDR(15),
819     CHARLIKE_HDR(16),
820     CHARLIKE_HDR(17),
821     CHARLIKE_HDR(18),
822     CHARLIKE_HDR(19),
823     CHARLIKE_HDR(20),
824     CHARLIKE_HDR(21),
825     CHARLIKE_HDR(22),
826     CHARLIKE_HDR(23),
827     CHARLIKE_HDR(24),
828     CHARLIKE_HDR(25),
829     CHARLIKE_HDR(26),
830     CHARLIKE_HDR(27),
831     CHARLIKE_HDR(28),
832     CHARLIKE_HDR(29),
833     CHARLIKE_HDR(30),
834     CHARLIKE_HDR(31),
835     CHARLIKE_HDR(32),
836     CHARLIKE_HDR(33),
837     CHARLIKE_HDR(34),
838     CHARLIKE_HDR(35),
839     CHARLIKE_HDR(36),
840     CHARLIKE_HDR(37),
841     CHARLIKE_HDR(38),
842     CHARLIKE_HDR(39),
843     CHARLIKE_HDR(40),
844     CHARLIKE_HDR(41),
845     CHARLIKE_HDR(42),
846     CHARLIKE_HDR(43),
847     CHARLIKE_HDR(44),
848     CHARLIKE_HDR(45),
849     CHARLIKE_HDR(46),
850     CHARLIKE_HDR(47),
851     CHARLIKE_HDR(48),
852     CHARLIKE_HDR(49),
853     CHARLIKE_HDR(50),
854     CHARLIKE_HDR(51),
855     CHARLIKE_HDR(52),
856     CHARLIKE_HDR(53),
857     CHARLIKE_HDR(54),
858     CHARLIKE_HDR(55),
859     CHARLIKE_HDR(56),
860     CHARLIKE_HDR(57),
861     CHARLIKE_HDR(58),
862     CHARLIKE_HDR(59),
863     CHARLIKE_HDR(60),
864     CHARLIKE_HDR(61),
865     CHARLIKE_HDR(62),
866     CHARLIKE_HDR(63),
867     CHARLIKE_HDR(64),
868     CHARLIKE_HDR(65),
869     CHARLIKE_HDR(66),
870     CHARLIKE_HDR(67),
871     CHARLIKE_HDR(68),
872     CHARLIKE_HDR(69),
873     CHARLIKE_HDR(70),
874     CHARLIKE_HDR(71),
875     CHARLIKE_HDR(72),
876     CHARLIKE_HDR(73),
877     CHARLIKE_HDR(74),
878     CHARLIKE_HDR(75),
879     CHARLIKE_HDR(76),
880     CHARLIKE_HDR(77),
881     CHARLIKE_HDR(78),
882     CHARLIKE_HDR(79),
883     CHARLIKE_HDR(80),
884     CHARLIKE_HDR(81),
885     CHARLIKE_HDR(82),
886     CHARLIKE_HDR(83),
887     CHARLIKE_HDR(84),
888     CHARLIKE_HDR(85),
889     CHARLIKE_HDR(86),
890     CHARLIKE_HDR(87),
891     CHARLIKE_HDR(88),
892     CHARLIKE_HDR(89),
893     CHARLIKE_HDR(90),
894     CHARLIKE_HDR(91),
895     CHARLIKE_HDR(92),
896     CHARLIKE_HDR(93),
897     CHARLIKE_HDR(94),
898     CHARLIKE_HDR(95),
899     CHARLIKE_HDR(96),
900     CHARLIKE_HDR(97),
901     CHARLIKE_HDR(98),
902     CHARLIKE_HDR(99),
903     CHARLIKE_HDR(100),
904     CHARLIKE_HDR(101),
905     CHARLIKE_HDR(102),
906     CHARLIKE_HDR(103),
907     CHARLIKE_HDR(104),
908     CHARLIKE_HDR(105),
909     CHARLIKE_HDR(106),
910     CHARLIKE_HDR(107),
911     CHARLIKE_HDR(108),
912     CHARLIKE_HDR(109),
913     CHARLIKE_HDR(110),
914     CHARLIKE_HDR(111),
915     CHARLIKE_HDR(112),
916     CHARLIKE_HDR(113),
917     CHARLIKE_HDR(114),
918     CHARLIKE_HDR(115),
919     CHARLIKE_HDR(116),
920     CHARLIKE_HDR(117),
921     CHARLIKE_HDR(118),
922     CHARLIKE_HDR(119),
923     CHARLIKE_HDR(120),
924     CHARLIKE_HDR(121),
925     CHARLIKE_HDR(122),
926     CHARLIKE_HDR(123),
927     CHARLIKE_HDR(124),
928     CHARLIKE_HDR(125),
929     CHARLIKE_HDR(126),
930     CHARLIKE_HDR(127),
931     CHARLIKE_HDR(128),
932     CHARLIKE_HDR(129),
933     CHARLIKE_HDR(130),
934     CHARLIKE_HDR(131),
935     CHARLIKE_HDR(132),
936     CHARLIKE_HDR(133),
937     CHARLIKE_HDR(134),
938     CHARLIKE_HDR(135),
939     CHARLIKE_HDR(136),
940     CHARLIKE_HDR(137),
941     CHARLIKE_HDR(138),
942     CHARLIKE_HDR(139),
943     CHARLIKE_HDR(140),
944     CHARLIKE_HDR(141),
945     CHARLIKE_HDR(142),
946     CHARLIKE_HDR(143),
947     CHARLIKE_HDR(144),
948     CHARLIKE_HDR(145),
949     CHARLIKE_HDR(146),
950     CHARLIKE_HDR(147),
951     CHARLIKE_HDR(148),
952     CHARLIKE_HDR(149),
953     CHARLIKE_HDR(150),
954     CHARLIKE_HDR(151),
955     CHARLIKE_HDR(152),
956     CHARLIKE_HDR(153),
957     CHARLIKE_HDR(154),
958     CHARLIKE_HDR(155),
959     CHARLIKE_HDR(156),
960     CHARLIKE_HDR(157),
961     CHARLIKE_HDR(158),
962     CHARLIKE_HDR(159),
963     CHARLIKE_HDR(160),
964     CHARLIKE_HDR(161),
965     CHARLIKE_HDR(162),
966     CHARLIKE_HDR(163),
967     CHARLIKE_HDR(164),
968     CHARLIKE_HDR(165),
969     CHARLIKE_HDR(166),
970     CHARLIKE_HDR(167),
971     CHARLIKE_HDR(168),
972     CHARLIKE_HDR(169),
973     CHARLIKE_HDR(170),
974     CHARLIKE_HDR(171),
975     CHARLIKE_HDR(172),
976     CHARLIKE_HDR(173),
977     CHARLIKE_HDR(174),
978     CHARLIKE_HDR(175),
979     CHARLIKE_HDR(176),
980     CHARLIKE_HDR(177),
981     CHARLIKE_HDR(178),
982     CHARLIKE_HDR(179),
983     CHARLIKE_HDR(180),
984     CHARLIKE_HDR(181),
985     CHARLIKE_HDR(182),
986     CHARLIKE_HDR(183),
987     CHARLIKE_HDR(184),
988     CHARLIKE_HDR(185),
989     CHARLIKE_HDR(186),
990     CHARLIKE_HDR(187),
991     CHARLIKE_HDR(188),
992     CHARLIKE_HDR(189),
993     CHARLIKE_HDR(190),
994     CHARLIKE_HDR(191),
995     CHARLIKE_HDR(192),
996     CHARLIKE_HDR(193),
997     CHARLIKE_HDR(194),
998     CHARLIKE_HDR(195),
999     CHARLIKE_HDR(196),
1000     CHARLIKE_HDR(197),
1001     CHARLIKE_HDR(198),
1002     CHARLIKE_HDR(199),
1003     CHARLIKE_HDR(200),
1004     CHARLIKE_HDR(201),
1005     CHARLIKE_HDR(202),
1006     CHARLIKE_HDR(203),
1007     CHARLIKE_HDR(204),
1008     CHARLIKE_HDR(205),
1009     CHARLIKE_HDR(206),
1010     CHARLIKE_HDR(207),
1011     CHARLIKE_HDR(208),
1012     CHARLIKE_HDR(209),
1013     CHARLIKE_HDR(210),
1014     CHARLIKE_HDR(211),
1015     CHARLIKE_HDR(212),
1016     CHARLIKE_HDR(213),
1017     CHARLIKE_HDR(214),
1018     CHARLIKE_HDR(215),
1019     CHARLIKE_HDR(216),
1020     CHARLIKE_HDR(217),
1021     CHARLIKE_HDR(218),
1022     CHARLIKE_HDR(219),
1023     CHARLIKE_HDR(220),
1024     CHARLIKE_HDR(221),
1025     CHARLIKE_HDR(222),
1026     CHARLIKE_HDR(223),
1027     CHARLIKE_HDR(224),
1028     CHARLIKE_HDR(225),
1029     CHARLIKE_HDR(226),
1030     CHARLIKE_HDR(227),
1031     CHARLIKE_HDR(228),
1032     CHARLIKE_HDR(229),
1033     CHARLIKE_HDR(230),
1034     CHARLIKE_HDR(231),
1035     CHARLIKE_HDR(232),
1036     CHARLIKE_HDR(233),
1037     CHARLIKE_HDR(234),
1038     CHARLIKE_HDR(235),
1039     CHARLIKE_HDR(236),
1040     CHARLIKE_HDR(237),
1041     CHARLIKE_HDR(238),
1042     CHARLIKE_HDR(239),
1043     CHARLIKE_HDR(240),
1044     CHARLIKE_HDR(241),
1045     CHARLIKE_HDR(242),
1046     CHARLIKE_HDR(243),
1047     CHARLIKE_HDR(244),
1048     CHARLIKE_HDR(245),
1049     CHARLIKE_HDR(246),
1050     CHARLIKE_HDR(247),
1051     CHARLIKE_HDR(248),
1052     CHARLIKE_HDR(249),
1053     CHARLIKE_HDR(250),
1054     CHARLIKE_HDR(251),
1055     CHARLIKE_HDR(252),
1056     CHARLIKE_HDR(253),
1057     CHARLIKE_HDR(254),
1058     CHARLIKE_HDR(255)
1059 };
1060
1061 StgIntCharlikeClosure INTLIKE_closure[] = {
1062     INTLIKE_HDR(-16),   /* MIN_INTLIKE == -16 */
1063     INTLIKE_HDR(-15),
1064     INTLIKE_HDR(-14),
1065     INTLIKE_HDR(-13),
1066     INTLIKE_HDR(-12),
1067     INTLIKE_HDR(-11),
1068     INTLIKE_HDR(-10),
1069     INTLIKE_HDR(-9),
1070     INTLIKE_HDR(-8),
1071     INTLIKE_HDR(-7),
1072     INTLIKE_HDR(-6),
1073     INTLIKE_HDR(-5),
1074     INTLIKE_HDR(-4),
1075     INTLIKE_HDR(-3),
1076     INTLIKE_HDR(-2),
1077     INTLIKE_HDR(-1),
1078     INTLIKE_HDR(0),
1079     INTLIKE_HDR(1),
1080     INTLIKE_HDR(2),
1081     INTLIKE_HDR(3),
1082     INTLIKE_HDR(4),
1083     INTLIKE_HDR(5),
1084     INTLIKE_HDR(6),
1085     INTLIKE_HDR(7),
1086     INTLIKE_HDR(8),
1087     INTLIKE_HDR(9),
1088     INTLIKE_HDR(10),
1089     INTLIKE_HDR(11),
1090     INTLIKE_HDR(12),
1091     INTLIKE_HDR(13),
1092     INTLIKE_HDR(14),
1093     INTLIKE_HDR(15),
1094     INTLIKE_HDR(16)     /* MAX_INTLIKE == 16 */
1095 };