[project @ 1996-07-25 20:43:49 by partain]
[ghc-hetmet.git] / ghc / includes / COptRegs.lh
1 %
2 % (c) The GRASP Project, Glasgow University, 1993
3 %
4 \section[StgRegs-decls]{STG-machine register mappings}
5
6 \begin{code}
7 #ifndef COPTREGS_H
8 #define COPTREGS_H
9
10 #include "StgMachDeps.h"
11 #include "StgTypes.h"
12 #include "MachRegs.h"
13
14 #define GLOBAL_REG_DECL(type,name,reg) register type name REG(reg);
15
16 \end{code}
17
18 Various parts of the GHC system use various sets of ``registers,'' by
19 which we mean (frequently-used) words of globally-visible information.
20 For example, the everyday ``Haskell threaded world,'' uses the
21 ``registers'' @Hp@, @R4@, etc., etc.
22
23 We would really like to ``steal'' machine registers from the C
24 execution model (via GCC's global-variable-in-register extension) and
25 map some/all of our ``STG registers'' onto real machine registers.
26 This has a profound benefit in terms of execution speed.
27
28 This file/document/section sets out the various (machine-dependent)
29 mappings that we use.
30
31 Note: for one machine, there are {\em several} possible register
32 mappings, {\em one} of which is in force at any time.  Obviously, the
33 ``main'' mapping (used in the Haskell threaded world) dominates, but
34 when garbage-collecting (for example), we'd rather not tie up all
35 those registers in that way (i.e., for global-variables that aren't
36 used in the GC). Instead, we'd rather bring in {\em another} register
37 mapping, tuned to the needs of a particular (isolated) bit of C code.
38 As there are several garbage collectors there are quite a few possible
39 mappings.
40
41 %************************************************************************
42 %*                                                                      *
43 \subsection[saved-STG-regs]{Saved STG registers}
44 %*                                                                      *
45 %************************************************************************
46
47 The following stuff is available regardless of register map.  It allows
48 us access to the saved STG registers from other parts of the RTS (notably
49 from the storage manager).
50
51 \begin{code}
52
53 typedef struct rt {
54     StgDouble rDbl[2];  /* Put a double first to ensure expected alignment */
55     StgFloat rFlt[4];
56     StgUnion rR[8];
57     PP_ rSpA;
58     PP_ rSuA;
59     P_ rSpB;
60     P_ rSuB;
61     P_ rHp;
62     P_ rHpLim;
63     I_ rTag;
64     StgRetAddr rRet;
65     I_ rActivity;       /* NB: UNUSED */
66     P_ rCstkptr;        /* used for iX86 registerizing only! offset=100 */
67     P_ rWrapReturn;     /* ditto; offset=104 */
68     P_ rSaveECX;        /* ditto; offset=108 */
69 #if defined(CONCURRENT)
70     P_ rStkO;
71     I_ rLiveness;
72 #endif
73 } STGRegisterTable;
74
75 \end{code}
76
77 There are several confusing macro sets for accessing STG registers at various
78 stages in their lives.  
79
80
81 The MAIN_* macros refer to the save locations for the main thread.
82 These are generally useful when the main thread is suspended.  Note
83 that the save locations for S[up][AB] are actually in the pseudo stack
84 object, MainStkO, when running threads.
85
86 The SAVE_* macros refer to the save locations for the current thread,
87 without using BaseReg.  These are used when we cannot be sure that any
88 STG registers are actually loaded in machine registers.
89
90 The RTBL_* macros refer to the register table locations for the current
91 thread, indexed from BaseReg.  If BaseReg is in a machine register, that
92 register {\em must} be loaded with the address of the register table.
93
94 OK, now... In the sequential world at least, each of those
95 ``register'' declarations also set up a ``backup'' location; for
96 register @r@, the backup location (a global variable) is @r_SAVE@.
97
98 We need @SAVE_STG_REGS@ and @RESTORE_STG_REGS@ macros, which copy back
99 and forth between the ``registers'' and their \tr{*_SAVE} backup
100 locations.
101
102 In the parallel world, we have the closely-related business of
103 saving/restoring ``thread state''.  We do it in two stages:
104 save/restore to/from \tr{*_SAVE} locations, then fill in the
105 ``thread-state object'' (TSO) from the \tr{*_SAVE} locations.  (This
106 means the thread-state saving can more easily be written in C, rather
107 than assembler.)
108
109 Why no space to save BaseReg?  Because either (1) if in a caller-save
110 register, the caller will have saved it; or (2) if in a callee-save
111 register, the miniInterpret machinery will have saved it.  This works
112 because we entered ``threaded Haskell land'' in a v disciplined
113 way---i.e., via miniInterpret.
114
115 However, the bits of code that use the various GC register maps (SCAV,
116 MARK, SCAN) are called in less-disciplined ways, so their base-regs
117 need saving/restoring.  (WDP 95/02)
118
119 \begin{code}
120
121 #ifndef PAR
122 extern STGRegisterTable MainRegTable;
123 #endif  /* PAR */
124
125 /* these are for the main register table */
126 #define MAIN_R1             (MainRegTable.rR[0])
127 #define MAIN_R2             (MainRegTable.rR[1])
128 #define MAIN_R3             (MainRegTable.rR[2])
129 #define MAIN_R4             (MainRegTable.rR[3])
130 #define MAIN_R5             (MainRegTable.rR[4])
131 #define MAIN_R6             (MainRegTable.rR[5])
132 #define MAIN_R7             (MainRegTable.rR[6])
133 #define MAIN_R8             (MainRegTable.rR[7])
134 #define MAIN_Flt1           (MainRegTable.rFlt[0])
135 #define MAIN_Flt2           (MainRegTable.rFlt[1])
136 #define MAIN_Flt3           (MainRegTable.rFlt[2])
137 #define MAIN_Flt4           (MainRegTable.rFlt[3])
138 #define MAIN_Dbl1           (MainRegTable.rDbl[0])
139 #define MAIN_Dbl2           (MainRegTable.rDbl[1])
140
141 #define MAIN_Hp             (MainRegTable.rHp)
142 #define MAIN_HpLim          (MainRegTable.rHpLim)
143 #define MAIN_Tag            (MainRegTable.rTag)
144 #define MAIN_Ret            (MainRegTable.rRet)
145
146 #define MAIN_StkO           (MainStkO)
147 #define MAIN_Liveness       (MainRegTable.rLiveness)
148
149 #ifndef CONCURRENT
150
151 #define MAIN_SpA            (MainRegTable.rSpA)
152 #define MAIN_SuA            (MainRegTable.rSuA)
153 #define MAIN_SpB            (MainRegTable.rSpB)
154 #define MAIN_SuB            (MainRegTable.rSuB)
155
156 /* these are really for *SAVE*ing */
157 #define SAVE_R1             MAIN_R1
158 #define SAVE_R2             MAIN_R2
159 #define SAVE_R3             MAIN_R3
160 #define SAVE_R4             MAIN_R4
161 #define SAVE_R5             MAIN_R5
162 #define SAVE_R6             MAIN_R6
163 #define SAVE_R7             MAIN_R7
164 #define SAVE_R8             MAIN_R8
165 #define SAVE_Flt1           MAIN_Flt1
166 #define SAVE_Flt2           MAIN_Flt2
167 #define SAVE_Flt3           MAIN_Flt3
168 #define SAVE_Flt4           MAIN_Flt4
169 #define SAVE_Dbl1           MAIN_Dbl1
170 #define SAVE_Dbl2           MAIN_Dbl2
171                             
172 #define SAVE_SpA            MAIN_SpA
173 #define SAVE_SuA            MAIN_SuA
174 #define SAVE_SpB            MAIN_SpB
175 #define SAVE_SuB            MAIN_SuB
176                             
177 #define SAVE_Tag            MAIN_Tag
178 #define SAVE_Ret            MAIN_Ret
179
180 #else
181
182 extern P_ MainStkO;
183
184 #define MAIN_SpA            (STKO_SpA(MainStkO))
185 #define MAIN_SuA            (STKO_SuA(MainStkO))
186 #define MAIN_SpB            (STKO_SpB(MainStkO))
187 #define MAIN_SuB            (STKO_SuB(MainStkO))
188
189 extern STGRegisterTable *CurrentRegTable;
190
191 /* these are really for *SAVE*ing */
192 #define SAVE_R1             (CurrentRegTable->rR[0])
193 #define SAVE_R2             (CurrentRegTable->rR[1])
194 #define SAVE_R3             (CurrentRegTable->rR[2])
195 #define SAVE_R4             (CurrentRegTable->rR[3])
196 #define SAVE_R5             (CurrentRegTable->rR[4])
197 #define SAVE_R6             (CurrentRegTable->rR[5])
198 #define SAVE_R7             (CurrentRegTable->rR[6])
199 #define SAVE_R8             (CurrentRegTable->rR[7])
200 #define SAVE_Flt1           (CurrentRegTable->rFlt[0])
201 #define SAVE_Flt2           (CurrentRegTable->rFlt[1])
202 #define SAVE_Flt3           (CurrentRegTable->rFlt[2])
203 #define SAVE_Flt4           (CurrentRegTable->rFlt[3])
204 #define SAVE_Dbl1           (CurrentRegTable->rDbl[0])
205 #define SAVE_Dbl2           (CurrentRegTable->rDbl[1])
206
207 /* These are only valid when StkOReg is loaded! */
208
209 #define SAVE_SpA            (STKO_SpA(StkOReg))
210 #define SAVE_SuA            (STKO_SuA(StkOReg))
211 #define SAVE_SpB            (STKO_SpB(StkOReg))
212 #define SAVE_SuB            (STKO_SuB(StkOReg))
213
214 #define SAVE_Tag            (CurrentRegTable->rTag)
215 #define SAVE_Ret            (CurrentRegTable->rRet)
216
217 #define SAVE_StkO           (CurrentRegTable->rStkO)
218 #define SAVE_Liveness       (CurrentRegTable->rLiveness)
219
220 #endif  /* CONCURRENT */
221
222 /* Note that the SAVE_ locations for the Hp registers are in the smInfo structure */
223
224 #define SAVE_Hp             (StorageMgrInfo.hp)
225 #define SAVE_HpLim          (StorageMgrInfo.hplim)
226
227 \end{code}
228
229 %************************************************************************
230 %*                                                                      *
231 \subsection[null-mapping-StgRegs]{The empty register mapping}
232 %*                                                                      *
233 %************************************************************************
234
235 This mapping leaves all machine registers free for normal C allocation.
236 In the RTS, this is the preferred mapping, because it allows gcc to use
237 all available registers, with the normal callee-saves conventions.
238 \begin{code}
239 #if defined(NULL_REG_MAP)
240 #else
241 \end{code}
242
243 This is a HACK here; see comment in COptJumps.lh.
244 \begin{code}
245 #if alpha_dec_osf1_TARGET && defined(__STG_TAILJUMPS__) && defined(__GNUC__)
246 register void *_procedure __asm__("$27");
247 #endif
248 #if (mipsel_TARGET_ARCH || mipseb_TARGET_ARCH) && defined(__STG_TAILJUMPS__) && defined(__GNUC__)
249 register void *_procedure __asm__("$25");
250 #endif
251 \end{code}
252
253 %************************************************************************
254 %*                                                                      *
255 \subsection[mark-mapping-StgRegs]{The ``mark'' register mapping}
256 %*                                                                      *
257 %************************************************************************
258
259 The mark mapping is used for pointer-reversal marking during GC.  It
260 is used by most of the current garbage collectors.
261
262 \begin{code}
263 #if defined(MARK_REG_MAP)
264 \end{code}
265
266 Mark (GC) register mapping:
267
268 \begin{verbatim}
269                 sparc  m68k  alpha  mipseX  hppa  iX86  powerpc
270                 -----  ----  -----  ------  ----  ----  -------
271 MarkBase                                          ebx
272                 
273 Mark            i0     a2    $9     $16     r4    ebp
274 MStack          i1     a3    $10    $17     r5    esi
275 MRoot           i2     a4    $11    $18     r6    edi
276 BitArray        i3     a5    $12    $19     r7
277 HeapBase        i4     d3    $13    $20     r8
278 HeapLim         i5     d4    $14    $21     r9
279
280 \end{verbatim}
281
282 \begin{code}
283
284 typedef struct {
285     P_ rMark;
286     P_ rMStack;
287     P_ rMRoot;
288     BitWord *rBitArray;
289     P_ rHeapBase;
290     P_ rHeapLim;
291     P_ rMarkBase;
292 } RegisterTable;
293
294 #define REGDUMP(dump)   static RegisterTable dump
295
296 #define SAVE_Mark       (MarkRegTable.rMark)
297 #define SAVE_MStack     (MarkRegTable.rMStack)
298 #define SAVE_MRoot      (MarkRegTable.rMRoot)
299 #define SAVE_BitArray   (MarkRegTable.rBitArray)
300 #define SAVE_HeapBase   (MarkRegTable.rHeapBase)
301 #define SAVE_HeapLim    (MarkRegTable.rHeapLim)
302
303 extern RegisterTable MarkRegTable;
304
305 #ifdef REG_MarkBase
306 GLOBAL_REG_DECL(RegisterTable *,MarkBaseReg,REG_MarkBase)
307 #else
308 #define MarkBaseReg (&MarkRegTable)
309 #endif
310
311 #ifdef REG_Mark
312 GLOBAL_REG_DECL(P_,Mark,REG_Mark)
313 #else
314 #define Mark SAVE_Mark
315 #endif
316
317 #ifdef REG_MStack
318 GLOBAL_REG_DECL(P_,MStack,REG_MStack)
319 #else
320 #define MStack SAVE_MStack
321 #endif
322
323 #ifdef REG_MRoot
324 GLOBAL_REG_DECL(P_,MRoot,REG_MRoot)
325 #else
326 #define MRoot SAVE_MRoot
327 #endif
328
329 #ifdef REG_BitArray
330 GLOBAL_REG_DECL(P_,BitArray,REG_BitArray)
331 #else
332 #define BitArray SAVE_BitArray
333 #endif
334
335 #ifdef REG_HeapBase
336 GLOBAL_REG_DECL(P_,HeapBase,REG_HeapBase)
337 #else
338 #define HeapBase SAVE_HeapBase
339 #endif
340
341 #ifdef REG_HeapLim
342 GLOBAL_REG_DECL(P_,HeapLim,REG_HeapLim)
343 #else
344 #define HeapLim SAVE_HeapLim
345 #endif
346
347 #if defined(__STG_GCC_REGS__)
348 /* Keep -Wmissing-prototypes from complaining */
349 void SAVE_REGS    PROTO((RegisterTable *dump));
350 void RESTORE_REGS PROTO((RegisterTable *dump));
351
352 extern STG_INLINE 
353 void SAVE_REGS(dump)
354 RegisterTable *dump;
355 {
356 #ifdef REG_MarkBase
357     dump->rMarkBase = (P_) MarkBaseReg; /* save whatever is in it */
358     MarkBaseReg = dump; /* set it correctly */
359 #endif
360 #ifdef REG_Mark    
361     dump->rMark = Mark;
362 #endif
363 #ifdef REG_MStack
364     dump->rMStack = MStack;
365 #endif
366 #ifdef REG_MRoot
367     dump->rMRoot = MRoot;
368 #endif
369 #ifdef REG_BitArray
370     dump->rBitArray = BitArray;
371 #endif
372 #ifdef REG_HeapBase
373     dump->rHeapBase = HeapBase;
374 #endif
375 #ifdef REG_HeapLim
376     dump->rHeapLim = HeapLim;
377 #endif
378 }
379
380 extern STG_INLINE 
381 void RESTORE_REGS(dump)
382 RegisterTable *dump;
383 {
384 #ifdef REG_Mark    
385     Mark = dump->rMark;
386 #endif
387 #ifdef REG_MStack
388     MStack = dump->rMStack;
389 #endif
390 #ifdef REG_MRoot
391     MRoot = dump->rMRoot;
392 #endif
393 #ifdef REG_BitArray
394     BitArray = dump->rBitArray;
395 #endif
396 #ifdef REG_HeapBase
397     HeapBase = dump->rHeapBase;
398 #endif
399 #ifdef REG_HeapLim
400     HeapLim = dump->rHeapLim;
401 #endif
402 #ifdef REG_MarkBase
403     MarkBaseReg = (RegisterTable *) dump->rMarkBase; /* restore to whatever it was */
404 #endif
405 }
406 #else
407 #define SAVE_REGS(dump)
408 #define RESTORE_REGS(dump)
409 #endif
410 \end{code}
411
412 %************************************************************************
413 %*                                                                      *
414 \subsection[scan-mapping-StgRegs]{The ``scan'' register mapping}
415 %*                                                                      *
416 %************************************************************************
417
418 The scan mapping is used for all of the in-place garbage collectors.
419 On architectures with register windows, like the SPARC, these must
420 reside in global registers, because the scan code is not threaded.
421
422 \begin{code}
423 #else
424 #if defined(SCAN_REG_MAP)
425 \end{code}
426
427 Scan (GC) register mapping:
428
429 \begin{verbatim}
430                 sparc  m68k  alpha  mipseX  hppa  iX86  powerpc
431                 -----  ----  -----  ------  ----  ----  -------
432 ScanBase        g4
433                 
434 Scan                   a2    $9     $16     r4    ebx
435 New                    a3    $10    $17     r5    ebp
436 LinkLim                a4    $11    $18     r6    esi
437
438 \end{verbatim}
439
440 \begin{code}
441
442 typedef struct {
443     P_ rScan;
444     P_ rNew;
445     P_ rLinkLim;
446     P_ rScanBase;
447 } RegisterTable;
448     
449 #define REGDUMP(dump)   static RegisterTable dump
450
451 #define SAVE_Scan       (ScanRegTable.rScan)
452 #define SAVE_New        (ScanRegTable.rNew)
453 #define SAVE_LinkLim    (ScanRegTable.rLinkLim)
454
455 extern RegisterTable ScanRegTable;
456
457 #ifdef REG_ScanBase
458 GLOBAL_REG_DECL(RegisterTable *,ScanBaseReg,REG_ScanBase)
459 #else
460 #define ScanBaseReg (&ScanRegTable)
461 #endif
462
463 #ifdef REG_Scan
464 GLOBAL_REG_DECL(P_,Scan,REG_Scan)
465 #else
466 # ifdef REG_ScanBase
467 #  define Scan (ScanBaseReg->rScan)
468 # else
469 #  define Scan SAVE_Scan
470 # endif
471 #endif
472
473 #ifdef REG_New
474 GLOBAL_REG_DECL(P_,New,REG_New)
475 #else
476 # ifdef REG_ScanBase
477 #  define New (ScanBaseReg->rNew)
478 # else
479 #  define New SAVE_New
480 # endif
481 #endif
482
483 #ifdef REG_LinkLim
484 GLOBAL_REG_DECL(P_,LinkLim,REG_LinkLim)
485 #else
486 # ifdef REG_ScanBase
487 #  define LinkLim (ScanBaseReg->rLinkLim)
488 # else
489 #  define LinkLim SAVE_LinkLim
490 # endif
491 #endif
492
493 #if defined(__STG_GCC_REGS__)
494 /* Keep -Wmissing-prototypes from complaining */
495 void SAVE_REGS    PROTO((RegisterTable *dump));
496 void RESTORE_REGS PROTO((RegisterTable *dump));
497
498 extern STG_INLINE 
499 void SAVE_REGS(dump)
500 RegisterTable *dump;
501 {
502 #ifdef REG_ScanBase
503     dump->rScanBase = (P_) ScanBaseReg; /* save whatever is in it */
504     ScanBaseReg = dump; /* set it correctly */
505 #endif
506 #ifdef REG_Scan    
507     dump->rScan = Scan;
508 #endif
509 #ifdef REG_New
510     dump->rNew = New;
511 #endif
512 #ifdef REG_LinkLim
513     dump->rLinkLim = LinkLim;
514 #endif
515 }
516
517 extern STG_INLINE 
518 void RESTORE_REGS(dump)
519 RegisterTable *dump;
520 {
521 #ifdef REG_Scan    
522     Scan = dump->rScan;
523 #endif
524 #ifdef REG_New
525     New = dump->rNew;
526 #endif
527 #ifdef REG_LinkLim
528     LinkLim = dump->rLinkLim;
529 #endif
530 #ifdef REG_ScanBase
531     ScanBaseReg = (RegisterTable *) dump->rScanBase; /* restore to whatever it was */
532 #endif
533 }
534 #else
535 #define SAVE_REGS(dump)
536 #define RESTORE_REGS(dump)
537 #endif
538 \end{code}
539
540 %************************************************************************
541 %*                                                                      *
542 \subsection[scav-mapping-StgRegs]{The ``scavenge'' register mapping}
543 %*                                                                      *
544 %************************************************************************
545
546 The scan mapping is used for all of the in-place garbage collectors.
547 (I believe that it must use a subset of the registers that are used
548 in the mark mapping, but I could be wrong. --JSM)
549
550 Note: registers must not be mangled by sliding register windows,
551 etc. or there'll be trouble. ADR
552
553 \begin{code}
554 #else
555 #if defined(SCAV_REG_MAP)
556 \end{code}
557
558 Scavenge (GC) register mapping:
559
560 \begin{verbatim}
561                 sparc  m68k  alpha  mipseX  hppa  iX86  powerpc
562                 -----  ----  -----  ------  ----  ----  -------
563 ScavBase        g4
564                 
565 Scav                   a2    $9     $16     r4    ebx
566 ToHp                   a3    $10    $17     r5    ebp
567 OldGen (gn/ap)         a4    $11    $18     r6    esi
568 AllocGen (gn)          a5
569 OldHp    (gn)          d3
570
571 \end{verbatim}
572
573 (Calling this struct @ScavRegisterTable@ would make it possible for
574 @gdb@ to display it properly. At the moment, @gdb@ confuses it with
575 the scan register table etc. ADR )
576
577 \begin{code}
578
579 typedef struct {
580     P_ rScav;
581     P_ rToHp;
582     P_ rOldGen;
583 #ifdef GCgn
584     P_ rAllocGen;
585     P_ rOldHp;
586 #endif
587     P_ rScavBase;
588 } RegisterTable;
589
590 #define REGDUMP(dump)   static RegisterTable dump
591
592 #define SAVE_Scav       (ScavRegTable.rScav)
593 #define SAVE_ToHp       (ScavRegTable.rToHp)
594 #define SAVE_OldGen     (ScavRegTable.rOldGen)
595 #define SAVE_AllocGen   (ScavRegTable.rAllocGen)
596 #define SAVE_OldHp      (ScavRegTable.rOldHp)
597
598 extern RegisterTable ScavRegTable;
599
600 #ifdef REG_ScavBase
601 GLOBAL_REG_DECL(RegisterTable *,ScavBaseReg,REG_ScavBase)
602 #else
603 #define ScavBaseReg (&ScavRegTable)
604 #endif
605
606 #ifdef REG_Scav
607 GLOBAL_REG_DECL(P_,Scav,REG_Scav)
608 #else
609 # ifdef REG_ScavBase
610 #  define Scav (ScavBaseReg->rScav)
611 # else
612 #  define Scav SAVE_Scav
613 # endif
614 #endif
615
616 #ifdef REG_ToHp
617 GLOBAL_REG_DECL(P_,ToHp,REG_ToHp)
618 #else
619 # ifdef REG_ScavBase
620 #  define ToHp (ScavBaseReg->rToHp)
621 # else
622 #  define ToHp SAVE_ToHp
623 # endif
624 #endif
625
626 #ifdef REG_OldGen
627 GLOBAL_REG_DECL(P_,OldGen,REG_OldGen)
628 #else
629 # ifdef REG_ScavBase
630 #  define OldGen (ScavBaseReg->rOldGen)
631 # else
632 #  define OldGen SAVE_OldGen
633 # endif
634 #endif
635
636 #ifdef REG_AllocGen
637 GLOBAL_REG_DECL(P_,AllocGen,REG_AllocGen)
638 #else
639 # ifdef REG_ScavBase
640 #  define AllocGen (ScavBaseReg->rAllocGen)
641 # else
642 #  define AllocGen SAVE_AllocGen
643 # endif
644 #endif
645
646 #ifdef REG_OldHp
647 GLOBAL_REG_DECL(P_,OldHp,REG_OldHp)
648 #else
649 # ifdef REG_ScavBase
650 #  define OldHp (ScavBaseReg->rOldHp)
651 # else
652 #  define OldHp SAVE_OldHp
653 # endif
654 #endif
655
656 #if defined(__STG_GCC_REGS__)
657 /* Keep -Wmissing-prototypes from complaining */
658 void SAVE_REGS    PROTO((RegisterTable *dump));
659 void RESTORE_REGS PROTO((RegisterTable *dump));
660
661 extern STG_INLINE 
662 void SAVE_REGS(dump)
663 RegisterTable *dump;
664 {
665 #ifdef REG_ScavBase
666     dump->rScavBase = (P_) ScavBaseReg; /* save whatever is in it */
667     ScavBaseReg = dump; /* set it correctly */
668 #endif
669 #ifdef REG_Scav    
670     dump->rScav = Scav;
671 #endif
672 #ifdef REG_ToHp
673     dump->rToHp = ToHp;
674 #endif
675 #ifdef REG_OldGen
676     dump->rOldGen = OldGen;
677 #endif
678 #ifdef REG_AllocGen
679     dump->rAllocGen = AllocGen;
680 #endif
681 #ifdef REG_OldHp
682     dump->rOldHp = OldHp;
683 #endif
684 }
685
686 extern STG_INLINE 
687 void RESTORE_REGS(dump)
688 RegisterTable *dump;
689 {
690 #ifdef REG_Scav    
691     Scav = dump->rScav;
692 #endif
693 #ifdef REG_ToHp
694     ToHp = dump->rToHp;
695 #endif
696 #ifdef REG_OldGen
697     OldGen = dump->rOldGen;
698 #endif
699 #ifdef REG_AllocGen
700     AllocGen = dump->rAllocGen;
701 #endif
702 #ifdef REG_OldHp
703     OldHp = dump->rOldHp;
704 #endif
705 #ifdef REG_ScavBase
706     ScavBaseReg = (RegisterTable *) dump->rScavBase; /* restore to whatever it was */
707 #endif
708 }
709 #else
710 #define SAVE_REGS(dump)
711 #define RESTORE_REGS(dump)
712 #endif
713 \end{code}
714
715 %************************************************************************
716 %*                                                                      *
717 \subsection[main-mapping-StgRegs]{The main register mapping (Haskell threaded world)}
718 %*                                                                      *
719 %************************************************************************
720
721 \begin{code}
722 #else   /* For simplicity, the default is MAIN_REG_MAP (this one) */
723 \end{code}
724
725 Main register-mapping summary: (1)~Specific architecture's details are
726 given later.  (2)~Entries marked \tr{!} are caller-saves registers
727 that {\em must be saved} across ccalls; those marked \tr{@} are
728 caller-saves registers that need {\em not} be saved; those marked
729 \tr{#} are caller-saves registers that need to be restored, but don't
730 need to be saved; the rest are callee-save registers (the best kind).
731
732 IF YOU CHANGE THIS TABLE, YOU MAY NEED TO CHANGE CallWrapper.s
733 (or equiv) and [who knows?] maybe something else.  Check the
734 documentation in the porter's part of the installation guide.
735
736 \begin{verbatim}
737                 sparc  m68k  alpha  mipseX  hppa   iX86  powerpc
738                 -----  ----  -----  ------  ----   ----  -------
739 BaseReg#               a5                          ebx
740
741 StkOReg                                                         (CONCURRENT)       
742                       
743 R1/Node         l1     d7    $1!    $9!     %r11
744 R2              l2     d6    $2!    $10!    %r12
745 R3              l3     d5    $3!    $11!    %r13
746 R4              l4           $4!    $12!    %r14
747 R5              l5           $5!    $13!    %r15
748 R6              l6           $6!    $14!    %r16
749 R7              l7           $7!    $15!    %r17
750 R8                           $8!    $24!    %r18
751
752 TagReg@
753
754 FltReg1         f2!    fp2   $f1    $f20    %fr12
755 FltReg2         f3!    fp3   $f2    $f22    %fr12R
756 FltReg3         f4!    fp4   $f3    $f24    %fr13
757 FltReg4         f5!    fp5   $f4    $f26    %fr13R
758                       
759 DblReg1         f6!    fp6   $f5    $f28    %fr20               * SEE NOTES!
760 DblReg2         f8!    fp7   $f6    $f30    %fr20               * SEE NOTES!
761                       
762 SpA             i0     a3    $9     $16     %r4
763 SuA             i1     d3    $10    $17     %r5
764 SpB             i2     a4    $11    $18     %r6
765 SuB             i3     d4    $12    $19     %r7
766
767 Hp              i4     a2    $13    $20     %r8
768 HpLim           i5           $14    $21     %r9
769
770 RetReg          l0           $15    $22     %r10
771
772 Liveness                                                        (CONCURRENT)  
773
774 StdUpdRetVec#
775 StkStub#        i7                  $23
776 \end{verbatim}
777
778 Notes:
779 \begin{enumerate}
780 \item
781 Registers not mentioned in the summary table end up in the default
782 (a memory location in @MainRegTable@).
783
784 \item
785 @BaseReg@ is in a machine register if anything is (well, unless everything is!)
786 It points to a block of memory in which the things which don't end up in machine
787 registers live.
788
789 \item
790 Exceptions to previous point:
791 If the following labels are in machine registers, then the
792 corresponding register name refers to what's in its register; otherwise,
793 it refers to the label:
794 \begin{verbatim}
795 StdUpdRetVecReg vtbl_StdUpdFrame
796 StkStubReg      STK_STUB_closure
797 \end{verbatim}
798 Also, if TagReg is not in a machine register, its name refers to
799 @INFO_TAG(InfoPtr)@, the tag field from the info table pointed to by
800 register R2 (InfoPtr).
801
802 \end{enumerate}
803
804 Next, we have the code to declare the various global registers.  Those
805 STG registers which don't actually live in machine registers are
806 defined as macros which refer to the registers as fixed offsets into
807 the register table.  Note that the register table will contain blank
808 spots for the STG registers that reside in machine registers.  Not to
809 worry; these blank spots will be filled in whenever the register
810 context is saved, so the space does not go to waste.
811
812 \begin{code}
813
814 #define Node    (R1.p)
815 #define InfoPtr (R2.d)
816
817 /* these are if we get stuck using the reg-tbl "register" (no machine reg avail) */
818 #define RTBL_Dbl1           (BaseReg->rDbl[0])
819 #define RTBL_Dbl2           (BaseReg->rDbl[1])
820 #define RTBL_Flt1           (BaseReg->rFlt[0])
821 #define RTBL_Flt2           (BaseReg->rFlt[1])
822 #define RTBL_Flt3           (BaseReg->rFlt[2])
823 #define RTBL_Flt4           (BaseReg->rFlt[3])
824 #define RTBL_R1             (BaseReg->rR[0])
825 #define RTBL_R2             (BaseReg->rR[1])
826 #define RTBL_R3             (BaseReg->rR[2])
827 #define RTBL_R4             (BaseReg->rR[3])
828 #define RTBL_R5             (BaseReg->rR[4])
829 #define RTBL_R6             (BaseReg->rR[5])
830 #define RTBL_R7             (BaseReg->rR[6])
831 #define RTBL_R8             (BaseReg->rR[7])
832 #define RTBL_SpA            (BaseReg->rSpA)
833 #define RTBL_SuA            (BaseReg->rSuA)
834 #define RTBL_SpB            (BaseReg->rSpB)
835 #define RTBL_SuB            (BaseReg->rSuB)
836 #define RTBL_Hp             (BaseReg->rHp)
837 #define RTBL_HpLim          (BaseReg->rHpLim)
838 #define RTBL_Tag            (BaseReg->rTag)
839 #define RTBL_Ret            (BaseReg->rRet)
840 #define RTBL_StkO           (BaseReg->rStkO)
841 #define RTBL_Liveness       (BaseReg->rLiveness)
842
843 #ifdef REG_Base
844 GLOBAL_REG_DECL(STGRegisterTable *,BaseReg,REG_Base)
845 #else
846 #ifdef CONCURRENT
847 #define BaseReg CurrentRegTable
848 #else
849 #define BaseReg (&MainRegTable)
850 #endif  /* CONCURRENT */
851 #endif /* REG_Base */
852
853 #ifdef REG_StkO
854 GLOBAL_REG_DECL(P_,StkOReg,REG_StkO)
855 #else
856 #define StkOReg RTBL_StkO
857 #endif
858
859 #ifndef __STG_REGS_AVAIL__ /* driver ensures it is 2 or more */
860 # define __STG_REGS_AVAIL__ 8 /* R1 to R8 */
861 /* this would only be non-8 if doing weird experiments (WDP 95/11) */
862 /* or it might be set lower for a particular arch... */
863 #endif
864
865 /* R1 is used for Node */
866 #ifdef REG_R1
867 GLOBAL_REG_DECL(StgUnion,R1,REG_R1)
868 #else
869 #define R1 RTBL_R1
870 #endif
871
872 /* R2 is used for InfoPtr */
873 #ifdef REG_R2
874 GLOBAL_REG_DECL(StgUnion,R2,REG_R2)
875 #else
876 #define R2 RTBL_R2
877 #endif
878
879 #ifdef REG_R3
880 GLOBAL_REG_DECL(StgUnion,R3,REG_R3)
881 #else
882 # define R3 RTBL_R3
883 #endif
884
885 #ifdef REG_R4
886 GLOBAL_REG_DECL(StgUnion,R4,REG_R4)
887 #else
888 # define R4 RTBL_R4
889 #endif
890
891 #ifdef REG_R5
892 GLOBAL_REG_DECL(StgUnion,R5,REG_R5)
893 #else
894 # define R5 RTBL_R5
895 #endif
896
897 #ifdef REG_R6
898 GLOBAL_REG_DECL(StgUnion,R6,REG_R6)
899 #else
900 # define R6 RTBL_R6
901 #endif
902
903 #ifdef REG_R7
904 GLOBAL_REG_DECL(StgUnion,R7,REG_R7)
905 #else
906 # define R7 RTBL_R7
907 #endif
908
909 #ifdef REG_R8
910 GLOBAL_REG_DECL(StgUnion,R8,REG_R8)
911 #else
912 # define R8 RTBL_R8
913 #endif
914
915 #ifdef REG_Flt1
916 GLOBAL_REG_DECL(StgFloat,FltReg1,REG_Flt1)
917 #else
918 #define FltReg1 RTBL_Flt1
919 #endif
920
921 #ifdef REG_Flt2
922 GLOBAL_REG_DECL(StgFloat,FltReg2,REG_Flt2)
923 #else
924 #define FltReg2 RTBL_Flt2
925 #endif
926
927 #ifdef REG_Flt3
928 GLOBAL_REG_DECL(StgFloat,FltReg3,REG_Flt3)
929 #else
930 #define FltReg3 RTBL_Flt3
931 #endif
932
933 #ifdef REG_Flt4
934 GLOBAL_REG_DECL(StgFloat,FltReg4,REG_Flt4)
935 #else
936 #define FltReg4 RTBL_Flt4
937 #endif
938
939 #ifdef REG_Dbl1
940 GLOBAL_REG_DECL(StgDouble,DblReg1,REG_Dbl1)
941 #else
942 #define DblReg1 RTBL_Dbl1
943 #endif
944
945 #ifdef REG_Dbl2
946 GLOBAL_REG_DECL(StgDouble,DblReg2,REG_Dbl2)
947 #else
948 #define DblReg2 RTBL_Dbl2
949 #endif
950
951 #ifdef REG_Tag
952 GLOBAL_REG_DECL(I_,TagReg,REG_Tag)
953
954 #define SET_TAG(tag)    TagReg = tag
955 #else
956 #define TagReg INFO_TAG(InfoPtr)
957 #define SET_TAG(tag)    /* nothing */
958 #endif
959
960 #ifdef REG_Ret
961 GLOBAL_REG_DECL(StgRetAddr,RetReg,REG_Ret)
962 #else
963 #define RetReg RTBL_Ret
964 #endif
965
966 #ifdef REG_SpA
967 GLOBAL_REG_DECL(PP_,SpA,REG_SpA)
968 #else
969 #define SpA RTBL_SpA
970 #endif
971
972 #ifdef REG_SuA
973 GLOBAL_REG_DECL(PP_,SuA,REG_SuA)
974 #else
975 #define SuA RTBL_SuA
976 #endif
977
978 #ifdef REG_SpB
979 GLOBAL_REG_DECL(P_,SpB,REG_SpB)
980 #else
981 #define SpB RTBL_SpB
982 #endif
983
984 #ifdef REG_SuB
985 GLOBAL_REG_DECL(P_,SuB,REG_SuB)
986 #else
987 #define SuB RTBL_SuB
988 #endif
989
990 #ifdef REG_Hp
991 GLOBAL_REG_DECL(P_,Hp,REG_Hp)
992 #else
993 #define Hp RTBL_Hp
994 #endif
995
996 #ifdef REG_HpLim
997 GLOBAL_REG_DECL(P_,HpLim,REG_HpLim)
998 #else
999 #define HpLim RTBL_HpLim
1000 #endif
1001
1002 #ifdef REG_Liveness
1003 GLOBAL_REG_DECL(I_,LivenessReg,REG_Liveness)
1004 #else
1005 #define LivenessReg RTBL_Liveness
1006 #endif
1007
1008 #ifdef REG_StdUpdRetVec
1009 GLOBAL_REG_DECL(D_,StdUpdRetVecReg,REG_StdUpdRetVec)
1010 #else
1011 #define StdUpdRetVecReg vtbl_StdUpdFrame
1012 #endif
1013
1014 #ifdef REG_StkStub
1015 GLOBAL_REG_DECL(P_,StkStubReg,REG_StkStub)
1016 #else
1017 #define StkStubReg STK_STUB_closure
1018 #endif
1019
1020 #ifdef CALLER_SAVES_StkO
1021 #define CALLER_SAVE_StkO        SAVE_StkO = StkOReg;
1022 #define CALLER_RESTORE_StkO     StkOReg = SAVE_StkO;
1023 #else
1024 #define CALLER_SAVE_StkO        /* nothing */
1025 #define CALLER_RESTORE_StkO     /* nothing */
1026 #endif
1027
1028 #ifdef CALLER_SAVES_R1
1029 #define CALLER_SAVE_R1          SAVE_R1 = R1;
1030 #define CALLER_RESTORE_R1       R1 = SAVE_R1;
1031 #else
1032 #define CALLER_SAVE_R1          /* nothing */
1033 #define CALLER_RESTORE_R1       /* nothing */
1034 #endif
1035
1036 #ifdef CALLER_SAVES_R2
1037 #define CALLER_SAVE_R2          SAVE_R2 = R2;
1038 #define CALLER_RESTORE_R2       R2 = SAVE_R2;
1039 #else
1040 #define CALLER_SAVE_R2          /* nothing */
1041 #define CALLER_RESTORE_R2       /* nothing */
1042 #endif
1043
1044 #ifdef CALLER_SAVES_R3
1045 #define CALLER_SAVE_R3          SAVE_R3 = R3;
1046 #define CALLER_RESTORE_R3       R3 = SAVE_R3;
1047 #else
1048 #define CALLER_SAVE_R3          /* nothing */
1049 #define CALLER_RESTORE_R3       /* nothing */
1050 #endif
1051
1052 #ifdef CALLER_SAVES_R4
1053 #define CALLER_SAVE_R4          SAVE_R4 = R4;
1054 #define CALLER_RESTORE_R4       R4 = SAVE_R4;
1055 #else
1056 #define CALLER_SAVE_R4          /* nothing */
1057 #define CALLER_RESTORE_R4       /* nothing */
1058 #endif
1059
1060 #ifdef CALLER_SAVES_R5
1061 #define CALLER_SAVE_R5          SAVE_R5 = R5;
1062 #define CALLER_RESTORE_R5       R5 = SAVE_R5;
1063 #else
1064 #define CALLER_SAVE_R5          /* nothing */
1065 #define CALLER_RESTORE_R5       /* nothing */
1066 #endif
1067
1068 #ifdef CALLER_SAVES_R6
1069 #define CALLER_SAVE_R6          SAVE_R6 = R6;
1070 #define CALLER_RESTORE_R6       R6 = SAVE_R6;
1071 #else
1072 #define CALLER_SAVE_R6          /* nothing */
1073 #define CALLER_RESTORE_R6       /* nothing */
1074 #endif
1075
1076 #ifdef CALLER_SAVES_R7
1077 #define CALLER_SAVE_R7          SAVE_R7 = R7;
1078 #define CALLER_RESTORE_R7       R7 = SAVE_R7;
1079 #else
1080 #define CALLER_SAVE_R7          /* nothing */
1081 #define CALLER_RESTORE_R7       /* nothing */
1082 #endif
1083
1084 #ifdef CALLER_SAVES_R8
1085 #define CALLER_SAVE_R8          SAVE_R8 = R8;
1086 #define CALLER_RESTORE_R8       R8 = SAVE_R8;
1087 #else
1088 #define CALLER_SAVE_R8          /* nothing */
1089 #define CALLER_RESTORE_R8       /* nothing */
1090 #endif
1091
1092 #ifdef CALLER_SAVES_FltReg1
1093 #define CALLER_SAVE_FltReg1     SAVE_Flt1 = FltReg1;
1094 #define CALLER_RESTORE_FltReg1  FltReg1 = SAVE_Flt1;
1095 #else
1096 #define CALLER_SAVE_FltReg1     /* nothing */
1097 #define CALLER_RESTORE_FltReg1  /* nothing */
1098 #endif
1099
1100 #ifdef CALLER_SAVES_FltReg2
1101 #define CALLER_SAVE_FltReg2     SAVE_Flt2 = FltReg2;
1102 #define CALLER_RESTORE_FltReg2  FltReg2 = SAVE_Flt2;
1103 #else
1104 #define CALLER_SAVE_FltReg2     /* nothing */
1105 #define CALLER_RESTORE_FltReg2  /* nothing */
1106 #endif
1107
1108 #ifdef CALLER_SAVES_FltReg3
1109 #define CALLER_SAVE_FltReg3     SAVE_Flt3 = FltReg3;
1110 #define CALLER_RESTORE_FltReg3  FltReg3 = SAVE_Flt3;
1111 #else
1112 #define CALLER_SAVE_FltReg3     /* nothing */
1113 #define CALLER_RESTORE_FltReg3  /* nothing */
1114 #endif
1115
1116 #ifdef CALLER_SAVES_FltReg4
1117 #define CALLER_SAVE_FltReg4     SAVE_Flt4 = FltReg4;
1118 #define CALLER_RESTORE_FltReg4  FltReg4 = SAVE_Flt4;
1119 #else
1120 #define CALLER_SAVE_FltReg4     /* nothing */
1121 #define CALLER_RESTORE_FltReg4  /* nothing */
1122 #endif
1123
1124 #ifdef CALLER_SAVES_DblReg1
1125 #define CALLER_SAVE_DblReg1     SAVE_Dbl1 = DblReg1;
1126 #define CALLER_RESTORE_DblReg1  DblReg1 = SAVE_Dbl1;
1127 #else
1128 #define CALLER_SAVE_DblReg1     /* nothing */
1129 #define CALLER_RESTORE_DblReg1  /* nothing */
1130 #endif
1131
1132 #ifdef CALLER_SAVES_DblReg2
1133 #define CALLER_SAVE_DblReg2     SAVE_Dbl2 = DblReg2;
1134 #define CALLER_RESTORE_DblReg2  DblReg2 = SAVE_Dbl2;
1135 #else
1136 #define CALLER_SAVE_DblReg2     /* nothing */
1137 #define CALLER_RESTORE_DblReg2  /* nothing */
1138 #endif
1139
1140 #ifdef CALLER_SAVES_Tag
1141 #define CALLER_SAVE_Tag         SAVE_Tag = TagReg;
1142 #define CALLER_RESTORE_Tag      TagReg = SAVE_Tag;
1143 #else
1144 #define CALLER_SAVE_Tag         /* nothing */
1145 #define CALLER_RESTORE_Tag      /* nothing */
1146 #endif
1147
1148 #ifdef CALLER_SAVES_Ret
1149 #define CALLER_SAVE_Ret         SAVE_Ret = RetReg;
1150 #define CALLER_RESTORE_Ret      RetReg = SAVE_Ret;
1151 #else
1152 #define CALLER_SAVE_Ret         /* nothing */
1153 #define CALLER_RESTORE_Ret      /* nothing */
1154 #endif
1155
1156 #ifdef CALLER_SAVES_SpA
1157 #define CALLER_SAVE_SpA         SAVE_SpA = SpA;
1158 #define CALLER_RESTORE_SpA      SpA = SAVE_SpA;
1159 #else
1160 #define CALLER_SAVE_SpA         /* nothing */
1161 #define CALLER_RESTORE_SpA      /* nothing */
1162 #endif
1163
1164 #ifdef CALLER_SAVES_SuA
1165 #define CALLER_SAVE_SuA         SAVE_SuA = SuA;
1166 #define CALLER_RESTORE_SuA      SuA = SAVE_SuA;
1167 #else
1168 #define CALLER_SAVE_SuA         /* nothing */
1169 #define CALLER_RESTORE_SuA      /* nothing */
1170 #endif
1171
1172 #ifdef CALLER_SAVES_SpB
1173 #define CALLER_SAVE_SpB         SAVE_SpB = SpB;
1174 #define CALLER_RESTORE_SpB      SpB = SAVE_SpB;
1175 #else
1176 #define CALLER_SAVE_SpB         /* nothing */
1177 #define CALLER_RESTORE_SpB      /* nothing */
1178 #endif
1179
1180 #ifdef CALLER_SAVES_SuB
1181 #define CALLER_SAVE_SuB         SAVE_SuB = SuB;
1182 #define CALLER_RESTORE_SuB      SuB = SAVE_SuB;
1183 #else
1184 #define CALLER_SAVE_SuB         /* nothing */
1185 #define CALLER_RESTORE_SuB      /* nothing */
1186 #endif
1187
1188 #ifdef CALLER_SAVES_Hp
1189 #define CALLER_SAVE_Hp          SAVE_Hp = Hp;
1190 #define CALLER_RESTORE_Hp       Hp = SAVE_Hp;
1191 #else
1192 #define CALLER_SAVE_Hp          /* nothing */
1193 #define CALLER_RESTORE_Hp       /* nothing */
1194 #endif
1195
1196 #ifdef CALLER_SAVES_HpLim
1197 #define CALLER_SAVE_HpLim       SAVE_HpLim = HpLim;
1198 #define CALLER_RESTORE_HpLim    HpLim = SAVE_HpLim;
1199 #else
1200 #define CALLER_SAVE_HpLim       /* nothing */
1201 #define CALLER_RESTORE_HpLim    /* nothing */
1202 #endif
1203
1204 #ifdef CALLER_SAVES_Liveness
1205 #define CALLER_SAVE_Liveness    SAVE_Liveness = LivenessReg;
1206 #define CALLER_RESTORE_Liveness LivenessReg = SAVE_Liveness;
1207 #else
1208 #define CALLER_SAVE_Liveness    /* nothing */
1209 #define CALLER_RESTORE_Liveness /* nothing */
1210 #endif
1211
1212 #ifdef CALLER_SAVES_Base
1213 #ifndef CONCURRENT
1214 #define CALLER_SAVE_Base        /* nothing, ever (it holds a fixed value) */
1215 #define CALLER_RESTORE_Base     BaseReg = &MainRegTable;
1216 #else
1217 #define CALLER_SAVE_Base        /* nothing */
1218 #define CALLER_RESTORE_Base     BaseReg = CurrentRegTable;
1219 #endif
1220 #else
1221 #define CALLER_SAVE_Base        /* nothing */
1222 #define CALLER_RESTORE_Base     /* nothing */
1223 #endif
1224
1225 #ifdef CALLER_SAVES_StdUpdRetVec
1226 #define CALLER_RESTORE_StdUpdRetVec     StdUpdRetVecReg = vtbl_StdUpdFrame;
1227 #else
1228 #define CALLER_RESTORE_StdUpdRetVec     /* nothing */
1229 #endif
1230
1231 #ifdef CALLER_SAVES_StkStub
1232 #define CALLER_RESTORE_StkStub          StdUpdRetVecReg = STK_STUB_closure;
1233 #else
1234 #define CALLER_RESTORE_StkStub          /* nothing */
1235 #endif
1236
1237 \end{code}
1238
1239 Concluding \tr{#endifs} and multi-slurp protection:
1240
1241 \begin{code}
1242
1243 #endif  /* SCAV_REG_MAP */
1244 #endif  /* SCAN_REG_MAP */
1245 #endif  /* MARK_REG_MAP */
1246 #endif  /* NULL_REG_MAP */
1247
1248 #endif  /* STGREGS_H */
1249 \end{code}