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