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