X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=ghc%2Fcompiler%2FnativeGen%2FMachRegs.lhs;h=20a1120cf3bb1e197bd5c48c879370139175ab57;hb=0bffc410964e1688ad80d277d53400659e697ab5;hp=5e7e586007d90428f5765e4ed1686ba168aa5bdd;hpb=418f5ec0f9775ec5c4f25f03c28b840a2ad5a5d1;p=ghc-hetmet.git diff --git a/ghc/compiler/nativeGen/MachRegs.lhs b/ghc/compiler/nativeGen/MachRegs.lhs index 5e7e586..20a1120 100644 --- a/ghc/compiler/nativeGen/MachRegs.lhs +++ b/ghc/compiler/nativeGen/MachRegs.lhs @@ -15,12 +15,12 @@ modules --- the pleasure has been foregone.) module MachRegs ( RegClass(..), regClass, - Reg(..), isRealReg, isVirtualReg, + VRegUnique(..), pprVRegUnique, getHiVRegFromLo, + Reg(..), isRealReg, isVirtualReg, getVRegUnique, allocatableRegs, argRegs, allArgRegs, callClobberedRegs, Imm(..), MachRegsAddr(..), - RegLoc(..), addrOffset, baseRegOffset, @@ -28,10 +28,10 @@ module MachRegs ( freeReg, getNewRegNCG, mkVReg, - magicIdRegMaybe, - saveLoc, + get_MagicId_reg_or_addr, + get_MagicId_addr, + get_Regtable_addr_from_offset, spRel, - stgReg, strImmLit #if alpha_TARGET_ARCH @@ -47,22 +47,31 @@ module MachRegs ( #if sparc_TARGET_ARCH , fits13Bits , fpRel, gReg, iReg, lReg, oReg, largeOffsetError - , fp, sp, g0, g1, g2, o0, f0, f6, f8, f26, f27 + , fp, sp, g0, g1, g2, o0, o1, f0, f6, f8, f26, f27 #endif +#if powerpc_TARGET_ARCH + , allFPArgRegs + , fits16Bits + , sp + , r3, r4, r27, r28 + , f1, f20, f21 +#endif ) where #include "HsVersions.h" import AbsCSyn ( MagicId(..) ) -import AbsCUtils ( magicIdPrimRep ) -import CLabel ( CLabel, mkMainRegTableLabel ) -import PrimOp ( PrimOp(..) ) +import CLabel ( CLabel, mkMainCapabilityLabel ) +import MachOp ( MachOp(..) ) import PrimRep ( PrimRep(..), isFloatingRep ) -import Stix ( StixTree(..), StixReg(..), +import Stix ( StixExpr(..), StixReg(..), getUniqueNat, returnNat, thenNat, NatM ) import Unique ( mkPseudoUnique2, Uniquable(..), Unique ) -import Outputable +import Pretty +import Outputable ( Outputable(..), pprPanic, panic ) +import qualified Outputable +import FastTypes \end{code} % - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -72,16 +81,20 @@ data Imm = ImmInt Int | ImmInteger Integer -- Sigh. | ImmCLbl CLabel -- AbstractC Label (with baggage) - | ImmLab Bool SDoc -- Simple string label (underscore-able) + | ImmLab Bool Doc -- Simple string label (underscore-able) -- Bool==True ==> in a different DLL - | ImmLit SDoc -- Simple string + | ImmLit Doc -- Simple string | ImmIndex CLabel Int | ImmFloat Rational | ImmDouble Rational IF_ARCH_sparc( | LO Imm -- Possible restrictions... | HI Imm - ,) + ,IF_ARCH_powerpc( + | LO Imm + | HI Imm + | HA Imm -- high halfword adjusted + ,)) strImmLit s = ImmLit (text s) \end{code} @@ -109,6 +122,11 @@ type Displacement = Imm | AddrRegImm Reg Imm #endif +#if powerpc_TARGET_ARCH + = AddrRegReg Reg Reg + | AddrRegImm Reg Imm +#endif + addrOffset :: MachRegsAddr -> Int -> Maybe MachRegsAddr addrOffset addr off @@ -141,6 +159,23 @@ addrOffset addr off _ -> Nothing #endif {-sparc-} +#if powerpc_TARGET_ARCH + AddrRegImm r (ImmInt n) + | fits16Bits n2 -> Just (AddrRegImm r (ImmInt n2)) + | otherwise -> Nothing + where n2 = n + off + + AddrRegImm r (ImmInteger n) + | fits16Bits n2 -> Just (AddrRegImm r (ImmInt (fromInteger n2))) + | otherwise -> Nothing + where n2 = n + toInteger off + + AddrRegReg r (RealReg 0) + | fits16Bits off -> Just (AddrRegImm r (ImmInt off)) + | otherwise -> Nothing + + _ -> Nothing +#endif {-powerpc-} ----------------- #if alpha_TARGET_ARCH @@ -163,46 +198,53 @@ largeOffsetError i "\nworkaround: use -fvia-C on this module.\n") #endif {-sparc-} + +#if powerpc_TARGET_ARCH +fits16Bits :: Integral a => a -> Bool +fits16Bits x = x >= -32768 && x < 32768 +#endif \end{code} % - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -@stgReg@: we map STG registers onto appropriate Stix Trees. First, we -handle the two constants, @STK_STUB_closure@ and @vtbl_StdUpdFrame@. -The rest are either in real machine registers or stored as offsets -from BaseReg. +@stgReg@: we map STG registers onto appropriate Stix Trees. Either +they map to real machine registers or stored as offsets from BaseReg. +Given a MagicId, get_MagicId_reg_or_addr produces either the real +register it is in, on this platform, or a StixExpr denoting the +address in the register table holding it. get_MagicId_addr always +produces the register table address for it. \begin{code} -data RegLoc = Save StixTree | Always StixTree -\end{code} - -Trees for register save locations: -\begin{code} -saveLoc :: MagicId -> StixTree - -saveLoc reg = case (stgReg reg) of {Always loc -> loc; Save loc -> loc} -\end{code} - -\begin{code} -stgReg :: MagicId -> RegLoc - -stgReg x - = case (magicIdRegMaybe x) of - Just _ -> Save nonReg - Nothing -> Always nonReg - where - offset = baseRegOffset x - - baseLoc = case (magicIdRegMaybe BaseReg) of - Just _ -> StReg (StixMagicId BaseReg) - Nothing -> StCLbl mkMainRegTableLabel - - nonReg = case x of - BaseReg -> StCLbl mkMainRegTableLabel - - _ -> StInd (magicIdPrimRep x) - (StPrim IntAddOp [baseLoc, - StInt (toInteger (offset*BYTES_PER_WORD))]) +get_MagicId_reg_or_addr :: MagicId -> Either Reg StixExpr +get_MagicId_addr :: MagicId -> StixExpr +get_Regtable_addr_from_offset :: Int -> StixExpr + +get_MagicId_reg_or_addr mid + = case magicIdRegMaybe mid of + Just rr -> Left rr + Nothing -> Right (get_MagicId_addr mid) + +get_MagicId_addr BaseReg + = -- This arch doesn't have BaseReg in a register, so we have to + -- use &MainRegTable.r instead. + StIndex PtrRep (StCLbl mkMainCapabilityLabel) + (StInt (toInteger OFFW_Capability_r)) +get_MagicId_addr mid + = get_Regtable_addr_from_offset (baseRegOffset mid) + +get_Regtable_addr_from_offset offset_in_words + = let ptr_to_RegTable + = case magicIdRegMaybe BaseReg of + Nothing + -> -- This arch doesn't have BaseReg in a register, so we have to + -- use &MainRegTable.r instead. + StIndex PtrRep (StCLbl mkMainCapabilityLabel) + (StInt (toInteger OFFW_Capability_r)) + Just _ + -> -- It's in a reg, so leave it as it is + StReg (StixMagicId BaseReg) + in + StIndex PtrRep ptr_to_RegTable (StInt (toInteger offset_in_words)) \end{code} % - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -255,6 +297,26 @@ Virtual regs can be of either class, so that info is attached. \begin{code} +data VRegUnique + = VRegUniqueLo Unique -- lower part of a split quantity + | VRegUniqueHi Unique -- upper part thereof + deriving (Eq, Ord) + +instance Show VRegUnique where + show (VRegUniqueLo u) = show u + show (VRegUniqueHi u) = "_hi_" ++ show u + +pprVRegUnique :: VRegUnique -> Outputable.SDoc +pprVRegUnique + = Outputable.text . show + +-- Determine the upper-half vreg for a 64-bit quantity on a 32-bit platform +-- when supplied with the vreg for the lower-half of the quantity. +getHiVRegFromLo (VirtualRegI (VRegUniqueLo u)) + = VirtualRegI (VRegUniqueHi u) +getHiVRegFromLo other + = pprPanic "getHiVRegFromLo" (ppr other) + data RegClass = RcInteger | RcFloat @@ -263,22 +325,29 @@ data RegClass data Reg = RealReg Int - | VirtualRegI Unique - | VirtualRegF Unique - | VirtualRegD Unique + | VirtualRegI VRegUnique + | VirtualRegF VRegUnique + | VirtualRegD VRegUnique unRealReg (RealReg i) = i unRealReg vreg = pprPanic "unRealReg on VirtualReg" (ppr vreg) +getVRegUnique :: Reg -> VRegUnique +getVRegUnique (VirtualRegI vu) = vu +getVRegUnique (VirtualRegF vu) = vu +getVRegUnique (VirtualRegD vu) = vu +getVRegUnique rreg = pprPanic "getVRegUnique on RealReg" (ppr rreg) + mkVReg :: Unique -> PrimRep -> Reg mkVReg u pk #if sparc_TARGET_ARCH = case pk of - FloatRep -> VirtualRegF u - DoubleRep -> VirtualRegD u - other -> VirtualRegI u + FloatRep -> VirtualRegF (VRegUniqueLo u) + DoubleRep -> VirtualRegD (VRegUniqueLo u) + other -> VirtualRegI (VRegUniqueLo u) #else - = if isFloatingRep pk then VirtualRegD u else VirtualRegI u + = if isFloatingRep pk then VirtualRegD (VRegUniqueLo u) + else VirtualRegI (VRegUniqueLo u) #endif isVirtualReg (RealReg _) = False @@ -321,19 +390,13 @@ instance Ord Reg where instance Show Reg where - showsPrec _ (RealReg i) = showString (showReg i) - showsPrec _ (VirtualRegI u) = showString "%vI_" . shows u - showsPrec _ (VirtualRegF u) = showString "%vF_" . shows u - showsPrec _ (VirtualRegD u) = showString "%vD_" . shows u + show (RealReg i) = showReg i + show (VirtualRegI u) = "%vI_" ++ show u + show (VirtualRegF u) = "%vF_" ++ show u + show (VirtualRegD u) = "%vD_" ++ show u instance Outputable Reg where - ppr r = text (show r) - -instance Uniquable Reg where - getUnique (RealReg i) = mkPseudoUnique2 i - getUnique (VirtualRegI u) = u - getUnique (VirtualRegF u) = u - getUnique (VirtualRegD u) = u + ppr r = Outputable.text (show r) \end{code} ** Machine-specific Reg stuff: ** @@ -372,6 +435,10 @@ Intel x86 architecture: fp registers, and 3-operand insns for them, and we translate this into real stack-based x86 fp code after register allocation. +The fp registers are all Double registers; we don't have any RcFloat class +regs. @regClass@ barfs if you give it a VirtualRegF, and mkVReg above should +never generate them. + \begin{code} #if i386_TARGET_ARCH @@ -394,8 +461,9 @@ fake5 = RealReg 13 regClass (RealReg i) = if i < 8 then RcInteger else RcDouble regClass (VirtualRegI u) = RcInteger -regClass (VirtualRegF u) = RcFloat regClass (VirtualRegD u) = RcDouble +regClass (VirtualRegF u) = pprPanic "regClass(x86):VirtualRegF" + (ppr (VirtualRegF u)) regNames = ["%eax", "%ebx", "%ecx", "%edx", "%esi", "%edi", "%ebp", "%esp", @@ -448,7 +516,7 @@ showReg n | n >= 32 && n < 64 = "%f" ++ show (n-32) | otherwise = "%unknown_sparc_real_reg_" ++ show n -g0, g1, g2, fp, sp, o0, f0, f1, f6, f8, f22, f26, f27 :: Reg +g0, g1, g2, fp, sp, o0, o1, f0, f1, f6, f8, f22, f26, f27 :: Reg f6 = RealReg (fReg 6) f8 = RealReg (fReg 8) @@ -466,33 +534,43 @@ g2 = RealReg (gReg 2) fp = RealReg (iReg 6) sp = RealReg (oReg 6) o0 = RealReg (oReg 0) +o1 = RealReg (oReg 1) f0 = RealReg (fReg 0) f1 = RealReg (fReg 1) #endif +\end{code} -------------------------------- -callClobberedRegs :: [Reg] -callClobberedRegs - = -#if alpha_TARGET_ARCH - [0, 1, 2, 3, 4, 5, 6, 7, 8, - 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, - fReg 0, fReg 1, fReg 10, fReg 11, fReg 12, fReg 13, fReg 14, fReg 15, - fReg 16, fReg 17, fReg 18, fReg 19, fReg 20, fReg 21, fReg 22, fReg 23, - fReg 24, fReg 25, fReg 26, fReg 27, fReg 28, fReg 29, fReg 30] -#endif {- alpha_TARGET_ARCH -} -#if i386_TARGET_ARCH - -- caller-saves registers - [eax,ecx,edx,fake0,fake1,fake2,fake3,fake4,fake5] -#endif {- i386_TARGET_ARCH -} -#if sparc_TARGET_ARCH - map RealReg - ( oReg 7 : - [oReg i | i <- [0..5]] ++ - [gReg i | i <- [1..7]] ++ - [fReg i | i <- [0..31]] ) -#endif {- sparc_TARGET_ARCH -} +The PowerPC has 64 registers of interest; 32 integer registers and 32 floating +point registers. +\begin{code} +#if powerpc_TARGET_ARCH +fReg :: Int -> Int +fReg x = (32 + x) + +regClass (VirtualRegI u) = RcInteger +regClass (VirtualRegF u) = RcFloat +regClass (VirtualRegD u) = RcDouble +regClass (RealReg i) | i < 32 = RcInteger + | otherwise = RcDouble + -- | i < nCG_FirstFloatReg = RcDouble + -- | otherwise = RcFloat + +showReg :: Int -> String +showReg n + | n >= 0 && n <= 31 = "%r" ++ show n + | n >= 32 && n <= 63 = "%f" ++ show (n - 32) + | otherwise = "%unknown_powerpc_real_reg_" ++ show n + +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 +#endif \end{code} Redefine the literals used for machine-registers with non-numeric @@ -614,43 +692,106 @@ names in the header files. Gag me with a spoon, eh? #define f29 61 #define f30 62 #define f31 63 +#endif +#if powerpc_TARGET_ARCH +#define r0 0 +#define r1 1 +#define r2 2 +#define r3 3 +#define r4 4 +#define r5 5 +#define r6 6 +#define r7 7 +#define r8 8 +#define r9 9 +#define r10 10 +#define r11 11 +#define r12 12 +#define r13 13 +#define r14 14 +#define r15 15 +#define r16 16 +#define r17 17 +#define r18 18 +#define r19 19 +#define r20 20 +#define r21 21 +#define r22 22 +#define r23 23 +#define r24 24 +#define r25 25 +#define r26 26 +#define r27 27 +#define r28 28 +#define r29 29 +#define r30 30 +#define r31 31 +#define f0 32 +#define f1 33 +#define f2 34 +#define f3 35 +#define f4 36 +#define f5 37 +#define f6 38 +#define f7 39 +#define f8 40 +#define f9 41 +#define f10 42 +#define f11 43 +#define f12 44 +#define f13 45 +#define f14 46 +#define f15 47 +#define f16 48 +#define f17 49 +#define f18 50 +#define f19 51 +#define f20 52 +#define f21 53 +#define f22 54 +#define f23 55 +#define f24 56 +#define f25 57 +#define f26 58 +#define f27 59 +#define f28 60 +#define f29 61 +#define f30 62 +#define f31 63 #endif \end{code} \begin{code} baseRegOffset :: MagicId -> Int -baseRegOffset (VanillaReg _ ILIT(1)) = OFFSET_R1 -baseRegOffset (VanillaReg _ ILIT(2)) = OFFSET_R2 -baseRegOffset (VanillaReg _ ILIT(3)) = OFFSET_R3 -baseRegOffset (VanillaReg _ ILIT(4)) = OFFSET_R4 -baseRegOffset (VanillaReg _ ILIT(5)) = OFFSET_R5 -baseRegOffset (VanillaReg _ ILIT(6)) = OFFSET_R6 -baseRegOffset (VanillaReg _ ILIT(7)) = OFFSET_R7 -baseRegOffset (VanillaReg _ ILIT(8)) = OFFSET_R8 -baseRegOffset (VanillaReg _ ILIT(9)) = OFFSET_R9 -baseRegOffset (VanillaReg _ ILIT(10)) = OFFSET_R10 -baseRegOffset (FloatReg ILIT(1)) = OFFSET_F1 -baseRegOffset (FloatReg ILIT(2)) = OFFSET_F2 -baseRegOffset (FloatReg ILIT(3)) = OFFSET_F3 -baseRegOffset (FloatReg ILIT(4)) = OFFSET_F4 -baseRegOffset (DoubleReg ILIT(1)) = OFFSET_D1 -baseRegOffset (DoubleReg ILIT(2)) = OFFSET_D2 +baseRegOffset (VanillaReg _ 1#) = OFFSET_R1 +baseRegOffset (VanillaReg _ 2#) = OFFSET_R2 +baseRegOffset (VanillaReg _ 3#) = OFFSET_R3 +baseRegOffset (VanillaReg _ 4#) = OFFSET_R4 +baseRegOffset (VanillaReg _ 5#) = OFFSET_R5 +baseRegOffset (VanillaReg _ 6#) = OFFSET_R6 +baseRegOffset (VanillaReg _ 7#) = OFFSET_R7 +baseRegOffset (VanillaReg _ 8#) = OFFSET_R8 +baseRegOffset (VanillaReg _ 9#) = OFFSET_R9 +baseRegOffset (VanillaReg _ 10#) = OFFSET_R10 +baseRegOffset (FloatReg 1#) = OFFSET_F1 +baseRegOffset (FloatReg 2#) = OFFSET_F2 +baseRegOffset (FloatReg 3#) = OFFSET_F3 +baseRegOffset (FloatReg 4#) = OFFSET_F4 +baseRegOffset (DoubleReg 1#) = OFFSET_D1 +baseRegOffset (DoubleReg 2#) = OFFSET_D2 baseRegOffset Sp = OFFSET_Sp -baseRegOffset Su = OFFSET_Su baseRegOffset SpLim = OFFSET_SpLim -#ifdef OFFSET_Lng1 -baseRegOffset (LongReg _ ILIT(1)) = OFFSET_Lng1 -#endif -#ifdef OFFSET_Lng2 -baseRegOffset (LongReg _ ILIT(2)) = OFFSET_Lng2 +#ifdef OFFSET_L1 +baseRegOffset (LongReg _ 1#) = OFFSET_L1 #endif baseRegOffset Hp = OFFSET_Hp baseRegOffset HpLim = OFFSET_HpLim baseRegOffset CurrentTSO = OFFSET_CurrentTSO baseRegOffset CurrentNursery = OFFSET_CurrentNursery -#ifdef DEBUG +baseRegOffset HpAlloc = OFFSET_HpAlloc +#ifdef NCG_DEBUG baseRegOffset BaseReg = panic "baseRegOffset:BaseReg" baseRegOffset CurCostCentre = panic "baseRegOffset:CurCostCentre" baseRegOffset VoidReg = panic "baseRegOffset:VoidReg" @@ -688,22 +829,22 @@ callerSaves (VanillaReg _ ILIT(7)) = True callerSaves (VanillaReg _ ILIT(8)) = True #endif #ifdef CALLER_SAVES_F1 -callerSaves (FloatReg ILIT(1)) = True +callerSaves (FloatReg 1#) = True #endif #ifdef CALLER_SAVES_F2 -callerSaves (FloatReg ILIT(2)) = True +callerSaves (FloatReg 2#) = True #endif #ifdef CALLER_SAVES_F3 -callerSaves (FloatReg ILIT(3)) = True +callerSaves (FloatReg 3#) = True #endif #ifdef CALLER_SAVES_F4 -callerSaves (FloatReg ILIT(4)) = True +callerSaves (FloatReg 4#) = True #endif #ifdef CALLER_SAVES_D1 -callerSaves (DoubleReg ILIT(1)) = True +callerSaves (DoubleReg 1#) = True #endif #ifdef CALLER_SAVES_D2 -callerSaves (DoubleReg ILIT(2)) = True +callerSaves (DoubleReg 2#) = True #endif #ifdef CALLER_SAVES_L1 callerSaves (LongReg _ ILIT(1)) = True @@ -711,9 +852,6 @@ callerSaves (LongReg _ ILIT(1)) = True #ifdef CALLER_SAVES_Sp callerSaves Sp = True #endif -#ifdef CALLER_SAVES_Su -callerSaves Su = True -#endif #ifdef CALLER_SAVES_SpLim callerSaves SpLim = True #endif @@ -739,52 +877,52 @@ magicIdRegMaybe :: MagicId -> Maybe Reg magicIdRegMaybe BaseReg = Just (RealReg REG_Base) #endif #ifdef REG_R1 -magicIdRegMaybe (VanillaReg _ ILIT(1)) = Just (RealReg REG_R1) +magicIdRegMaybe (VanillaReg _ 1#) = Just (RealReg REG_R1) #endif #ifdef REG_R2 -magicIdRegMaybe (VanillaReg _ ILIT(2)) = Just (RealReg REG_R2) +magicIdRegMaybe (VanillaReg _ 2#) = Just (RealReg REG_R2) #endif #ifdef REG_R3 -magicIdRegMaybe (VanillaReg _ ILIT(3)) = Just (RealReg REG_R3) +magicIdRegMaybe (VanillaReg _ 3#) = Just (RealReg REG_R3) #endif #ifdef REG_R4 -magicIdRegMaybe (VanillaReg _ ILIT(4)) = Just (RealReg REG_R4) +magicIdRegMaybe (VanillaReg _ 4#) = Just (RealReg REG_R4) #endif #ifdef REG_R5 -magicIdRegMaybe (VanillaReg _ ILIT(5)) = Just (RealReg REG_R5) +magicIdRegMaybe (VanillaReg _ 5#) = Just (RealReg REG_R5) #endif #ifdef REG_R6 -magicIdRegMaybe (VanillaReg _ ILIT(6)) = Just (RealReg REG_R6) +magicIdRegMaybe (VanillaReg _ 6#) = Just (RealReg REG_R6) #endif #ifdef REG_R7 -magicIdRegMaybe (VanillaReg _ ILIT(7)) = Just (RealReg REG_R7) +magicIdRegMaybe (VanillaReg _ 7#) = Just (RealReg REG_R7) #endif #ifdef REG_R8 -magicIdRegMaybe (VanillaReg _ ILIT(8)) = Just (RealReg REG_R8) +magicIdRegMaybe (VanillaReg _ 8#) = Just (RealReg REG_R8) #endif #ifdef REG_R9 -magicIdRegMaybe (VanillaReg _ ILIT(9)) = Just (RealReg REG_R9) +magicIdRegMaybe (VanillaReg _ 9#) = Just (RealReg REG_R9) #endif #ifdef REG_R10 -magicIdRegMaybe (VanillaReg _ ILIT(10)) = Just (RealReg REG_R10) +magicIdRegMaybe (VanillaReg _ 10#) = Just (RealReg REG_R10) #endif #ifdef REG_F1 -magicIdRegMaybe (FloatReg ILIT(1)) = Just (RealReg REG_F1) +magicIdRegMaybe (FloatReg 1#) = Just (RealReg REG_F1) #endif #ifdef REG_F2 -magicIdRegMaybe (FloatReg ILIT(2)) = Just (RealReg REG_F2) +magicIdRegMaybe (FloatReg 2#) = Just (RealReg REG_F2) #endif #ifdef REG_F3 -magicIdRegMaybe (FloatReg ILIT(3)) = Just (RealReg REG_F3) +magicIdRegMaybe (FloatReg 3#) = Just (RealReg REG_F3) #endif #ifdef REG_F4 -magicIdRegMaybe (FloatReg ILIT(4)) = Just (RealReg REG_F4) +magicIdRegMaybe (FloatReg 4#) = Just (RealReg REG_F4) #endif #ifdef REG_D1 -magicIdRegMaybe (DoubleReg ILIT(1)) = Just (RealReg REG_D1) +magicIdRegMaybe (DoubleReg 1#) = Just (RealReg REG_D1) #endif #ifdef REG_D2 -magicIdRegMaybe (DoubleReg ILIT(2)) = Just (RealReg REG_D2) +magicIdRegMaybe (DoubleReg 2#) = Just (RealReg REG_D2) #endif #ifdef REG_Sp magicIdRegMaybe Sp = Just (RealReg REG_Sp) @@ -795,9 +933,6 @@ magicIdRegMaybe (LongReg _ ILIT(1)) = Just (RealReg REG_Lng1) #ifdef REG_Lng2 magicIdRegMaybe (LongReg _ ILIT(2)) = Just (RealReg REG_Lng2) #endif -#ifdef REG_Su -magicIdRegMaybe Su = Just (RealReg REG_Su) -#endif #ifdef REG_SpLim magicIdRegMaybe SpLim = Just (RealReg REG_SpLim) #endif @@ -826,12 +961,43 @@ allMachRegNos IF_ARCH_sparc( ([0..31] ++ [f0,f2 .. nCG_FirstFloatReg-1] ++ [nCG_FirstFloatReg .. f31]), - ))) + IF_ARCH_powerpc([0..63], + )))) -- 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 :: [Reg] allocatableRegs - = let isFree (RealReg (I# i)) = _IS_TRUE_(freeReg i) - in filter isFree (map RealReg allMachRegNos) + = let isFree i = isFastTrue (freeReg i) + in map RealReg (filter isFree allMachRegNos) + +------------------------------- +-- these are the regs which we cannot assume stay alive over a +-- C call. +callClobberedRegs :: [Reg] +callClobberedRegs + = +#if alpha_TARGET_ARCH + [0, 1, 2, 3, 4, 5, 6, 7, 8, + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, + fReg 0, fReg 1, fReg 10, fReg 11, fReg 12, fReg 13, fReg 14, fReg 15, + fReg 16, fReg 17, fReg 18, fReg 19, fReg 20, fReg 21, fReg 22, fReg 23, + fReg 24, fReg 25, fReg 26, fReg 27, fReg 28, fReg 29, fReg 30] +#endif {- alpha_TARGET_ARCH -} +#if i386_TARGET_ARCH + -- caller-saves registers + map RealReg [eax,ecx,edx,fake0,fake1,fake2,fake3,fake4,fake5] +#endif {- i386_TARGET_ARCH -} +#if sparc_TARGET_ARCH + map RealReg + ( oReg 7 : + [oReg i | i <- [0..5]] ++ + [gReg i | i <- [1..7]] ++ + [fReg i | i <- [0..31]] ) +#endif {- sparc_TARGET_ARCH -} +#if powerpc_TARGET_ARCH + map RealReg ([0..12] ++ map fReg [0..13]) +#endif {- powerpc_TARGET_ARCH -} ------------------------------- -- argRegs is the set of regs which are read for an n-argument call to C. @@ -866,7 +1032,18 @@ argRegs 6 = map (RealReg . oReg) [0,1,2,3,4,5] argRegs _ = panic "MachRegs.argRegs(sparc): don't know about >6 arguments!" #endif {- sparc_TARGET_ARCH -} - +#if powerpc_TARGET_ARCH +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 _ = panic "MachRegs.argRegs(powerpc): don't know about >8 arguments!" +#endif {- powerpc_TARGET_ARCH -} ------------------------------- -- all of the arg regs ?? @@ -884,94 +1061,112 @@ allArgRegs = map RealReg [oReg i | i <- [0..5]] allArgRegs :: [Reg] allArgRegs = panic "MachRegs.allArgRegs(x86): should not be used!" #endif + +#if powerpc_TARGET_ARCH +allArgRegs :: [Reg] +allArgRegs = map RealReg [3..10] +allFPArgRegs :: [Reg] +allFPArgRegs = map (RealReg . fReg) [1..13] +#endif {- powerpc_TARGET_ARCH -} \end{code} \begin{code} -freeReg :: FAST_INT -> FAST_BOOL +freeReg :: Int -> FastBool #if alpha_TARGET_ARCH -freeReg ILIT(26) = _FALSE_ -- return address (ra) -freeReg ILIT(28) = _FALSE_ -- reserved for the assembler (at) -freeReg ILIT(29) = _FALSE_ -- global pointer (gp) -freeReg ILIT(30) = _FALSE_ -- stack pointer (sp) -freeReg ILIT(31) = _FALSE_ -- always zero (zeroh) -freeReg ILIT(63) = _FALSE_ -- always zero (f31) +freeReg 26 = fastBool False -- return address (ra) +freeReg 28 = fastBool False -- reserved for the assembler (at) +freeReg 29 = fastBool False -- global pointer (gp) +freeReg 30 = fastBool False -- stack pointer (sp) +freeReg 31 = fastBool False -- always zero (zeroh) +freeReg 63 = fastBool False -- always zero (f31) #endif #if i386_TARGET_ARCH -freeReg ILIT(esp) = _FALSE_ -- %esp is the C stack pointer +freeReg esp = fastBool False -- %esp is the C stack pointer #endif #if sparc_TARGET_ARCH -freeReg ILIT(g0) = _FALSE_ -- %g0 is always 0. -freeReg ILIT(g5) = _FALSE_ -- %g5 is reserved (ABI). -freeReg ILIT(g6) = _FALSE_ -- %g6 is reserved (ABI). -freeReg ILIT(g7) = _FALSE_ -- %g7 is reserved (ABI). -freeReg ILIT(i6) = _FALSE_ -- %i6 is our frame pointer. -freeReg ILIT(o6) = _FALSE_ -- %o6 is our stack pointer. -freeReg ILIT(f0) = _FALSE_ -- %f0/%f1 are the C fp return registers. -freeReg ILIT(f1) = _FALSE_ +freeReg g0 = fastBool False -- %g0 is always 0. +freeReg g5 = fastBool False -- %g5 is reserved (ABI). +freeReg g6 = fastBool False -- %g6 is reserved (ABI). +freeReg g7 = fastBool False -- %g7 is reserved (ABI). +freeReg i6 = fastBool False -- %i6 is our frame pointer. +freeReg i7 = fastBool False -- %i7 tends to have ret-addr-ish things +freeReg o6 = fastBool False -- %o6 is our stack pointer. +freeReg o7 = fastBool False -- %o7 holds ret addrs (???) +freeReg f0 = fastBool False -- %f0/%f1 are the C fp return registers. +freeReg f1 = fastBool False +#endif + +#if powerpc_TARGET_ARCH +freeReg 0 = fastBool False -- Hack: r0 can't be used in all insns, but it's actually free +freeReg 1 = fastBool False -- The Stack Pointer +#if !darwin_TARGET_OS + -- most non-darwin powerpc OSes use r2 as a TOC pointer or something like that +freeReg 2 = fastBool False +#endif #endif #ifdef REG_Base -freeReg ILIT(REG_Base) = _FALSE_ +freeReg REG_Base = fastBool False #endif #ifdef REG_R1 -freeReg ILIT(REG_R1) = _FALSE_ +freeReg REG_R1 = fastBool False #endif #ifdef REG_R2 -freeReg ILIT(REG_R2) = _FALSE_ +freeReg REG_R2 = fastBool False #endif #ifdef REG_R3 -freeReg ILIT(REG_R3) = _FALSE_ +freeReg REG_R3 = fastBool False #endif #ifdef REG_R4 -freeReg ILIT(REG_R4) = _FALSE_ +freeReg REG_R4 = fastBool False #endif #ifdef REG_R5 -freeReg ILIT(REG_R5) = _FALSE_ +freeReg REG_R5 = fastBool False #endif #ifdef REG_R6 -freeReg ILIT(REG_R6) = _FALSE_ +freeReg REG_R6 = fastBool False #endif #ifdef REG_R7 -freeReg ILIT(REG_R7) = _FALSE_ +freeReg REG_R7 = fastBool False #endif #ifdef REG_R8 -freeReg ILIT(REG_R8) = _FALSE_ +freeReg REG_R8 = fastBool False #endif #ifdef REG_F1 -freeReg ILIT(REG_F1) = _FALSE_ +freeReg REG_F1 = fastBool False #endif #ifdef REG_F2 -freeReg ILIT(REG_F2) = _FALSE_ +freeReg REG_F2 = fastBool False #endif #ifdef REG_F3 -freeReg ILIT(REG_F3) = _FALSE_ +freeReg REG_F3 = fastBool False #endif #ifdef REG_F4 -freeReg ILIT(REG_F4) = _FALSE_ +freeReg REG_F4 = fastBool False #endif #ifdef REG_D1 -freeReg ILIT(REG_D1) = _FALSE_ +freeReg REG_D1 = fastBool False #endif #ifdef REG_D2 -freeReg ILIT(REG_D2) = _FALSE_ +freeReg REG_D2 = fastBool False #endif #ifdef REG_Sp -freeReg ILIT(REG_Sp) = _FALSE_ +freeReg REG_Sp = fastBool False #endif #ifdef REG_Su -freeReg ILIT(REG_Su) = _FALSE_ +freeReg REG_Su = fastBool False #endif #ifdef REG_SpLim -freeReg ILIT(REG_SpLim) = _FALSE_ +freeReg REG_SpLim = fastBool False #endif #ifdef REG_Hp -freeReg ILIT(REG_Hp) = _FALSE_ +freeReg REG_Hp = fastBool False #endif #ifdef REG_HpLim -freeReg ILIT(REG_HpLim) = _FALSE_ +freeReg REG_HpLim = fastBool False #endif -freeReg n = _TRUE_ +freeReg n = fastBool True \end{code}