-- -----------------------------------------------------------------------------
module PPC.Regs (
- -- sizes
- Size(..),
- intSize,
- floatSize,
- isFloatSize,
- wordSize,
- cmmTypeSize,
- sizeToWidth,
- mkVReg,
+ -- squeeze functions
+ virtualRegSqueeze,
+ realRegSqueeze,
+
+ mkVirtualReg,
+ regDotColor,
-- immediates
Imm(..),
allArgRegs,
callClobberedRegs,
allMachRegNos,
- regClass,
+ classOfRealReg,
showReg,
-- machine specific
-- horrow show
freeReg,
- globalRegMaybe
+ globalRegMaybe,
+ allocatableRegs
+
)
where
#include "nativeGen/NCG.h"
#include "HsVersions.h"
-#include "../includes/MachRegs.h"
+#include "../includes/stg/MachRegs.h"
-import RegsBase
+import Reg
+import RegClass
+import Size
import BlockId
-import Cmm
+import OldCmm
import CLabel ( CLabel )
+import Unique
+
import Pretty
-import Outputable ( Outputable(..), pprPanic, panic )
+import Outputable ( panic, SDoc )
import qualified Outputable
-import Unique
import Constants
import FastBool
+import FastTypes
import Data.Word ( Word8, Word16, Word32 )
import Data.Int ( Int8, Int16, Int32 )
--- sizes -----------------------------------------------------------------------
--- For these three, the "size" also gives the int/float
--- distinction, because the instructions for int/float
--- differ only in their suffices
-data Size
- = II8 | II16 | II32 | II64 | FF32 | FF64 | FF80
- deriving Eq
-
-intSize, floatSize :: Width -> Size
-intSize W8 = II8
-intSize W16 = II16
-intSize W32 = II32
-intSize W64 = II64
-intSize other = pprPanic "MachInstrs.intSize" (ppr other)
-
-floatSize W32 = FF32
-floatSize W64 = FF64
-floatSize other = pprPanic "MachInstrs.intSize" (ppr other)
-
-
-isFloatSize :: Size -> Bool
-isFloatSize FF32 = True
-isFloatSize FF64 = True
-isFloatSize FF80 = True
-isFloatSize _ = False
+-- squeese functions for the graph allocator -----------------------------------
-wordSize :: Size
-wordSize = intSize wordWidth
-
-
-cmmTypeSize :: CmmType -> Size
-cmmTypeSize ty
- | isFloatType ty = floatSize (typeWidth ty)
- | otherwise = intSize (typeWidth ty)
-
-
-sizeToWidth :: Size -> Width
-sizeToWidth II8 = W8
-sizeToWidth II16 = W16
-sizeToWidth II32 = W32
-sizeToWidth II64 = W64
-sizeToWidth FF32 = W32
-sizeToWidth FF64 = W64
-sizeToWidth _ = panic "MachInstrs.sizeToWidth"
-
-
-mkVReg :: Unique -> Size -> Reg
-mkVReg u size
+-- | 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)
+ _other -> _ILIT(0)
+
+ RcDouble
+ -> case vr of
+ VirtualRegD{} -> _ILIT(1)
+ VirtualRegF{} -> _ILIT(0)
+ _other -> _ILIT(0)
+
+ _other -> _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)
+
+ RcDouble
+ -> case rr of
+ RealRegSingle regNo
+ | regNo < 32 -> _ILIT(0)
+ | otherwise -> _ILIT(1)
+
+ RealRegPair{} -> _ILIT(0)
+
+ _other -> _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 "mkVReg"
+ 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"
+ RcDoubleSSE -> Outputable.text "yellow"
-- immediates ------------------------------------------------------------------
-- 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
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
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"
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
#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
globalRegMaybe _ = panic "PPC.Regs.globalRegMaybe: not defined"
#endif /* powerpc_TARGET_ARCH */
+
+
+-- 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 :: [RealReg]
+allocatableRegs
+ = let isFree i = isFastTrue (freeReg i)
+ in map RealRegSingle $ filter isFree allMachRegNos