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 */
55 #if HAVE_LONG_LONG && SIZEOF_LONG < 8
68 I_ rActivity; /* NB: UNUSED */
69 P_ rCstkptr; /* used for iX86 registerizing only! offset=100 */
70 P_ rWrapReturn; /* ditto; offset=104 */
71 P_ rSaveECX; /* ditto; offset=108 */
72 #if defined(CONCURRENT)
80 There are several confusing macro sets for accessing STG registers at various
81 stages in their lives.
84 The MAIN_* macros refer to the save locations for the main thread.
85 These are generally useful when the main thread is suspended. Note
86 that the save locations for S[up][AB] are actually in the pseudo stack
87 object, MainStkO, when running threads.
89 The SAVE_* macros refer to the save locations for the current thread,
90 without using BaseReg. These are used when we cannot be sure that any
91 STG registers are actually loaded in machine registers.
93 The RTBL_* macros refer to the register table locations for the current
94 thread, indexed from BaseReg. If BaseReg is in a machine register, that
95 register {\em must} be loaded with the address of the register table.
97 OK, now... In the sequential world at least, each of those
98 ``register'' declarations also set up a ``backup'' location; for
99 register @r@, the backup location (a global variable) is @r_SAVE@.
101 We need @SAVE_STG_REGS@ and @RESTORE_STG_REGS@ macros, which copy back
102 and forth between the ``registers'' and their \tr{*_SAVE} backup
105 In the parallel world, we have the closely-related business of
106 saving/restoring ``thread state''. We do it in two stages:
107 save/restore to/from \tr{*_SAVE} locations, then fill in the
108 ``thread-state object'' (TSO) from the \tr{*_SAVE} locations. (This
109 means the thread-state saving can more easily be written in C, rather
112 Why no space to save BaseReg? Because either (1) if in a caller-save
113 register, the caller will have saved it; or (2) if in a callee-save
114 register, the miniInterpret machinery will have saved it. This works
115 because we entered ``threaded Haskell land'' in a v disciplined
116 way---i.e., via miniInterpret.
118 However, the bits of code that use the various GC register maps (SCAV,
119 MARK, SCAN) are called in less-disciplined ways, so their base-regs
120 need saving/restoring. (WDP 95/02)
125 extern STGRegisterTable MainRegTable;
128 /* these are for the main register table */
129 #define MAIN_R1 (MainRegTable.rR[0])
130 #define MAIN_R2 (MainRegTable.rR[1])
131 #define MAIN_R3 (MainRegTable.rR[2])
132 #define MAIN_R4 (MainRegTable.rR[3])
133 #define MAIN_R5 (MainRegTable.rR[4])
134 #define MAIN_R6 (MainRegTable.rR[5])
135 #define MAIN_R7 (MainRegTable.rR[6])
136 #define MAIN_R8 (MainRegTable.rR[7])
137 #define MAIN_Flt1 (MainRegTable.rFlt[0])
138 #define MAIN_Flt2 (MainRegTable.rFlt[1])
139 #define MAIN_Flt3 (MainRegTable.rFlt[2])
140 #define MAIN_Flt4 (MainRegTable.rFlt[3])
141 #define MAIN_Dbl1 (MainRegTable.rDbl[0])
142 #define MAIN_Dbl2 (MainRegTable.rDbl[1])
143 #if HAVE_LONG_LONG && SIZEOF_LONG < 8
144 #define MAIN_Lng1 (MainRegTable.rLng[0])
145 #define MAIN_Lng2 (MainRegTable.rLng[1])
148 #define MAIN_Hp (MainRegTable.rHp)
149 #define MAIN_HpLim (MainRegTable.rHpLim)
150 #define MAIN_Tag (MainRegTable.rTag)
151 #define MAIN_Ret (MainRegTable.rRet)
153 #define MAIN_StkO (MainStkO)
154 #define MAIN_Liveness (MainRegTable.rLiveness)
158 #define MAIN_SpA (MainRegTable.rSpA)
159 #define MAIN_SuA (MainRegTable.rSuA)
160 #define MAIN_SpB (MainRegTable.rSpB)
161 #define MAIN_SuB (MainRegTable.rSuB)
163 /* these are really for *SAVE*ing */
164 #define SAVE_R1 MAIN_R1
165 #define SAVE_R2 MAIN_R2
166 #define SAVE_R3 MAIN_R3
167 #define SAVE_R4 MAIN_R4
168 #define SAVE_R5 MAIN_R5
169 #define SAVE_R6 MAIN_R6
170 #define SAVE_R7 MAIN_R7
171 #define SAVE_R8 MAIN_R8
172 #define SAVE_Flt1 MAIN_Flt1
173 #define SAVE_Flt2 MAIN_Flt2
174 #define SAVE_Flt3 MAIN_Flt3
175 #define SAVE_Flt4 MAIN_Flt4
176 #define SAVE_Dbl1 MAIN_Dbl1
177 #define SAVE_Dbl2 MAIN_Dbl2
178 #if HAVE_LONG_LONG && SIZEOF_LONG < 8
179 #define SAVE_Lng1 MAIN_Lng1
180 #define SAVE_Lng2 MAIN_Lng2
183 #define SAVE_SpA MAIN_SpA
184 #define SAVE_SuA MAIN_SuA
185 #define SAVE_SpB MAIN_SpB
186 #define SAVE_SuB MAIN_SuB
188 #define SAVE_Tag MAIN_Tag
189 #define SAVE_Ret MAIN_Ret
195 #define MAIN_SpA (STKO_SpA(MainStkO))
196 #define MAIN_SuA (STKO_SuA(MainStkO))
197 #define MAIN_SpB (STKO_SpB(MainStkO))
198 #define MAIN_SuB (STKO_SuB(MainStkO))
200 extern STGRegisterTable *CurrentRegTable;
202 /* these are really for *SAVE*ing */
203 #define SAVE_R1 (CurrentRegTable->rR[0])
204 #define SAVE_R2 (CurrentRegTable->rR[1])
205 #define SAVE_R3 (CurrentRegTable->rR[2])
206 #define SAVE_R4 (CurrentRegTable->rR[3])
207 #define SAVE_R5 (CurrentRegTable->rR[4])
208 #define SAVE_R6 (CurrentRegTable->rR[5])
209 #define SAVE_R7 (CurrentRegTable->rR[6])
210 #define SAVE_R8 (CurrentRegTable->rR[7])
211 #define SAVE_Flt1 (CurrentRegTable->rFlt[0])
212 #define SAVE_Flt2 (CurrentRegTable->rFlt[1])
213 #define SAVE_Flt3 (CurrentRegTable->rFlt[2])
214 #define SAVE_Flt4 (CurrentRegTable->rFlt[3])
215 #define SAVE_Dbl1 (CurrentRegTable->rDbl[0])
216 #define SAVE_Dbl2 (CurrentRegTable->rDbl[1])
217 #if HAVE_LONG_LONG && SIZEOF_LONG < 8
218 #define SAVE_Lng1 (CurrentRegTable->rLng[0])
219 #define SAVE_Lng2 (CurrentRegTable->rLng[1])
222 /* These are only valid when StkOReg is loaded! */
224 #define SAVE_SpA (STKO_SpA(StkOReg))
225 #define SAVE_SuA (STKO_SuA(StkOReg))
226 #define SAVE_SpB (STKO_SpB(StkOReg))
227 #define SAVE_SuB (STKO_SuB(StkOReg))
229 #define SAVE_Tag (CurrentRegTable->rTag)
230 #define SAVE_Ret (CurrentRegTable->rRet)
232 #define SAVE_StkO (CurrentRegTable->rStkO)
233 #define SAVE_Liveness (CurrentRegTable->rLiveness)
235 #endif /* CONCURRENT */
237 /* Note that the SAVE_ locations for the Hp registers are in the smInfo structure */
239 #define SAVE_Hp (StorageMgrInfo.hp)
240 #define SAVE_HpLim (StorageMgrInfo.hplim)
244 %************************************************************************
246 \subsection[null-mapping-StgRegs]{The empty register mapping}
248 %************************************************************************
250 This mapping leaves all machine registers free for normal C allocation.
251 In the RTS, this is the preferred mapping, because it allows gcc to use
252 all available registers, with the normal callee-saves conventions.
254 #if defined(NULL_REG_MAP)
258 This is a HACK here; see comment in COptJumps.lh.
260 #if alpha_TARGET_ARCH && defined(__STG_TAILJUMPS__) && defined(__GNUC__)
261 register void *_procedure __asm__("$27");
263 #if (mipsel_TARGET_ARCH || mipseb_TARGET_ARCH) && defined(__STG_TAILJUMPS__) && defined(__GNUC__)
264 register void *_procedure __asm__("$25");
268 %************************************************************************
270 \subsection[mark-mapping-StgRegs]{The ``mark'' register mapping}
272 %************************************************************************
274 The mark mapping is used for pointer-reversal marking during GC. It
275 is used by most of the current garbage collectors.
278 #if defined(MARK_REG_MAP)
281 Mark (GC) register mapping:
284 sparc m68k alpha mipseX hppa iX86 powerpc
285 ----- ---- ----- ------ ---- ---- -------
288 Mark i0 a2 $9 $16 r4 ebp
289 MStack i1 a3 $10 $17 r5 esi
290 MRoot i2 a4 $11 $18 r6 edi
291 BitArray i3 a5 $12 $19 r7
292 HeapBase i4 d3 $13 $20 r8
293 HeapLim i5 d4 $14 $21 r9
309 #define REGDUMP(dump) static RegisterTable dump
311 #define SAVE_Mark (MarkRegTable.rMark)
312 #define SAVE_MStack (MarkRegTable.rMStack)
313 #define SAVE_MRoot (MarkRegTable.rMRoot)
314 #define SAVE_BitArray (MarkRegTable.rBitArray)
315 #define SAVE_HeapBase (MarkRegTable.rHeapBase)
316 #define SAVE_HeapLim (MarkRegTable.rHeapLim)
318 extern RegisterTable MarkRegTable;
321 GLOBAL_REG_DECL(RegisterTable *,MarkBaseReg,REG_MarkBase)
323 #define MarkBaseReg (&MarkRegTable)
327 GLOBAL_REG_DECL(P_,Mark,REG_Mark)
329 #define Mark SAVE_Mark
333 GLOBAL_REG_DECL(P_,MStack,REG_MStack)
335 #define MStack SAVE_MStack
339 GLOBAL_REG_DECL(P_,MRoot,REG_MRoot)
341 #define MRoot SAVE_MRoot
345 GLOBAL_REG_DECL(P_,BitArray,REG_BitArray)
347 #define BitArray SAVE_BitArray
351 GLOBAL_REG_DECL(P_,HeapBase,REG_HeapBase)
353 #define HeapBase SAVE_HeapBase
357 GLOBAL_REG_DECL(P_,HeapLim,REG_HeapLim)
359 #define HeapLim SAVE_HeapLim
362 #if defined(__STG_GCC_REGS__)
363 /* Keep -Wmissing-prototypes from complaining */
364 void SAVE_REGS PROTO((RegisterTable *dump));
365 void RESTORE_REGS PROTO((RegisterTable *dump));
372 dump->rMarkBase = (P_) MarkBaseReg; /* save whatever is in it */
373 MarkBaseReg = dump; /* set it correctly */
379 dump->rMStack = MStack;
382 dump->rMRoot = MRoot;
385 dump->rBitArray = BitArray;
388 dump->rHeapBase = HeapBase;
391 dump->rHeapLim = HeapLim;
396 void RESTORE_REGS(dump)
403 MStack = dump->rMStack;
406 MRoot = dump->rMRoot;
409 BitArray = dump->rBitArray;
412 HeapBase = dump->rHeapBase;
415 HeapLim = dump->rHeapLim;
418 MarkBaseReg = (RegisterTable *) dump->rMarkBase; /* restore to whatever it was */
422 #define SAVE_REGS(dump)
423 #define RESTORE_REGS(dump)
427 %************************************************************************
429 \subsection[scan-mapping-StgRegs]{The ``scan'' register mapping}
431 %************************************************************************
433 The scan mapping is used for all of the in-place garbage collectors.
434 On architectures with register windows, like the SPARC, these must
435 reside in global registers, because the scan code is not threaded.
439 #if defined(SCAN_REG_MAP)
442 Scan (GC) register mapping:
445 sparc m68k alpha mipseX hppa iX86 powerpc
446 ----- ---- ----- ------ ---- ---- -------
449 Scan a2 $9 $16 r4 ebx
450 New a3 $10 $17 r5 ebp
451 LinkLim a4 $11 $18 r6 esi
464 #define REGDUMP(dump) static RegisterTable dump
466 #define SAVE_Scan (ScanRegTable.rScan)
467 #define SAVE_New (ScanRegTable.rNew)
468 #define SAVE_LinkLim (ScanRegTable.rLinkLim)
470 extern RegisterTable ScanRegTable;
473 GLOBAL_REG_DECL(RegisterTable *,ScanBaseReg,REG_ScanBase)
475 #define ScanBaseReg (&ScanRegTable)
479 GLOBAL_REG_DECL(P_,Scan,REG_Scan)
482 # define Scan (ScanBaseReg->rScan)
484 # define Scan SAVE_Scan
489 GLOBAL_REG_DECL(P_,New,REG_New)
492 # define New (ScanBaseReg->rNew)
494 # define New SAVE_New
499 GLOBAL_REG_DECL(P_,LinkLim,REG_LinkLim)
502 # define LinkLim (ScanBaseReg->rLinkLim)
504 # define LinkLim SAVE_LinkLim
508 #if defined(__STG_GCC_REGS__)
509 /* Keep -Wmissing-prototypes from complaining */
510 void SAVE_REGS PROTO((RegisterTable *dump));
511 void RESTORE_REGS PROTO((RegisterTable *dump));
518 dump->rScanBase = (P_) ScanBaseReg; /* save whatever is in it */
519 ScanBaseReg = dump; /* set it correctly */
528 dump->rLinkLim = LinkLim;
533 void RESTORE_REGS(dump)
543 LinkLim = dump->rLinkLim;
546 ScanBaseReg = (RegisterTable *) dump->rScanBase; /* restore to whatever it was */
550 #define SAVE_REGS(dump)
551 #define RESTORE_REGS(dump)
555 %************************************************************************
557 \subsection[scav-mapping-StgRegs]{The ``scavenge'' register mapping}
559 %************************************************************************
561 The scan mapping is used for all of the in-place garbage collectors.
562 (I believe that it must use a subset of the registers that are used
563 in the mark mapping, but I could be wrong. --JSM)
565 Note: registers must not be mangled by sliding register windows,
566 etc. or there'll be trouble. ADR
570 #if defined(SCAV_REG_MAP)
573 Scavenge (GC) register mapping:
576 sparc m68k alpha mipseX hppa iX86 powerpc
577 ----- ---- ----- ------ ---- ---- -------
580 Scav a2 $9 $16 r4 ebx
581 ToHp a3 $10 $17 r5 ebp
582 OldGen (gn/ap) a4 $11 $18 r6 esi
588 (Calling this struct @ScavRegisterTable@ would make it possible for
589 @gdb@ to display it properly. At the moment, @gdb@ confuses it with
590 the scan register table etc. ADR )
605 #define REGDUMP(dump) static RegisterTable dump
607 #define SAVE_Scav (ScavRegTable.rScav)
608 #define SAVE_ToHp (ScavRegTable.rToHp)
609 #define SAVE_OldGen (ScavRegTable.rOldGen)
610 #define SAVE_AllocGen (ScavRegTable.rAllocGen)
611 #define SAVE_OldHp (ScavRegTable.rOldHp)
613 extern RegisterTable ScavRegTable;
616 GLOBAL_REG_DECL(RegisterTable *,ScavBaseReg,REG_ScavBase)
618 #define ScavBaseReg (&ScavRegTable)
622 GLOBAL_REG_DECL(P_,Scav,REG_Scav)
625 # define Scav (ScavBaseReg->rScav)
627 # define Scav SAVE_Scav
632 GLOBAL_REG_DECL(P_,ToHp,REG_ToHp)
635 # define ToHp (ScavBaseReg->rToHp)
637 # define ToHp SAVE_ToHp
642 GLOBAL_REG_DECL(P_,OldGen,REG_OldGen)
645 # define OldGen (ScavBaseReg->rOldGen)
647 # define OldGen SAVE_OldGen
652 GLOBAL_REG_DECL(P_,AllocGen,REG_AllocGen)
655 # define AllocGen (ScavBaseReg->rAllocGen)
657 # define AllocGen SAVE_AllocGen
662 GLOBAL_REG_DECL(P_,OldHp,REG_OldHp)
665 # define OldHp (ScavBaseReg->rOldHp)
667 # define OldHp SAVE_OldHp
671 #if defined(__STG_GCC_REGS__)
672 /* Keep -Wmissing-prototypes from complaining */
673 void SAVE_REGS PROTO((RegisterTable *dump));
674 void RESTORE_REGS PROTO((RegisterTable *dump));
681 dump->rScavBase = (P_) ScavBaseReg; /* save whatever is in it */
682 ScavBaseReg = dump; /* set it correctly */
691 dump->rOldGen = OldGen;
694 dump->rAllocGen = AllocGen;
697 dump->rOldHp = OldHp;
702 void RESTORE_REGS(dump)
712 OldGen = dump->rOldGen;
715 AllocGen = dump->rAllocGen;
718 OldHp = dump->rOldHp;
721 ScavBaseReg = (RegisterTable *) dump->rScavBase; /* restore to whatever it was */
725 #define SAVE_REGS(dump)
726 #define RESTORE_REGS(dump)
730 %************************************************************************
732 \subsection[main-mapping-StgRegs]{The main register mapping (Haskell threaded world)}
734 %************************************************************************
737 #else /* For simplicity, the default is MAIN_REG_MAP (this one) */
740 Main register-mapping summary: (1)~Specific architecture's details are
741 given later. (2)~Entries marked \tr{!} are caller-saves registers
742 that {\em must be saved} across ccalls; those marked \tr{@} are
743 caller-saves registers that need {\em not} be saved; those marked
744 \tr{#} are caller-saves registers that need to be restored, but don't
745 need to be saved; the rest are callee-save registers (the best kind).
747 IF YOU CHANGE THIS TABLE, YOU MAY NEED TO CHANGE CallWrapper.s
748 (or equiv) and [who knows?] maybe something else. Check the
749 documentation in the porter's part of the installation guide.
752 sparc m68k alpha mipseX hppa iX86 powerpc
753 ----- ---- ----- ------ ---- ---- -------
758 R1/Node l1 d7 $1! $9! %r11
759 R2 l2 d6 $2! $10! %r12
760 R3 l3 d5 $3! $11! %r13
769 FltReg1 f2! fp2 $f1 $f20 %fr12
770 FltReg2 f3! fp3 $f2 $f22 %fr12R
771 FltReg3 f4! fp4 $f3 $f24 %fr13
772 FltReg4 f5! fp5 $f4 $f26 %fr13R
774 DblReg1 f6! fp6 $f5 $f28 %fr20 * SEE NOTES!
775 DblReg2 f8! fp7 $f6 $f30 %fr20 * SEE NOTES!
778 SuA i1 d3 $10 $17 %r5
779 SpB i2 a4 $11 $18 %r6
780 SuB i3 d4 $12 $19 %r7
785 RetReg l0 $15 $22 %r10
787 Liveness (CONCURRENT)
796 Registers not mentioned in the summary table end up in the default
797 (a memory location in @MainRegTable@).
800 @BaseReg@ is in a machine register if anything is (well, unless everything is!)
801 It points to a block of memory in which the things which don't end up in machine
805 Exceptions to previous point:
806 If the following labels are in machine registers, then the
807 corresponding register name refers to what's in its register; otherwise,
808 it refers to the label:
810 StdUpdRetVecReg vtbl_StdUpdFrame
811 StkStubReg STK_STUB_closure
813 Also, if TagReg is not in a machine register, its name refers to
814 @INFO_TAG(InfoPtr)@, the tag field from the info table pointed to by
815 register R2 (InfoPtr).
819 Next, we have the code to declare the various global registers. Those
820 STG registers which don't actually live in machine registers are
821 defined as macros which refer to the registers as fixed offsets into
822 the register table. Note that the register table will contain blank
823 spots for the STG registers that reside in machine registers. Not to
824 worry; these blank spots will be filled in whenever the register
825 context is saved, so the space does not go to waste.
830 #define InfoPtr (R2.d)
832 /* these are if we get stuck using the reg-tbl "register" (no machine reg avail) */
833 #define RTBL_Dbl1 (BaseReg->rDbl[0])
834 #define RTBL_Dbl2 (BaseReg->rDbl[1])
835 #if HAVE_LONG_LONG && SIZEOF_LONG < 8
836 #define RTBL_Lng1 (BaseReg->rLng[0])
837 #define RTBL_Lng2 (BaseReg->rLng[1])
839 #define RTBL_Flt1 (BaseReg->rFlt[0])
840 #define RTBL_Flt2 (BaseReg->rFlt[1])
841 #define RTBL_Flt3 (BaseReg->rFlt[2])
842 #define RTBL_Flt4 (BaseReg->rFlt[3])
843 #define RTBL_R1 (BaseReg->rR[0])
844 #define RTBL_R2 (BaseReg->rR[1])
845 #define RTBL_R3 (BaseReg->rR[2])
846 #define RTBL_R4 (BaseReg->rR[3])
847 #define RTBL_R5 (BaseReg->rR[4])
848 #define RTBL_R6 (BaseReg->rR[5])
849 #define RTBL_R7 (BaseReg->rR[6])
850 #define RTBL_R8 (BaseReg->rR[7])
851 #define RTBL_SpA (BaseReg->rSpA)
852 #define RTBL_SuA (BaseReg->rSuA)
853 #define RTBL_SpB (BaseReg->rSpB)
854 #define RTBL_SuB (BaseReg->rSuB)
855 #define RTBL_Hp (BaseReg->rHp)
856 #define RTBL_HpLim (BaseReg->rHpLim)
857 #define RTBL_Tag (BaseReg->rTag)
858 #define RTBL_Ret (BaseReg->rRet)
859 #define RTBL_StkO (BaseReg->rStkO)
860 #define RTBL_Liveness (BaseReg->rLiveness)
863 GLOBAL_REG_DECL(STGRegisterTable *,BaseReg,REG_Base)
866 #define BaseReg CurrentRegTable
868 #define BaseReg (&MainRegTable)
869 #endif /* CONCURRENT */
870 #endif /* REG_Base */
873 GLOBAL_REG_DECL(P_,StkOReg,REG_StkO)
875 #define StkOReg RTBL_StkO
878 #ifndef __STG_REGS_AVAIL__ /* driver ensures it is 2 or more */
879 # define __STG_REGS_AVAIL__ 8 /* R1 to R8 */
880 /* this would only be non-8 if doing weird experiments (WDP 95/11) */
881 /* or it might be set lower for a particular arch... */
884 /* R1 is used for Node */
886 GLOBAL_REG_DECL(StgUnion,R1,REG_R1)
891 /* R2 is used for InfoPtr */
893 GLOBAL_REG_DECL(StgUnion,R2,REG_R2)
899 GLOBAL_REG_DECL(StgUnion,R3,REG_R3)
905 GLOBAL_REG_DECL(StgUnion,R4,REG_R4)
911 GLOBAL_REG_DECL(StgUnion,R5,REG_R5)
917 GLOBAL_REG_DECL(StgUnion,R6,REG_R6)
923 GLOBAL_REG_DECL(StgUnion,R7,REG_R7)
929 GLOBAL_REG_DECL(StgUnion,R8,REG_R8)
935 GLOBAL_REG_DECL(StgFloat,FltReg1,REG_Flt1)
937 #define FltReg1 RTBL_Flt1
941 GLOBAL_REG_DECL(StgFloat,FltReg2,REG_Flt2)
943 #define FltReg2 RTBL_Flt2
947 GLOBAL_REG_DECL(StgFloat,FltReg3,REG_Flt3)
949 #define FltReg3 RTBL_Flt3
953 GLOBAL_REG_DECL(StgFloat,FltReg4,REG_Flt4)
955 #define FltReg4 RTBL_Flt4
959 GLOBAL_REG_DECL(StgDouble,DblReg1,REG_Dbl1)
961 #define DblReg1 RTBL_Dbl1
965 GLOBAL_REG_DECL(StgDouble,DblReg2,REG_Dbl2)
967 #define DblReg2 RTBL_Dbl2
970 #if HAVE_LONG_LONG && SIZEOF_LONG < 8
972 GLOBAL_REG_DECL(StgWord64,LngReg1,REG_Lng1)
974 #define LngReg1 RTBL_Lng1
978 #if HAVE_LONG_LONG && SIZEOF_LONG < 8
980 GLOBAL_REG_DECL(StgWord64,LngReg2,REG_Lng2)
982 #define LngReg2 RTBL_Lng2
987 GLOBAL_REG_DECL(I_,TagReg,REG_Tag)
989 #define SET_TAG(tag) TagReg = tag
991 #define TagReg INFO_TAG(InfoPtr)
992 #define SET_TAG(tag) /* nothing */
996 GLOBAL_REG_DECL(StgRetAddr,RetReg,REG_Ret)
998 #define RetReg RTBL_Ret
1002 GLOBAL_REG_DECL(PP_,SpA,REG_SpA)
1004 #define SpA RTBL_SpA
1008 GLOBAL_REG_DECL(PP_,SuA,REG_SuA)
1010 #define SuA RTBL_SuA
1014 GLOBAL_REG_DECL(P_,SpB,REG_SpB)
1016 #define SpB RTBL_SpB
1020 GLOBAL_REG_DECL(P_,SuB,REG_SuB)
1022 #define SuB RTBL_SuB
1026 GLOBAL_REG_DECL(P_,Hp,REG_Hp)
1032 GLOBAL_REG_DECL(P_,HpLim,REG_HpLim)
1034 #define HpLim RTBL_HpLim
1038 GLOBAL_REG_DECL(I_,LivenessReg,REG_Liveness)
1040 #define LivenessReg RTBL_Liveness
1043 #ifdef REG_StdUpdRetVec
1044 GLOBAL_REG_DECL(D_,StdUpdRetVecReg,REG_StdUpdRetVec)
1046 #define StdUpdRetVecReg vtbl_StdUpdFrame
1050 GLOBAL_REG_DECL(P_,StkStubReg,REG_StkStub)
1052 #define StkStubReg STK_STUB_closure
1055 #ifdef CALLER_SAVES_StkO
1056 #define CALLER_SAVE_StkO SAVE_StkO = StkOReg;
1057 #define CALLER_RESTORE_StkO StkOReg = SAVE_StkO;
1059 #define CALLER_SAVE_StkO /* nothing */
1060 #define CALLER_RESTORE_StkO /* nothing */
1063 #ifdef CALLER_SAVES_R1
1064 #define CALLER_SAVE_R1 SAVE_R1 = R1;
1065 #define CALLER_RESTORE_R1 R1 = SAVE_R1;
1067 #define CALLER_SAVE_R1 /* nothing */
1068 #define CALLER_RESTORE_R1 /* nothing */
1071 #ifdef CALLER_SAVES_R2
1072 #define CALLER_SAVE_R2 SAVE_R2 = R2;
1073 #define CALLER_RESTORE_R2 R2 = SAVE_R2;
1075 #define CALLER_SAVE_R2 /* nothing */
1076 #define CALLER_RESTORE_R2 /* nothing */
1079 #ifdef CALLER_SAVES_R3
1080 #define CALLER_SAVE_R3 SAVE_R3 = R3;
1081 #define CALLER_RESTORE_R3 R3 = SAVE_R3;
1083 #define CALLER_SAVE_R3 /* nothing */
1084 #define CALLER_RESTORE_R3 /* nothing */
1087 #ifdef CALLER_SAVES_R4
1088 #define CALLER_SAVE_R4 SAVE_R4 = R4;
1089 #define CALLER_RESTORE_R4 R4 = SAVE_R4;
1091 #define CALLER_SAVE_R4 /* nothing */
1092 #define CALLER_RESTORE_R4 /* nothing */
1095 #ifdef CALLER_SAVES_R5
1096 #define CALLER_SAVE_R5 SAVE_R5 = R5;
1097 #define CALLER_RESTORE_R5 R5 = SAVE_R5;
1099 #define CALLER_SAVE_R5 /* nothing */
1100 #define CALLER_RESTORE_R5 /* nothing */
1103 #ifdef CALLER_SAVES_R6
1104 #define CALLER_SAVE_R6 SAVE_R6 = R6;
1105 #define CALLER_RESTORE_R6 R6 = SAVE_R6;
1107 #define CALLER_SAVE_R6 /* nothing */
1108 #define CALLER_RESTORE_R6 /* nothing */
1111 #ifdef CALLER_SAVES_R7
1112 #define CALLER_SAVE_R7 SAVE_R7 = R7;
1113 #define CALLER_RESTORE_R7 R7 = SAVE_R7;
1115 #define CALLER_SAVE_R7 /* nothing */
1116 #define CALLER_RESTORE_R7 /* nothing */
1119 #ifdef CALLER_SAVES_R8
1120 #define CALLER_SAVE_R8 SAVE_R8 = R8;
1121 #define CALLER_RESTORE_R8 R8 = SAVE_R8;
1123 #define CALLER_SAVE_R8 /* nothing */
1124 #define CALLER_RESTORE_R8 /* nothing */
1127 #ifdef CALLER_SAVES_FltReg1
1128 #define CALLER_SAVE_FltReg1 SAVE_Flt1 = FltReg1;
1129 #define CALLER_RESTORE_FltReg1 FltReg1 = SAVE_Flt1;
1131 #define CALLER_SAVE_FltReg1 /* nothing */
1132 #define CALLER_RESTORE_FltReg1 /* nothing */
1135 #ifdef CALLER_SAVES_FltReg2
1136 #define CALLER_SAVE_FltReg2 SAVE_Flt2 = FltReg2;
1137 #define CALLER_RESTORE_FltReg2 FltReg2 = SAVE_Flt2;
1139 #define CALLER_SAVE_FltReg2 /* nothing */
1140 #define CALLER_RESTORE_FltReg2 /* nothing */
1143 #ifdef CALLER_SAVES_FltReg3
1144 #define CALLER_SAVE_FltReg3 SAVE_Flt3 = FltReg3;
1145 #define CALLER_RESTORE_FltReg3 FltReg3 = SAVE_Flt3;
1147 #define CALLER_SAVE_FltReg3 /* nothing */
1148 #define CALLER_RESTORE_FltReg3 /* nothing */
1151 #ifdef CALLER_SAVES_FltReg4
1152 #define CALLER_SAVE_FltReg4 SAVE_Flt4 = FltReg4;
1153 #define CALLER_RESTORE_FltReg4 FltReg4 = SAVE_Flt4;
1155 #define CALLER_SAVE_FltReg4 /* nothing */
1156 #define CALLER_RESTORE_FltReg4 /* nothing */
1159 #ifdef CALLER_SAVES_DblReg1
1160 #define CALLER_SAVE_DblReg1 SAVE_Dbl1 = DblReg1;
1161 #define CALLER_RESTORE_DblReg1 DblReg1 = SAVE_Dbl1;
1163 #define CALLER_SAVE_DblReg1 /* nothing */
1164 #define CALLER_RESTORE_DblReg1 /* nothing */
1167 #ifdef CALLER_SAVES_DblReg2
1168 #define CALLER_SAVE_DblReg2 SAVE_Dbl2 = DblReg2;
1169 #define CALLER_RESTORE_DblReg2 DblReg2 = SAVE_Dbl2;
1171 #define CALLER_SAVE_DblReg2 /* nothing */
1172 #define CALLER_RESTORE_DblReg2 /* nothing */
1175 #if HAVE_LONG_LONG && SIZEOF_LONG < 8
1176 #ifdef CALLER_SAVES_LngReg1
1177 #define CALLER_SAVE_LngReg1 SAVE_Lng1 = LngReg1;
1178 #define CALLER_RESTORE_LngReg1 LngReg1 = SAVE_Lng1;
1180 #define CALLER_SAVE_LngReg1 /* nothing */
1181 #define CALLER_RESTORE_LngReg1 /* nothing */
1185 #if HAVE_LONG_LONG && SIZEOF_LONG < 8
1186 #ifdef CALLER_SAVES_LngReg2
1187 #define CALLER_SAVE_LngReg2 SAVE_Lng2 = LngReg2;
1188 #define CALLER_RESTORE_LngReg2 LngReg2 = SAVE_Lng2;
1190 #define CALLER_SAVE_LngReg2 /* nothing */
1191 #define CALLER_RESTORE_LngReg2 /* nothing */
1195 #ifdef CALLER_SAVES_Tag
1196 #define CALLER_SAVE_Tag SAVE_Tag = TagReg;
1197 #define CALLER_RESTORE_Tag TagReg = SAVE_Tag;
1199 #define CALLER_SAVE_Tag /* nothing */
1200 #define CALLER_RESTORE_Tag /* nothing */
1203 #ifdef CALLER_SAVES_Ret
1204 #define CALLER_SAVE_Ret SAVE_Ret = RetReg;
1205 #define CALLER_RESTORE_Ret RetReg = SAVE_Ret;
1207 #define CALLER_SAVE_Ret /* nothing */
1208 #define CALLER_RESTORE_Ret /* nothing */
1211 #ifdef CALLER_SAVES_SpA
1212 #define CALLER_SAVE_SpA SAVE_SpA = SpA;
1213 #define CALLER_RESTORE_SpA SpA = SAVE_SpA;
1215 #define CALLER_SAVE_SpA /* nothing */
1216 #define CALLER_RESTORE_SpA /* nothing */
1219 #ifdef CALLER_SAVES_SuA
1220 #define CALLER_SAVE_SuA SAVE_SuA = SuA;
1221 #define CALLER_RESTORE_SuA SuA = SAVE_SuA;
1223 #define CALLER_SAVE_SuA /* nothing */
1224 #define CALLER_RESTORE_SuA /* nothing */
1227 #ifdef CALLER_SAVES_SpB
1228 #define CALLER_SAVE_SpB SAVE_SpB = SpB;
1229 #define CALLER_RESTORE_SpB SpB = SAVE_SpB;
1231 #define CALLER_SAVE_SpB /* nothing */
1232 #define CALLER_RESTORE_SpB /* nothing */
1235 #ifdef CALLER_SAVES_SuB
1236 #define CALLER_SAVE_SuB SAVE_SuB = SuB;
1237 #define CALLER_RESTORE_SuB SuB = SAVE_SuB;
1239 #define CALLER_SAVE_SuB /* nothing */
1240 #define CALLER_RESTORE_SuB /* nothing */
1243 #ifdef CALLER_SAVES_Hp
1244 #define CALLER_SAVE_Hp SAVE_Hp = Hp;
1245 #define CALLER_RESTORE_Hp Hp = SAVE_Hp;
1247 #define CALLER_SAVE_Hp /* nothing */
1248 #define CALLER_RESTORE_Hp /* nothing */
1251 #ifdef CALLER_SAVES_HpLim
1252 #define CALLER_SAVE_HpLim SAVE_HpLim = HpLim;
1253 #define CALLER_RESTORE_HpLim HpLim = SAVE_HpLim;
1255 #define CALLER_SAVE_HpLim /* nothing */
1256 #define CALLER_RESTORE_HpLim /* nothing */
1259 #ifdef CALLER_SAVES_Liveness
1260 #define CALLER_SAVE_Liveness SAVE_Liveness = LivenessReg;
1261 #define CALLER_RESTORE_Liveness LivenessReg = SAVE_Liveness;
1263 #define CALLER_SAVE_Liveness /* nothing */
1264 #define CALLER_RESTORE_Liveness /* nothing */
1267 #ifdef CALLER_SAVES_Base
1269 #define CALLER_SAVE_Base /* nothing, ever (it holds a fixed value) */
1270 #define CALLER_RESTORE_Base BaseReg = &MainRegTable;
1272 #define CALLER_SAVE_Base /* nothing */
1273 #define CALLER_RESTORE_Base BaseReg = CurrentRegTable;
1276 #define CALLER_SAVE_Base /* nothing */
1277 #define CALLER_RESTORE_Base /* nothing */
1280 #ifdef CALLER_SAVES_StdUpdRetVec
1281 #define CALLER_RESTORE_StdUpdRetVec StdUpdRetVecReg = vtbl_StdUpdFrame;
1283 #define CALLER_RESTORE_StdUpdRetVec /* nothing */
1286 #ifdef CALLER_SAVES_StkStub
1287 #define CALLER_RESTORE_StkStub StdUpdRetVecReg = STK_STUB_closure;
1289 #define CALLER_RESTORE_StkStub /* nothing */
1294 Concluding \tr{#endifs} and multi-slurp protection:
1298 #endif /* SCAV_REG_MAP */
1299 #endif /* SCAN_REG_MAP */
1300 #endif /* MARK_REG_MAP */
1301 #endif /* NULL_REG_MAP */
1303 #endif /* STGREGS_H */