Draw STG F and D registers from the same pool of available SSE registers on x86-64.
authorGeoffrey Mainland <gmainlan@microsoft.com>
Fri, 5 Oct 2012 14:19:55 +0000 (15:19 +0100)
committerGeoffrey Mainland <gmainlan@microsoft.com>
Tue, 30 Oct 2012 20:50:48 +0000 (20:50 +0000)
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.

compiler/cmm/CmmCallConv.hs
compiler/cmm/CmmParse.y
compiler/codeGen/CgUtils.hs
compiler/llvmGen/LlvmCodeGen/Regs.hs
includes/Cmm.h
includes/CodeGen.Platform.hs
includes/mkDerivedConstants.c
includes/rts/Constants.h
includes/stg/MachRegs.h
includes/stg/Regs.h

index 180b2d7..7fc89e2 100644 (file)
@@ -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
index a02e742..1291f64 100644 (file)
@@ -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] }
index 8ac0341..67d8fd8 100644 (file)
@@ -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
index 49c900d..e6cfcb2 100644 (file)
@@ -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
index 36aae9b..211d2a8 100644 (file)
 
 #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;                                    \
     f2 = F2;                                    \
     f3 = F3;                                    \
     f4 = F4;                                    \
+    f5 = F5;                                    \
+    f6 = F6;                                    \
                                                 \
     d1 = D1;                                    \
     d2 = D2;                                    \
+    d3 = D3;                                    \
+    d4 = D4;                                    \
+    d5 = D5;                                    \
+    d6 = D6;                                    \
                                                 \
     l1 = L1;
 
     F2 = f2;                                    \
     F3 = f3;                                    \
     F4 = f4;                                    \
+    F5 = f5;                                    \
+    F6 = f6;                                    \
                                                 \
     D1 = d1;                                    \
     D2 = d2;                                    \
+    D3 = d3;                                    \
+    D4 = d4;                                    \
+    D5 = d5;                                    \
+    D6 = d6;                                    \
                                                 \
     L1 = l1;
 
index 0ba57a4..b038f82 100644 (file)
@@ -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
index 1393112..79242d9 100644 (file)
@@ -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
index 2fab041..5ff4d4e 100644 (file)
    -------------------------------------------------------------------------- */
 
 #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
index 6a70d08..8cefe9b 100644 (file)
@@ -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
 #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
 #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
 #  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).
  */
index 70e93d3..fd1577e 100644 (file)
@@ -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
+#define D6 (BaseReg->rD6)
+#endif
+
 #if defined(REG_L1) && !defined(NO_GLOBAL_REG_DECLS)
 GLOBAL_REG_DECL(StgWord64,L1,REG_L1)
 #else