X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=ghc%2Fcompiler%2FnativeGen%2FMachRegs.lhs;h=20a1120cf3bb1e197bd5c48c879370139175ab57;hb=0bffc410964e1688ad80d277d53400659e697ab5;hp=c30d6cf24392733c88226e98b7c9cc725ebb554a;hpb=91b4fb8d9cd5bdefb552e643df8bedab0ec2a526;p=ghc-hetmet.git diff --git a/ghc/compiler/nativeGen/MachRegs.lhs b/ghc/compiler/nativeGen/MachRegs.lhs index c30d6cf..20a1120 100644 --- a/ghc/compiler/nativeGen/MachRegs.lhs +++ b/ghc/compiler/nativeGen/MachRegs.lhs @@ -1,5 +1,5 @@ % -% (c) The AQUA Project, Glasgow University, 1996 +% (c) The AQUA Project, Glasgow University, 1996-1998 % \section[MachRegs]{Machine-specific info about registers} @@ -14,29 +14,24 @@ modules --- the pleasure has been foregone.) module MachRegs ( - Reg(..), + RegClass(..), regClass, + VRegUnique(..), pprVRegUnique, getHiVRegFromLo, + Reg(..), isRealReg, isVirtualReg, getVRegUnique, + allocatableRegs, argRegs, allArgRegs, callClobberedRegs, + Imm(..), MachRegsAddr(..), - RegLoc(..), - RegNo, addrOffset, - argRegs, baseRegOffset, - callClobberedRegs, callerSaves, - dblImmLit, - extractMappedRegNos, - freeMappedRegs, - freeReg, freeRegs, + freeReg, getNewRegNCG, - magicIdRegMaybe, - mkReg, - realReg, - reservedRegs, - saveLoc, + mkVReg, + get_MagicId_reg_or_addr, + get_MagicId_addr, + get_Regtable_addr_from_offset, spRel, - stgReg, strImmLit #if alpha_TARGET_ARCH @@ -47,32 +42,36 @@ module MachRegs ( #endif #if i386_TARGET_ARCH , eax, ebx, ecx, edx, esi, esp - , st0, st1, st2, st3, st4, st5, st6, st7 + , fake0, fake1, fake2, fake3, fake4, fake5 #endif #if sparc_TARGET_ARCH - , allArgRegs , fits13Bits - , fPair, fpRel, gReg, iReg, lReg, oReg, largeOffsetError - , fp, g0, o0, f0 + , fpRel, gReg, iReg, lReg, oReg, largeOffsetError + , 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 ) -import PrimOp ( PrimOp(..) ) -import PrimRep ( PrimRep(..) ) -import Stix ( sStLitLbl, StixTree(..), StixReg(..), - CodeSegment - ) -import Unique ( mkPseudoUnique1, mkPseudoUnique2, mkPseudoUnique3, - Uniquable(..), Unique - ) -import UniqSupply ( getUnique, returnUs, thenUs, UniqSM ) -import Outputable +import CLabel ( CLabel, mkMainCapabilityLabel ) +import MachOp ( MachOp(..) ) +import PrimRep ( PrimRep(..), isFloatingRep ) +import Stix ( StixExpr(..), StixReg(..), + getUniqueNat, returnNat, thenNat, NatM ) +import Unique ( mkPseudoUnique2, Uniquable(..), Unique ) +import Pretty +import Outputable ( Outputable(..), pprPanic, panic ) +import qualified Outputable +import FastTypes \end{code} % - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -82,19 +81,21 @@ data Imm = ImmInt Int | ImmInteger Integer -- Sigh. | ImmCLbl CLabel -- AbstractC Label (with baggage) - | ImmLab SDoc -- Simple string label (underscore-able) - | ImmLit SDoc -- Simple string + | ImmLab Bool Doc -- Simple string label (underscore-able) + -- Bool==True ==> in a different DLL + | 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) -dblImmLit r - = strImmLit ( - IF_ARCH_alpha({-prepend nothing-} - ,IF_ARCH_i386( '0' : 'd' : - ,IF_ARCH_sparc('0' : 'r' :,))) - showSDoc (rational r)) \end{code} % - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -121,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 @@ -146,13 +152,30 @@ addrOffset addr off | otherwise -> Nothing where n2 = n + toInteger off - AddrRegReg r (FixedReg ILIT(0)) + AddrRegReg r (RealReg 0) | fits13Bits off -> Just (AddrRegImm r (ImmInt off)) | otherwise -> Nothing _ -> 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,81 +186,65 @@ fits8Bits i = i >= -256 && i < 256 #endif #if sparc_TARGET_ARCH -{-# SPECIALIZE - fits13Bits :: Int -> Bool - #-} -{-# SPECIALIZE - fits13Bits :: Integer -> Bool - #-} +{-# SPECIALIZE fits13Bits :: Int -> Bool, Integer -> Bool #-} fits13Bits :: Integral a => a -> Bool fits13Bits x = x >= -4096 && x < 4096 ----------------- largeOffsetError i - = error ("ERROR: SPARC native-code generator cannot handle large offset ("++show i++");\nprobably because of large constant data structures;\nworkaround: use -fvia-C on this module.\n") + = error ("ERROR: SPARC native-code generator cannot handle large offset (" + ++show i++");\nprobably because of large constant data structures;" ++ + "\nworkaround: use -fvia-C on this module.\n") #endif {-sparc-} -\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. - -\begin{code} -data RegLoc = Save StixTree | Always StixTree +#if powerpc_TARGET_ARCH +fits16Bits :: Integral a => a -> Bool +fits16Bits x = x >= -32768 && x < 32768 +#endif \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} +@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} -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 -> sStLitLbl SLIT("MainRegTable") - - nonReg = case x of - StkStubReg -> sStLitLbl SLIT("STK_STUB_closure") - StdUpdRetVecReg -> sStLitLbl SLIT("vtbl_StdUpdFrame") - BaseReg -> sStLitLbl SLIT("MainRegTable") - -- these Hp&HpLim cases perhaps should - -- not be here for i386 (???) WDP 96/03 -#ifndef i386_TARGET_ARCH - -- Yup, Hp&HpLim are not mapped into registers for x86's at the mo, so - -- fetching Hp off BaseReg is the sensible option, since that's - -- where gcc generated code stuffs/expects it (RTBL_Hp & RTBL_HpLim). - -- SOF 97/09 - -- In fact, why use StorageMgrInfo at all? - Hp -> StInd PtrRep (sStLitLbl SLIT("StorageMgrInfo")) - HpLim -> StInd PtrRep (sStLitLbl - (_PK_ ("StorageMgrInfo+" ++ BYTES_PER_WORD_STR))) -#endif - TagReg -> StInd IntRep (StPrim IntSubOp [infoptr, - StInt (1*BYTES_PER_WORD)]) - where - r2 = VanillaReg PtrRep ILIT(2) - infoptr = case (stgReg r2) of - Always t -> t - Save _ -> StReg (StixMagicId r2) - _ -> 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} % - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -272,97 +279,124 @@ fpRel n %* * %************************************************************************ -Static Registers correspond to actual machine registers. These should -be avoided until the last possible moment. +RealRegs are machine regs which are available for allocation, in the +usual way. We know what class they are, because that's part of the +processor's architecture. -Dynamic registers are allocated on the fly, usually to represent a single -value in the abstract assembly code (i.e. dynamic registers are usually -single assignment). Ultimately, they are mapped to available machine -registers before spitting out the code. +VirtualRegs are virtual registers. The register allocator will +eventually have to map them into RealRegs, or into spill slots. +VirtualRegs are allocated on the fly, usually to represent a single +value in the abstract assembly code (i.e. dynamic registers are +usually single assignment). With the new register allocator, the +single assignment restriction isn't necessary to get correct code, +although a better register allocation will result if single assignment +is used -- because the allocator maps a VirtualReg into a single +RealReg, even if the VirtualReg has multiple live ranges. + +Virtual regs can be of either class, so that info is attached. \begin{code} -data Reg - = FixedReg FAST_INT -- A pre-allocated machine register - | MappedReg FAST_INT -- A dynamically allocated machine register +data VRegUnique + = VRegUniqueLo Unique -- lower part of a split quantity + | VRegUniqueHi Unique -- upper part thereof + deriving (Eq, Ord) - | MemoryReg Int PrimRep -- A machine "register" actually held in - -- a memory allocated table of - -- registers which didn't fit in real - -- registers. +instance Show VRegUnique where + show (VRegUniqueLo u) = show u + show (VRegUniqueHi u) = "_hi_" ++ show u - | UnmappedReg Unique PrimRep -- One of an infinite supply of registers, - -- always mapped to one of the earlier - -- two (?) before we're done. -mkReg :: Unique -> PrimRep -> Reg -mkReg = UnmappedReg +pprVRegUnique :: VRegUnique -> Outputable.SDoc +pprVRegUnique + = Outputable.text . show -getNewRegNCG :: PrimRep -> UniqSM Reg -getNewRegNCG pk - = getUnique `thenUs` \ u -> - returnUs (UnmappedReg u pk) +-- 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) -instance Text Reg where - showsPrec _ (FixedReg i) = showString "%" . shows IBOX(i) - showsPrec _ (MappedReg i) = showString "%" . shows IBOX(i) - showsPrec _ (MemoryReg i _) = showString "%M" . shows i - showsPrec _ (UnmappedReg i _) = showString "%U" . shows i +data RegClass + = RcInteger + | RcFloat + | RcDouble + deriving Eq -#ifdef DEBUG -instance Outputable Reg where - ppr r = text (show r) -#endif - -cmpReg (FixedReg i) (FixedReg i') = cmp_ihash i i' -cmpReg (MappedReg i) (MappedReg i') = cmp_ihash i i' -cmpReg (MemoryReg i _) (MemoryReg i' _) = i `compare` i' -cmpReg (UnmappedReg u _) (UnmappedReg u' _) = compare u u' -cmpReg r1 r2 - = let tag1 = tagReg r1 - tag2 = tagReg r2 - in - if tag1 _LT_ tag2 then LT else GT - where - tagReg (FixedReg _) = (ILIT(1) :: FAST_INT) - tagReg (MappedReg _) = ILIT(2) - tagReg (MemoryReg _ _) = ILIT(3) - tagReg (UnmappedReg _ _) = ILIT(4) - -cmp_ihash :: FAST_INT -> FAST_INT -> Ordering -cmp_ihash a1 a2 = if a1 _EQ_ a2 then EQ else if a1 _LT_ a2 then LT else GT +data Reg + = RealReg Int + | 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 (VRegUniqueLo u) + DoubleRep -> VirtualRegD (VRegUniqueLo u) + other -> VirtualRegI (VRegUniqueLo u) +#else + = if isFloatingRep pk then VirtualRegD (VRegUniqueLo u) + else VirtualRegI (VRegUniqueLo u) +#endif + +isVirtualReg (RealReg _) = False +isVirtualReg (VirtualRegI _) = True +isVirtualReg (VirtualRegF _) = True +isVirtualReg (VirtualRegD _) = True +isRealReg = not . isVirtualReg + +getNewRegNCG :: PrimRep -> NatM Reg +getNewRegNCG pk + = getUniqueNat `thenNat` \ u -> returnNat (mkVReg u pk) instance Eq Reg where - a == b = case (a `compare` b) of { EQ -> True; _ -> False } - a /= b = case (a `compare` b) of { EQ -> False; _ -> True } + (==) (RealReg i1) (RealReg i2) = i1 == i2 + (==) (VirtualRegI u1) (VirtualRegI u2) = u1 == u2 + (==) (VirtualRegF u1) (VirtualRegF u2) = u1 == u2 + (==) (VirtualRegD u1) (VirtualRegD u2) = u1 == u2 + (==) reg1 reg2 = False instance Ord Reg where - a <= b = case (a `compare` b) of { LT -> True; EQ -> True; GT -> False } - a < b = case (a `compare` b) of { LT -> True; EQ -> False; GT -> False } - a >= b = case (a `compare` b) of { LT -> False; EQ -> True; GT -> True } - a > b = case (a `compare` b) of { LT -> False; EQ -> False; GT -> True } - compare a b = cmpReg a b - -instance Uniquable Reg where - uniqueOf (UnmappedReg u _) = u - uniqueOf (FixedReg i) = mkPseudoUnique1 IBOX(i) - uniqueOf (MappedReg i) = mkPseudoUnique2 IBOX(i) - uniqueOf (MemoryReg i _) = mkPseudoUnique3 i -\end{code} + compare (RealReg i1) (RealReg i2) = compare i1 i2 + compare (RealReg _) (VirtualRegI _) = LT + compare (RealReg _) (VirtualRegF _) = LT + compare (RealReg _) (VirtualRegD _) = LT -\begin{code} -type RegNo = Int + compare (VirtualRegI _) (RealReg _) = GT + compare (VirtualRegI u1) (VirtualRegI u2) = compare u1 u2 + compare (VirtualRegI _) (VirtualRegF _) = LT + compare (VirtualRegI _) (VirtualRegD _) = LT + + compare (VirtualRegF _) (RealReg _) = GT + compare (VirtualRegF _) (VirtualRegI _) = GT + compare (VirtualRegF u1) (VirtualRegF u2) = compare u1 u2 + compare (VirtualRegF _) (VirtualRegD _) = LT + + compare (VirtualRegD _) (RealReg _) = GT + compare (VirtualRegD _) (VirtualRegI _) = GT + compare (VirtualRegD _) (VirtualRegF _) = GT + compare (VirtualRegD u1) (VirtualRegD u2) = compare u1 u2 -realReg :: RegNo -> Reg -realReg n@IBOX(i) - = if _IS_TRUE_(freeReg i) then MappedReg i else FixedReg i -extractMappedRegNos :: [Reg] -> [RegNo] +instance Show Reg where + show (RealReg i) = showReg i + show (VirtualRegI u) = "%vI_" ++ show u + show (VirtualRegF u) = "%vF_" ++ show u + show (VirtualRegD u) = "%vD_" ++ show u -extractMappedRegNos regs - = foldr ex [] regs - where - ex (MappedReg i) acc = IBOX(i) : acc -- we'll take it - ex _ acc = acc -- leave it out +instance Outputable Reg where + ppr r = Outputable.text (show r) \end{code} ** Machine-specific Reg stuff: ** @@ -397,31 +431,49 @@ Intel x86 architecture: - Only ebx, esi, edi and esp are available across a C call (they are callee-saves). - Registers 0-7 have 16-bit counterparts (ax, bx etc.) - Registers 0-3 have 8 bit counterparts (ah, bh etc.) -- Registers 8-15 hold extended floating point values. +- Registers 8-13 are fakes; we pretend x86 has 6 conventionally-addressable + 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 -gReg,fReg :: Int -> Int -gReg x = x -fReg x = (8 + x) - -st0, st1, st2, st3, st4, st5, st6, st7, eax, ebx, ecx, edx, esp :: Reg -eax = case (gReg 0) of { IBOX(g0) -> FixedReg g0 } -ebx = case (gReg 1) of { IBOX(g1) -> FixedReg g1 } -ecx = case (gReg 2) of { IBOX(g2) -> FixedReg g2 } -edx = case (gReg 3) of { IBOX(g3) -> FixedReg g3 } -esi = case (gReg 4) of { IBOX(g4) -> FixedReg g4 } -edi = case (gReg 5) of { IBOX(g5) -> FixedReg g5 } -ebp = case (gReg 6) of { IBOX(g6) -> FixedReg g6 } -esp = case (gReg 7) of { IBOX(g7) -> FixedReg g7 } -st0 = realReg (fReg 0) -st1 = realReg (fReg 1) -st2 = realReg (fReg 2) -st3 = realReg (fReg 3) -st4 = realReg (fReg 4) -st5 = realReg (fReg 5) -st6 = realReg (fReg 6) -st7 = realReg (fReg 7) +fake0, fake1, fake2, fake3, fake4, fake5, + eax, ebx, ecx, edx, esp, ebp, esi, edi :: Reg +eax = RealReg 0 +ebx = RealReg 1 +ecx = RealReg 2 +edx = RealReg 3 +esi = RealReg 4 +edi = RealReg 5 +ebp = RealReg 6 +esp = RealReg 7 +fake0 = RealReg 8 +fake1 = RealReg 9 +fake2 = RealReg 10 +fake3 = RealReg 11 +fake4 = RealReg 12 +fake5 = RealReg 13 + +regClass (RealReg i) = if i < 8 then RcInteger else RcDouble +regClass (VirtualRegI u) = RcInteger +regClass (VirtualRegD u) = RcDouble +regClass (VirtualRegF u) = pprPanic "regClass(x86):VirtualRegF" + (ppr (VirtualRegF u)) + +regNames + = ["%eax", "%ebx", "%ecx", "%edx", "%esi", "%edi", "%ebp", "%esp", + "%fake0", "%fake1", "%fake2", "%fake3", "%fake4", "%fake5", "%fake6"] + +showReg :: Int -> String +showReg n + = if n >= 0 && n < 14 + then regNames !! n + else "%unknown_x86_real_reg_" ++ show n #endif \end{code} @@ -431,6 +483,10 @@ floating point registers. The mapping of STG registers to SPARC machine registers is defined in StgRegs.h. We are, of course, prepared for any eventuality. +The whole fp-register pairing thing on sparcs is a huge nuisance. See +fptools/ghc/includes/MachRegs.h for a description of what's going on +here. + \begin{code} #if sparc_TARGET_ARCH @@ -441,17 +497,79 @@ lReg x = (16 + x) iReg x = (24 + x) fReg x = (32 + x) -fPair :: Reg -> Reg -fPair (FixedReg i) = FixedReg (i _ADD_ ILIT(1)) -fPair (MappedReg i) = MappedReg (i _ADD_ ILIT(1)) +nCG_FirstFloatReg :: Int +nCG_FirstFloatReg = unRealReg NCG_FirstFloatReg + +regClass (VirtualRegI u) = RcInteger +regClass (VirtualRegF u) = RcFloat +regClass (VirtualRegD u) = RcDouble +regClass (RealReg i) | i < 32 = RcInteger + | i < nCG_FirstFloatReg = RcDouble + | otherwise = RcFloat + +showReg :: Int -> String +showReg n + | n >= 0 && n < 8 = "%g" ++ show n + | n >= 8 && n < 16 = "%o" ++ show (n-8) + | n >= 16 && n < 24 = "%l" ++ show (n-16) + | n >= 24 && n < 32 = "%i" ++ show (n-24) + | n >= 32 && n < 64 = "%f" ++ show (n-32) + | otherwise = "%unknown_sparc_real_reg_" ++ show n -g0, fp, sp, o0, f0 :: Reg -g0 = case (gReg 0) of { IBOX(g0) -> FixedReg g0 } -fp = case (iReg 6) of { IBOX(i6) -> FixedReg i6 } -sp = case (oReg 6) of { IBOX(o6) -> FixedReg o6 } -o0 = realReg (oReg 0) -f0 = realReg (fReg 0) +g0, g1, g2, fp, sp, o0, o1, f0, f1, f6, f8, f22, f26, f27 :: Reg + +f6 = RealReg (fReg 6) +f8 = RealReg (fReg 8) +f22 = RealReg (fReg 22) +f26 = RealReg (fReg 26) +f27 = RealReg (fReg 27) + + +-- g0 is useful for codegen; is always zero, and writes to it vanish. +g0 = RealReg (gReg 0) +g1 = RealReg (gReg 1) +g2 = RealReg (gReg 2) + +-- FP, SP, int and float return (from C) regs. +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} + +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} @@ -501,14 +619,12 @@ names in the header files. Gag me with a spoon, eh? #define edi 5 #define ebp 6 #define esp 7 -#define st0 8 -#define st1 9 -#define st2 10 -#define st3 11 -#define st4 12 -#define st5 13 -#define st6 14 -#define st7 15 +#define fake0 8 +#define fake1 9 +#define fake2 10 +#define fake3 11 +#define fake4 12 +#define fake5 13 #endif #if sparc_TARGET_ARCH #define g0 0 @@ -543,16 +659,84 @@ names in the header files. Gag me with a spoon, eh? #define i5 29 #define i6 30 #define i7 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 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 + +#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 @@ -581,40 +765,34 @@ names in the header files. Gag me with a spoon, eh? \begin{code} baseRegOffset :: MagicId -> Int -baseRegOffset StkOReg = OFFSET_StkO -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 (FloatReg ILIT(1)) = OFFSET_Flt1 -baseRegOffset (FloatReg ILIT(2)) = OFFSET_Flt2 -baseRegOffset (FloatReg ILIT(3)) = OFFSET_Flt3 -baseRegOffset (FloatReg ILIT(4)) = OFFSET_Flt4 -baseRegOffset (DoubleReg ILIT(1)) = OFFSET_Dbl1 -baseRegOffset (DoubleReg ILIT(2)) = OFFSET_Dbl2 -#ifdef OFFSET_Lng1 -baseRegOffset (LongReg _ ILIT(1)) = OFFSET_Lng1 -#endif -#ifdef OFFSET_Lng2 -baseRegOffset (LongReg _ ILIT(2)) = OFFSET_Lng2 -#endif -baseRegOffset TagReg = OFFSET_Tag -baseRegOffset RetReg = OFFSET_Ret -baseRegOffset SpA = OFFSET_SpA -baseRegOffset SuA = OFFSET_SuA -baseRegOffset SpB = OFFSET_SpB -baseRegOffset SuB = OFFSET_SuB +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 SpLim = OFFSET_SpLim +#ifdef OFFSET_L1 +baseRegOffset (LongReg _ 1#) = OFFSET_L1 +#endif baseRegOffset Hp = OFFSET_Hp baseRegOffset HpLim = OFFSET_HpLim -baseRegOffset LivenessReg = OFFSET_Liveness -#ifdef DEBUG +baseRegOffset CurrentTSO = OFFSET_CurrentTSO +baseRegOffset CurrentNursery = OFFSET_CurrentNursery +baseRegOffset HpAlloc = OFFSET_HpAlloc +#ifdef NCG_DEBUG baseRegOffset BaseReg = panic "baseRegOffset:BaseReg" -baseRegOffset StdUpdRetVecReg = panic "baseRegOffset:StgUpdRetVecReg" -baseRegOffset StkStubReg = panic "baseRegOffset:StkStubReg" baseRegOffset CurCostCentre = panic "baseRegOffset:CurCostCentre" baseRegOffset VoidReg = panic "baseRegOffset:VoidReg" #endif @@ -626,9 +804,6 @@ callerSaves :: MagicId -> Bool #ifdef CALLER_SAVES_Base callerSaves BaseReg = True #endif -#ifdef CALLER_SAVES_StkO -callerSaves StkOReg = True -#endif #ifdef CALLER_SAVES_R1 callerSaves (VanillaReg _ ILIT(1)) = True #endif @@ -653,47 +828,32 @@ callerSaves (VanillaReg _ ILIT(7)) = True #ifdef CALLER_SAVES_R8 callerSaves (VanillaReg _ ILIT(8)) = True #endif -#ifdef CALLER_SAVES_FltReg1 -callerSaves (FloatReg ILIT(1)) = True +#ifdef CALLER_SAVES_F1 +callerSaves (FloatReg 1#) = True #endif -#ifdef CALLER_SAVES_FltReg2 -callerSaves (FloatReg ILIT(2)) = True +#ifdef CALLER_SAVES_F2 +callerSaves (FloatReg 2#) = True #endif -#ifdef CALLER_SAVES_FltReg3 -callerSaves (FloatReg ILIT(3)) = True +#ifdef CALLER_SAVES_F3 +callerSaves (FloatReg 3#) = True #endif -#ifdef CALLER_SAVES_FltReg4 -callerSaves (FloatReg ILIT(4)) = True +#ifdef CALLER_SAVES_F4 +callerSaves (FloatReg 4#) = True #endif -#ifdef CALLER_SAVES_DblReg1 -callerSaves (DoubleReg ILIT(1)) = True +#ifdef CALLER_SAVES_D1 +callerSaves (DoubleReg 1#) = True #endif -#ifdef CALLER_SAVES_DblReg2 -callerSaves (DoubleReg ILIT(2)) = True +#ifdef CALLER_SAVES_D2 +callerSaves (DoubleReg 2#) = True #endif -#ifdef CALLER_SAVES_LngReg1 +#ifdef CALLER_SAVES_L1 callerSaves (LongReg _ ILIT(1)) = True #endif -#ifdef CALLER_SAVES_LngReg2 -callerSaves (LongReg _ ILIT(2)) = True -#endif -#ifdef CALLER_SAVES_Tag -callerSaves TagReg = True -#endif -#ifdef CALLER_SAVES_Ret -callerSaves RetReg = True +#ifdef CALLER_SAVES_Sp +callerSaves Sp = True #endif -#ifdef CALLER_SAVES_SpA -callerSaves SpA = True -#endif -#ifdef CALLER_SAVES_SuA -callerSaves SuA = True -#endif -#ifdef CALLER_SAVES_SpB -callerSaves SpB = True -#endif -#ifdef CALLER_SAVES_SuB -callerSaves SuB = True +#ifdef CALLER_SAVES_SpLim +callerSaves SpLim = True #endif #ifdef CALLER_SAVES_Hp callerSaves Hp = True @@ -701,14 +861,11 @@ callerSaves Hp = True #ifdef CALLER_SAVES_HpLim callerSaves HpLim = True #endif -#ifdef CALLER_SAVES_Liveness -callerSaves LivenessReg = True +#ifdef CALLER_SAVES_CurrentTSO +callerSaves CurrentTSO = True #endif -#ifdef CALLER_SAVES_StdUpdRetVec -callerSaves StdUpdRetVecReg = True -#endif -#ifdef CALLER_SAVES_StkStub -callerSaves StkStubReg = True +#ifdef CALLER_SAVES_CurrentNursery +callerSaves CurrentNursery = True #endif callerSaves _ = False \end{code} @@ -717,140 +874,109 @@ callerSaves _ = False magicIdRegMaybe :: MagicId -> Maybe Reg #ifdef REG_Base -magicIdRegMaybe BaseReg = Just (FixedReg ILIT(REG_Base)) -#endif -#ifdef REG_StkO -magicIdRegMaybe StkOReg = Just (FixedReg ILIT(REG_StkOReg)) +magicIdRegMaybe BaseReg = Just (RealReg REG_Base) #endif #ifdef REG_R1 -magicIdRegMaybe (VanillaReg _ ILIT(1)) = Just (FixedReg ILIT(REG_R1)) +magicIdRegMaybe (VanillaReg _ 1#) = Just (RealReg REG_R1) #endif #ifdef REG_R2 -magicIdRegMaybe (VanillaReg _ ILIT(2)) = Just (FixedReg ILIT(REG_R2)) +magicIdRegMaybe (VanillaReg _ 2#) = Just (RealReg REG_R2) #endif #ifdef REG_R3 -magicIdRegMaybe (VanillaReg _ ILIT(3)) = Just (FixedReg ILIT(REG_R3)) +magicIdRegMaybe (VanillaReg _ 3#) = Just (RealReg REG_R3) #endif #ifdef REG_R4 -magicIdRegMaybe (VanillaReg _ ILIT(4)) = Just (FixedReg ILIT(REG_R4)) +magicIdRegMaybe (VanillaReg _ 4#) = Just (RealReg REG_R4) #endif #ifdef REG_R5 -magicIdRegMaybe (VanillaReg _ ILIT(5)) = Just (FixedReg ILIT(REG_R5)) +magicIdRegMaybe (VanillaReg _ 5#) = Just (RealReg REG_R5) #endif #ifdef REG_R6 -magicIdRegMaybe (VanillaReg _ ILIT(6)) = Just (FixedReg ILIT(REG_R6)) +magicIdRegMaybe (VanillaReg _ 6#) = Just (RealReg REG_R6) #endif #ifdef REG_R7 -magicIdRegMaybe (VanillaReg _ ILIT(7)) = Just (FixedReg ILIT(REG_R7)) +magicIdRegMaybe (VanillaReg _ 7#) = Just (RealReg REG_R7) #endif #ifdef REG_R8 -magicIdRegMaybe (VanillaReg _ ILIT(8)) = Just (FixedReg ILIT(REG_R8)) +magicIdRegMaybe (VanillaReg _ 8#) = Just (RealReg REG_R8) #endif -#ifdef REG_Flt1 -magicIdRegMaybe (FloatReg ILIT(1)) = Just (FixedReg ILIT(REG_Flt1)) +#ifdef REG_R9 +magicIdRegMaybe (VanillaReg _ 9#) = Just (RealReg REG_R9) +#endif +#ifdef REG_R10 +magicIdRegMaybe (VanillaReg _ 10#) = Just (RealReg REG_R10) +#endif +#ifdef REG_F1 +magicIdRegMaybe (FloatReg 1#) = Just (RealReg REG_F1) #endif -#ifdef REG_Flt2 -magicIdRegMaybe (FloatReg ILIT(2)) = Just (FixedReg ILIT(REG_Flt2)) +#ifdef REG_F2 +magicIdRegMaybe (FloatReg 2#) = Just (RealReg REG_F2) #endif -#ifdef REG_Flt3 -magicIdRegMaybe (FloatReg ILIT(3)) = Just (FixedReg ILIT(REG_Flt3)) +#ifdef REG_F3 +magicIdRegMaybe (FloatReg 3#) = Just (RealReg REG_F3) #endif -#ifdef REG_Flt4 -magicIdRegMaybe (FloatReg ILIT(4)) = Just (FixedReg ILIT(REG_Flt4)) +#ifdef REG_F4 +magicIdRegMaybe (FloatReg 4#) = Just (RealReg REG_F4) #endif -#ifdef REG_Dbl1 -magicIdRegMaybe (DoubleReg ILIT(1)) = Just (FixedReg ILIT(REG_Dbl1)) +#ifdef REG_D1 +magicIdRegMaybe (DoubleReg 1#) = Just (RealReg REG_D1) #endif -#ifdef REG_Dbl2 -magicIdRegMaybe (DoubleReg ILIT(2)) = Just (FixedReg ILIT(REG_Dbl2)) +#ifdef REG_D2 +magicIdRegMaybe (DoubleReg 2#) = Just (RealReg REG_D2) +#endif +#ifdef REG_Sp +magicIdRegMaybe Sp = Just (RealReg REG_Sp) #endif #ifdef REG_Lng1 -magicIdRegMaybe (LongReg _ ILIT(1)) = Just (FixedReg ILIT(REG_Lng1)) +magicIdRegMaybe (LongReg _ ILIT(1)) = Just (RealReg REG_Lng1) #endif #ifdef REG_Lng2 -magicIdRegMaybe (LongReg _ ILIT(2)) = Just (FixedReg ILIT(REG_Lng2)) -#endif -#ifdef REG_Tag -magicIdRegMaybe TagReg = Just (FixedReg ILIT(REG_TagReg)) -#endif -#ifdef REG_Ret -magicIdRegMaybe RetReg = Just (FixedReg ILIT(REG_Ret)) -#endif -#ifdef REG_SpA -magicIdRegMaybe SpA = Just (FixedReg ILIT(REG_SpA)) -#endif -#ifdef REG_SuA -magicIdRegMaybe SuA = Just (FixedReg ILIT(REG_SuA)) -#endif -#ifdef REG_SpB -magicIdRegMaybe SpB = Just (FixedReg ILIT(REG_SpB)) -#endif -#ifdef REG_SuB -magicIdRegMaybe SuB = Just (FixedReg ILIT(REG_SuB)) +magicIdRegMaybe (LongReg _ ILIT(2)) = Just (RealReg REG_Lng2) +#endif +#ifdef REG_SpLim +magicIdRegMaybe SpLim = Just (RealReg REG_SpLim) #endif #ifdef REG_Hp -magicIdRegMaybe Hp = Just (FixedReg ILIT(REG_Hp)) +magicIdRegMaybe Hp = Just (RealReg REG_Hp) #endif #ifdef REG_HpLim -magicIdRegMaybe HpLim = Just (FixedReg ILIT(REG_HpLim)) -#endif -#ifdef REG_Liveness -magicIdRegMaybe LivenessReg = Just (FixedReg ILIT(REG_Liveness)) +magicIdRegMaybe HpLim = Just (RealReg REG_HpLim) #endif -#ifdef REG_StdUpdRetVec -magicIdRegMaybe StdUpdRetVecReg = Just (FixedReg ILIT(REG_StdUpdRetVec)) +#ifdef REG_CurrentTSO +magicIdRegMaybe CurrentTSO = Just (RealReg REG_CurrentTSO) #endif -#ifdef REG_StkStub -magicIdRegMaybe StkStubReg = Just (FixedReg ILIT(REG_StkStub)) +#ifdef REG_CurrentNursery +magicIdRegMaybe CurrentNursery = Just (RealReg REG_CurrentNursery) #endif magicIdRegMaybe _ = Nothing \end{code} -%************************************************************************ -%* * -\subsection{Free, reserved, call-clobbered, and argument registers} -%* * -%************************************************************************ - -@freeRegs@ is the list of registers we can use in register allocation. -@freeReg@ (below) says if a particular register is free. - -With a per-instruction clobber list, we might be able to get some of -these back, but it's probably not worth the hassle. - -@callClobberedRegs@ ... the obvious. - -@argRegs@: assuming a call with N arguments, what registers will be -used to hold arguments? (NB: it doesn't know whether the arguments -are integer or floating-point...) - \begin{code} -reservedRegs :: [RegNo] -reservedRegs -#if alpha_TARGET_ARCH - = [NCG_Reserved_I1, NCG_Reserved_I2, - NCG_Reserved_F1, NCG_Reserved_F2] -#endif -#if i386_TARGET_ARCH - = [{-certainly cannot afford any!-}] -#endif -#if sparc_TARGET_ARCH - = [NCG_Reserved_I1, NCG_Reserved_I2, - NCG_Reserved_F1, NCG_Reserved_F2, - NCG_Reserved_D1, NCG_Reserved_D2] -#endif - ------------------------------- -freeRegs :: [Reg] -freeRegs - = freeMappedRegs IF_ARCH_alpha( [0..63], - IF_ARCH_i386( [0..15], - IF_ARCH_sparc( [0..63],))) +-- allMachRegs is the complete set of machine regs. +allMachRegNos :: [Int] +allMachRegNos + = IF_ARCH_alpha( [0..63], + IF_ARCH_i386( [0..13], + 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 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 - = freeMappedRegs + = #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, @@ -859,180 +985,188 @@ callClobberedRegs fReg 24, fReg 25, fReg 26, fReg 27, fReg 28, fReg 29, fReg 30] #endif {- alpha_TARGET_ARCH -} #if i386_TARGET_ARCH - [{-none-}] + -- caller-saves registers + map RealReg [eax,ecx,edx,fake0,fake1,fake2,fake3,fake4,fake5] #endif {- i386_TARGET_ARCH -} #if sparc_TARGET_ARCH - ( oReg 7 : - [oReg i | i <- [0..5]] ++ - [gReg i | i <- [1..7]] ++ - [fReg i | i <- [0..31]] ) + 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. +-- 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 :: Int -> [Reg] -argRegs 0 = [] +#if i386_TARGET_ARCH +argRegs _ = panic "MachRegs.argRegs(x86): should not be used!" +#endif + #if alpha_TARGET_ARCH +argRegs 0 = [] argRegs 1 = freeMappedRegs [16, fReg 16] argRegs 2 = freeMappedRegs [16, 17, fReg 16, fReg 17] argRegs 3 = freeMappedRegs [16, 17, 18, fReg 16, fReg 17, fReg 18] argRegs 4 = freeMappedRegs [16, 17, 18, 19, fReg 16, fReg 17, fReg 18, fReg 19] argRegs 5 = freeMappedRegs [16, 17, 18, 19, 20, fReg 16, fReg 17, fReg 18, fReg 19, fReg 20] argRegs 6 = freeMappedRegs [16, 17, 18, 19, 20, 21, fReg 16, fReg 17, fReg 18, fReg 19, fReg 20, fReg 21] +argRegs _ = panic "MachRegs.argRegs(alpha): don't know about >6 arguments!" #endif {- alpha_TARGET_ARCH -} -#if i386_TARGET_ARCH -argRegs _ = panic "MachRegs.argRegs: doesn't work on I386" -#endif {- i386_TARGET_ARCH -} + #if sparc_TARGET_ARCH -argRegs 1 = freeMappedRegs (map oReg [0]) -argRegs 2 = freeMappedRegs (map oReg [0,1]) -argRegs 3 = freeMappedRegs (map oReg [0,1,2]) -argRegs 4 = freeMappedRegs (map oReg [0,1,2,3]) -argRegs 5 = freeMappedRegs (map oReg [0,1,2,3,4]) -argRegs 6 = freeMappedRegs (map oReg [0,1,2,3,4,5]) +argRegs 0 = [] +argRegs 1 = map (RealReg . oReg) [0] +argRegs 2 = map (RealReg . oReg) [0,1] +argRegs 3 = map (RealReg . oReg) [0,1,2] +argRegs 4 = map (RealReg . oReg) [0,1,2,3] +argRegs 5 = map (RealReg . oReg) [0,1,2,3,4] +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 -} -argRegs _ = panic "MachRegs.argRegs: don't know about >6 arguments!" -------------------------------- +#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 ?? #if alpha_TARGET_ARCH allArgRegs :: [(Reg, Reg)] - allArgRegs = [(realReg i, realReg (fReg i)) | i <- [16..21]] #endif {- alpha_TARGET_ARCH -} #if sparc_TARGET_ARCH allArgRegs :: [Reg] - -allArgRegs = map realReg [oReg i | i <- [0..5]] +allArgRegs = map RealReg [oReg i | i <- [0..5]] #endif {- sparc_TARGET_ARCH -} -------------------------------- -freeMappedRegs :: [Int] -> [Reg] +#if i386_TARGET_ARCH +allArgRegs :: [Reg] +allArgRegs = panic "MachRegs.allArgRegs(x86): should not be used!" +#endif -freeMappedRegs nums - = foldr free [] nums - where - free IBOX(i) acc - = if _IS_TRUE_(freeReg i) then (MappedReg i) : acc else acc +#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 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 -#ifdef REG_Base -freeReg ILIT(REG_Base) = _FALSE_ +#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_StkO -freeReg ILIT(REG_StkO) = _FALSE_ + +#ifdef REG_Base +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_Flt1 -freeReg ILIT(REG_Flt1) = _FALSE_ +#ifdef REG_F1 +freeReg REG_F1 = fastBool False #endif -#ifdef REG_Flt2 -freeReg ILIT(REG_Flt2) = _FALSE_ +#ifdef REG_F2 +freeReg REG_F2 = fastBool False #endif -#ifdef REG_Flt3 -freeReg ILIT(REG_Flt3) = _FALSE_ +#ifdef REG_F3 +freeReg REG_F3 = fastBool False #endif -#ifdef REG_Flt4 -freeReg ILIT(REG_Flt4) = _FALSE_ +#ifdef REG_F4 +freeReg REG_F4 = fastBool False #endif -#ifdef REG_Dbl1 -freeReg ILIT(REG_Dbl1) = _FALSE_ +#ifdef REG_D1 +freeReg REG_D1 = fastBool False #endif -#ifdef REG_Dbl2 -freeReg ILIT(REG_Dbl2) = _FALSE_ +#ifdef REG_D2 +freeReg REG_D2 = fastBool False #endif -#ifdef REG_Tag -freeReg ILIT(REG_Tag) = _FALSE_ -#endif -#ifdef REG_Ret -freeReg ILIT(REG_Ret) = _FALSE_ -#endif -#ifdef REG_SpA -freeReg ILIT(REG_SpA) = _FALSE_ -#endif -#ifdef REG_SuA -freeReg ILIT(REG_SuA) = _FALSE_ +#ifdef REG_Sp +freeReg REG_Sp = fastBool False #endif -#ifdef REG_SpB -freeReg ILIT(REG_SpB) = _FALSE_ +#ifdef REG_Su +freeReg REG_Su = fastBool False #endif -#ifdef REG_SuB -freeReg ILIT(REG_SuB) = _FALSE_ +#ifdef REG_SpLim +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_ -#endif -#ifdef REG_Liveness -freeReg ILIT(REG_Liveness) = _FALSE_ -#endif -#ifdef REG_StdUpdRetVec -freeReg ILIT(REG_StdUpdRetVec) = _FALSE_ -#endif -#ifdef REG_StkStub -freeReg ILIT(REG_StkStub) = _FALSE_ -#endif -freeReg _ = _TRUE_ -freeReg n - -- we hang onto two double regs for dedicated - -- use; this is not necessary on Alphas and - -- may not be on other non-SPARCs. -#ifdef REG_Dbl1 - | n _EQ_ (ILIT(REG_Dbl1) _ADD_ ILIT(1)) = _FALSE_ -#endif -#ifdef REG_Dbl2 - | n _EQ_ (ILIT(REG_Dbl2) _ADD_ ILIT(1)) = _FALSE_ +freeReg REG_HpLim = fastBool False #endif - | otherwise = _TRUE_ +freeReg n = fastBool True \end{code}