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