+++ /dev/null
-%
-% (c) The GRASP Project, Glasgow University, 1993
-%
-\section[StgRegs-decls]{STG-machine register mappings}
-
-\begin{code}
-#ifndef COPTREGS_H
-#define COPTREGS_H
-
-#include "StgMachDeps.h"
-#include "StgTypes.h"
-#include "MachRegs.h"
-
-#define GLOBAL_REG_DECL(type,name,reg) register type name REG(reg);
-
-\end{code}
-
-Various parts of the GHC system use various sets of ``registers,'' by
-which we mean (frequently-used) words of globally-visible information.
-For example, the everyday ``Haskell threaded world,'' uses the
-``registers'' @Hp@, @R4@, etc., etc.
-
-We would really like to ``steal'' machine registers from the C
-execution model (via GCC's global-variable-in-register extension) and
-map some/all of our ``STG registers'' onto real machine registers.
-This has a profound benefit in terms of execution speed.
-
-This file/document/section sets out the various (machine-dependent)
-mappings that we use.
-
-Note: for one machine, there are {\em several} possible register
-mappings, {\em one} of which is in force at any time. Obviously, the
-``main'' mapping (used in the Haskell threaded world) dominates, but
-when garbage-collecting (for example), we'd rather not tie up all
-those registers in that way (i.e., for global-variables that aren't
-used in the GC). Instead, we'd rather bring in {\em another} register
-mapping, tuned to the needs of a particular (isolated) bit of C code.
-As there are several garbage collectors there are quite a few possible
-mappings.
-
-%************************************************************************
-%* *
-\subsection[saved-STG-regs]{Saved STG registers}
-%* *
-%************************************************************************
-
-The following stuff is available regardless of register map. It allows
-us access to the saved STG registers from other parts of the RTS (notably
-from the storage manager).
-
-\begin{code}
-
-typedef struct rt {
- StgDouble rDbl[2]; /* Put a double first to ensure expected alignment */
-#if HAVE_LONG_LONG && SIZEOF_LONG < 8
- StgWord64 rLng[2];
-#endif
- StgFloat rFlt[4];
- StgUnion rR[8];
- PP_ rSpA;
- PP_ rSuA;
- P_ rSpB;
- P_ rSuB;
- P_ rHp;
- P_ rHpLim;
- I_ rTag;
- StgRetAddr rRet;
- I_ rActivity; /* NB: UNUSED */
- P_ rCstkptr; /* used for iX86 registerizing only! offset=100 */
- P_ rWrapReturn; /* ditto; offset=104 */
- P_ rSaveECX; /* ditto; offset=108 */
-#if defined(CONCURRENT)
- P_ rStkO;
- I_ rLiveness;
-#endif
-} STGRegisterTable;
-
-\end{code}
-
-There are several confusing macro sets for accessing STG registers at various
-stages in their lives.
-
-
-The MAIN_* macros refer to the save locations for the main thread.
-These are generally useful when the main thread is suspended. Note
-that the save locations for S[up][AB] are actually in the pseudo stack
-object, MainStkO, when running threads.
-
-The SAVE_* macros refer to the save locations for the current thread,
-without using BaseReg. These are used when we cannot be sure that any
-STG registers are actually loaded in machine registers.
-
-The RTBL_* macros refer to the register table locations for the current
-thread, indexed from BaseReg. If BaseReg is in a machine register, that
-register {\em must} be loaded with the address of the register table.
-
-OK, now... In the sequential world at least, each of those
-``register'' declarations also set up a ``backup'' location; for
-register @r@, the backup location (a global variable) is @r_SAVE@.
-
-We need @SAVE_STG_REGS@ and @RESTORE_STG_REGS@ macros, which copy back
-and forth between the ``registers'' and their \tr{*_SAVE} backup
-locations.
-
-In the parallel world, we have the closely-related business of
-saving/restoring ``thread state''. We do it in two stages:
-save/restore to/from \tr{*_SAVE} locations, then fill in the
-``thread-state object'' (TSO) from the \tr{*_SAVE} locations. (This
-means the thread-state saving can more easily be written in C, rather
-than assembler.)
-
-Why no space to save BaseReg? Because either (1) if in a caller-save
-register, the caller will have saved it; or (2) if in a callee-save
-register, the miniInterpret machinery will have saved it. This works
-because we entered ``threaded Haskell land'' in a v disciplined
-way---i.e., via miniInterpret.
-
-However, the bits of code that use the various GC register maps (SCAV,
-MARK, SCAN) are called in less-disciplined ways, so their base-regs
-need saving/restoring. (WDP 95/02)
-
-\begin{code}
-
-#ifndef PAR
-extern STGRegisterTable MainRegTable;
-#endif /* PAR */
-
-/* these are for the main register table */
-#define MAIN_R1 (MainRegTable.rR[0])
-#define MAIN_R2 (MainRegTable.rR[1])
-#define MAIN_R3 (MainRegTable.rR[2])
-#define MAIN_R4 (MainRegTable.rR[3])
-#define MAIN_R5 (MainRegTable.rR[4])
-#define MAIN_R6 (MainRegTable.rR[5])
-#define MAIN_R7 (MainRegTable.rR[6])
-#define MAIN_R8 (MainRegTable.rR[7])
-#define MAIN_Flt1 (MainRegTable.rFlt[0])
-#define MAIN_Flt2 (MainRegTable.rFlt[1])
-#define MAIN_Flt3 (MainRegTable.rFlt[2])
-#define MAIN_Flt4 (MainRegTable.rFlt[3])
-#define MAIN_Dbl1 (MainRegTable.rDbl[0])
-#define MAIN_Dbl2 (MainRegTable.rDbl[1])
-#if HAVE_LONG_LONG && SIZEOF_LONG < 8
-#define MAIN_Lng1 (MainRegTable.rLng[0])
-#define MAIN_Lng2 (MainRegTable.rLng[1])
-#endif
-
-#define MAIN_Hp (MainRegTable.rHp)
-#define MAIN_HpLim (MainRegTable.rHpLim)
-#define MAIN_Tag (MainRegTable.rTag)
-#define MAIN_Ret (MainRegTable.rRet)
-
-#define MAIN_StkO (MainStkO)
-#define MAIN_Liveness (MainRegTable.rLiveness)
-
-#ifndef CONCURRENT
-
-#define MAIN_SpA (MainRegTable.rSpA)
-#define MAIN_SuA (MainRegTable.rSuA)
-#define MAIN_SpB (MainRegTable.rSpB)
-#define MAIN_SuB (MainRegTable.rSuB)
-
-/* these are really for *SAVE*ing */
-#define SAVE_R1 MAIN_R1
-#define SAVE_R2 MAIN_R2
-#define SAVE_R3 MAIN_R3
-#define SAVE_R4 MAIN_R4
-#define SAVE_R5 MAIN_R5
-#define SAVE_R6 MAIN_R6
-#define SAVE_R7 MAIN_R7
-#define SAVE_R8 MAIN_R8
-#define SAVE_Flt1 MAIN_Flt1
-#define SAVE_Flt2 MAIN_Flt2
-#define SAVE_Flt3 MAIN_Flt3
-#define SAVE_Flt4 MAIN_Flt4
-#define SAVE_Dbl1 MAIN_Dbl1
-#define SAVE_Dbl2 MAIN_Dbl2
-#if HAVE_LONG_LONG && SIZEOF_LONG < 8
-#define SAVE_Lng1 MAIN_Lng1
-#define SAVE_Lng2 MAIN_Lng2
-#endif
-
-#define SAVE_SpA MAIN_SpA
-#define SAVE_SuA MAIN_SuA
-#define SAVE_SpB MAIN_SpB
-#define SAVE_SuB MAIN_SuB
-
-#define SAVE_Tag MAIN_Tag
-#define SAVE_Ret MAIN_Ret
-
-#else
-
-extern P_ MainStkO;
-
-#define MAIN_SpA (STKO_SpA(MainStkO))
-#define MAIN_SuA (STKO_SuA(MainStkO))
-#define MAIN_SpB (STKO_SpB(MainStkO))
-#define MAIN_SuB (STKO_SuB(MainStkO))
-
-extern STGRegisterTable *CurrentRegTable;
-
-/* these are really for *SAVE*ing */
-#define SAVE_R1 (CurrentRegTable->rR[0])
-#define SAVE_R2 (CurrentRegTable->rR[1])
-#define SAVE_R3 (CurrentRegTable->rR[2])
-#define SAVE_R4 (CurrentRegTable->rR[3])
-#define SAVE_R5 (CurrentRegTable->rR[4])
-#define SAVE_R6 (CurrentRegTable->rR[5])
-#define SAVE_R7 (CurrentRegTable->rR[6])
-#define SAVE_R8 (CurrentRegTable->rR[7])
-#define SAVE_Flt1 (CurrentRegTable->rFlt[0])
-#define SAVE_Flt2 (CurrentRegTable->rFlt[1])
-#define SAVE_Flt3 (CurrentRegTable->rFlt[2])
-#define SAVE_Flt4 (CurrentRegTable->rFlt[3])
-#define SAVE_Dbl1 (CurrentRegTable->rDbl[0])
-#define SAVE_Dbl2 (CurrentRegTable->rDbl[1])
-#if HAVE_LONG_LONG && SIZEOF_LONG < 8
-#define SAVE_Lng1 (CurrentRegTable->rLng[0])
-#define SAVE_Lng2 (CurrentRegTable->rLng[1])
-#endif
-
-/* These are only valid when StkOReg is loaded! */
-
-#define SAVE_SpA (STKO_SpA(StkOReg))
-#define SAVE_SuA (STKO_SuA(StkOReg))
-#define SAVE_SpB (STKO_SpB(StkOReg))
-#define SAVE_SuB (STKO_SuB(StkOReg))
-
-#define SAVE_Tag (CurrentRegTable->rTag)
-#define SAVE_Ret (CurrentRegTable->rRet)
-
-#define SAVE_StkO (CurrentRegTable->rStkO)
-#define SAVE_Liveness (CurrentRegTable->rLiveness)
-
-#endif /* CONCURRENT */
-
-/* Note that the SAVE_ locations for the Hp registers are in the smInfo structure */
-
-#define SAVE_Hp (StorageMgrInfo.hp)
-#define SAVE_HpLim (StorageMgrInfo.hplim)
-
-\end{code}
-
-%************************************************************************
-%* *
-\subsection[null-mapping-StgRegs]{The empty register mapping}
-%* *
-%************************************************************************
-
-This mapping leaves all machine registers free for normal C allocation.
-In the RTS, this is the preferred mapping, because it allows gcc to use
-all available registers, with the normal callee-saves conventions.
-\begin{code}
-#if defined(NULL_REG_MAP)
-#else
-\end{code}
-
-This is a HACK here; see comment in COptJumps.lh.
-\begin{code}
-#if alpha_TARGET_ARCH && defined(__STG_TAILJUMPS__) && defined(__GNUC__)
-register void *_procedure __asm__("$27");
-#endif
-#if (mipsel_TARGET_ARCH || mipseb_TARGET_ARCH) && defined(__STG_TAILJUMPS__) && defined(__GNUC__)
-register void *_procedure __asm__("$25");
-#endif
-\end{code}
-
-%************************************************************************
-%* *
-\subsection[mark-mapping-StgRegs]{The ``mark'' register mapping}
-%* *
-%************************************************************************
-
-The mark mapping is used for pointer-reversal marking during GC. It
-is used by most of the current garbage collectors.
-
-\begin{code}
-#if defined(MARK_REG_MAP)
-\end{code}
-
-Mark (GC) register mapping:
-
-\begin{verbatim}
- sparc m68k alpha mipseX hppa iX86 powerpc
- ----- ---- ----- ------ ---- ---- -------
-MarkBase ebx
-
-Mark i0 a2 $9 $16 r4 ebp
-MStack i1 a3 $10 $17 r5 esi
-MRoot i2 a4 $11 $18 r6 edi
-BitArray i3 a5 $12 $19 r7
-HeapBase i4 d3 $13 $20 r8
-HeapLim i5 d4 $14 $21 r9
-
-\end{verbatim}
-
-\begin{code}
-
-typedef struct {
- P_ rMark;
- P_ rMStack;
- P_ rMRoot;
- BitWord *rBitArray;
- P_ rHeapBase;
- P_ rHeapLim;
- P_ rMarkBase;
-} RegisterTable;
-
-#define REGDUMP(dump) static RegisterTable dump
-
-#define SAVE_Mark (MarkRegTable.rMark)
-#define SAVE_MStack (MarkRegTable.rMStack)
-#define SAVE_MRoot (MarkRegTable.rMRoot)
-#define SAVE_BitArray (MarkRegTable.rBitArray)
-#define SAVE_HeapBase (MarkRegTable.rHeapBase)
-#define SAVE_HeapLim (MarkRegTable.rHeapLim)
-
-extern RegisterTable MarkRegTable;
-
-#ifdef REG_MarkBase
-GLOBAL_REG_DECL(RegisterTable *,MarkBaseReg,REG_MarkBase)
-#else
-#define MarkBaseReg (&MarkRegTable)
-#endif
-
-#ifdef REG_Mark
-GLOBAL_REG_DECL(P_,Mark,REG_Mark)
-#else
-#define Mark SAVE_Mark
-#endif
-
-#ifdef REG_MStack
-GLOBAL_REG_DECL(P_,MStack,REG_MStack)
-#else
-#define MStack SAVE_MStack
-#endif
-
-#ifdef REG_MRoot
-GLOBAL_REG_DECL(P_,MRoot,REG_MRoot)
-#else
-#define MRoot SAVE_MRoot
-#endif
-
-#ifdef REG_BitArray
-GLOBAL_REG_DECL(P_,BitArray,REG_BitArray)
-#else
-#define BitArray SAVE_BitArray
-#endif
-
-#ifdef REG_HeapBase
-GLOBAL_REG_DECL(P_,HeapBase,REG_HeapBase)
-#else
-#define HeapBase SAVE_HeapBase
-#endif
-
-#ifdef REG_HeapLim
-GLOBAL_REG_DECL(P_,HeapLim,REG_HeapLim)
-#else
-#define HeapLim SAVE_HeapLim
-#endif
-
-#if defined(__STG_GCC_REGS__)
-/* Keep -Wmissing-prototypes from complaining */
-void SAVE_REGS PROTO((RegisterTable *dump));
-void RESTORE_REGS PROTO((RegisterTable *dump));
-
-extern STG_INLINE
-void SAVE_REGS(dump)
-RegisterTable *dump;
-{
-#ifdef REG_MarkBase
- dump->rMarkBase = (P_) MarkBaseReg; /* save whatever is in it */
- MarkBaseReg = dump; /* set it correctly */
-#endif
-#ifdef REG_Mark
- dump->rMark = Mark;
-#endif
-#ifdef REG_MStack
- dump->rMStack = MStack;
-#endif
-#ifdef REG_MRoot
- dump->rMRoot = MRoot;
-#endif
-#ifdef REG_BitArray
- dump->rBitArray = BitArray;
-#endif
-#ifdef REG_HeapBase
- dump->rHeapBase = HeapBase;
-#endif
-#ifdef REG_HeapLim
- dump->rHeapLim = HeapLim;
-#endif
-}
-
-extern STG_INLINE
-void RESTORE_REGS(dump)
-RegisterTable *dump;
-{
-#ifdef REG_Mark
- Mark = dump->rMark;
-#endif
-#ifdef REG_MStack
- MStack = dump->rMStack;
-#endif
-#ifdef REG_MRoot
- MRoot = dump->rMRoot;
-#endif
-#ifdef REG_BitArray
- BitArray = dump->rBitArray;
-#endif
-#ifdef REG_HeapBase
- HeapBase = dump->rHeapBase;
-#endif
-#ifdef REG_HeapLim
- HeapLim = dump->rHeapLim;
-#endif
-#ifdef REG_MarkBase
- MarkBaseReg = (RegisterTable *) dump->rMarkBase; /* restore to whatever it was */
-#endif
-}
-#else
-#define SAVE_REGS(dump)
-#define RESTORE_REGS(dump)
-#endif
-\end{code}
-
-%************************************************************************
-%* *
-\subsection[scan-mapping-StgRegs]{The ``scan'' register mapping}
-%* *
-%************************************************************************
-
-The scan mapping is used for all of the in-place garbage collectors.
-On architectures with register windows, like the SPARC, these must
-reside in global registers, because the scan code is not threaded.
-
-\begin{code}
-#else
-#if defined(SCAN_REG_MAP)
-\end{code}
-
-Scan (GC) register mapping:
-
-\begin{verbatim}
- sparc m68k alpha mipseX hppa iX86 powerpc
- ----- ---- ----- ------ ---- ---- -------
-ScanBase g4
-
-Scan a2 $9 $16 r4 ebx
-New a3 $10 $17 r5 ebp
-LinkLim a4 $11 $18 r6 esi
-
-\end{verbatim}
-
-\begin{code}
-
-typedef struct {
- P_ rScan;
- P_ rNew;
- P_ rLinkLim;
- P_ rScanBase;
-} RegisterTable;
-
-#define REGDUMP(dump) static RegisterTable dump
-
-#define SAVE_Scan (ScanRegTable.rScan)
-#define SAVE_New (ScanRegTable.rNew)
-#define SAVE_LinkLim (ScanRegTable.rLinkLim)
-
-extern RegisterTable ScanRegTable;
-
-#ifdef REG_ScanBase
-GLOBAL_REG_DECL(RegisterTable *,ScanBaseReg,REG_ScanBase)
-#else
-#define ScanBaseReg (&ScanRegTable)
-#endif
-
-#ifdef REG_Scan
-GLOBAL_REG_DECL(P_,Scan,REG_Scan)
-#else
-# ifdef REG_ScanBase
-# define Scan (ScanBaseReg->rScan)
-# else
-# define Scan SAVE_Scan
-# endif
-#endif
-
-#ifdef REG_New
-GLOBAL_REG_DECL(P_,New,REG_New)
-#else
-# ifdef REG_ScanBase
-# define New (ScanBaseReg->rNew)
-# else
-# define New SAVE_New
-# endif
-#endif
-
-#ifdef REG_LinkLim
-GLOBAL_REG_DECL(P_,LinkLim,REG_LinkLim)
-#else
-# ifdef REG_ScanBase
-# define LinkLim (ScanBaseReg->rLinkLim)
-# else
-# define LinkLim SAVE_LinkLim
-# endif
-#endif
-
-#if defined(__STG_GCC_REGS__)
-/* Keep -Wmissing-prototypes from complaining */
-void SAVE_REGS PROTO((RegisterTable *dump));
-void RESTORE_REGS PROTO((RegisterTable *dump));
-
-extern STG_INLINE
-void SAVE_REGS(dump)
-RegisterTable *dump;
-{
-#ifdef REG_ScanBase
- dump->rScanBase = (P_) ScanBaseReg; /* save whatever is in it */
- ScanBaseReg = dump; /* set it correctly */
-#endif
-#ifdef REG_Scan
- dump->rScan = Scan;
-#endif
-#ifdef REG_New
- dump->rNew = New;
-#endif
-#ifdef REG_LinkLim
- dump->rLinkLim = LinkLim;
-#endif
-}
-
-extern STG_INLINE
-void RESTORE_REGS(dump)
-RegisterTable *dump;
-{
-#ifdef REG_Scan
- Scan = dump->rScan;
-#endif
-#ifdef REG_New
- New = dump->rNew;
-#endif
-#ifdef REG_LinkLim
- LinkLim = dump->rLinkLim;
-#endif
-#ifdef REG_ScanBase
- ScanBaseReg = (RegisterTable *) dump->rScanBase; /* restore to whatever it was */
-#endif
-}
-#else
-#define SAVE_REGS(dump)
-#define RESTORE_REGS(dump)
-#endif
-\end{code}
-
-%************************************************************************
-%* *
-\subsection[scav-mapping-StgRegs]{The ``scavenge'' register mapping}
-%* *
-%************************************************************************
-
-The scan mapping is used for all of the in-place garbage collectors.
-(I believe that it must use a subset of the registers that are used
-in the mark mapping, but I could be wrong. --JSM)
-
-Note: registers must not be mangled by sliding register windows,
-etc. or there'll be trouble. ADR
-
-\begin{code}
-#else
-#if defined(SCAV_REG_MAP)
-\end{code}
-
-Scavenge (GC) register mapping:
-
-\begin{verbatim}
- sparc m68k alpha mipseX hppa iX86 powerpc
- ----- ---- ----- ------ ---- ---- -------
-ScavBase g4
-
-Scav a2 $9 $16 r4 ebx
-ToHp a3 $10 $17 r5 ebp
-OldGen (gn/ap) a4 $11 $18 r6 esi
-AllocGen (gn) a5
-OldHp (gn) d3
-
-\end{verbatim}
-
-(Calling this struct @ScavRegisterTable@ would make it possible for
-@gdb@ to display it properly. At the moment, @gdb@ confuses it with
-the scan register table etc. ADR )
-
-\begin{code}
-
-typedef struct {
- P_ rScav;
- P_ rToHp;
- P_ rOldGen;
-#ifdef GCgn
- P_ rAllocGen;
- P_ rOldHp;
-#endif
- P_ rScavBase;
-} RegisterTable;
-
-#define REGDUMP(dump) static RegisterTable dump
-
-#define SAVE_Scav (ScavRegTable.rScav)
-#define SAVE_ToHp (ScavRegTable.rToHp)
-#define SAVE_OldGen (ScavRegTable.rOldGen)
-#define SAVE_AllocGen (ScavRegTable.rAllocGen)
-#define SAVE_OldHp (ScavRegTable.rOldHp)
-
-extern RegisterTable ScavRegTable;
-
-#ifdef REG_ScavBase
-GLOBAL_REG_DECL(RegisterTable *,ScavBaseReg,REG_ScavBase)
-#else
-#define ScavBaseReg (&ScavRegTable)
-#endif
-
-#ifdef REG_Scav
-GLOBAL_REG_DECL(P_,Scav,REG_Scav)
-#else
-# ifdef REG_ScavBase
-# define Scav (ScavBaseReg->rScav)
-# else
-# define Scav SAVE_Scav
-# endif
-#endif
-
-#ifdef REG_ToHp
-GLOBAL_REG_DECL(P_,ToHp,REG_ToHp)
-#else
-# ifdef REG_ScavBase
-# define ToHp (ScavBaseReg->rToHp)
-# else
-# define ToHp SAVE_ToHp
-# endif
-#endif
-
-#ifdef REG_OldGen
-GLOBAL_REG_DECL(P_,OldGen,REG_OldGen)
-#else
-# ifdef REG_ScavBase
-# define OldGen (ScavBaseReg->rOldGen)
-# else
-# define OldGen SAVE_OldGen
-# endif
-#endif
-
-#ifdef REG_AllocGen
-GLOBAL_REG_DECL(P_,AllocGen,REG_AllocGen)
-#else
-# ifdef REG_ScavBase
-# define AllocGen (ScavBaseReg->rAllocGen)
-# else
-# define AllocGen SAVE_AllocGen
-# endif
-#endif
-
-#ifdef REG_OldHp
-GLOBAL_REG_DECL(P_,OldHp,REG_OldHp)
-#else
-# ifdef REG_ScavBase
-# define OldHp (ScavBaseReg->rOldHp)
-# else
-# define OldHp SAVE_OldHp
-# endif
-#endif
-
-#if defined(__STG_GCC_REGS__)
-/* Keep -Wmissing-prototypes from complaining */
-void SAVE_REGS PROTO((RegisterTable *dump));
-void RESTORE_REGS PROTO((RegisterTable *dump));
-
-extern STG_INLINE
-void SAVE_REGS(dump)
-RegisterTable *dump;
-{
-#ifdef REG_ScavBase
- dump->rScavBase = (P_) ScavBaseReg; /* save whatever is in it */
- ScavBaseReg = dump; /* set it correctly */
-#endif
-#ifdef REG_Scav
- dump->rScav = Scav;
-#endif
-#ifdef REG_ToHp
- dump->rToHp = ToHp;
-#endif
-#ifdef REG_OldGen
- dump->rOldGen = OldGen;
-#endif
-#ifdef REG_AllocGen
- dump->rAllocGen = AllocGen;
-#endif
-#ifdef REG_OldHp
- dump->rOldHp = OldHp;
-#endif
-}
-
-extern STG_INLINE
-void RESTORE_REGS(dump)
-RegisterTable *dump;
-{
-#ifdef REG_Scav
- Scav = dump->rScav;
-#endif
-#ifdef REG_ToHp
- ToHp = dump->rToHp;
-#endif
-#ifdef REG_OldGen
- OldGen = dump->rOldGen;
-#endif
-#ifdef REG_AllocGen
- AllocGen = dump->rAllocGen;
-#endif
-#ifdef REG_OldHp
- OldHp = dump->rOldHp;
-#endif
-#ifdef REG_ScavBase
- ScavBaseReg = (RegisterTable *) dump->rScavBase; /* restore to whatever it was */
-#endif
-}
-#else
-#define SAVE_REGS(dump)
-#define RESTORE_REGS(dump)
-#endif
-\end{code}
-
-%************************************************************************
-%* *
-\subsection[main-mapping-StgRegs]{The main register mapping (Haskell threaded world)}
-%* *
-%************************************************************************
-
-\begin{code}
-#else /* For simplicity, the default is MAIN_REG_MAP (this one) */
-\end{code}
-
-Main register-mapping summary: (1)~Specific architecture's details are
-given later. (2)~Entries marked \tr{!} are caller-saves registers
-that {\em must be saved} across ccalls; those marked \tr{@} are
-caller-saves registers that need {\em not} be saved; those marked
-\tr{#} are caller-saves registers that need to be restored, but don't
-need to be saved; the rest are callee-save registers (the best kind).
-
-IF YOU CHANGE THIS TABLE, YOU MAY NEED TO CHANGE CallWrapper.s
-(or equiv) and [who knows?] maybe something else. Check the
-documentation in the porter's part of the installation guide.
-
-\begin{verbatim}
- sparc m68k alpha mipseX hppa iX86 powerpc
- ----- ---- ----- ------ ---- ---- -------
-BaseReg# a5 ebx
-
-StkOReg (CONCURRENT)
-
-R1/Node l1 d7 $1! $9! %r11
-R2 l2 d6 $2! $10! %r12
-R3 l3 d5 $3! $11! %r13
-R4 l4 $4! $12! %r14
-R5 l5 $5! $13! %r15
-R6 l6 $6! $14! %r16
-R7 l7 $7! $15! %r17
-R8 $8! $24! %r18
-
-TagReg@
-
-FltReg1 f2! fp2 $f1 $f20 %fr12
-FltReg2 f3! fp3 $f2 $f22 %fr12R
-FltReg3 f4! fp4 $f3 $f24 %fr13
-FltReg4 f5! fp5 $f4 $f26 %fr13R
-
-DblReg1 f6! fp6 $f5 $f28 %fr20 * SEE NOTES!
-DblReg2 f8! fp7 $f6 $f30 %fr20 * SEE NOTES!
-
-SpA i0 a3 $9 $16 %r4
-SuA i1 d3 $10 $17 %r5
-SpB i2 a4 $11 $18 %r6
-SuB i3 d4 $12 $19 %r7
-
-Hp i4 a2 $13 $20 %r8
-HpLim i5 $14 $21 %r9
-
-RetReg l0 $15 $22 %r10
-
-Liveness (CONCURRENT)
-
-StdUpdRetVec#
-StkStub# i7 $23
-\end{verbatim}
-
-Notes:
-\begin{enumerate}
-\item
-Registers not mentioned in the summary table end up in the default
-(a memory location in @MainRegTable@).
-
-\item
-@BaseReg@ is in a machine register if anything is (well, unless everything is!)
-It points to a block of memory in which the things which don't end up in machine
-registers live.
-
-\item
-Exceptions to previous point:
-If the following labels are in machine registers, then the
-corresponding register name refers to what's in its register; otherwise,
-it refers to the label:
-\begin{verbatim}
-StdUpdRetVecReg vtbl_StdUpdFrame
-StkStubReg STK_STUB_closure
-\end{verbatim}
-Also, if TagReg is not in a machine register, its name refers to
-@INFO_TAG(InfoPtr)@, the tag field from the info table pointed to by
-register R2 (InfoPtr).
-
-\end{enumerate}
-
-Next, we have the code to declare the various global registers. Those
-STG registers which don't actually live in machine registers are
-defined as macros which refer to the registers as fixed offsets into
-the register table. Note that the register table will contain blank
-spots for the STG registers that reside in machine registers. Not to
-worry; these blank spots will be filled in whenever the register
-context is saved, so the space does not go to waste.
-
-\begin{code}
-
-#define Node (R1.p)
-#define InfoPtr (R2.d)
-
-/* these are if we get stuck using the reg-tbl "register" (no machine reg avail) */
-#define RTBL_Dbl1 (BaseReg->rDbl[0])
-#define RTBL_Dbl2 (BaseReg->rDbl[1])
-#if HAVE_LONG_LONG && SIZEOF_LONG < 8
-#define RTBL_Lng1 (BaseReg->rLng[0])
-#define RTBL_Lng2 (BaseReg->rLng[1])
-#endif
-#define RTBL_Flt1 (BaseReg->rFlt[0])
-#define RTBL_Flt2 (BaseReg->rFlt[1])
-#define RTBL_Flt3 (BaseReg->rFlt[2])
-#define RTBL_Flt4 (BaseReg->rFlt[3])
-#define RTBL_R1 (BaseReg->rR[0])
-#define RTBL_R2 (BaseReg->rR[1])
-#define RTBL_R3 (BaseReg->rR[2])
-#define RTBL_R4 (BaseReg->rR[3])
-#define RTBL_R5 (BaseReg->rR[4])
-#define RTBL_R6 (BaseReg->rR[5])
-#define RTBL_R7 (BaseReg->rR[6])
-#define RTBL_R8 (BaseReg->rR[7])
-#define RTBL_SpA (BaseReg->rSpA)
-#define RTBL_SuA (BaseReg->rSuA)
-#define RTBL_SpB (BaseReg->rSpB)
-#define RTBL_SuB (BaseReg->rSuB)
-#define RTBL_Hp (BaseReg->rHp)
-#define RTBL_HpLim (BaseReg->rHpLim)
-#define RTBL_Tag (BaseReg->rTag)
-#define RTBL_Ret (BaseReg->rRet)
-#define RTBL_StkO (BaseReg->rStkO)
-#define RTBL_Liveness (BaseReg->rLiveness)
-
-#ifdef REG_Base
-GLOBAL_REG_DECL(STGRegisterTable *,BaseReg,REG_Base)
-#else
-#ifdef CONCURRENT
-#define BaseReg CurrentRegTable
-#else
-#define BaseReg (&MainRegTable)
-#endif /* CONCURRENT */
-#endif /* REG_Base */
-
-#ifdef REG_StkO
-GLOBAL_REG_DECL(P_,StkOReg,REG_StkO)
-#else
-#define StkOReg RTBL_StkO
-#endif
-
-#ifndef __STG_REGS_AVAIL__ /* driver ensures it is 2 or more */
-# define __STG_REGS_AVAIL__ 8 /* R1 to R8 */
-/* this would only be non-8 if doing weird experiments (WDP 95/11) */
-/* or it might be set lower for a particular arch... */
-#endif
-
-/* R1 is used for Node */
-#ifdef REG_R1
-GLOBAL_REG_DECL(StgUnion,R1,REG_R1)
-#else
-#define R1 RTBL_R1
-#endif
-
-/* R2 is used for InfoPtr */
-#ifdef REG_R2
-GLOBAL_REG_DECL(StgUnion,R2,REG_R2)
-#else
-#define R2 RTBL_R2
-#endif
-
-#ifdef REG_R3
-GLOBAL_REG_DECL(StgUnion,R3,REG_R3)
-#else
-# define R3 RTBL_R3
-#endif
-
-#ifdef REG_R4
-GLOBAL_REG_DECL(StgUnion,R4,REG_R4)
-#else
-# define R4 RTBL_R4
-#endif
-
-#ifdef REG_R5
-GLOBAL_REG_DECL(StgUnion,R5,REG_R5)
-#else
-# define R5 RTBL_R5
-#endif
-
-#ifdef REG_R6
-GLOBAL_REG_DECL(StgUnion,R6,REG_R6)
-#else
-# define R6 RTBL_R6
-#endif
-
-#ifdef REG_R7
-GLOBAL_REG_DECL(StgUnion,R7,REG_R7)
-#else
-# define R7 RTBL_R7
-#endif
-
-#ifdef REG_R8
-GLOBAL_REG_DECL(StgUnion,R8,REG_R8)
-#else
-# define R8 RTBL_R8
-#endif
-
-#ifdef REG_Flt1
-GLOBAL_REG_DECL(StgFloat,FltReg1,REG_Flt1)
-#else
-#define FltReg1 RTBL_Flt1
-#endif
-
-#ifdef REG_Flt2
-GLOBAL_REG_DECL(StgFloat,FltReg2,REG_Flt2)
-#else
-#define FltReg2 RTBL_Flt2
-#endif
-
-#ifdef REG_Flt3
-GLOBAL_REG_DECL(StgFloat,FltReg3,REG_Flt3)
-#else
-#define FltReg3 RTBL_Flt3
-#endif
-
-#ifdef REG_Flt4
-GLOBAL_REG_DECL(StgFloat,FltReg4,REG_Flt4)
-#else
-#define FltReg4 RTBL_Flt4
-#endif
-
-#ifdef REG_Dbl1
-GLOBAL_REG_DECL(StgDouble,DblReg1,REG_Dbl1)
-#else
-#define DblReg1 RTBL_Dbl1
-#endif
-
-#ifdef REG_Dbl2
-GLOBAL_REG_DECL(StgDouble,DblReg2,REG_Dbl2)
-#else
-#define DblReg2 RTBL_Dbl2
-#endif
-
-#if HAVE_LONG_LONG && SIZEOF_LONG < 8
-#ifdef REG_Lng1
-GLOBAL_REG_DECL(StgWord64,LngReg1,REG_Lng1)
-#else
-#define LngReg1 RTBL_Lng1
-#endif
-#endif
-
-#if HAVE_LONG_LONG && SIZEOF_LONG < 8
-#ifdef REG_Lng2
-GLOBAL_REG_DECL(StgWord64,LngReg2,REG_Lng2)
-#else
-#define LngReg2 RTBL_Lng2
-#endif
-#endif
-
-#ifdef REG_Tag
-GLOBAL_REG_DECL(I_,TagReg,REG_Tag)
-
-#define SET_TAG(tag) TagReg = tag
-#else
-#define TagReg INFO_TAG(InfoPtr)
-#define SET_TAG(tag) /* nothing */
-#endif
-
-#ifdef REG_Ret
-GLOBAL_REG_DECL(StgRetAddr,RetReg,REG_Ret)
-#else
-#define RetReg RTBL_Ret
-#endif
-
-#ifdef REG_SpA
-GLOBAL_REG_DECL(PP_,SpA,REG_SpA)
-#else
-#define SpA RTBL_SpA
-#endif
-
-#ifdef REG_SuA
-GLOBAL_REG_DECL(PP_,SuA,REG_SuA)
-#else
-#define SuA RTBL_SuA
-#endif
-
-#ifdef REG_SpB
-GLOBAL_REG_DECL(P_,SpB,REG_SpB)
-#else
-#define SpB RTBL_SpB
-#endif
-
-#ifdef REG_SuB
-GLOBAL_REG_DECL(P_,SuB,REG_SuB)
-#else
-#define SuB RTBL_SuB
-#endif
-
-#ifdef REG_Hp
-GLOBAL_REG_DECL(P_,Hp,REG_Hp)
-#else
-#define Hp RTBL_Hp
-#endif
-
-#ifdef REG_HpLim
-GLOBAL_REG_DECL(P_,HpLim,REG_HpLim)
-#else
-#define HpLim RTBL_HpLim
-#endif
-
-#ifdef REG_Liveness
-GLOBAL_REG_DECL(I_,LivenessReg,REG_Liveness)
-#else
-#define LivenessReg RTBL_Liveness
-#endif
-
-#ifdef REG_StdUpdRetVec
-GLOBAL_REG_DECL(D_,StdUpdRetVecReg,REG_StdUpdRetVec)
-#else
-#define StdUpdRetVecReg vtbl_StdUpdFrame
-#endif
-
-#ifdef REG_StkStub
-GLOBAL_REG_DECL(P_,StkStubReg,REG_StkStub)
-#else
-#define StkStubReg STK_STUB_closure
-#endif
-
-#ifdef CALLER_SAVES_StkO
-#define CALLER_SAVE_StkO SAVE_StkO = StkOReg;
-#define CALLER_RESTORE_StkO StkOReg = SAVE_StkO;
-#else
-#define CALLER_SAVE_StkO /* nothing */
-#define CALLER_RESTORE_StkO /* nothing */
-#endif
-
-#ifdef CALLER_SAVES_R1
-#define CALLER_SAVE_R1 SAVE_R1 = R1;
-#define CALLER_RESTORE_R1 R1 = SAVE_R1;
-#else
-#define CALLER_SAVE_R1 /* nothing */
-#define CALLER_RESTORE_R1 /* nothing */
-#endif
-
-#ifdef CALLER_SAVES_R2
-#define CALLER_SAVE_R2 SAVE_R2 = R2;
-#define CALLER_RESTORE_R2 R2 = SAVE_R2;
-#else
-#define CALLER_SAVE_R2 /* nothing */
-#define CALLER_RESTORE_R2 /* nothing */
-#endif
-
-#ifdef CALLER_SAVES_R3
-#define CALLER_SAVE_R3 SAVE_R3 = R3;
-#define CALLER_RESTORE_R3 R3 = SAVE_R3;
-#else
-#define CALLER_SAVE_R3 /* nothing */
-#define CALLER_RESTORE_R3 /* nothing */
-#endif
-
-#ifdef CALLER_SAVES_R4
-#define CALLER_SAVE_R4 SAVE_R4 = R4;
-#define CALLER_RESTORE_R4 R4 = SAVE_R4;
-#else
-#define CALLER_SAVE_R4 /* nothing */
-#define CALLER_RESTORE_R4 /* nothing */
-#endif
-
-#ifdef CALLER_SAVES_R5
-#define CALLER_SAVE_R5 SAVE_R5 = R5;
-#define CALLER_RESTORE_R5 R5 = SAVE_R5;
-#else
-#define CALLER_SAVE_R5 /* nothing */
-#define CALLER_RESTORE_R5 /* nothing */
-#endif
-
-#ifdef CALLER_SAVES_R6
-#define CALLER_SAVE_R6 SAVE_R6 = R6;
-#define CALLER_RESTORE_R6 R6 = SAVE_R6;
-#else
-#define CALLER_SAVE_R6 /* nothing */
-#define CALLER_RESTORE_R6 /* nothing */
-#endif
-
-#ifdef CALLER_SAVES_R7
-#define CALLER_SAVE_R7 SAVE_R7 = R7;
-#define CALLER_RESTORE_R7 R7 = SAVE_R7;
-#else
-#define CALLER_SAVE_R7 /* nothing */
-#define CALLER_RESTORE_R7 /* nothing */
-#endif
-
-#ifdef CALLER_SAVES_R8
-#define CALLER_SAVE_R8 SAVE_R8 = R8;
-#define CALLER_RESTORE_R8 R8 = SAVE_R8;
-#else
-#define CALLER_SAVE_R8 /* nothing */
-#define CALLER_RESTORE_R8 /* nothing */
-#endif
-
-#ifdef CALLER_SAVES_FltReg1
-#define CALLER_SAVE_FltReg1 SAVE_Flt1 = FltReg1;
-#define CALLER_RESTORE_FltReg1 FltReg1 = SAVE_Flt1;
-#else
-#define CALLER_SAVE_FltReg1 /* nothing */
-#define CALLER_RESTORE_FltReg1 /* nothing */
-#endif
-
-#ifdef CALLER_SAVES_FltReg2
-#define CALLER_SAVE_FltReg2 SAVE_Flt2 = FltReg2;
-#define CALLER_RESTORE_FltReg2 FltReg2 = SAVE_Flt2;
-#else
-#define CALLER_SAVE_FltReg2 /* nothing */
-#define CALLER_RESTORE_FltReg2 /* nothing */
-#endif
-
-#ifdef CALLER_SAVES_FltReg3
-#define CALLER_SAVE_FltReg3 SAVE_Flt3 = FltReg3;
-#define CALLER_RESTORE_FltReg3 FltReg3 = SAVE_Flt3;
-#else
-#define CALLER_SAVE_FltReg3 /* nothing */
-#define CALLER_RESTORE_FltReg3 /* nothing */
-#endif
-
-#ifdef CALLER_SAVES_FltReg4
-#define CALLER_SAVE_FltReg4 SAVE_Flt4 = FltReg4;
-#define CALLER_RESTORE_FltReg4 FltReg4 = SAVE_Flt4;
-#else
-#define CALLER_SAVE_FltReg4 /* nothing */
-#define CALLER_RESTORE_FltReg4 /* nothing */
-#endif
-
-#ifdef CALLER_SAVES_DblReg1
-#define CALLER_SAVE_DblReg1 SAVE_Dbl1 = DblReg1;
-#define CALLER_RESTORE_DblReg1 DblReg1 = SAVE_Dbl1;
-#else
-#define CALLER_SAVE_DblReg1 /* nothing */
-#define CALLER_RESTORE_DblReg1 /* nothing */
-#endif
-
-#ifdef CALLER_SAVES_DblReg2
-#define CALLER_SAVE_DblReg2 SAVE_Dbl2 = DblReg2;
-#define CALLER_RESTORE_DblReg2 DblReg2 = SAVE_Dbl2;
-#else
-#define CALLER_SAVE_DblReg2 /* nothing */
-#define CALLER_RESTORE_DblReg2 /* nothing */
-#endif
-
-#if HAVE_LONG_LONG && SIZEOF_LONG < 8
-#ifdef CALLER_SAVES_LngReg1
-#define CALLER_SAVE_LngReg1 SAVE_Lng1 = LngReg1;
-#define CALLER_RESTORE_LngReg1 LngReg1 = SAVE_Lng1;
-#else
-#define CALLER_SAVE_LngReg1 /* nothing */
-#define CALLER_RESTORE_LngReg1 /* nothing */
-#endif
-#endif
-
-#if HAVE_LONG_LONG && SIZEOF_LONG < 8
-#ifdef CALLER_SAVES_LngReg2
-#define CALLER_SAVE_LngReg2 SAVE_Lng2 = LngReg2;
-#define CALLER_RESTORE_LngReg2 LngReg2 = SAVE_Lng2;
-#else
-#define CALLER_SAVE_LngReg2 /* nothing */
-#define CALLER_RESTORE_LngReg2 /* nothing */
-#endif
-#endif
-
-#ifdef CALLER_SAVES_Tag
-#define CALLER_SAVE_Tag SAVE_Tag = TagReg;
-#define CALLER_RESTORE_Tag TagReg = SAVE_Tag;
-#else
-#define CALLER_SAVE_Tag /* nothing */
-#define CALLER_RESTORE_Tag /* nothing */
-#endif
-
-#ifdef CALLER_SAVES_Ret
-#define CALLER_SAVE_Ret SAVE_Ret = RetReg;
-#define CALLER_RESTORE_Ret RetReg = SAVE_Ret;
-#else
-#define CALLER_SAVE_Ret /* nothing */
-#define CALLER_RESTORE_Ret /* nothing */
-#endif
-
-#ifdef CALLER_SAVES_SpA
-#define CALLER_SAVE_SpA SAVE_SpA = SpA;
-#define CALLER_RESTORE_SpA SpA = SAVE_SpA;
-#else
-#define CALLER_SAVE_SpA /* nothing */
-#define CALLER_RESTORE_SpA /* nothing */
-#endif
-
-#ifdef CALLER_SAVES_SuA
-#define CALLER_SAVE_SuA SAVE_SuA = SuA;
-#define CALLER_RESTORE_SuA SuA = SAVE_SuA;
-#else
-#define CALLER_SAVE_SuA /* nothing */
-#define CALLER_RESTORE_SuA /* nothing */
-#endif
-
-#ifdef CALLER_SAVES_SpB
-#define CALLER_SAVE_SpB SAVE_SpB = SpB;
-#define CALLER_RESTORE_SpB SpB = SAVE_SpB;
-#else
-#define CALLER_SAVE_SpB /* nothing */
-#define CALLER_RESTORE_SpB /* nothing */
-#endif
-
-#ifdef CALLER_SAVES_SuB
-#define CALLER_SAVE_SuB SAVE_SuB = SuB;
-#define CALLER_RESTORE_SuB SuB = SAVE_SuB;
-#else
-#define CALLER_SAVE_SuB /* nothing */
-#define CALLER_RESTORE_SuB /* nothing */
-#endif
-
-#ifdef CALLER_SAVES_Hp
-#define CALLER_SAVE_Hp SAVE_Hp = Hp;
-#define CALLER_RESTORE_Hp Hp = SAVE_Hp;
-#else
-#define CALLER_SAVE_Hp /* nothing */
-#define CALLER_RESTORE_Hp /* nothing */
-#endif
-
-#ifdef CALLER_SAVES_HpLim
-#define CALLER_SAVE_HpLim SAVE_HpLim = HpLim;
-#define CALLER_RESTORE_HpLim HpLim = SAVE_HpLim;
-#else
-#define CALLER_SAVE_HpLim /* nothing */
-#define CALLER_RESTORE_HpLim /* nothing */
-#endif
-
-#ifdef CALLER_SAVES_Liveness
-#define CALLER_SAVE_Liveness SAVE_Liveness = LivenessReg;
-#define CALLER_RESTORE_Liveness LivenessReg = SAVE_Liveness;
-#else
-#define CALLER_SAVE_Liveness /* nothing */
-#define CALLER_RESTORE_Liveness /* nothing */
-#endif
-
-#ifdef CALLER_SAVES_Base
-#ifndef CONCURRENT
-#define CALLER_SAVE_Base /* nothing, ever (it holds a fixed value) */
-#define CALLER_RESTORE_Base BaseReg = &MainRegTable;
-#else
-#define CALLER_SAVE_Base /* nothing */
-#define CALLER_RESTORE_Base BaseReg = CurrentRegTable;
-#endif
-#else
-#define CALLER_SAVE_Base /* nothing */
-#define CALLER_RESTORE_Base /* nothing */
-#endif
-
-#ifdef CALLER_SAVES_StdUpdRetVec
-#define CALLER_RESTORE_StdUpdRetVec StdUpdRetVecReg = vtbl_StdUpdFrame;
-#else
-#define CALLER_RESTORE_StdUpdRetVec /* nothing */
-#endif
-
-#ifdef CALLER_SAVES_StkStub
-#define CALLER_RESTORE_StkStub StdUpdRetVecReg = STK_STUB_closure;
-#else
-#define CALLER_RESTORE_StkStub /* nothing */
-#endif
-
-\end{code}
-
-Concluding \tr{#endifs} and multi-slurp protection:
-
-\begin{code}
-
-#endif /* SCAV_REG_MAP */
-#endif /* SCAN_REG_MAP */
-#endif /* MARK_REG_MAP */
-#endif /* NULL_REG_MAP */
-
-#endif /* STGREGS_H */
-\end{code}