X-Git-Url: http://git.megacz.com/?p=ghc-hetmet.git;a=blobdiff_plain;f=compiler%2FnativeGen%2FPPC%2FRegs.hs;h=c39313a6f2f5bd454122b19b93d3597450358c3f;hp=d6993b210bc5b204465b547fcb9418cd829e6388;hb=f9288086f935c97812b2d80defcff38baf7b6a6c;hpb=79607e5359a381ee5f40a5dcec313f1c94105c7b diff --git a/compiler/nativeGen/PPC/Regs.hs b/compiler/nativeGen/PPC/Regs.hs index d6993b2..c39313a 100644 --- a/compiler/nativeGen/PPC/Regs.hs +++ b/compiler/nativeGen/PPC/Regs.hs @@ -5,16 +5,6 @@ -- ----------------------------------------------------------------------------- module PPC.Regs ( - -- sizes - Size(..), - intSize, - floatSize, - isFloatSize, - wordSize, - cmmTypeSize, - sizeToWidth, - mkVReg, - -- immediates Imm(..), strImmLit, @@ -42,7 +32,10 @@ module PPC.Regs ( -- horrow show freeReg, - globalRegMaybe + globalRegMaybe, + get_GlobalReg_reg_or_addr, + allocatableRegs + ) where @@ -51,78 +44,22 @@ where #include "HsVersions.h" #include "../includes/MachRegs.h" -import RegsBase +import Reg +import RegClass +import CgUtils ( get_GlobalReg_addr ) import BlockId import Cmm import CLabel ( CLabel ) import Pretty import Outputable ( Outputable(..), pprPanic, panic ) import qualified Outputable -import Unique import Constants import FastBool 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 - - -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 - | not (isFloatSize size) = VirtualRegI u - | otherwise - = case size of - FF32 -> VirtualRegD u - FF64 -> VirtualRegD u - _ -> panic "mkVReg" - - -- immediates ------------------------------------------------------------------ data Imm @@ -201,30 +138,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 @@ -238,14 +175,17 @@ 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) +regClass (RegVirtual (VirtualRegI _)) = RcInteger +regClass (RegVirtual (VirtualRegHi _)) = RcInteger +regClass (RegVirtual (VirtualRegF u)) = pprPanic ("regClass(ppc):VirtualRegF ") (ppr u) +regClass (RegVirtual (VirtualRegD _)) = RcDouble + +regClass (RegReal (RealRegSingle i)) | i < 32 = RcInteger | otherwise = RcDouble +regClass (RegReal (RealRegPair{})) + = panic "regClass(ppr): no reg pairs on this architecture" showReg :: RegNo -> String showReg n @@ -259,10 +199,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" @@ -303,14 +243,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 @@ -490,7 +430,7 @@ freeReg REG_Hp = fastBool False #ifdef REG_HpLim freeReg REG_HpLim = fastBool False #endif -freeReg n = fastBool True +freeReg _ = fastBool True -- | Returns 'Nothing' if this global register is not stored @@ -499,79 +439,79 @@ freeReg n = 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 @@ -582,3 +522,26 @@ freeReg _ = 0# 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 + = let isFree i = isFastTrue (freeReg i) + in filter isFree allMachRegNos