Draw STG F and D registers from the same pool of available SSE registers on x86-64.

On x86-64 F and D registers are both drawn from SSE registers, so there is no
reason not to draw them from the same pool of available SSE registers. This
means that whereas previously a function could only receive two Double arguments
in registers even if it did not have any Float arguments, now it can receive up
to 6 arguments that are any mix of Float and Double in registers.

This patch breaks the LLVM back end. The next patch will fix this breakage.
parent 5ee08ddf
......@@ -9,7 +9,7 @@ module CmmCallConv (
ParamLocation(..),
assignArgumentsPos,
assignStack,
globalArgRegs, realArgRegs
globalArgRegs, realArgRegsCover
) where
#include "HsVersions.h"
......@@ -69,22 +69,27 @@ assignArgumentsPos dflags off conv arg_ty reps = (stk_off, assignments)
assign_regs assts [] _ = (assts, [])
assign_regs assts (r:rs) regs = if isFloatType ty then float else int
where float = case (w, regs) of
(W32, (vs, f:fs, ds, ls)) -> k (RegisterParam f, (vs, fs, ds, ls))
(W64, (vs, fs, d:ds, ls)) -> k (RegisterParam d, (vs, fs, ds, ls))
(W32, (vs, fs, ds, ls, s:ss)) -> k (RegisterParam (FloatReg s), (vs, fs, ds, ls, ss))
(W32, (vs, f:fs, ds, ls, ss))
| not hasSseRegs -> k (RegisterParam f, (vs, fs, ds, ls, ss))
(W64, (vs, fs, ds, ls, s:ss)) -> k (RegisterParam (DoubleReg s), (vs, fs, ds, ls, ss))
(W64, (vs, fs, d:ds, ls, ss))
| not hasSseRegs -> k (RegisterParam d, (vs, fs, ds, ls, ss))
(W80, _) -> panic "F80 unsupported register type"
_ -> (assts, (r:rs))
int = case (w, regs) of
(W128, _) -> panic "W128 unsupported register type"
(_, (v:vs, fs, ds, ls)) | widthInBits w <= widthInBits (wordWidth dflags)
-> k (RegisterParam (v gcp), (vs, fs, ds, ls))
(_, (vs, fs, ds, l:ls)) | widthInBits w > widthInBits (wordWidth dflags)
-> k (RegisterParam l, (vs, fs, ds, ls))
(_, (v:vs, fs, ds, ls, ss)) | widthInBits w <= widthInBits (wordWidth dflags)
-> k (RegisterParam (v gcp), (vs, fs, ds, ls, ss))
(_, (vs, fs, ds, l:ls, ss)) | widthInBits w > widthInBits (wordWidth dflags)
-> k (RegisterParam l, (vs, fs, ds, ls, ss))
_ -> (assts, (r:rs))
k (asst, regs') = assign_regs ((r, asst) : assts) rs regs'
ty = arg_ty r
w = typeWidth ty
gcp | isGcPtrType ty = VGcPtr
| otherwise = VNonGcPtr
hasSseRegs = mAX_Real_SSE_REG dflags /= 0
assignStack :: DynFlags -> ByteOff -> (a -> CmmType) -> [a]
......@@ -109,6 +114,7 @@ type AvailRegs = ( [VGcPtr -> GlobalReg] -- available vanilla regs.
, [GlobalReg] -- floats
, [GlobalReg] -- doubles
, [GlobalReg] -- longs (int64 and word64)
, [Int] -- SSE (floats and doubles)
)
-- Vanilla registers can contain pointers, Ints, Chars.
......@@ -122,7 +128,8 @@ getRegsWithoutNode dflags =
( filter (\r -> r VGcPtr /= node) (realVanillaRegs dflags)
, realFloatRegs dflags
, realDoubleRegs dflags
, realLongRegs dflags)
, realLongRegs dflags
, sseRegNos dflags)
-- getRegsWithNode uses R1/node even if it isn't a register
getRegsWithNode dflags =
......@@ -131,15 +138,18 @@ getRegsWithNode dflags =
else realVanillaRegs dflags
, realFloatRegs dflags
, realDoubleRegs dflags
, realLongRegs dflags)
, realLongRegs dflags
, sseRegNos dflags)
allFloatRegs, allDoubleRegs, allLongRegs :: DynFlags -> [GlobalReg]
allVanillaRegs :: DynFlags -> [VGcPtr -> GlobalReg]
allSseRegs :: DynFlags -> [Int]
allVanillaRegs dflags = map VanillaReg $ regList (mAX_Vanilla_REG dflags)
allFloatRegs dflags = map FloatReg $ regList (mAX_Float_REG dflags)
allDoubleRegs dflags = map DoubleReg $ regList (mAX_Double_REG dflags)
allLongRegs dflags = map LongReg $ regList (mAX_Long_REG dflags)
allSseRegs dflags = regList (mAX_SSE_REG dflags)
realFloatRegs, realDoubleRegs, realLongRegs :: DynFlags -> [GlobalReg]
realVanillaRegs :: DynFlags -> [VGcPtr -> GlobalReg]
......@@ -149,6 +159,9 @@ realFloatRegs dflags = map FloatReg $ regList (mAX_Real_Float_REG dflags)
realDoubleRegs dflags = map DoubleReg $ regList (mAX_Real_Double_REG dflags)
realLongRegs dflags = map LongReg $ regList (mAX_Real_Long_REG dflags)
sseRegNos :: DynFlags -> [Int]
sseRegNos dflags =regList (mAX_SSE_REG dflags)
regList :: Int -> [Int]
regList n = [1 .. n]
......@@ -156,10 +169,11 @@ allRegs :: DynFlags -> AvailRegs
allRegs dflags = (allVanillaRegs dflags,
allFloatRegs dflags,
allDoubleRegs dflags,
allLongRegs dflags)
allLongRegs dflags,
allSseRegs dflags)
noRegs :: AvailRegs
noRegs = ([], [], [], [])
noRegs = ([], [], [], [], [])
globalArgRegs :: DynFlags -> [GlobalReg]
globalArgRegs dflags = map ($ VGcPtr) (allVanillaRegs dflags) ++
......@@ -167,8 +181,19 @@ globalArgRegs dflags = map ($ VGcPtr) (allVanillaRegs dflags) ++
allDoubleRegs dflags ++
allLongRegs dflags
realArgRegs :: DynFlags -> [GlobalReg]
realArgRegs dflags = map ($VGcPtr) (realVanillaRegs dflags) ++
realFloatRegs dflags ++
realDoubleRegs dflags ++
realLongRegs dflags
-- This returns the set of global registers that *cover* the machine registers
-- used for argument passing. On platforms where registers can overlap---right
-- now just x86-64, where Float and Double registers overlap---passing this set
-- of registers is guaranteed to preserve the contents of all live registers. We
-- only use this functionality in hand-written C-- code in the RTS.
realArgRegsCover :: DynFlags -> [GlobalReg]
realArgRegsCover dflags
| hasSseRegs = map ($VGcPtr) (realVanillaRegs dflags) ++
realDoubleRegs dflags ++
realLongRegs dflags
| otherwise = map ($VGcPtr) (realVanillaRegs dflags) ++
realFloatRegs dflags ++
realDoubleRegs dflags ++
realLongRegs dflags
where
hasSseRegs = mAX_Real_SSE_REG dflags /= 0
......@@ -609,8 +609,9 @@ safety :: { Safety }
vols :: { [GlobalReg] }
: '[' ']' { [] }
| '[' '*' ']' {% do df <- getDynFlags
; return (realArgRegs df) }
-- all of them
; return (realArgRegsCover df) }
-- All of them. See comment attached
-- to realArgRegsCover
| '[' globals ']' { $2 }
globals :: { [GlobalReg] }
......
......@@ -36,10 +36,16 @@ baseRegOffset dflags (FloatReg 1) = oFFSET_StgRegTable_rF1 dflags
baseRegOffset dflags (FloatReg 2) = oFFSET_StgRegTable_rF2 dflags
baseRegOffset dflags (FloatReg 3) = oFFSET_StgRegTable_rF3 dflags
baseRegOffset dflags (FloatReg 4) = oFFSET_StgRegTable_rF4 dflags
baseRegOffset _ (FloatReg n) = panic ("Registers above F4 are not supported (tried to use F" ++ show n ++ ")")
baseRegOffset dflags (FloatReg 5) = oFFSET_StgRegTable_rF5 dflags
baseRegOffset dflags (FloatReg 6) = oFFSET_StgRegTable_rF6 dflags
baseRegOffset _ (FloatReg n) = panic ("Registers above F6 are not supported (tried to use F" ++ show n ++ ")")
baseRegOffset dflags (DoubleReg 1) = oFFSET_StgRegTable_rD1 dflags
baseRegOffset dflags (DoubleReg 2) = oFFSET_StgRegTable_rD2 dflags
baseRegOffset _ (DoubleReg n) = panic ("Registers above D2 are not supported (tried to use D" ++ show n ++ ")")
baseRegOffset dflags (DoubleReg 3) = oFFSET_StgRegTable_rD3 dflags
baseRegOffset dflags (DoubleReg 4) = oFFSET_StgRegTable_rD4 dflags
baseRegOffset dflags (DoubleReg 5) = oFFSET_StgRegTable_rD5 dflags
baseRegOffset dflags (DoubleReg 6) = oFFSET_StgRegTable_rD6 dflags
baseRegOffset _ (DoubleReg n) = panic ("Registers above D6 are not supported (tried to use D" ++ show n ++ ")")
baseRegOffset dflags Sp = oFFSET_StgRegTable_rSp dflags
baseRegOffset dflags SpLim = oFFSET_StgRegTable_rSpLim dflags
baseRegOffset dflags (LongReg 1) = oFFSET_StgRegTable_rL1 dflags
......
......@@ -47,8 +47,14 @@ lmGlobalReg dflags suf reg
FloatReg 2 -> floatGlobal $"F2" ++ suf
FloatReg 3 -> floatGlobal $"F3" ++ suf
FloatReg 4 -> floatGlobal $"F4" ++ suf
FloatReg 5 -> floatGlobal $"F5" ++ suf
FloatReg 6 -> floatGlobal $"F6" ++ suf
DoubleReg 1 -> doubleGlobal $ "D1" ++ suf
DoubleReg 2 -> doubleGlobal $ "D2" ++ suf
DoubleReg 3 -> doubleGlobal $ "D3" ++ suf
DoubleReg 4 -> doubleGlobal $ "D4" ++ suf
DoubleReg 5 -> doubleGlobal $ "D5" ++ suf
DoubleReg 6 -> doubleGlobal $ "D6" ++ suf
_other -> panic $ "LlvmCodeGen.Reg: GlobalReg (" ++ (show reg)
++ ") not supported!"
-- LongReg, HpLim, CCSS, CurrentTSO, CurrentNusery, HpAlloc
......
......@@ -682,8 +682,8 @@
#define SAVE_STGREGS \
W_ r1, r2, r3, r4, r5, r6, r7, r8; \
F_ f1, f2, f3, f4; \
D_ d1, d2; \
F_ f1, f2, f3, f4, f5, f6; \
D_ d1, d2, d3, d4, d5, d6; \
L_ l1; \
\
r1 = R1; \
......@@ -699,9 +699,15 @@
f2 = F2; \
f3 = F3; \
f4 = F4; \
f5 = F5; \
f6 = F6; \
\
d1 = D1; \
d2 = D2; \
d3 = D3; \
d4 = D4; \
d5 = D5; \
d6 = D6; \
\
l1 = L1;
......@@ -720,9 +726,15 @@
F2 = f2; \
F3 = f3; \
F4 = f4; \
F5 = f5; \
F6 = f6; \
\
D1 = d1; \
D2 = d2; \
D3 = d3; \
D4 = d4; \
D5 = d5; \
D6 = d6; \
\
L1 = l1;
......
......@@ -286,12 +286,30 @@ callerSaves (FloatReg 3) = True
#ifdef CALLER_SAVES_F4
callerSaves (FloatReg 4) = True
#endif
#ifdef CALLER_SAVES_F5
callerSaves (FloatReg 5) = True
#endif
#ifdef CALLER_SAVES_F6
callerSaves (FloatReg 6) = True
#endif
#ifdef CALLER_SAVES_D1
callerSaves (DoubleReg 1) = True
#endif
#ifdef CALLER_SAVES_D2
callerSaves (DoubleReg 2) = True
#endif
#ifdef CALLER_SAVES_D3
callerSaves (DoubleReg 3) = True
#endif
#ifdef CALLER_SAVES_D4
callerSaves (DoubleReg 4) = True
#endif
#ifdef CALLER_SAVES_D5
callerSaves (DoubleReg 5) = True
#endif
#ifdef CALLER_SAVES_D6
callerSaves (DoubleReg 6) = True
#endif
#ifdef CALLER_SAVES_L1
callerSaves (LongReg 1) = True
#endif
......@@ -362,24 +380,81 @@ activeStgRegs = [
#ifdef REG_SpLim
,SpLim
#endif
#if MAX_REAL_SSE_REG != 0
#ifdef REG_F1
,FloatReg 1
#endif
#ifdef REG_D1
,DoubleReg 1
#endif
#ifdef REG_F2
,FloatReg 2
#endif
#ifdef REG_D2
,DoubleReg 2
#endif
#ifdef REG_F3
,FloatReg 3
#endif
#ifdef REG_D3
,DoubleReg 3
#endif
#ifdef REG_F4
,FloatReg 4
#endif
#ifdef REG_D4
,DoubleReg 4
#endif
#ifdef REG_F5
,FloatReg 5
#endif
#ifdef REG_D5
,DoubleReg 5
#endif
#ifdef REG_F6
,FloatReg 6
#endif
#ifdef REG_D6
,DoubleReg 6
#endif
#else /* MAX_REAL_SSE_REG == 0 */
#ifdef REG_F1
,FloatReg 1
#endif
#ifdef REG_F2
,FloatReg 2
#endif
#ifdef REG_F3
,FloatReg 3
#endif
#ifdef REG_F4
,FloatReg 4
#endif
#ifdef REG_F5
,FloatReg 5
#endif
#ifdef REG_F6
,FloatReg 6
#endif
#ifdef REG_D1
,DoubleReg 1
#endif
#ifdef REG_D2
,DoubleReg 2
#endif
#ifdef REG_D3
,DoubleReg 3
#endif
#ifdef REG_D4
,DoubleReg 4
#endif
#ifdef REG_D5
,DoubleReg 5
#endif
#ifdef REG_D6
,DoubleReg 6
#endif
#endif /* MAX_REAL_SSE_REG == 0 */
]
haveRegBase :: Bool
......@@ -439,6 +514,12 @@ globalRegMaybe (FloatReg 3) = Just (RealRegSingle REG_F3)
# ifdef REG_F4
globalRegMaybe (FloatReg 4) = Just (RealRegSingle REG_F4)
# endif
# ifdef REG_F5
globalRegMaybe (FloatReg 5) = Just (RealRegSingle REG_F5)
# endif
# ifdef REG_F6
globalRegMaybe (FloatReg 6) = Just (RealRegSingle REG_F6)
# endif
# ifdef REG_D1
globalRegMaybe (DoubleReg 1) =
# if MACHREGS_sparc
......@@ -455,6 +536,38 @@ globalRegMaybe (DoubleReg 2) =
Just (RealRegSingle REG_D2)
# endif
# endif
# ifdef REG_D3
globalRegMaybe (DoubleReg 3) =
# if MACHREGS_sparc
Just (RealRegPair REG_D3 (REG_D3 + 1))
# else
Just (RealRegSingle REG_D3)
# endif
# endif
# ifdef REG_D4
globalRegMaybe (DoubleReg 4) =
# if MACHREGS_sparc
Just (RealRegPair REG_D4 (REG_D4 + 1))
# else
Just (RealRegSingle REG_D4)
# endif
# endif
# ifdef REG_D5
globalRegMaybe (DoubleReg 5) =
# if MACHREGS_sparc
Just (RealRegPair REG_D5 (REG_D5 + 1))
# else
Just (RealRegSingle REG_D5)
# endif
# endif
# ifdef REG_D6
globalRegMaybe (DoubleReg 6) =
# if MACHREGS_sparc
Just (RealRegPair REG_D6 (REG_D6 + 1))
# else
Just (RealRegSingle REG_D6)
# endif
# endif
# ifdef REG_Sp
globalRegMaybe Sp = Just (RealRegSingle REG_Sp)
# endif
......@@ -588,12 +701,30 @@ freeReg REG_F3 = fastBool False
# ifdef REG_F4
freeReg REG_F4 = fastBool False
# endif
# ifdef REG_F5
freeReg REG_F5 = fastBool False
# endif
# ifdef REG_F6
freeReg REG_F6 = fastBool False
# endif
# ifdef REG_D1
freeReg REG_D1 = fastBool False
# endif
# ifdef REG_D2
freeReg REG_D2 = fastBool False
# endif
# ifdef REG_D3
freeReg REG_D3 = fastBool False
# endif
# ifdef REG_D4
freeReg REG_D4 = fastBool False
# endif
# ifdef REG_D5
freeReg REG_D5 = fastBool False
# endif
# ifdef REG_D6
freeReg REG_D6 = fastBool False
# endif
# ifdef REG_Sp
freeReg REG_Sp = fastBool False
# endif
......@@ -698,6 +829,12 @@ freeReg REG_F3 = fastBool False
# ifdef REG_F4
freeReg REG_F4 = fastBool False
# endif
# ifdef REG_F5
freeReg REG_F5 = fastBool False
# endif
# ifdef REG_F6
freeReg REG_F6 = fastBool False
# endif
# ifdef REG_D1
freeReg REG_D1 = fastBool False
# endif
......@@ -710,6 +847,30 @@ freeReg REG_D2 = fastBool False
# ifdef REG_D2_2
freeReg REG_D2_2 = fastBool False
# endif
# ifdef REG_D3
freeReg REG_D3 = fastBool False
# endif
# ifdef REG_D3_2
freeReg REG_D3_2 = fastBool False
# endif
# ifdef REG_D4
freeReg REG_D4 = fastBool False
# endif
# ifdef REG_D4_2
freeReg REG_D4_2 = fastBool False
# endif
# ifdef REG_D5
freeReg REG_D5 = fastBool False
# endif
# ifdef REG_D5_2
freeReg REG_D5_2 = fastBool False
# endif
# ifdef REG_D6
freeReg REG_D6 = fastBool False
# endif
# ifdef REG_D6_2
freeReg REG_D6_2 = fastBool False
# endif
# ifdef REG_Sp
freeReg REG_Sp = fastBool False
# endif
......
......@@ -458,8 +458,14 @@ main(int argc, char *argv[])
field_offset(StgRegTable, rF2);
field_offset(StgRegTable, rF3);
field_offset(StgRegTable, rF4);
field_offset(StgRegTable, rF5);
field_offset(StgRegTable, rF6);
field_offset(StgRegTable, rD1);
field_offset(StgRegTable, rD2);
field_offset(StgRegTable, rD3);
field_offset(StgRegTable, rD4);
field_offset(StgRegTable, rD5);
field_offset(StgRegTable, rD6);
field_offset(StgRegTable, rL1);
field_offset(StgRegTable, rSp);
field_offset(StgRegTable, rSpLim);
......@@ -736,9 +742,11 @@ main(int argc, char *argv[])
constantInt("mAX_Float_REG", MAX_FLOAT_REG);
constantInt("mAX_Double_REG", MAX_DOUBLE_REG);
constantInt("mAX_Long_REG", MAX_LONG_REG);
constantInt("mAX_SSE_REG", MAX_SSE_REG);
constantInt("mAX_Real_Vanilla_REG", MAX_REAL_VANILLA_REG);
constantInt("mAX_Real_Float_REG", MAX_REAL_FLOAT_REG);
constantInt("mAX_Real_Double_REG", MAX_REAL_DOUBLE_REG);
constantInt("mAX_Real_SSE_REG", MAX_REAL_SSE_REG);
constantInt("mAX_Real_Long_REG", MAX_REAL_LONG_REG);
// This tells the native code generator the size of the spill
......
......@@ -81,9 +81,10 @@
-------------------------------------------------------------------------- */
#define MAX_VANILLA_REG 10
#define MAX_FLOAT_REG 4
#define MAX_DOUBLE_REG 2
#define MAX_FLOAT_REG 6
#define MAX_DOUBLE_REG 6
#define MAX_LONG_REG 1
#define MAX_SSE_REG 6
/* -----------------------------------------------------------------------------
Semi-Tagging constants
......
......@@ -92,6 +92,7 @@
#define MAX_REAL_FLOAT_REG 0
#define MAX_REAL_DOUBLE_REG 0
#define MAX_REAL_LONG_REG 0
#define MAX_REAL_SSE_REG 0
/* -----------------------------------------------------------------------------
The x86-64 register mapping
......@@ -141,9 +142,22 @@
#define REG_F2 xmm2
#define REG_F3 xmm3
#define REG_F4 xmm4
#define REG_D1 xmm5
#define REG_D2 xmm6
#define REG_F5 xmm5
#define REG_F6 xmm6
#define REG_D1 xmm1
#define REG_D2 xmm2
#define REG_D3 xmm3
#define REG_D4 xmm4
#define REG_D5 xmm5
#define REG_D6 xmm6
#define REG_SSE1 xmm1
#define REG_SSE2 xmm2
#define REG_SSE3 xmm3
#define REG_SSE4 xmm4
#define REG_SSE5 xmm5
#define REG_SSE6 xmm6
#if !defined(mingw32_HOST_OS)
#define CALLER_SAVES_R3
......@@ -156,16 +170,34 @@
#define CALLER_SAVES_F2
#define CALLER_SAVES_F3
#define CALLER_SAVES_F4
#define CALLER_SAVES_F5
#if !defined(mingw32_HOST_OS)
#define CALLER_SAVES_F6
#endif
#define CALLER_SAVES_D1
#if !defined(mingw32_HOST_OS)
#define CALLER_SAVES_D2
#define CALLER_SAVES_D3
#define CALLER_SAVES_D4
#define CALLER_SAVES_D5
#if !defined(mingw32_HOST_OS)
#define CALLER_SAVES_D6
#endif
#define CALLER_SAVES_SSE1
#define CALLER_SAVES_SSE2
#define CALLER_SAVES_SSE3
#define CALLER_SAVES_SSE4
#define CALLER_SAVES_SSE5
#if !defined(mingw32_HOST_OS)
#define CALLER_SAVES_SSE6
#endif
#define MAX_REAL_VANILLA_REG 6
#define MAX_REAL_FLOAT_REG 4
#define MAX_REAL_DOUBLE_REG 2
#define MAX_REAL_FLOAT_REG 6
#define MAX_REAL_DOUBLE_REG 6
#define MAX_REAL_LONG_REG 0
#define MAX_REAL_SSE_REG 6
/* -----------------------------------------------------------------------------
The PowerPC register mapping
......@@ -518,6 +550,24 @@
# endif
#endif
#ifndef MAX_REAL_SSE_REG
# if defined(REG_SSE6)
# define MAX_REAL_SSE_REG 6
# elif defined(REG_SSE5)
# define MAX_REAL_SSE_REG 5
# elif defined(REG_SSE4)
# define MAX_REAL_SSE_REG 4
# elif defined(REG_SSE3)
# define MAX_REAL_SSE_REG 3
# elif defined(REG_SSE2)
# define MAX_REAL_SSE_REG 2
# elif defined(REG_SSE1)
# define MAX_REAL_SSE_REG 1
# else
# define MAX_REAL_SSE_REG 0
# endif
#endif
/* define NO_ARG_REGS if we have no argument registers at all (we can
* optimise certain code paths using this predicate).
*/
......
......@@ -73,8 +73,14 @@ typedef struct {
StgFloat rF2;
StgFloat rF3;
StgFloat rF4;
StgFloat rF5;
StgFloat rF6;
StgDouble rD1;
StgDouble rD2;
StgDouble rD3;
StgDouble rD4;
StgDouble rD5;
StgDouble rD6;
StgWord64 rL1;
StgPtr rSp;
StgPtr rSpLim;
......@@ -216,6 +222,18 @@ GLOBAL_REG_DECL(StgFloat,F4,REG_F4)
#define F4 (BaseReg->rF4)
#endif
#if defined(REG_F5) && !defined(NO_GLOBAL_REG_DECLS)
GLOBAL_REG_DECL(StgFloat,F5,REG_F5)
#else
#define F5 (BaseReg->rF5)
#endif
#if defined(REG_F6) && !defined(NO_GLOBAL_REG_DECLS)
GLOBAL_REG_DECL(StgFloat,F6,REG_F6)
#else
#define F6 (BaseReg->rF6)
#endif
#if defined(REG_D1) && !defined(NO_GLOBAL_REG_DECLS)
GLOBAL_REG_DECL(StgDouble,D1,REG_D1)
#else
......@@ -228,6 +246,30 @@ GLOBAL_REG_DECL(StgDouble,D2,REG_D2)
#define D2 (BaseReg->rD2)
#endif
#if defined(REG_D3) && !defined(NO_GLOBAL_REG_DECLS)
GLOBAL_REG_DECL(StgDouble,D3,REG_D3)
#else
#define D3 (BaseReg->rD3)
#endif
#if defined(REG_D4) && !defined(NO_GLOBAL_REG_DECLS)
GLOBAL_REG_DECL(StgDouble,D4,REG_D4)
#else
#define D4 (BaseReg->rD4)
#endif
#if defined(REG_D5) && !defined(NO_GLOBAL_REG_DECLS)
GLOBAL_REG_DECL(StgDouble,D5,REG_D5)
#else
#define D5 (BaseReg->rD5)
#endif
#if defined(REG_D6) && !defined(NO_GLOBAL_REG_DECLS)
GLOBAL_REG_DECL(StgDouble,D6,REG_D6)
#else