Draw STG F and D registers from the same pool of available SSE registers on x86-64.
[ghc.git] / includes / mkDerivedConstants.c
1 /* --------------------------------------------------------------------------
2 *
3 * (c) The GHC Team, 1992-2012
4 *
5 * mkDerivedConstants.c
6 *
7 * Basically this is a C program that extracts information from the C
8 * declarations in the header files (primarily struct field offsets)
9 * and generates a header file that can be #included into non-C source
10 * containing this information.
11 *
12 * ------------------------------------------------------------------------*/
13
14 #define IN_STG_CODE 0
15
16 /*
17 * We need offsets of profiled things... better be careful that this
18 * doesn't affect the offsets of anything else.
19 */
20
21 #define PROFILING
22 #define THREADED_RTS
23
24 #include "PosixSource.h"
25 #include "Rts.h"
26 #include "Stable.h"
27 #include "Capability.h"
28
29 #include <inttypes.h>
30 #include <stdio.h>
31 #include <string.h>
32
33 enum Mode { Gen_Haskell_Type, Gen_Haskell_Value, Gen_Haskell_Wrappers, Gen_Haskell_Exports, Gen_Header } mode;
34
35 #define str(a,b) #a "_" #b
36
37 #define OFFSET(s_type, field) ((size_t)&(((s_type*)0)->field))
38 #define FIELD_SIZE(s_type, field) ((size_t)sizeof(((s_type*)0)->field))
39 #define TYPE_SIZE(type) (sizeof(type))
40
41 #pragma GCC poison sizeof
42
43 #define def_offset(str, offset) \
44 switch (mode) { \
45 case Gen_Haskell_Type: \
46 printf(" , pc_OFFSET_" str " :: Int\n"); \
47 break; \
48 case Gen_Haskell_Value: \
49 printf(" , pc_OFFSET_" str " = %" PRIdPTR "\n", (intptr_t)(offset)); \
50 break; \
51 case Gen_Haskell_Wrappers: \
52 printf("oFFSET_" str " :: DynFlags -> Int\n"); \
53 printf("oFFSET_" str " dflags = pc_OFFSET_" str " (sPlatformConstants (settings dflags))\n"); \
54 break; \
55 case Gen_Haskell_Exports: \
56 printf(" oFFSET_" str ",\n"); \
57 break; \
58 case Gen_Header: \
59 printf("#define OFFSET_" str " %" PRIdPTR "\n", (intptr_t)(offset)); \
60 break; \
61 }
62
63 #define ctype(type) \
64 switch (mode) { \
65 case Gen_Haskell_Type: \
66 case Gen_Haskell_Value: \
67 case Gen_Haskell_Wrappers: \
68 case Gen_Haskell_Exports: \
69 break; \
70 case Gen_Header: \
71 printf("#define SIZEOF_" #type " %" FMT_SizeT "\n", \
72 (size_t)TYPE_SIZE(type)); \
73 break; \
74 }
75
76 /* Defining REP_x to be b32 etc
77 These are both the C-- types used in a load
78 e.g. b32[addr]
79 and the names of the CmmTypes in the compiler
80 b32 :: CmmType
81 */
82 #define field_type_(want_haskell, str, s_type, field) \
83 switch (mode) { \
84 case Gen_Haskell_Type: \
85 if (want_haskell) { \
86 printf(" , pc_REP_" str " :: Int\n"); \
87 break; \
88 } \
89 case Gen_Haskell_Value: \
90 if (want_haskell) { \
91 printf(" , pc_REP_" str " = %" PRIdPTR "\n", (intptr_t)(FIELD_SIZE(s_type, field))); \
92 break; \
93 } \
94 case Gen_Haskell_Wrappers: \
95 case Gen_Haskell_Exports: \
96 break; \
97 case Gen_Header: \
98 printf("#define REP_" str " b"); \
99 printf("%" FMT_SizeT "\n", FIELD_SIZE(s_type, field) * 8); \
100 break; \
101 }
102
103 #define field_type_gcptr_(str, s_type, field) \
104 switch (mode) { \
105 case Gen_Haskell_Type: \
106 case Gen_Haskell_Value: \
107 case Gen_Haskell_Wrappers: \
108 case Gen_Haskell_Exports: \
109 break; \
110 case Gen_Header: \
111 printf("#define REP_" str " gcptr\n"); \
112 break; \
113 }
114
115 #define field_type(want_haskell, s_type, field) \
116 field_type_(want_haskell,str(s_type,field),s_type,field);
117
118 #define field_offset_(str, s_type, field) \
119 def_offset(str, OFFSET(s_type,field));
120
121 #define field_offset(s_type, field) \
122 field_offset_(str(s_type,field),s_type,field);
123
124 /* An access macro for use in C-- sources. */
125 #define struct_field_macro(str) \
126 switch (mode) { \
127 case Gen_Haskell_Type: \
128 case Gen_Haskell_Value: \
129 case Gen_Haskell_Wrappers: \
130 case Gen_Haskell_Exports: \
131 break; \
132 case Gen_Header: \
133 printf("#define " str "(__ptr__) REP_" str "[__ptr__+OFFSET_" str "]\n"); \
134 break; \
135 }
136
137 /* Outputs the byte offset and MachRep for a field */
138 #define struct_field_helper(want_haskell, s_type, field) \
139 field_offset(s_type, field); \
140 field_type(want_haskell, s_type, field); \
141 struct_field_macro(str(s_type,field))
142
143 #define struct_field(s_type, field) \
144 struct_field_helper(0, s_type, field)
145
146 #define struct_field_h(s_type, field) \
147 struct_field_helper(1, s_type, field)
148
149 #define struct_field_(str, s_type, field) \
150 field_offset_(str, s_type, field); \
151 field_type_(0,str, s_type, field); \
152 struct_field_macro(str)
153
154 #define def_size(str, size) \
155 switch (mode) { \
156 case Gen_Haskell_Type: \
157 printf(" , pc_SIZEOF_" str " :: Int\n"); \
158 break; \
159 case Gen_Haskell_Value: \
160 printf(" , pc_SIZEOF_" str " = %" FMT_SizeT "\n", (size_t)size); \
161 break; \
162 case Gen_Haskell_Wrappers: \
163 printf("sIZEOF_" str " :: DynFlags -> Int\n"); \
164 printf("sIZEOF_" str " dflags = pc_SIZEOF_" str " (sPlatformConstants (settings dflags))\n"); \
165 break; \
166 case Gen_Haskell_Exports: \
167 printf(" sIZEOF_" str ",\n"); \
168 break; \
169 case Gen_Header: \
170 printf("#define SIZEOF_" str " %" FMT_SizeT "\n", (size_t)size); \
171 break; \
172 }
173
174 #define def_closure_size(str, size) \
175 switch (mode) { \
176 case Gen_Haskell_Type: \
177 case Gen_Haskell_Value: \
178 case Gen_Haskell_Wrappers: \
179 case Gen_Haskell_Exports: \
180 break; \
181 case Gen_Header: \
182 printf("#define SIZEOF_" str " (SIZEOF_StgHeader+%" FMT_SizeT ")\n", (size_t)size); \
183 break; \
184 }
185
186 #define struct_size(s_type) \
187 def_size(#s_type, TYPE_SIZE(s_type));
188
189 /*
190 * Size of a closure type, minus the header, named SIZEOF_<type>_NoHdr
191 * Also, we #define SIZEOF_<type> to be the size of the whole closure for .cmm.
192 */
193 #define closure_size(s_type) \
194 def_size(#s_type "_NoHdr", TYPE_SIZE(s_type) - TYPE_SIZE(StgHeader)); \
195 def_closure_size(#s_type, TYPE_SIZE(s_type) - TYPE_SIZE(StgHeader));
196
197 #define thunk_size(s_type) \
198 def_size(#s_type "_NoThunkHdr", TYPE_SIZE(s_type) - TYPE_SIZE(StgThunkHeader)); \
199 closure_size(s_type)
200
201 /* An access macro for use in C-- sources. */
202 #define closure_field_macro(str) \
203 switch (mode) { \
204 case Gen_Haskell_Type: \
205 case Gen_Haskell_Value: \
206 case Gen_Haskell_Wrappers: \
207 case Gen_Haskell_Exports: \
208 break; \
209 case Gen_Header: \
210 printf("#define " str "(__ptr__) REP_" str "[__ptr__+SIZEOF_StgHeader+OFFSET_" str "]\n"); \
211 break; \
212 }
213
214 #define closure_field_offset_(str, s_type,field) \
215 def_offset(str, OFFSET(s_type,field) - TYPE_SIZE(StgHeader));
216
217 #define closure_field_offset(s_type,field) \
218 closure_field_offset_(str(s_type,field),s_type,field)
219
220 #define closure_payload_macro(str) \
221 switch (mode) { \
222 case Gen_Haskell_Type: \
223 case Gen_Haskell_Value: \
224 case Gen_Haskell_Wrappers: \
225 case Gen_Haskell_Exports: \
226 break; \
227 case Gen_Header: \
228 printf("#define " str "(__ptr__,__ix__) W_[__ptr__+SIZEOF_StgHeader+OFFSET_" str " + WDS(__ix__)]\n"); \
229 break; \
230 }
231
232 #define closure_payload(s_type,field) \
233 closure_field_offset_(str(s_type,field),s_type,field); \
234 closure_payload_macro(str(s_type,field));
235
236 /* Byte offset and MachRep for a closure field, minus the header */
237 #define closure_field_(str, s_type, field) \
238 closure_field_offset_(str,s_type,field) \
239 field_type_(0, str, s_type, field); \
240 closure_field_macro(str)
241
242 #define closure_field(s_type, field) \
243 closure_field_(str(s_type,field),s_type,field)
244
245 /* Byte offset and MachRep for a closure field, minus the header */
246 #define closure_field_gcptr_(str, s_type, field) \
247 closure_field_offset_(str,s_type,field) \
248 field_type_gcptr_(str, s_type, field); \
249 closure_field_macro(str)
250
251 #define closure_field_gcptr(s_type, field) \
252 closure_field_gcptr_(str(s_type,field),s_type,field)
253
254 /* Byte offset for a TSO field, minus the header and variable prof bit. */
255 #define tso_payload_offset(s_type, field) \
256 def_offset(str(s_type,field), OFFSET(s_type,field) - TYPE_SIZE(StgHeader) - TYPE_SIZE(StgTSOProfInfo));
257
258 /* Full byte offset for a TSO field, for use from Cmm */
259 #define tso_field_offset_macro(str) \
260 switch (mode) { \
261 case Gen_Haskell_Type: \
262 case Gen_Haskell_Value: \
263 case Gen_Haskell_Wrappers: \
264 case Gen_Haskell_Exports: \
265 break; \
266 case Gen_Header: \
267 printf("#define TSO_OFFSET_" str " (SIZEOF_StgHeader+SIZEOF_OPT_StgTSOProfInfo+OFFSET_" str ")\n"); \
268 break; \
269 }
270
271 #define tso_field_offset(s_type, field) \
272 tso_payload_offset(s_type, field); \
273 tso_field_offset_macro(str(s_type,field));
274
275 #define tso_field_macro(str) \
276 switch (mode) { \
277 case Gen_Haskell_Type: \
278 case Gen_Haskell_Value: \
279 case Gen_Haskell_Wrappers: \
280 case Gen_Haskell_Exports: \
281 break; \
282 case Gen_Header: \
283 printf("#define " str "(__ptr__) REP_" str "[__ptr__+TSO_OFFSET_" str "]\n") \
284 break; \
285 }
286
287 #define tso_field(s_type, field) \
288 field_type(0, s_type, field); \
289 tso_field_offset(s_type,field); \
290 tso_field_macro(str(s_type,field))
291
292 #define opt_struct_size(s_type, option) \
293 switch (mode) { \
294 case Gen_Haskell_Type: \
295 case Gen_Haskell_Value: \
296 case Gen_Haskell_Wrappers: \
297 case Gen_Haskell_Exports: \
298 break; \
299 case Gen_Header: \
300 printf("#ifdef " #option "\n"); \
301 printf("#define SIZEOF_OPT_" #s_type " SIZEOF_" #s_type "\n"); \
302 printf("#else\n"); \
303 printf("#define SIZEOF_OPT_" #s_type " 0\n"); \
304 printf("#endif\n\n"); \
305 break; \
306 }
307
308 #define FUN_OFFSET(sym) (OFFSET(Capability,f.sym) - OFFSET(Capability,r))
309
310 void constantBool(char *haskellName, int val) {
311 switch (mode) {
312 case Gen_Haskell_Type:
313 printf(" , pc_%s :: Bool\n", haskellName);
314 break;
315 case Gen_Haskell_Value:
316 printf(" , pc_%s = %s\n", haskellName, val ? "True" : "False");
317 break;
318 case Gen_Haskell_Wrappers:
319 printf("%s :: DynFlags -> Bool\n", haskellName);
320 printf("%s dflags = pc_%s (sPlatformConstants (settings dflags))\n",
321 haskellName, haskellName);
322 break;
323 case Gen_Haskell_Exports:
324 printf(" %s,\n", haskellName);
325 break;
326 case Gen_Header:
327 break;
328 }
329 }
330
331 void constantIntegralC(char *haskellType, char *cName, char *haskellName,
332 intptr_t val) {
333 switch (mode) {
334 case Gen_Haskell_Type:
335 printf(" , pc_%s :: %s\n", haskellName, haskellType);
336 break;
337 case Gen_Haskell_Value:
338 printf(" , pc_%s = %" PRIdPTR "\n", haskellName, val);
339 break;
340 case Gen_Haskell_Wrappers:
341 printf("%s :: DynFlags -> %s\n", haskellName, haskellType);
342 printf("%s dflags = pc_%s (sPlatformConstants (settings dflags))\n",
343 haskellName, haskellName);
344 break;
345 case Gen_Haskell_Exports:
346 printf(" %s,\n", haskellName);
347 break;
348 case Gen_Header:
349 if (cName != NULL) {
350 printf("#define %s %" PRIdPTR "\n", cName, val);
351 }
352 break;
353 }
354 }
355
356 void constantIntC(char *cName, char *haskellName, intptr_t val) {
357 /* If the value is larger than 2^28 or smaller than -2^28, then fail.
358 This test is a bit conservative, but if any constants are roughly
359 maxBoun or minBound then we probably need them to be Integer
360 rather than Int so that cross-compiling between 32bit and 64bit
361 platforms works. */
362 if (val > 268435456) {
363 printf("Value too large for constantInt: %" PRIdPTR "\n", val);
364 exit(1);
365 }
366 if (val < -268435456) {
367 printf("Value too small for constantInt: %" PRIdPTR "\n", val);
368 exit(1);
369 }
370
371 constantIntegralC("Int", cName, haskellName, val);
372 }
373
374 void constantInt(char *name, intptr_t val) {
375 constantIntC(NULL, name, val);
376 }
377
378 void constantInteger(char *name, intptr_t val) {
379 constantIntegralC("Integer", NULL, name, val);
380 }
381
382 int
383 main(int argc, char *argv[])
384 {
385 if (argc == 1) {
386 mode = Gen_Header;
387 }
388 else if (argc == 2) {
389 if (0 == strcmp("--gen-haskell-type", argv[1])) {
390 mode = Gen_Haskell_Type;
391 }
392 else if (0 == strcmp("--gen-haskell-value", argv[1])) {
393 mode = Gen_Haskell_Value;
394 }
395 else if (0 == strcmp("--gen-haskell-wrappers", argv[1])) {
396 mode = Gen_Haskell_Wrappers;
397 }
398 else if (0 == strcmp("--gen-haskell-exports", argv[1])) {
399 mode = Gen_Haskell_Exports;
400 }
401 else {
402 printf("Bad args\n");
403 exit(1);
404 }
405 }
406 else {
407 printf("Bad args\n");
408 exit(1);
409 }
410
411 switch (mode) {
412 case Gen_Haskell_Type:
413 printf("data PlatformConstants = PlatformConstants {\n");
414 /* Now a kludge that allows the real entries to all start with a
415 comma, which makes life a little easier */
416 printf(" pc_platformConstants :: ()\n");
417 break;
418 case Gen_Haskell_Value:
419 printf("PlatformConstants {\n");
420 printf(" pc_platformConstants = ()\n");
421 break;
422 case Gen_Haskell_Wrappers:
423 case Gen_Haskell_Exports:
424 break;
425 case Gen_Header:
426 printf("/* This file is created automatically. Do not edit by hand.*/\n\n");
427
428 break;
429 }
430
431 // Closure header sizes.
432 constantIntC("STD_HDR_SIZE", "sTD_HDR_SIZE",
433 sizeofW(StgHeader) - sizeofW(StgProfHeader));
434 /* grrr.. PROFILING is on so we need to subtract sizeofW(StgProfHeader) */
435 constantIntC("PROF_HDR_SIZE", "pROF_HDR_SIZE", sizeofW(StgProfHeader));
436
437 // Size of a storage manager block (in bytes).
438 constantIntC("BLOCK_SIZE", "bLOCK_SIZE", BLOCK_SIZE);
439 if (mode == Gen_Header) {
440 constantIntC("MBLOCK_SIZE", "mBLOCK_SIZE", MBLOCK_SIZE);
441 }
442 // blocks that fit in an MBlock, leaving space for the block descriptors
443 constantIntC("BLOCKS_PER_MBLOCK", "bLOCKS_PER_MBLOCK", BLOCKS_PER_MBLOCK);
444 // could be derived, but better to save doing the calculation twice
445
446
447 field_offset(StgRegTable, rR1);
448 field_offset(StgRegTable, rR2);
449 field_offset(StgRegTable, rR3);
450 field_offset(StgRegTable, rR4);
451 field_offset(StgRegTable, rR5);
452 field_offset(StgRegTable, rR6);
453 field_offset(StgRegTable, rR7);
454 field_offset(StgRegTable, rR8);
455 field_offset(StgRegTable, rR9);
456 field_offset(StgRegTable, rR10);
457 field_offset(StgRegTable, rF1);
458 field_offset(StgRegTable, rF2);
459 field_offset(StgRegTable, rF3);
460 field_offset(StgRegTable, rF4);
461 field_offset(StgRegTable, rF5);
462 field_offset(StgRegTable, rF6);
463 field_offset(StgRegTable, rD1);
464 field_offset(StgRegTable, rD2);
465 field_offset(StgRegTable, rD3);
466 field_offset(StgRegTable, rD4);
467 field_offset(StgRegTable, rD5);
468 field_offset(StgRegTable, rD6);
469 field_offset(StgRegTable, rL1);
470 field_offset(StgRegTable, rSp);
471 field_offset(StgRegTable, rSpLim);
472 field_offset(StgRegTable, rHp);
473 field_offset(StgRegTable, rHpLim);
474 field_offset(StgRegTable, rCCCS);
475 field_offset(StgRegTable, rCurrentTSO);
476 field_offset(StgRegTable, rCurrentNursery);
477 field_offset(StgRegTable, rHpAlloc);
478 if (mode == Gen_Header) {
479 struct_field(StgRegTable, rRet);
480 struct_field(StgRegTable, rNursery);
481 }
482
483 def_offset("stgEagerBlackholeInfo", FUN_OFFSET(stgEagerBlackholeInfo));
484 def_offset("stgGCEnter1", FUN_OFFSET(stgGCEnter1));
485 def_offset("stgGCFun", FUN_OFFSET(stgGCFun));
486
487 field_offset(Capability, r);
488 if (mode == Gen_Header) {
489 field_offset(Capability, lock);
490 struct_field(Capability, no);
491 struct_field(Capability, mut_lists);
492 struct_field(Capability, context_switch);
493 struct_field(Capability, interrupt);
494 struct_field(Capability, sparks);
495 }
496
497 struct_field(bdescr, start);
498 struct_field(bdescr, free);
499 struct_field(bdescr, blocks);
500 if (mode == Gen_Header) {
501 struct_field(bdescr, gen_no);
502 struct_field(bdescr, link);
503
504 struct_size(generation);
505 struct_field(generation, n_new_large_words);
506 }
507
508 struct_size(CostCentreStack);
509 if (mode == Gen_Header) {
510 struct_field(CostCentreStack, ccsID);
511 }
512 struct_field_h(CostCentreStack, mem_alloc);
513 struct_field_h(CostCentreStack, scc_count);
514 if (mode == Gen_Header) {
515 struct_field(CostCentreStack, prevStack);
516
517 struct_field(CostCentre, ccID);
518 struct_field(CostCentre, link);
519
520 struct_field(StgHeader, info);
521 }
522 struct_field_("StgHeader_ccs", StgHeader, prof.ccs);
523 struct_field_("StgHeader_ldvw", StgHeader, prof.hp.ldvw);
524
525 struct_size(StgSMPThunkHeader);
526
527 if (mode == Gen_Header) {
528 closure_payload(StgClosure,payload);
529 }
530
531 struct_field_h(StgEntCounter, allocs);
532 struct_field(StgEntCounter, registeredp);
533 struct_field(StgEntCounter, link);
534 struct_field(StgEntCounter, entry_count);
535
536 closure_size(StgUpdateFrame);
537 if (mode == Gen_Header) {
538 closure_size(StgCatchFrame);
539 closure_size(StgStopFrame);
540 }
541
542 closure_size(StgMutArrPtrs);
543 closure_field(StgMutArrPtrs, ptrs);
544 closure_field(StgMutArrPtrs, size);
545
546 closure_size(StgArrWords);
547 if (mode == Gen_Header) {
548 closure_field(StgArrWords, bytes);
549 closure_payload(StgArrWords, payload);
550
551 closure_field(StgTSO, _link);
552 closure_field(StgTSO, global_link);
553 closure_field(StgTSO, what_next);
554 closure_field(StgTSO, why_blocked);
555 closure_field(StgTSO, block_info);
556 closure_field(StgTSO, blocked_exceptions);
557 closure_field(StgTSO, id);
558 closure_field(StgTSO, cap);
559 closure_field(StgTSO, saved_errno);
560 closure_field(StgTSO, trec);
561 closure_field(StgTSO, flags);
562 closure_field(StgTSO, dirty);
563 closure_field(StgTSO, bq);
564 }
565 closure_field_("StgTSO_cccs", StgTSO, prof.cccs);
566 closure_field(StgTSO, stackobj);
567
568 closure_field(StgStack, sp);
569 closure_field_offset(StgStack, stack);
570 if (mode == Gen_Header) {
571 closure_field(StgStack, stack_size);
572 closure_field(StgStack, dirty);
573
574 struct_size(StgTSOProfInfo);
575
576 opt_struct_size(StgTSOProfInfo,PROFILING);
577 }
578
579 closure_field(StgUpdateFrame, updatee);
580
581 if (mode == Gen_Header) {
582 closure_field(StgCatchFrame, handler);
583 closure_field(StgCatchFrame, exceptions_blocked);
584
585 closure_size(StgPAP);
586 closure_field(StgPAP, n_args);
587 closure_field_gcptr(StgPAP, fun);
588 closure_field(StgPAP, arity);
589 closure_payload(StgPAP, payload);
590
591 thunk_size(StgAP);
592 closure_field(StgAP, n_args);
593 closure_field_gcptr(StgAP, fun);
594 closure_payload(StgAP, payload);
595
596 thunk_size(StgAP_STACK);
597 closure_field(StgAP_STACK, size);
598 closure_field_gcptr(StgAP_STACK, fun);
599 closure_payload(StgAP_STACK, payload);
600
601 thunk_size(StgSelector);
602
603 closure_field_gcptr(StgInd, indirectee);
604
605 closure_size(StgMutVar);
606 closure_field(StgMutVar, var);
607
608 closure_size(StgAtomicallyFrame);
609 closure_field(StgAtomicallyFrame, code);
610 closure_field(StgAtomicallyFrame, next_invariant_to_check);
611 closure_field(StgAtomicallyFrame, result);
612
613 closure_field(StgInvariantCheckQueue, invariant);
614 closure_field(StgInvariantCheckQueue, my_execution);
615 closure_field(StgInvariantCheckQueue, next_queue_entry);
616
617 closure_field(StgAtomicInvariant, code);
618
619 closure_field(StgTRecHeader, enclosing_trec);
620
621 closure_size(StgCatchSTMFrame);
622 closure_field(StgCatchSTMFrame, handler);
623 closure_field(StgCatchSTMFrame, code);
624
625 closure_size(StgCatchRetryFrame);
626 closure_field(StgCatchRetryFrame, running_alt_code);
627 closure_field(StgCatchRetryFrame, first_code);
628 closure_field(StgCatchRetryFrame, alt_code);
629
630 closure_field(StgTVarWatchQueue, closure);
631 closure_field(StgTVarWatchQueue, next_queue_entry);
632 closure_field(StgTVarWatchQueue, prev_queue_entry);
633
634 closure_field(StgTVar, current_value);
635
636 closure_size(StgWeak);
637 closure_field(StgWeak,link);
638 closure_field(StgWeak,key);
639 closure_field(StgWeak,value);
640 closure_field(StgWeak,finalizer);
641 closure_field(StgWeak,cfinalizer);
642
643 closure_size(StgDeadWeak);
644 closure_field(StgDeadWeak,link);
645
646 closure_size(StgMVar);
647 closure_field(StgMVar,head);
648 closure_field(StgMVar,tail);
649 closure_field(StgMVar,value);
650
651 closure_size(StgMVarTSOQueue);
652 closure_field(StgMVarTSOQueue, link);
653 closure_field(StgMVarTSOQueue, tso);
654
655 closure_size(StgBCO);
656 closure_field(StgBCO, instrs);
657 closure_field(StgBCO, literals);
658 closure_field(StgBCO, ptrs);
659 closure_field(StgBCO, arity);
660 closure_field(StgBCO, size);
661 closure_payload(StgBCO, bitmap);
662
663 closure_size(StgStableName);
664 closure_field(StgStableName,sn);
665
666 closure_size(StgBlockingQueue);
667 closure_field(StgBlockingQueue, bh);
668 closure_field(StgBlockingQueue, owner);
669 closure_field(StgBlockingQueue, queue);
670 closure_field(StgBlockingQueue, link);
671
672 closure_size(MessageBlackHole);
673 closure_field(MessageBlackHole, link);
674 closure_field(MessageBlackHole, tso);
675 closure_field(MessageBlackHole, bh);
676
677 struct_field_("RtsFlags_ProfFlags_showCCSOnException",
678 RTS_FLAGS, ProfFlags.showCCSOnException);
679 struct_field_("RtsFlags_DebugFlags_apply",
680 RTS_FLAGS, DebugFlags.apply);
681 struct_field_("RtsFlags_DebugFlags_sanity",
682 RTS_FLAGS, DebugFlags.sanity);
683 struct_field_("RtsFlags_DebugFlags_weak",
684 RTS_FLAGS, DebugFlags.weak);
685 struct_field_("RtsFlags_GcFlags_initialStkSize",
686 RTS_FLAGS, GcFlags.initialStkSize);
687 struct_field_("RtsFlags_MiscFlags_tickInterval",
688 RTS_FLAGS, MiscFlags.tickInterval);
689
690 struct_size(StgFunInfoExtraFwd);
691 struct_field(StgFunInfoExtraFwd, slow_apply);
692 struct_field(StgFunInfoExtraFwd, fun_type);
693 struct_field(StgFunInfoExtraFwd, arity);
694 struct_field_("StgFunInfoExtraFwd_bitmap", StgFunInfoExtraFwd, b.bitmap);
695 }
696
697 struct_size(StgFunInfoExtraRev);
698 if (mode == Gen_Header) {
699 struct_field(StgFunInfoExtraRev, slow_apply_offset);
700 struct_field(StgFunInfoExtraRev, fun_type);
701 struct_field(StgFunInfoExtraRev, arity);
702 struct_field_("StgFunInfoExtraRev_bitmap", StgFunInfoExtraRev, b.bitmap);
703
704 struct_field(StgLargeBitmap, size);
705 field_offset(StgLargeBitmap, bitmap);
706
707 struct_size(snEntry);
708 struct_field(snEntry,sn_obj);
709 struct_field(snEntry,addr);
710 }
711
712 #ifdef mingw32_HOST_OS
713 /* Note that this conditional part only affects the C headers.
714 That's important, as it means we get the same PlatformConstants
715 type on all platforms. */
716 if (mode == Gen_Header) {
717 struct_size(StgAsyncIOResult);
718 struct_field(StgAsyncIOResult, reqID);
719 struct_field(StgAsyncIOResult, len);
720 struct_field(StgAsyncIOResult, errCode);
721 }
722 #endif
723
724 // pre-compiled thunk types
725 constantInt("mAX_SPEC_SELECTEE_SIZE", MAX_SPEC_SELECTEE_SIZE);
726 constantInt("mAX_SPEC_AP_SIZE", MAX_SPEC_AP_SIZE);
727
728 // closure sizes: these do NOT include the header (see below for
729 // header sizes)
730 constantInt("mIN_PAYLOAD_SIZE", MIN_PAYLOAD_SIZE);
731
732 constantInt("mIN_INTLIKE", MIN_INTLIKE);
733 constantInt("mAX_INTLIKE", MAX_INTLIKE);
734
735 constantInt("mIN_CHARLIKE", MIN_CHARLIKE);
736 constantInt("mAX_CHARLIKE", MAX_CHARLIKE);
737
738 constantInt("mUT_ARR_PTRS_CARD_BITS", MUT_ARR_PTRS_CARD_BITS);
739
740 // A section of code-generator-related MAGIC CONSTANTS.
741 constantInt("mAX_Vanilla_REG", MAX_VANILLA_REG);
742 constantInt("mAX_Float_REG", MAX_FLOAT_REG);
743 constantInt("mAX_Double_REG", MAX_DOUBLE_REG);
744 constantInt("mAX_Long_REG", MAX_LONG_REG);
745 constantInt("mAX_SSE_REG", MAX_SSE_REG);
746 constantInt("mAX_Real_Vanilla_REG", MAX_REAL_VANILLA_REG);
747 constantInt("mAX_Real_Float_REG", MAX_REAL_FLOAT_REG);
748 constantInt("mAX_Real_Double_REG", MAX_REAL_DOUBLE_REG);
749 constantInt("mAX_Real_SSE_REG", MAX_REAL_SSE_REG);
750 constantInt("mAX_Real_Long_REG", MAX_REAL_LONG_REG);
751
752 // This tells the native code generator the size of the spill
753 // area is has available.
754 constantInt("rESERVED_C_STACK_BYTES", RESERVED_C_STACK_BYTES);
755 // The amount of (Haskell) stack to leave free for saving registers when
756 // returning to the scheduler.
757 constantInt("rESERVED_STACK_WORDS", RESERVED_STACK_WORDS);
758 // Continuations that need more than this amount of stack should do their
759 // own stack check (see bug #1466).
760 constantInt("aP_STACK_SPLIM", AP_STACK_SPLIM);
761
762 // Size of a word, in bytes
763 constantInt("wORD_SIZE", SIZEOF_HSWORD);
764
765 // Size of a double in StgWords.
766 constantInt("dOUBLE_SIZE", SIZEOF_DOUBLE);
767
768 // Size of a C int, in bytes. May be smaller than wORD_SIZE.
769 constantInt("cINT_SIZE", SIZEOF_INT);
770 constantInt("cLONG_SIZE", SIZEOF_LONG);
771 constantInt("cLONG_LONG_SIZE", SIZEOF_LONG_LONG);
772
773 // Number of bits to shift a bitfield left by in an info table.
774 constantInt("bITMAP_BITS_SHIFT", BITMAP_BITS_SHIFT);
775
776 // Amount of pointer bits used for semi-tagging constructor closures
777 constantInt("tAG_BITS", TAG_BITS);
778
779 constantBool("wORDS_BIGENDIAN",
780 #ifdef WORDS_BIGENDIAN
781 1
782 #else
783 0
784 #endif
785 );
786
787 constantBool("dYNAMIC_BY_DEFAULT",
788 #ifdef DYNAMIC_BY_DEFAULT
789 1
790 #else
791 0
792 #endif
793 );
794
795 constantInt("lDV_SHIFT", LDV_SHIFT);
796 constantInteger("iLDV_CREATE_MASK", LDV_CREATE_MASK);
797 constantInteger("iLDV_STATE_CREATE", LDV_STATE_CREATE);
798 constantInteger("iLDV_STATE_USE", LDV_STATE_USE);
799
800 switch (mode) {
801 case Gen_Haskell_Type:
802 printf(" } deriving Read\n");
803 break;
804 case Gen_Haskell_Value:
805 printf(" }\n");
806 break;
807 case Gen_Haskell_Wrappers:
808 case Gen_Haskell_Exports:
809 case Gen_Header:
810 break;
811 }
812
813 return 0;
814 }