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 */
65 I_ rActivity; /* NB: UNUSED */
66 P_ rCstkptr; /* used for iX86 registerizing only! offset=100 */
67 P_ rWrapReturn; /* ditto; offset=104 */
68 P_ rSaveECX; /* ditto; offset=108 */
69 #if defined(CONCURRENT)
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_Hp (MainRegTable.rHp)
142 #define MAIN_HpLim (MainRegTable.rHpLim)
143 #define MAIN_Tag (MainRegTable.rTag)
144 #define MAIN_Ret (MainRegTable.rRet)
146 #define MAIN_StkO (MainStkO)
147 #define MAIN_Liveness (MainRegTable.rLiveness)
151 #define MAIN_SpA (MainRegTable.rSpA)
152 #define MAIN_SuA (MainRegTable.rSuA)
153 #define MAIN_SpB (MainRegTable.rSpB)
154 #define MAIN_SuB (MainRegTable.rSuB)
156 /* these are really for *SAVE*ing */
157 #define SAVE_R1 MAIN_R1
158 #define SAVE_R2 MAIN_R2
159 #define SAVE_R3 MAIN_R3
160 #define SAVE_R4 MAIN_R4
161 #define SAVE_R5 MAIN_R5
162 #define SAVE_R6 MAIN_R6
163 #define SAVE_R7 MAIN_R7
164 #define SAVE_R8 MAIN_R8
165 #define SAVE_Flt1 MAIN_Flt1
166 #define SAVE_Flt2 MAIN_Flt2
167 #define SAVE_Flt3 MAIN_Flt3
168 #define SAVE_Flt4 MAIN_Flt4
169 #define SAVE_Dbl1 MAIN_Dbl1
170 #define SAVE_Dbl2 MAIN_Dbl2
172 #define SAVE_SpA MAIN_SpA
173 #define SAVE_SuA MAIN_SuA
174 #define SAVE_SpB MAIN_SpB
175 #define SAVE_SuB MAIN_SuB
177 #define SAVE_Tag MAIN_Tag
178 #define SAVE_Ret MAIN_Ret
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)
217 #define SAVE_StkO (CurrentRegTable->rStkO)
218 #define SAVE_Liveness (CurrentRegTable->rLiveness)
220 #endif /* CONCURRENT */
222 /* Note that the SAVE_ locations for the Hp registers are in the smInfo structure */
224 #define SAVE_Hp (StorageMgrInfo.hp)
225 #define SAVE_HpLim (StorageMgrInfo.hplim)
229 %************************************************************************
231 \subsection[null-mapping-StgRegs]{The empty register mapping}
233 %************************************************************************
235 This mapping leaves all machine registers free for normal C allocation.
236 In the RTS, this is the preferred mapping, because it allows gcc to use
237 all available registers, with the normal callee-saves conventions.
239 #if defined(NULL_REG_MAP)
243 This is a HACK here; see comment in COptJumps.lh.
245 #if alpha_dec_osf1_TARGET && defined(__STG_TAILJUMPS__) && defined(__GNUC__)
246 register void *_procedure __asm__("$27");
248 #if (mipsel_TARGET_ARCH || mipseb_TARGET_ARCH) && defined(__STG_TAILJUMPS__) && defined(__GNUC__)
249 register void *_procedure __asm__("$25");
253 %************************************************************************
255 \subsection[mark-mapping-StgRegs]{The ``mark'' register mapping}
257 %************************************************************************
259 The mark mapping is used for pointer-reversal marking during GC. It
260 is used by most of the current garbage collectors.
263 #if defined(MARK_REG_MAP)
266 Mark (GC) register mapping:
269 sparc m68k alpha mipseX hppa iX86 powerpc
270 ----- ---- ----- ------ ---- ---- -------
273 Mark i0 a2 $9 $16 r4 ebp
274 MStack i1 a3 $10 $17 r5 esi
275 MRoot i2 a4 $11 $18 r6 edi
276 BitArray i3 a5 $12 $19 r7
277 HeapBase i4 d3 $13 $20 r8
278 HeapLim i5 d4 $14 $21 r9
294 #define REGDUMP(dump) static RegisterTable dump
296 #define SAVE_Mark (MarkRegTable.rMark)
297 #define SAVE_MStack (MarkRegTable.rMStack)
298 #define SAVE_MRoot (MarkRegTable.rMRoot)
299 #define SAVE_BitArray (MarkRegTable.rBitArray)
300 #define SAVE_HeapBase (MarkRegTable.rHeapBase)
301 #define SAVE_HeapLim (MarkRegTable.rHeapLim)
303 extern RegisterTable MarkRegTable;
306 GLOBAL_REG_DECL(RegisterTable *,MarkBaseReg,REG_MarkBase)
308 #define MarkBaseReg (&MarkRegTable)
312 GLOBAL_REG_DECL(P_,Mark,REG_Mark)
314 #define Mark SAVE_Mark
318 GLOBAL_REG_DECL(P_,MStack,REG_MStack)
320 #define MStack SAVE_MStack
324 GLOBAL_REG_DECL(P_,MRoot,REG_MRoot)
326 #define MRoot SAVE_MRoot
330 GLOBAL_REG_DECL(P_,BitArray,REG_BitArray)
332 #define BitArray SAVE_BitArray
336 GLOBAL_REG_DECL(P_,HeapBase,REG_HeapBase)
338 #define HeapBase SAVE_HeapBase
342 GLOBAL_REG_DECL(P_,HeapLim,REG_HeapLim)
344 #define HeapLim SAVE_HeapLim
347 #if defined(__STG_GCC_REGS__)
348 /* Keep -Wmissing-prototypes from complaining */
349 void SAVE_REGS PROTO((RegisterTable *dump));
350 void RESTORE_REGS PROTO((RegisterTable *dump));
357 dump->rMarkBase = (P_) MarkBaseReg; /* save whatever is in it */
358 MarkBaseReg = dump; /* set it correctly */
364 dump->rMStack = MStack;
367 dump->rMRoot = MRoot;
370 dump->rBitArray = BitArray;
373 dump->rHeapBase = HeapBase;
376 dump->rHeapLim = HeapLim;
381 void RESTORE_REGS(dump)
388 MStack = dump->rMStack;
391 MRoot = dump->rMRoot;
394 BitArray = dump->rBitArray;
397 HeapBase = dump->rHeapBase;
400 HeapLim = dump->rHeapLim;
403 MarkBaseReg = (RegisterTable *) dump->rMarkBase; /* restore to whatever it was */
407 #define SAVE_REGS(dump)
408 #define RESTORE_REGS(dump)
412 %************************************************************************
414 \subsection[scan-mapping-StgRegs]{The ``scan'' register mapping}
416 %************************************************************************
418 The scan mapping is used for all of the in-place garbage collectors.
419 On architectures with register windows, like the SPARC, these must
420 reside in global registers, because the scan code is not threaded.
424 #if defined(SCAN_REG_MAP)
427 Scan (GC) register mapping:
430 sparc m68k alpha mipseX hppa iX86 powerpc
431 ----- ---- ----- ------ ---- ---- -------
434 Scan a2 $9 $16 r4 ebx
435 New a3 $10 $17 r5 ebp
436 LinkLim a4 $11 $18 r6 esi
449 #define REGDUMP(dump) static RegisterTable dump
451 #define SAVE_Scan (ScanRegTable.rScan)
452 #define SAVE_New (ScanRegTable.rNew)
453 #define SAVE_LinkLim (ScanRegTable.rLinkLim)
455 extern RegisterTable ScanRegTable;
458 GLOBAL_REG_DECL(RegisterTable *,ScanBaseReg,REG_ScanBase)
460 #define ScanBaseReg (&ScanRegTable)
464 GLOBAL_REG_DECL(P_,Scan,REG_Scan)
467 # define Scan (ScanBaseReg->rScan)
469 # define Scan SAVE_Scan
474 GLOBAL_REG_DECL(P_,New,REG_New)
477 # define New (ScanBaseReg->rNew)
479 # define New SAVE_New
484 GLOBAL_REG_DECL(P_,LinkLim,REG_LinkLim)
487 # define LinkLim (ScanBaseReg->rLinkLim)
489 # define LinkLim SAVE_LinkLim
493 #if defined(__STG_GCC_REGS__)
494 /* Keep -Wmissing-prototypes from complaining */
495 void SAVE_REGS PROTO((RegisterTable *dump));
496 void RESTORE_REGS PROTO((RegisterTable *dump));
503 dump->rScanBase = (P_) ScanBaseReg; /* save whatever is in it */
504 ScanBaseReg = dump; /* set it correctly */
513 dump->rLinkLim = LinkLim;
518 void RESTORE_REGS(dump)
528 LinkLim = dump->rLinkLim;
531 ScanBaseReg = (RegisterTable *) dump->rScanBase; /* restore to whatever it was */
535 #define SAVE_REGS(dump)
536 #define RESTORE_REGS(dump)
540 %************************************************************************
542 \subsection[scav-mapping-StgRegs]{The ``scavenge'' register mapping}
544 %************************************************************************
546 The scan mapping is used for all of the in-place garbage collectors.
547 (I believe that it must use a subset of the registers that are used
548 in the mark mapping, but I could be wrong. --JSM)
550 Note: registers must not be mangled by sliding register windows,
551 etc. or there'll be trouble. ADR
555 #if defined(SCAV_REG_MAP)
558 Scavenge (GC) register mapping:
561 sparc m68k alpha mipseX hppa iX86 powerpc
562 ----- ---- ----- ------ ---- ---- -------
565 Scav a2 $9 $16 r4 ebx
566 ToHp a3 $10 $17 r5 ebp
567 OldGen (gn/ap) a4 $11 $18 r6 esi
573 (Calling this struct @ScavRegisterTable@ would make it possible for
574 @gdb@ to display it properly. At the moment, @gdb@ confuses it with
575 the scan register table etc. ADR )
590 #define REGDUMP(dump) static RegisterTable dump
592 #define SAVE_Scav (ScavRegTable.rScav)
593 #define SAVE_ToHp (ScavRegTable.rToHp)
594 #define SAVE_OldGen (ScavRegTable.rOldGen)
595 #define SAVE_AllocGen (ScavRegTable.rAllocGen)
596 #define SAVE_OldHp (ScavRegTable.rOldHp)
598 extern RegisterTable ScavRegTable;
601 GLOBAL_REG_DECL(RegisterTable *,ScavBaseReg,REG_ScavBase)
603 #define ScavBaseReg (&ScavRegTable)
607 GLOBAL_REG_DECL(P_,Scav,REG_Scav)
610 # define Scav (ScavBaseReg->rScav)
612 # define Scav SAVE_Scav
617 GLOBAL_REG_DECL(P_,ToHp,REG_ToHp)
620 # define ToHp (ScavBaseReg->rToHp)
622 # define ToHp SAVE_ToHp
627 GLOBAL_REG_DECL(P_,OldGen,REG_OldGen)
630 # define OldGen (ScavBaseReg->rOldGen)
632 # define OldGen SAVE_OldGen
637 GLOBAL_REG_DECL(P_,AllocGen,REG_AllocGen)
640 # define AllocGen (ScavBaseReg->rAllocGen)
642 # define AllocGen SAVE_AllocGen
647 GLOBAL_REG_DECL(P_,OldHp,REG_OldHp)
650 # define OldHp (ScavBaseReg->rOldHp)
652 # define OldHp SAVE_OldHp
656 #if defined(__STG_GCC_REGS__)
657 /* Keep -Wmissing-prototypes from complaining */
658 void SAVE_REGS PROTO((RegisterTable *dump));
659 void RESTORE_REGS PROTO((RegisterTable *dump));
666 dump->rScavBase = (P_) ScavBaseReg; /* save whatever is in it */
667 ScavBaseReg = dump; /* set it correctly */
676 dump->rOldGen = OldGen;
679 dump->rAllocGen = AllocGen;
682 dump->rOldHp = OldHp;
687 void RESTORE_REGS(dump)
697 OldGen = dump->rOldGen;
700 AllocGen = dump->rAllocGen;
703 OldHp = dump->rOldHp;
706 ScavBaseReg = (RegisterTable *) dump->rScavBase; /* restore to whatever it was */
710 #define SAVE_REGS(dump)
711 #define RESTORE_REGS(dump)
715 %************************************************************************
717 \subsection[main-mapping-StgRegs]{The main register mapping (Haskell threaded world)}
719 %************************************************************************
722 #else /* For simplicity, the default is MAIN_REG_MAP (this one) */
725 Main register-mapping summary: (1)~Specific architecture's details are
726 given later. (2)~Entries marked \tr{!} are caller-saves registers
727 that {\em must be saved} across ccalls; those marked \tr{@} are
728 caller-saves registers that need {\em not} be saved; those marked
729 \tr{#} are caller-saves registers that need to be restored, but don't
730 need to be saved; the rest are callee-save registers (the best kind).
732 IF YOU CHANGE THIS TABLE, YOU MAY NEED TO CHANGE CallWrapper.s
733 (or equiv) and [who knows?] maybe something else. Check the
734 documentation in the porter's part of the installation guide.
737 sparc m68k alpha mipseX hppa iX86 powerpc
738 ----- ---- ----- ------ ---- ---- -------
743 R1/Node l1 d7 $1! $9! %r11
744 R2 l2 d6 $2! $10! %r12
745 R3 l3 d5 $3! $11! %r13
754 FltReg1 f2! fp2 $f1 $f20 %fr12
755 FltReg2 f3! fp3 $f2 $f22 %fr12R
756 FltReg3 f4! fp4 $f3 $f24 %fr13
757 FltReg4 f5! fp5 $f4 $f26 %fr13R
759 DblReg1 f6! fp6 $f5 $f28 %fr20 * SEE NOTES!
760 DblReg2 f8! fp7 $f6 $f30 %fr20 * SEE NOTES!
763 SuA i1 d3 $10 $17 %r5
764 SpB i2 a4 $11 $18 %r6
765 SuB i3 d4 $12 $19 %r7
770 RetReg l0 $15 $22 %r10
772 Liveness (CONCURRENT)
781 Registers not mentioned in the summary table end up in the default
782 (a memory location in @MainRegTable@).
785 @BaseReg@ is in a machine register if anything is (well, unless everything is!)
786 It points to a block of memory in which the things which don't end up in machine
790 Exceptions to previous point:
791 If the following labels are in machine registers, then the
792 corresponding register name refers to what's in its register; otherwise,
793 it refers to the label:
795 StdUpdRetVecReg vtbl_StdUpdFrame
796 StkStubReg STK_STUB_closure
798 Also, if TagReg is not in a machine register, its name refers to
799 @INFO_TAG(InfoPtr)@, the tag field from the info table pointed to by
800 register R2 (InfoPtr).
804 Next, we have the code to declare the various global registers. Those
805 STG registers which don't actually live in machine registers are
806 defined as macros which refer to the registers as fixed offsets into
807 the register table. Note that the register table will contain blank
808 spots for the STG registers that reside in machine registers. Not to
809 worry; these blank spots will be filled in whenever the register
810 context is saved, so the space does not go to waste.
815 #define InfoPtr (R2.d)
817 /* these are if we get stuck using the reg-tbl "register" (no machine reg avail) */
818 #define RTBL_Dbl1 (BaseReg->rDbl[0])
819 #define RTBL_Dbl2 (BaseReg->rDbl[1])
820 #define RTBL_Flt1 (BaseReg->rFlt[0])
821 #define RTBL_Flt2 (BaseReg->rFlt[1])
822 #define RTBL_Flt3 (BaseReg->rFlt[2])
823 #define RTBL_Flt4 (BaseReg->rFlt[3])
824 #define RTBL_R1 (BaseReg->rR[0])
825 #define RTBL_R2 (BaseReg->rR[1])
826 #define RTBL_R3 (BaseReg->rR[2])
827 #define RTBL_R4 (BaseReg->rR[3])
828 #define RTBL_R5 (BaseReg->rR[4])
829 #define RTBL_R6 (BaseReg->rR[5])
830 #define RTBL_R7 (BaseReg->rR[6])
831 #define RTBL_R8 (BaseReg->rR[7])
832 #define RTBL_SpA (BaseReg->rSpA)
833 #define RTBL_SuA (BaseReg->rSuA)
834 #define RTBL_SpB (BaseReg->rSpB)
835 #define RTBL_SuB (BaseReg->rSuB)
836 #define RTBL_Hp (BaseReg->rHp)
837 #define RTBL_HpLim (BaseReg->rHpLim)
838 #define RTBL_Tag (BaseReg->rTag)
839 #define RTBL_Ret (BaseReg->rRet)
840 #define RTBL_StkO (BaseReg->rStkO)
841 #define RTBL_Liveness (BaseReg->rLiveness)
844 GLOBAL_REG_DECL(STGRegisterTable *,BaseReg,REG_Base)
847 #define BaseReg CurrentRegTable
849 #define BaseReg (&MainRegTable)
850 #endif /* CONCURRENT */
851 #endif /* REG_Base */
854 GLOBAL_REG_DECL(P_,StkOReg,REG_StkO)
856 #define StkOReg RTBL_StkO
859 #ifndef __STG_REGS_AVAIL__ /* driver ensures it is 2 or more */
860 # define __STG_REGS_AVAIL__ 8 /* R1 to R8 */
861 /* this would only be non-8 if doing weird experiments (WDP 95/11) */
862 /* or it might be set lower for a particular arch... */
865 /* R1 is used for Node */
867 GLOBAL_REG_DECL(StgUnion,R1,REG_R1)
872 /* R2 is used for InfoPtr */
874 GLOBAL_REG_DECL(StgUnion,R2,REG_R2)
880 GLOBAL_REG_DECL(StgUnion,R3,REG_R3)
886 GLOBAL_REG_DECL(StgUnion,R4,REG_R4)
892 GLOBAL_REG_DECL(StgUnion,R5,REG_R5)
898 GLOBAL_REG_DECL(StgUnion,R6,REG_R6)
904 GLOBAL_REG_DECL(StgUnion,R7,REG_R7)
910 GLOBAL_REG_DECL(StgUnion,R8,REG_R8)
916 GLOBAL_REG_DECL(StgFloat,FltReg1,REG_Flt1)
918 #define FltReg1 RTBL_Flt1
922 GLOBAL_REG_DECL(StgFloat,FltReg2,REG_Flt2)
924 #define FltReg2 RTBL_Flt2
928 GLOBAL_REG_DECL(StgFloat,FltReg3,REG_Flt3)
930 #define FltReg3 RTBL_Flt3
934 GLOBAL_REG_DECL(StgFloat,FltReg4,REG_Flt4)
936 #define FltReg4 RTBL_Flt4
940 GLOBAL_REG_DECL(StgDouble,DblReg1,REG_Dbl1)
942 #define DblReg1 RTBL_Dbl1
946 GLOBAL_REG_DECL(StgDouble,DblReg2,REG_Dbl2)
948 #define DblReg2 RTBL_Dbl2
952 GLOBAL_REG_DECL(I_,TagReg,REG_Tag)
954 #define SET_TAG(tag) TagReg = tag
956 #define TagReg INFO_TAG(InfoPtr)
957 #define SET_TAG(tag) /* nothing */
961 GLOBAL_REG_DECL(StgRetAddr,RetReg,REG_Ret)
963 #define RetReg RTBL_Ret
967 GLOBAL_REG_DECL(PP_,SpA,REG_SpA)
973 GLOBAL_REG_DECL(PP_,SuA,REG_SuA)
979 GLOBAL_REG_DECL(P_,SpB,REG_SpB)
985 GLOBAL_REG_DECL(P_,SuB,REG_SuB)
991 GLOBAL_REG_DECL(P_,Hp,REG_Hp)
997 GLOBAL_REG_DECL(P_,HpLim,REG_HpLim)
999 #define HpLim RTBL_HpLim
1003 GLOBAL_REG_DECL(I_,LivenessReg,REG_Liveness)
1005 #define LivenessReg RTBL_Liveness
1008 #ifdef REG_StdUpdRetVec
1009 GLOBAL_REG_DECL(D_,StdUpdRetVecReg,REG_StdUpdRetVec)
1011 #define StdUpdRetVecReg vtbl_StdUpdFrame
1015 GLOBAL_REG_DECL(P_,StkStubReg,REG_StkStub)
1017 #define StkStubReg STK_STUB_closure
1020 #ifdef CALLER_SAVES_StkO
1021 #define CALLER_SAVE_StkO SAVE_StkO = StkOReg;
1022 #define CALLER_RESTORE_StkO StkOReg = SAVE_StkO;
1024 #define CALLER_SAVE_StkO /* nothing */
1025 #define CALLER_RESTORE_StkO /* nothing */
1028 #ifdef CALLER_SAVES_R1
1029 #define CALLER_SAVE_R1 SAVE_R1 = R1;
1030 #define CALLER_RESTORE_R1 R1 = SAVE_R1;
1032 #define CALLER_SAVE_R1 /* nothing */
1033 #define CALLER_RESTORE_R1 /* nothing */
1036 #ifdef CALLER_SAVES_R2
1037 #define CALLER_SAVE_R2 SAVE_R2 = R2;
1038 #define CALLER_RESTORE_R2 R2 = SAVE_R2;
1040 #define CALLER_SAVE_R2 /* nothing */
1041 #define CALLER_RESTORE_R2 /* nothing */
1044 #ifdef CALLER_SAVES_R3
1045 #define CALLER_SAVE_R3 SAVE_R3 = R3;
1046 #define CALLER_RESTORE_R3 R3 = SAVE_R3;
1048 #define CALLER_SAVE_R3 /* nothing */
1049 #define CALLER_RESTORE_R3 /* nothing */
1052 #ifdef CALLER_SAVES_R4
1053 #define CALLER_SAVE_R4 SAVE_R4 = R4;
1054 #define CALLER_RESTORE_R4 R4 = SAVE_R4;
1056 #define CALLER_SAVE_R4 /* nothing */
1057 #define CALLER_RESTORE_R4 /* nothing */
1060 #ifdef CALLER_SAVES_R5
1061 #define CALLER_SAVE_R5 SAVE_R5 = R5;
1062 #define CALLER_RESTORE_R5 R5 = SAVE_R5;
1064 #define CALLER_SAVE_R5 /* nothing */
1065 #define CALLER_RESTORE_R5 /* nothing */
1068 #ifdef CALLER_SAVES_R6
1069 #define CALLER_SAVE_R6 SAVE_R6 = R6;
1070 #define CALLER_RESTORE_R6 R6 = SAVE_R6;
1072 #define CALLER_SAVE_R6 /* nothing */
1073 #define CALLER_RESTORE_R6 /* nothing */
1076 #ifdef CALLER_SAVES_R7
1077 #define CALLER_SAVE_R7 SAVE_R7 = R7;
1078 #define CALLER_RESTORE_R7 R7 = SAVE_R7;
1080 #define CALLER_SAVE_R7 /* nothing */
1081 #define CALLER_RESTORE_R7 /* nothing */
1084 #ifdef CALLER_SAVES_R8
1085 #define CALLER_SAVE_R8 SAVE_R8 = R8;
1086 #define CALLER_RESTORE_R8 R8 = SAVE_R8;
1088 #define CALLER_SAVE_R8 /* nothing */
1089 #define CALLER_RESTORE_R8 /* nothing */
1092 #ifdef CALLER_SAVES_FltReg1
1093 #define CALLER_SAVE_FltReg1 SAVE_Flt1 = FltReg1;
1094 #define CALLER_RESTORE_FltReg1 FltReg1 = SAVE_Flt1;
1096 #define CALLER_SAVE_FltReg1 /* nothing */
1097 #define CALLER_RESTORE_FltReg1 /* nothing */
1100 #ifdef CALLER_SAVES_FltReg2
1101 #define CALLER_SAVE_FltReg2 SAVE_Flt2 = FltReg2;
1102 #define CALLER_RESTORE_FltReg2 FltReg2 = SAVE_Flt2;
1104 #define CALLER_SAVE_FltReg2 /* nothing */
1105 #define CALLER_RESTORE_FltReg2 /* nothing */
1108 #ifdef CALLER_SAVES_FltReg3
1109 #define CALLER_SAVE_FltReg3 SAVE_Flt3 = FltReg3;
1110 #define CALLER_RESTORE_FltReg3 FltReg3 = SAVE_Flt3;
1112 #define CALLER_SAVE_FltReg3 /* nothing */
1113 #define CALLER_RESTORE_FltReg3 /* nothing */
1116 #ifdef CALLER_SAVES_FltReg4
1117 #define CALLER_SAVE_FltReg4 SAVE_Flt4 = FltReg4;
1118 #define CALLER_RESTORE_FltReg4 FltReg4 = SAVE_Flt4;
1120 #define CALLER_SAVE_FltReg4 /* nothing */
1121 #define CALLER_RESTORE_FltReg4 /* nothing */
1124 #ifdef CALLER_SAVES_DblReg1
1125 #define CALLER_SAVE_DblReg1 SAVE_Dbl1 = DblReg1;
1126 #define CALLER_RESTORE_DblReg1 DblReg1 = SAVE_Dbl1;
1128 #define CALLER_SAVE_DblReg1 /* nothing */
1129 #define CALLER_RESTORE_DblReg1 /* nothing */
1132 #ifdef CALLER_SAVES_DblReg2
1133 #define CALLER_SAVE_DblReg2 SAVE_Dbl2 = DblReg2;
1134 #define CALLER_RESTORE_DblReg2 DblReg2 = SAVE_Dbl2;
1136 #define CALLER_SAVE_DblReg2 /* nothing */
1137 #define CALLER_RESTORE_DblReg2 /* nothing */
1140 #ifdef CALLER_SAVES_Tag
1141 #define CALLER_SAVE_Tag SAVE_Tag = TagReg;
1142 #define CALLER_RESTORE_Tag TagReg = SAVE_Tag;
1144 #define CALLER_SAVE_Tag /* nothing */
1145 #define CALLER_RESTORE_Tag /* nothing */
1148 #ifdef CALLER_SAVES_Ret
1149 #define CALLER_SAVE_Ret SAVE_Ret = RetReg;
1150 #define CALLER_RESTORE_Ret RetReg = SAVE_Ret;
1152 #define CALLER_SAVE_Ret /* nothing */
1153 #define CALLER_RESTORE_Ret /* nothing */
1156 #ifdef CALLER_SAVES_SpA
1157 #define CALLER_SAVE_SpA SAVE_SpA = SpA;
1158 #define CALLER_RESTORE_SpA SpA = SAVE_SpA;
1160 #define CALLER_SAVE_SpA /* nothing */
1161 #define CALLER_RESTORE_SpA /* nothing */
1164 #ifdef CALLER_SAVES_SuA
1165 #define CALLER_SAVE_SuA SAVE_SuA = SuA;
1166 #define CALLER_RESTORE_SuA SuA = SAVE_SuA;
1168 #define CALLER_SAVE_SuA /* nothing */
1169 #define CALLER_RESTORE_SuA /* nothing */
1172 #ifdef CALLER_SAVES_SpB
1173 #define CALLER_SAVE_SpB SAVE_SpB = SpB;
1174 #define CALLER_RESTORE_SpB SpB = SAVE_SpB;
1176 #define CALLER_SAVE_SpB /* nothing */
1177 #define CALLER_RESTORE_SpB /* nothing */
1180 #ifdef CALLER_SAVES_SuB
1181 #define CALLER_SAVE_SuB SAVE_SuB = SuB;
1182 #define CALLER_RESTORE_SuB SuB = SAVE_SuB;
1184 #define CALLER_SAVE_SuB /* nothing */
1185 #define CALLER_RESTORE_SuB /* nothing */
1188 #ifdef CALLER_SAVES_Hp
1189 #define CALLER_SAVE_Hp SAVE_Hp = Hp;
1190 #define CALLER_RESTORE_Hp Hp = SAVE_Hp;
1192 #define CALLER_SAVE_Hp /* nothing */
1193 #define CALLER_RESTORE_Hp /* nothing */
1196 #ifdef CALLER_SAVES_HpLim
1197 #define CALLER_SAVE_HpLim SAVE_HpLim = HpLim;
1198 #define CALLER_RESTORE_HpLim HpLim = SAVE_HpLim;
1200 #define CALLER_SAVE_HpLim /* nothing */
1201 #define CALLER_RESTORE_HpLim /* nothing */
1204 #ifdef CALLER_SAVES_Liveness
1205 #define CALLER_SAVE_Liveness SAVE_Liveness = LivenessReg;
1206 #define CALLER_RESTORE_Liveness LivenessReg = SAVE_Liveness;
1208 #define CALLER_SAVE_Liveness /* nothing */
1209 #define CALLER_RESTORE_Liveness /* nothing */
1212 #ifdef CALLER_SAVES_Base
1214 #define CALLER_SAVE_Base /* nothing, ever (it holds a fixed value) */
1215 #define CALLER_RESTORE_Base BaseReg = &MainRegTable;
1217 #define CALLER_SAVE_Base /* nothing */
1218 #define CALLER_RESTORE_Base BaseReg = CurrentRegTable;
1221 #define CALLER_SAVE_Base /* nothing */
1222 #define CALLER_RESTORE_Base /* nothing */
1225 #ifdef CALLER_SAVES_StdUpdRetVec
1226 #define CALLER_RESTORE_StdUpdRetVec StdUpdRetVecReg = vtbl_StdUpdFrame;
1228 #define CALLER_RESTORE_StdUpdRetVec /* nothing */
1231 #ifdef CALLER_SAVES_StkStub
1232 #define CALLER_RESTORE_StkStub StdUpdRetVecReg = STK_STUB_closure;
1234 #define CALLER_RESTORE_StkStub /* nothing */
1239 Concluding \tr{#endifs} and multi-slurp protection:
1243 #endif /* SCAV_REG_MAP */
1244 #endif /* SCAN_REG_MAP */
1245 #endif /* MARK_REG_MAP */
1246 #endif /* NULL_REG_MAP */
1248 #endif /* STGREGS_H */