2 % (c) The GRASP Project, Glasgow University, 1993
4 \section[StgRegs-decls]{STG-machine register mappings}
10 #include "StgMachDeps.h"
14 #define GLOBAL_REG_DECL(type,name,reg) register type name REG(reg);
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.
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.
28 This file/document/section sets out the various (machine-dependent)
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
41 %************************************************************************
43 \subsection[saved-STG-regs]{Saved STG registers}
45 %************************************************************************
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).
54 StgDouble rDbl[2]; /* Put a double first to ensure expected alignment */
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)
77 There are several confusing macro sets for accessing STG registers at various
78 stages in their lives.
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.
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.
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.
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@.
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
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
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.
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)
122 extern STGRegisterTable MainRegTable;
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])
141 #define MAIN_Tag (MainRegTable.rTag)
142 #define MAIN_Ret (MainRegTable.rRet)
143 #define MAIN_Activity (MainRegTable.rActivity)
145 #define MAIN_StkO (MainStkO)
146 #define MAIN_Liveness (MainRegTable.rLiveness)
150 #define MAIN_SpA (MainRegTable.rSpA)
151 #define MAIN_SuA (MainRegTable.rSuA)
152 #define MAIN_SpB (MainRegTable.rSpB)
153 #define MAIN_SuB (MainRegTable.rSuB)
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
171 #define SAVE_SpA MAIN_SpA
172 #define SAVE_SuA MAIN_SuA
173 #define SAVE_SpB MAIN_SpB
174 #define SAVE_SuB MAIN_SuB
176 #define SAVE_Tag MAIN_Tag
177 #define SAVE_Ret MAIN_Ret
178 #define SAVE_Activity MAIN_Activity
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))
189 extern STGRegisterTable *CurrentRegTable;
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])
207 /* These are only valid when StkOReg is loaded! */
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))
214 #define SAVE_Tag (CurrentRegTable->rTag)
215 #define SAVE_Ret (CurrentRegTable->rRet)
216 #define SAVE_Activity (CurrentRegTable->rActivity)
218 #define SAVE_StkO (CurrentRegTable->rStkO)
219 #define SAVE_Liveness (CurrentRegTable->rLiveness)
221 #endif /* CONCURRENT */
223 /* Note that the SAVE_ locations for the Hp registers are in the smInfo structure */
225 #define SAVE_Hp (StorageMgrInfo.hp)
226 #define SAVE_HpLim (StorageMgrInfo.hplim)
230 %************************************************************************
232 \subsection[null-mapping-StgRegs]{The empty register mapping}
234 %************************************************************************
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.
240 #if defined(NULL_REG_MAP)
244 This is a HACK here; see comment in COptJumps.lh.
246 #if alpha_dec_osf1_TARGET && defined(__STG_TAILJUMPS__) && defined(__GNUC__)
247 register void *_procedure __asm__("$27");
249 #if (mipsel_TARGET_ARCH || mipseb_TARGET_ARCH) && defined(__STG_TAILJUMPS__) && defined(__GNUC__)
250 register void *_procedure __asm__("$25");
254 %************************************************************************
256 \subsection[mark-mapping-StgRegs]{The ``mark'' register mapping}
258 %************************************************************************
260 The mark mapping is used for pointer-reversal marking during GC. It
261 is used by most of the current garbage collectors.
264 #if defined(MARK_REG_MAP)
267 Mark (GC) register mapping:
270 sparc m68k alpha mipseX hppa iX86 rs6000
271 ----- ---- ----- ------ ---- ---- ------
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
295 #define REGDUMP(dump) static RegisterTable dump
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)
304 extern RegisterTable MarkRegTable;
307 GLOBAL_REG_DECL(RegisterTable *,MarkBaseReg,REG_MarkBase)
309 #define MarkBaseReg (&MarkRegTable)
313 GLOBAL_REG_DECL(P_,Mark,REG_Mark)
315 #define Mark SAVE_Mark
319 GLOBAL_REG_DECL(P_,MStack,REG_MStack)
321 #define MStack SAVE_MStack
325 GLOBAL_REG_DECL(P_,MRoot,REG_MRoot)
327 #define MRoot SAVE_MRoot
331 GLOBAL_REG_DECL(P_,BitArray,REG_BitArray)
333 #define BitArray SAVE_BitArray
337 GLOBAL_REG_DECL(P_,HeapBase,REG_HeapBase)
339 #define HeapBase SAVE_HeapBase
343 GLOBAL_REG_DECL(P_,HeapLim,REG_HeapLim)
345 #define HeapLim SAVE_HeapLim
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));
358 dump->rMarkBase = (P_) MarkBaseReg; /* save whatever is in it */
359 MarkBaseReg = dump; /* set it correctly */
365 dump->rMStack = MStack;
368 dump->rMRoot = MRoot;
371 dump->rBitArray = BitArray;
374 dump->rHeapBase = HeapBase;
377 dump->rHeapLim = HeapLim;
382 void RESTORE_REGS(dump)
389 MStack = dump->rMStack;
392 MRoot = dump->rMRoot;
395 BitArray = dump->rBitArray;
398 HeapBase = dump->rHeapBase;
401 HeapLim = dump->rHeapLim;
404 MarkBaseReg = (RegisterTable *) dump->rMarkBase; /* restore to whatever it was */
408 #define SAVE_REGS(dump)
409 #define RESTORE_REGS(dump)
413 %************************************************************************
415 \subsection[scan-mapping-StgRegs]{The ``scan'' register mapping}
417 %************************************************************************
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.
425 #if defined(SCAN_REG_MAP)
428 Scan (GC) register mapping:
431 sparc m68k alpha mipseX hppa iX86 rs6000
432 ----- ---- ----- ------ ---- ---- ------
435 Scan a2 $9 $16 r4 ebx
436 New a3 $10 $17 r5 ebp
437 LinkLim a4 $11 $18 r6 esi
450 #define REGDUMP(dump) static RegisterTable dump
452 #define SAVE_Scan (ScanRegTable.rScan)
453 #define SAVE_New (ScanRegTable.rNew)
454 #define SAVE_LinkLim (ScanRegTable.rLinkLim)
456 extern RegisterTable ScanRegTable;
459 GLOBAL_REG_DECL(RegisterTable *,ScanBaseReg,REG_ScanBase)
461 #define ScanBaseReg (&ScanRegTable)
465 GLOBAL_REG_DECL(P_,Scan,REG_Scan)
468 # define Scan (ScanBaseReg->rScan)
470 # define Scan SAVE_Scan
475 GLOBAL_REG_DECL(P_,New,REG_New)
478 # define New (ScanBaseReg->rNew)
480 # define New SAVE_New
485 GLOBAL_REG_DECL(P_,LinkLim,REG_LinkLim)
488 # define LinkLim (ScanBaseReg->rLinkLim)
490 # define LinkLim SAVE_LinkLim
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));
504 dump->rScanBase = (P_) ScanBaseReg; /* save whatever is in it */
505 ScanBaseReg = dump; /* set it correctly */
514 dump->rLinkLim = LinkLim;
519 void RESTORE_REGS(dump)
529 LinkLim = dump->rLinkLim;
532 ScanBaseReg = (RegisterTable *) dump->rScanBase; /* restore to whatever it was */
536 #define SAVE_REGS(dump)
537 #define RESTORE_REGS(dump)
541 %************************************************************************
543 \subsection[scav-mapping-StgRegs]{The ``scavenge'' register mapping}
545 %************************************************************************
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)
551 Note: registers must not be mangled by sliding register windows,
552 etc. or there'll be trouble. ADR
556 #if defined(SCAV_REG_MAP)
559 Scavenge (GC) register mapping:
562 sparc m68k alpha mipseX hppa iX86 rs6000
563 ----- ---- ----- ------ ---- ---- ------
566 Scav a2 $9 $16 r4 ebx
567 ToHp a3 $10 $17 r5 ebp
568 OldGen (gn/ap) a4 $11 $18 r6 esi
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 )
591 #define REGDUMP(dump) static RegisterTable dump
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)
599 extern RegisterTable ScavRegTable;
602 GLOBAL_REG_DECL(RegisterTable *,ScavBaseReg,REG_ScavBase)
604 #define ScavBaseReg (&ScavRegTable)
608 GLOBAL_REG_DECL(P_,Scav,REG_Scav)
611 # define Scav (ScavBaseReg->rScav)
613 # define Scav SAVE_Scav
618 GLOBAL_REG_DECL(P_,ToHp,REG_ToHp)
621 # define ToHp (ScavBaseReg->rToHp)
623 # define ToHp SAVE_ToHp
628 GLOBAL_REG_DECL(P_,OldGen,REG_OldGen)
631 # define OldGen (ScavBaseReg->rOldGen)
633 # define OldGen SAVE_OldGen
638 GLOBAL_REG_DECL(P_,AllocGen,REG_AllocGen)
641 # define AllocGen (ScavBaseReg->rAllocGen)
643 # define AllocGen SAVE_AllocGen
648 GLOBAL_REG_DECL(P_,OldHp,REG_OldHp)
651 # define OldHp (ScavBaseReg->rOldHp)
653 # define OldHp SAVE_OldHp
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));
667 dump->rScavBase = (P_) ScavBaseReg; /* save whatever is in it */
668 ScavBaseReg = dump; /* set it correctly */
677 dump->rOldGen = OldGen;
680 dump->rAllocGen = AllocGen;
683 dump->rOldHp = OldHp;
688 void RESTORE_REGS(dump)
698 OldGen = dump->rOldGen;
701 AllocGen = dump->rAllocGen;
704 OldHp = dump->rOldHp;
707 ScavBaseReg = (RegisterTable *) dump->rScavBase; /* restore to whatever it was */
711 #define SAVE_REGS(dump)
712 #define RESTORE_REGS(dump)
716 %************************************************************************
718 \subsection[main-mapping-StgRegs]{The main register mapping (Haskell threaded world)}
720 %************************************************************************
723 #else /* For simplicity, the default is MAIN_REG_MAP (this one) */
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).
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.
738 sparc m68k alpha mipseX hppa iX86 rs6000
739 ----- ---- ----- ------ ---- ---- ------
744 R1/Node l1 d7 $1! $9! %r11
745 R2 l2 d6 $2! $10! %r12
746 R3 l3 d5 $3! $11! %r13
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
760 DblReg1 f6! fp6 $f5 $f28 %fr20 * SEE NOTES!
761 DblReg2 f8! fp7 $f6 $f30 %fr20 * SEE NOTES!
764 SuA i1 d3 $10 $17 %r5
765 SpB i2 a4 $11 $18 %r6
766 SuB i3 d4 $12 $19 %r7
771 RetReg l0 $15 $22 %r10
773 Liveness (CONCURRENT)
775 Activity g5 (DO_SPAT_PROFILING)
784 Registers not mentioned in the summary table end up in the default
785 (a memory location in @MainRegTable@).
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
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:
798 StdUpdRetVecReg vtbl_StdUpdFrame
799 StkStubReg STK_STUB_closure
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).
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.
818 #define InfoPtr (R2.d)
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)
848 GLOBAL_REG_DECL(STGRegisterTable *,BaseReg,REG_Base)
851 #define BaseReg CurrentRegTable
853 #define BaseReg (&MainRegTable)
854 #endif /* CONCURRENT */
855 #endif /* REG_Base */
858 GLOBAL_REG_DECL(P_,StkOReg,REG_StkO)
860 #define StkOReg RTBL_StkO
863 /* R1 is used for Node */
865 GLOBAL_REG_DECL(StgUnion,R1,REG_R1)
870 /* R2 is used for InfoPtr */
872 GLOBAL_REG_DECL(StgUnion,R2,REG_R2)
878 GLOBAL_REG_DECL(StgUnion,R3,REG_R3)
884 GLOBAL_REG_DECL(StgUnion,R4,REG_R4)
890 GLOBAL_REG_DECL(StgUnion,R5,REG_R5)
896 GLOBAL_REG_DECL(StgUnion,R6,REG_R6)
902 GLOBAL_REG_DECL(StgUnion,R7,REG_R7)
908 GLOBAL_REG_DECL(StgUnion,R8,REG_R8)
914 GLOBAL_REG_DECL(StgFloat,FltReg1,REG_Flt1)
916 #define FltReg1 RTBL_Flt1
920 GLOBAL_REG_DECL(StgFloat,FltReg2,REG_Flt2)
922 #define FltReg2 RTBL_Flt2
926 GLOBAL_REG_DECL(StgFloat,FltReg3,REG_Flt3)
928 #define FltReg3 RTBL_Flt3
932 GLOBAL_REG_DECL(StgFloat,FltReg4,REG_Flt4)
934 #define FltReg4 RTBL_Flt4
938 GLOBAL_REG_DECL(StgDouble,DblReg1,REG_Dbl1)
940 #define DblReg1 RTBL_Dbl1
944 GLOBAL_REG_DECL(StgDouble,DblReg2,REG_Dbl2)
946 #define DblReg2 RTBL_Dbl2
950 GLOBAL_REG_DECL(I_,TagReg,REG_Tag)
952 #define SET_TAG(tag) TagReg = tag
954 #define TagReg INFO_TAG(InfoPtr)
955 #define SET_TAG(tag) /* nothing */
959 GLOBAL_REG_DECL(StgRetAddr,RetReg,REG_Ret)
961 #define RetReg RTBL_Ret
965 GLOBAL_REG_DECL(PP_,SpA,REG_SpA)
971 GLOBAL_REG_DECL(PP_,SuA,REG_SuA)
977 GLOBAL_REG_DECL(P_,SpB,REG_SpB)
983 GLOBAL_REG_DECL(P_,SuB,REG_SuB)
989 GLOBAL_REG_DECL(P_,Hp,REG_Hp)
995 GLOBAL_REG_DECL(P_,HpLim,REG_HpLim)
997 #define HpLim RTBL_HpLim
1001 GLOBAL_REG_DECL(I_,LivenessReg,REG_Liveness)
1003 #define LivenessReg RTBL_Liveness
1007 GLOBAL_REG_DECL(I_,ActivityReg,REG_Activity)
1009 #define ActivityReg RTBL_Activity
1012 #ifdef REG_StdUpdRetVec
1013 GLOBAL_REG_DECL(D_,StdUpdRetVecReg,REG_StdUpdRetVec)
1015 #define StdUpdRetVecReg vtbl_StdUpdFrame
1019 GLOBAL_REG_DECL(P_,StkStubReg,REG_StkStub)
1021 #define StkStubReg STK_STUB_closure
1024 #ifdef CALLER_SAVES_StkO
1025 #define CALLER_SAVE_StkO SAVE_StkO = StkOReg;
1026 #define CALLER_RESTORE_StkO StkOReg = SAVE_StkO;
1028 #define CALLER_SAVE_StkO /* nothing */
1029 #define CALLER_RESTORE_StkO /* nothing */
1032 #ifdef CALLER_SAVES_R1
1033 #define CALLER_SAVE_R1 SAVE_R1 = R1;
1034 #define CALLER_RESTORE_R1 R1 = SAVE_R1;
1036 #define CALLER_SAVE_R1 /* nothing */
1037 #define CALLER_RESTORE_R1 /* nothing */
1040 #ifdef CALLER_SAVES_R2
1041 #define CALLER_SAVE_R2 SAVE_R2 = R2;
1042 #define CALLER_RESTORE_R2 R2 = SAVE_R2;
1044 #define CALLER_SAVE_R2 /* nothing */
1045 #define CALLER_RESTORE_R2 /* nothing */
1048 #ifdef CALLER_SAVES_R3
1049 #define CALLER_SAVE_R3 SAVE_R3 = R3;
1050 #define CALLER_RESTORE_R3 R3 = SAVE_R3;
1052 #define CALLER_SAVE_R3 /* nothing */
1053 #define CALLER_RESTORE_R3 /* nothing */
1056 #ifdef CALLER_SAVES_R4
1057 #define CALLER_SAVE_R4 SAVE_R4 = R4;
1058 #define CALLER_RESTORE_R4 R4 = SAVE_R4;
1060 #define CALLER_SAVE_R4 /* nothing */
1061 #define CALLER_RESTORE_R4 /* nothing */
1064 #ifdef CALLER_SAVES_R5
1065 #define CALLER_SAVE_R5 SAVE_R5 = R5;
1066 #define CALLER_RESTORE_R5 R5 = SAVE_R5;
1068 #define CALLER_SAVE_R5 /* nothing */
1069 #define CALLER_RESTORE_R5 /* nothing */
1072 #ifdef CALLER_SAVES_R6
1073 #define CALLER_SAVE_R6 SAVE_R6 = R6;
1074 #define CALLER_RESTORE_R6 R6 = SAVE_R6;
1076 #define CALLER_SAVE_R6 /* nothing */
1077 #define CALLER_RESTORE_R6 /* nothing */
1080 #ifdef CALLER_SAVES_R7
1081 #define CALLER_SAVE_R7 SAVE_R7 = R7;
1082 #define CALLER_RESTORE_R7 R7 = SAVE_R7;
1084 #define CALLER_SAVE_R7 /* nothing */
1085 #define CALLER_RESTORE_R7 /* nothing */
1088 #ifdef CALLER_SAVES_R8
1089 #define CALLER_SAVE_R8 SAVE_R8 = R8;
1090 #define CALLER_RESTORE_R8 R8 = SAVE_R8;
1092 #define CALLER_SAVE_R8 /* nothing */
1093 #define CALLER_RESTORE_R8 /* nothing */
1096 #ifdef CALLER_SAVES_FltReg1
1097 #define CALLER_SAVE_FltReg1 SAVE_Flt1 = FltReg1;
1098 #define CALLER_RESTORE_FltReg1 FltReg1 = SAVE_Flt1;
1100 #define CALLER_SAVE_FltReg1 /* nothing */
1101 #define CALLER_RESTORE_FltReg1 /* nothing */
1104 #ifdef CALLER_SAVES_FltReg2
1105 #define CALLER_SAVE_FltReg2 SAVE_Flt2 = FltReg2;
1106 #define CALLER_RESTORE_FltReg2 FltReg2 = SAVE_Flt2;
1108 #define CALLER_SAVE_FltReg2 /* nothing */
1109 #define CALLER_RESTORE_FltReg2 /* nothing */
1112 #ifdef CALLER_SAVES_FltReg3
1113 #define CALLER_SAVE_FltReg3 SAVE_Flt3 = FltReg3;
1114 #define CALLER_RESTORE_FltReg3 FltReg3 = SAVE_Flt3;
1116 #define CALLER_SAVE_FltReg3 /* nothing */
1117 #define CALLER_RESTORE_FltReg3 /* nothing */
1120 #ifdef CALLER_SAVES_FltReg4
1121 #define CALLER_SAVE_FltReg4 SAVE_Flt4 = FltReg4;
1122 #define CALLER_RESTORE_FltReg4 FltReg4 = SAVE_Flt4;
1124 #define CALLER_SAVE_FltReg4 /* nothing */
1125 #define CALLER_RESTORE_FltReg4 /* nothing */
1128 #ifdef CALLER_SAVES_DblReg1
1129 #define CALLER_SAVE_DblReg1 SAVE_Dbl1 = DblReg1;
1130 #define CALLER_RESTORE_DblReg1 DblReg1 = SAVE_Dbl1;
1132 #define CALLER_SAVE_DblReg1 /* nothing */
1133 #define CALLER_RESTORE_DblReg1 /* nothing */
1136 #ifdef CALLER_SAVES_DblReg2
1137 #define CALLER_SAVE_DblReg2 SAVE_Dbl2 = DblReg2;
1138 #define CALLER_RESTORE_DblReg2 DblReg2 = SAVE_Dbl2;
1140 #define CALLER_SAVE_DblReg2 /* nothing */
1141 #define CALLER_RESTORE_DblReg2 /* nothing */
1144 #ifdef CALLER_SAVES_Tag
1145 #define CALLER_SAVE_Tag SAVE_Tag = TagReg;
1146 #define CALLER_RESTORE_Tag TagReg = SAVE_Tag;
1148 #define CALLER_SAVE_Tag /* nothing */
1149 #define CALLER_RESTORE_Tag /* nothing */
1152 #ifdef CALLER_SAVES_Ret
1153 #define CALLER_SAVE_Ret SAVE_Ret = RetReg;
1154 #define CALLER_RESTORE_Ret RetReg = SAVE_Ret;
1156 #define CALLER_SAVE_Ret /* nothing */
1157 #define CALLER_RESTORE_Ret /* nothing */
1160 #ifdef CALLER_SAVES_SpA
1161 #define CALLER_SAVE_SpA SAVE_SpA = SpA;
1162 #define CALLER_RESTORE_SpA SpA = SAVE_SpA;
1164 #define CALLER_SAVE_SpA /* nothing */
1165 #define CALLER_RESTORE_SpA /* nothing */
1168 #ifdef CALLER_SAVES_SuA
1169 #define CALLER_SAVE_SuA SAVE_SuA = SuA;
1170 #define CALLER_RESTORE_SuA SuA = SAVE_SuA;
1172 #define CALLER_SAVE_SuA /* nothing */
1173 #define CALLER_RESTORE_SuA /* nothing */
1176 #ifdef CALLER_SAVES_SpB
1177 #define CALLER_SAVE_SpB SAVE_SpB = SpB;
1178 #define CALLER_RESTORE_SpB SpB = SAVE_SpB;
1180 #define CALLER_SAVE_SpB /* nothing */
1181 #define CALLER_RESTORE_SpB /* nothing */
1184 #ifdef CALLER_SAVES_SuB
1185 #define CALLER_SAVE_SuB SAVE_SuB = SuB;
1186 #define CALLER_RESTORE_SuB SuB = SAVE_SuB;
1188 #define CALLER_SAVE_SuB /* nothing */
1189 #define CALLER_RESTORE_SuB /* nothing */
1192 #ifdef CALLER_SAVES_Hp
1193 #define CALLER_SAVE_Hp SAVE_Hp = Hp;
1194 #define CALLER_RESTORE_Hp Hp = SAVE_Hp;
1196 #define CALLER_SAVE_Hp /* nothing */
1197 #define CALLER_RESTORE_Hp /* nothing */
1200 #ifdef CALLER_SAVES_HpLim
1201 #define CALLER_SAVE_HpLim SAVE_HpLim = HpLim;
1202 #define CALLER_RESTORE_HpLim HpLim = SAVE_HpLim;
1204 #define CALLER_SAVE_HpLim /* nothing */
1205 #define CALLER_RESTORE_HpLim /* nothing */
1208 #ifdef CALLER_SAVES_Liveness
1209 #define CALLER_SAVE_Liveness SAVE_Liveness = LivenessReg;
1210 #define CALLER_RESTORE_Liveness LivenessReg = SAVE_Liveness;
1212 #define CALLER_SAVE_Liveness /* nothing */
1213 #define CALLER_RESTORE_Liveness /* nothing */
1216 #ifdef CALLER_SAVES_Activity
1217 #define CALLER_SAVE_Activity SAVE_Activity = ActivityReg;
1218 #define CALLER_RESTORE_Activity ActivityReg = SAVE_Activity;
1220 #define CALLER_SAVE_Activity /* nothing */
1221 #define CALLER_RESTORE_Activity /* nothing */
1224 #ifdef CALLER_SAVES_Base
1226 #define CALLER_SAVE_Base /* nothing, ever (it holds a fixed value) */
1227 #define CALLER_RESTORE_Base BaseReg = MainRegTable;
1229 #define CALLER_SAVE_Base /* nothing */
1230 #define CALLER_RESTORE_Base BaseReg = CurrentRegTable;
1233 #define CALLER_SAVE_Base /* nothing */
1234 #define CALLER_RESTORE_Base /* nothing */
1237 #ifdef CALLER_SAVES_StdUpdRetVec
1238 #define CALLER_RESTORE_StdUpdRetVec StdUpdRetVecReg = vtbl_StdUpdFrame;
1240 #define CALLER_RESTORE_StdUpdRetVec /* nothing */
1243 #ifdef CALLER_SAVES_StkStub
1244 #define CALLER_RESTORE_StkStub StdUpdRetVecReg = STK_STUB_closure;
1246 #define CALLER_RESTORE_StkStub /* nothing */
1251 Concluding \tr{#endifs} and multi-slurp protection:
1255 #endif /* SCAV_REG_MAP */
1256 #endif /* SCAN_REG_MAP */
1257 #endif /* MARK_REG_MAP */
1258 #endif /* NULL_REG_MAP */
1260 #endif /* STGREGS_H */