X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=compiler%2FnativeGen%2FPPC%2FRegs.hs;h=7a2a84b68c9020d4eed2b24f39ae886b438c7399;hb=35ce906d57d3135a749069b8bfe3e98587258e46;hp=80c68dd0969486f38233b36aa8fa7348db961eff;hpb=b04a210e26ca57242fd052f2aa91011a80b76299;p=ghc-hetmet.git diff --git a/compiler/nativeGen/PPC/Regs.hs b/compiler/nativeGen/PPC/Regs.hs index 80c68dd..7a2a84b 100644 --- a/compiler/nativeGen/PPC/Regs.hs +++ b/compiler/nativeGen/PPC/Regs.hs @@ -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 @@ -33,7 +40,6 @@ module PPC.Regs ( -- horrow show freeReg, globalRegMaybe, - get_GlobalReg_reg_or_addr, allocatableRegs ) @@ -42,25 +48,93 @@ 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 OldCmm 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) + _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 "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 ------------------------------------------------------------------ data Imm = ImmInt Int @@ -135,33 +209,32 @@ spRel n = AddrRegImm sp (ImmInt (n * wORD_SIZE)) -- argRegs is the set of regs which are read for an n-argument call to C. -- For archs which pass all args on the stack (x86), is empty. -- Sparc passes up to the first 6 args in regs. --- 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 +246,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 +267,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 +311,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 +507,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 @@ -521,24 +592,10 @@ globalRegMaybe _ = panic "PPC.Regs.globalRegMaybe: not defined" #endif /* powerpc_TARGET_ARCH */ --- We map STG registers onto appropriate CmmExprs. Either they map --- to real machine registers or stored as offsets from BaseReg. Given --- a GlobalReg, get_GlobalReg_reg_or_addr produces either the real --- register it is in, on this platform, or a CmmExpr denoting the --- address in the register table holding it. --- (See also get_GlobalReg_addr in CgUtils.) - -get_GlobalReg_reg_or_addr :: GlobalReg -> Either Reg CmmExpr -get_GlobalReg_reg_or_addr mid - = case globalRegMaybe mid of - Just rr -> Left rr - Nothing -> Right (get_GlobalReg_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