RTS tidyup sweep, first phase
[ghc-hetmet.git] / compiler / nativeGen / PPC / Regs.hs
index 80c68dd..18f06ed 100644 (file)
@@ -5,6 +5,13 @@
 -- -----------------------------------------------------------------------------
 
 module PPC.Regs (
+       -- squeeze functions
+       virtualRegSqueeze,
+       realRegSqueeze,
+
+       mkVirtualReg,
+       regDotColor,
+
        -- immediates
        Imm(..),
        strImmLit,
@@ -20,7 +27,7 @@ module PPC.Regs (
        allArgRegs,
        callClobberedRegs,
        allMachRegNos,
-       regClass,
+       classOfRealReg,
        showReg,
        
        -- machine specific
@@ -42,25 +49,111 @@ where
 
 #include "nativeGen/NCG.h"
 #include "HsVersions.h"
-#include "../includes/MachRegs.h"
+#include "../includes/stg/MachRegs.h"
 
 import Reg
 import RegClass
+import Size
 
 import CgUtils          ( get_GlobalReg_addr )
 import BlockId
 import Cmm
 import CLabel           ( CLabel )
+import Unique
+
 import Pretty
-import Outputable      ( Outputable(..), pprPanic, panic )
+import Outputable       ( panic, SDoc )        
 import qualified Outputable
 import Constants
 import FastBool
+import FastTypes
 
 import Data.Word       ( Word8, Word16, Word32 )
 import Data.Int        ( Int8, Int16, Int32 )
 
 
+-- squeese functions for the graph allocator -----------------------------------
+
+-- | regSqueeze_class reg
+--     Calculuate the maximum number of register colors that could be
+--     denied to a node of this class due to having this reg 
+--     as a neighbour.
+--
+{-# INLINE virtualRegSqueeze #-}
+virtualRegSqueeze :: RegClass -> VirtualReg -> FastInt
+virtualRegSqueeze cls vr
+ = case cls of
+       RcInteger
+        -> case vr of
+               VirtualRegI{}           -> _ILIT(1)
+               VirtualRegHi{}          -> _ILIT(1)
+               VirtualRegD{}           -> _ILIT(0)
+               VirtualRegF{}           -> _ILIT(0)
+
+       -- We don't use floats on this arch, but we can't
+       --      return error because the return type is unboxed...
+       RcFloat
+        -> case vr of
+               VirtualRegI{}           -> _ILIT(0)
+               VirtualRegHi{}          -> _ILIT(0)
+               VirtualRegD{}           -> _ILIT(0)
+               VirtualRegF{}           -> _ILIT(0)
+
+       RcDouble
+        -> case vr of
+               VirtualRegI{}           -> _ILIT(0)
+               VirtualRegHi{}          -> _ILIT(0)
+               VirtualRegD{}           -> _ILIT(1)
+               VirtualRegF{}           -> _ILIT(0)
+
+
+{-# INLINE realRegSqueeze #-}
+realRegSqueeze :: RegClass -> RealReg -> FastInt
+realRegSqueeze cls rr
+ = case cls of
+       RcInteger
+        -> case rr of
+               RealRegSingle regNo
+                       | regNo < 32    -> _ILIT(1)     -- first fp reg is 32 
+                       | otherwise     -> _ILIT(0)
+                       
+               RealRegPair{}           -> _ILIT(0)
+
+       -- We don't use floats on this arch, but we can't
+       --      return error because the return type is unboxed...
+       RcFloat
+        -> case rr of
+               RealRegSingle regNo
+                       | regNo < 32    -> _ILIT(0)
+                       | otherwise     -> _ILIT(0)
+                       
+               RealRegPair{}           -> _ILIT(0)
+
+       RcDouble
+        -> case rr of
+               RealRegSingle regNo
+                       | regNo < 32    -> _ILIT(0)
+                       | otherwise     -> _ILIT(1)
+                       
+               RealRegPair{}           -> _ILIT(0)
+
+mkVirtualReg :: Unique -> Size -> VirtualReg
+mkVirtualReg u size
+   | not (isFloatSize size) = VirtualRegI u
+   | otherwise
+   = case size of
+        FF32    -> VirtualRegD u
+        FF64    -> VirtualRegD u
+        _       -> panic "mkVirtualReg"
+
+regDotColor :: RealReg -> SDoc
+regDotColor reg
+ = case classOfRealReg reg of
+        RcInteger       -> Outputable.text "blue"
+        RcFloat         -> Outputable.text "red"
+        RcDouble        -> Outputable.text "green"
+
+
 -- immediates ------------------------------------------------------------------
 data Imm
        = ImmInt        Int
@@ -138,30 +231,30 @@ spRel n   = AddrRegImm sp (ImmInt (n * wORD_SIZE))
 -- Dunno about Alpha.
 argRegs :: RegNo -> [Reg]
 argRegs 0 = []
-argRegs 1 = map RealReg [3]
-argRegs 2 = map RealReg [3,4]
-argRegs 3 = map RealReg [3..5]
-argRegs 4 = map RealReg [3..6]
-argRegs 5 = map RealReg [3..7]
-argRegs 6 = map RealReg [3..8]
-argRegs 7 = map RealReg [3..9]
-argRegs 8 = map RealReg [3..10]
+argRegs 1 = map regSingle [3]
+argRegs 2 = map regSingle [3,4]
+argRegs 3 = map regSingle [3..5]
+argRegs 4 = map regSingle [3..6]
+argRegs 5 = map regSingle [3..7]
+argRegs 6 = map regSingle [3..8]
+argRegs 7 = map regSingle [3..9]
+argRegs 8 = map regSingle [3..10]
 argRegs _ = panic "MachRegs.argRegs(powerpc): don't know about >8 arguments!"
 
 
 allArgRegs :: [Reg]
-allArgRegs = map RealReg [3..10]
+allArgRegs = map regSingle [3..10]
 
 
 -- these are the regs which we cannot assume stay alive over a C call.  
 callClobberedRegs :: [Reg]
 #if   defined(darwin_TARGET_OS)
 callClobberedRegs
-  = map RealReg (0:[2..12] ++ map fReg [0..13])
+  = map regSingle (0:[2..12] ++ map fReg [0..13])
 
 #elif defined(linux_TARGET_OS)
 callClobberedRegs
-  = map RealReg (0:[2..13] ++ map fReg [0..13])
+  = map regSingle (0:[2..13] ++ map fReg [0..13])
 
 #else
 callClobberedRegs
@@ -173,16 +266,14 @@ allMachRegNos     :: [RegNo]
 allMachRegNos  = [0..63]
 
 
-{-# INLINE regClass      #-}
-regClass :: Reg -> RegClass
-regClass (VirtualRegI  _) = RcInteger
-regClass (VirtualRegHi _) = RcInteger
-regClass (VirtualRegF  u) = pprPanic ("regClass(ppc):VirtualRegF ") (ppr u)
-regClass (VirtualRegD  _) = RcDouble
-regClass (RealReg i) 
+{-# INLINE classOfRealReg      #-}
+classOfRealReg :: RealReg -> RegClass
+classOfRealReg (RealRegSingle i)
        | i < 32        = RcInteger 
        | otherwise     = RcDouble
 
+classOfRealReg (RealRegPair{})
+       = panic "regClass(ppr): no reg pairs on this architecture"
 
 showReg :: RegNo -> String
 showReg n
@@ -196,10 +287,10 @@ showReg n
 
 allFPArgRegs :: [Reg]
 #if    defined(darwin_TARGET_OS)
-allFPArgRegs = map (RealReg . fReg) [1..13]
+allFPArgRegs = map (regSingle . fReg) [1..13]
 
 #elif  defined(linux_TARGET_OS)
-allFPArgRegs = map (RealReg . fReg) [1..8]
+allFPArgRegs = map (regSingle . fReg) [1..8]
 
 #else
 allFPArgRegs = panic "PPC.Regs.allFPArgRegs: not defined for this architecture"
@@ -240,14 +331,14 @@ fReg :: Int -> RegNo
 fReg x = (32 + x)
 
 sp, r3, r4, r27, r28, f1, f20, f21 :: Reg
-sp     = RealReg 1
-r3     = RealReg 3
-r4     = RealReg 4
-r27    = RealReg 27
-r28    = RealReg 28
-f1     = RealReg $ fReg 1
-f20    = RealReg $ fReg 20
-f21    = RealReg $ fReg 21
+sp     = regSingle 1
+r3     = regSingle 3
+r4     = regSingle 4
+r27    = regSingle 27
+r28    = regSingle 28
+f1     = regSingle $ fReg 1
+f20    = regSingle $ fReg 20
+f21    = regSingle $ fReg 21
 
 
 
@@ -436,79 +527,79 @@ freeReg _               = fastBool True
 
 
 #ifdef REG_Base
-globalRegMaybe BaseReg                 = Just (RealReg REG_Base)
+globalRegMaybe BaseReg                 = Just (regSingle REG_Base)
 #endif
 #ifdef REG_R1
-globalRegMaybe (VanillaReg 1 _)                = Just (RealReg REG_R1)
+globalRegMaybe (VanillaReg 1 _)                = Just (regSingle REG_R1)
 #endif 
 #ifdef REG_R2 
-globalRegMaybe (VanillaReg 2 _)                = Just (RealReg REG_R2)
+globalRegMaybe (VanillaReg 2 _)                = Just (regSingle REG_R2)
 #endif 
 #ifdef REG_R3 
-globalRegMaybe (VanillaReg 3 _)        = Just (RealReg REG_R3)
+globalRegMaybe (VanillaReg 3 _)        = Just (regSingle REG_R3)
 #endif 
 #ifdef REG_R4 
-globalRegMaybe (VanillaReg 4 _)                = Just (RealReg REG_R4)
+globalRegMaybe (VanillaReg 4 _)                = Just (regSingle REG_R4)
 #endif 
 #ifdef REG_R5 
-globalRegMaybe (VanillaReg 5 _)                = Just (RealReg REG_R5)
+globalRegMaybe (VanillaReg 5 _)                = Just (regSingle REG_R5)
 #endif 
 #ifdef REG_R6 
-globalRegMaybe (VanillaReg 6 _)                = Just (RealReg REG_R6)
+globalRegMaybe (VanillaReg 6 _)                = Just (regSingle REG_R6)
 #endif 
 #ifdef REG_R7 
-globalRegMaybe (VanillaReg 7 _)                = Just (RealReg REG_R7)
+globalRegMaybe (VanillaReg 7 _)                = Just (regSingle REG_R7)
 #endif 
 #ifdef REG_R8 
-globalRegMaybe (VanillaReg 8 _)                = Just (RealReg REG_R8)
+globalRegMaybe (VanillaReg 8 _)                = Just (regSingle REG_R8)
 #endif
 #ifdef REG_R9 
-globalRegMaybe (VanillaReg 9 _)                = Just (RealReg REG_R9)
+globalRegMaybe (VanillaReg 9 _)                = Just (regSingle REG_R9)
 #endif
 #ifdef REG_R10 
-globalRegMaybe (VanillaReg 10 _)       = Just (RealReg REG_R10)
+globalRegMaybe (VanillaReg 10 _)       = Just (regSingle REG_R10)
 #endif
 #ifdef REG_F1
-globalRegMaybe (FloatReg 1)            = Just (RealReg REG_F1)
+globalRegMaybe (FloatReg 1)            = Just (regSingle REG_F1)
 #endif                                 
 #ifdef REG_F2                          
-globalRegMaybe (FloatReg 2)            = Just (RealReg REG_F2)
+globalRegMaybe (FloatReg 2)            = Just (regSingle REG_F2)
 #endif                                 
 #ifdef REG_F3                          
-globalRegMaybe (FloatReg 3)            = Just (RealReg REG_F3)
+globalRegMaybe (FloatReg 3)            = Just (regSingle REG_F3)
 #endif                                 
 #ifdef REG_F4                          
-globalRegMaybe (FloatReg 4)            = Just (RealReg REG_F4)
+globalRegMaybe (FloatReg 4)            = Just (regSingle REG_F4)
 #endif                                 
 #ifdef REG_D1                          
-globalRegMaybe (DoubleReg 1)           = Just (RealReg REG_D1)
+globalRegMaybe (DoubleReg 1)           = Just (regSingle REG_D1)
 #endif                                 
 #ifdef REG_D2                          
-globalRegMaybe (DoubleReg 2)           = Just (RealReg REG_D2)
+globalRegMaybe (DoubleReg 2)           = Just (regSingle REG_D2)
 #endif
 #ifdef REG_Sp      
-globalRegMaybe Sp                      = Just (RealReg REG_Sp)
+globalRegMaybe Sp                      = Just (regSingle REG_Sp)
 #endif
 #ifdef REG_Lng1                                
-globalRegMaybe (LongReg 1)             = Just (RealReg REG_Lng1)
+globalRegMaybe (LongReg 1)             = Just (regSingle REG_Lng1)
 #endif                                 
 #ifdef REG_Lng2                                
-globalRegMaybe (LongReg 2)             = Just (RealReg REG_Lng2)
+globalRegMaybe (LongReg 2)             = Just (regSingle REG_Lng2)
 #endif
 #ifdef REG_SpLim                               
-globalRegMaybe SpLim                   = Just (RealReg REG_SpLim)
+globalRegMaybe SpLim                   = Just (regSingle REG_SpLim)
 #endif                                 
 #ifdef REG_Hp                          
-globalRegMaybe Hp                      = Just (RealReg REG_Hp)
+globalRegMaybe Hp                      = Just (regSingle REG_Hp)
 #endif                                 
 #ifdef REG_HpLim                       
-globalRegMaybe HpLim                   = Just (RealReg REG_HpLim)
+globalRegMaybe HpLim                   = Just (regSingle REG_HpLim)
 #endif                                 
 #ifdef REG_CurrentTSO                          
-globalRegMaybe CurrentTSO              = Just (RealReg REG_CurrentTSO)
+globalRegMaybe CurrentTSO              = Just (regSingle REG_CurrentTSO)
 #endif                                 
 #ifdef REG_CurrentNursery                              
-globalRegMaybe CurrentNursery          = Just (RealReg REG_CurrentNursery)
+globalRegMaybe CurrentNursery          = Just (regSingle REG_CurrentNursery)
 #endif                                 
 globalRegMaybe _                       = Nothing
 
@@ -538,7 +629,7 @@ get_GlobalReg_reg_or_addr mid
 -- allocatableRegs is allMachRegNos with the fixed-use regs removed.
 -- i.e., these are the regs for which we are prepared to allow the
 -- register allocator to attempt to map VRegs to.
-allocatableRegs :: [RegNo]
+allocatableRegs :: [RealReg]
 allocatableRegs
    = let isFree i = isFastTrue (freeReg i)
-     in  filter isFree allMachRegNos
+     in  map RealRegSingle $ filter isFree allMachRegNos