module MachRegs (
RegClass(..), regClass,
- Reg(..), isRealReg, isVirtualReg,
+ VRegUnique(..), pprVRegUnique, getHiVRegFromLo,
+ Reg(..), isRealReg, isVirtualReg, getVRegUnique,
allocatableRegs, argRegs, allArgRegs, callClobberedRegs,
Imm(..),
MachRegsAddr(..),
- RegLoc(..),
addrOffset,
baseRegOffset,
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
#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}
% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
= 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}
| AddrRegImm Reg Imm
#endif
+#if powerpc_TARGET_ARCH
+ = AddrRegReg Reg Reg
+ | AddrRegImm Reg Imm
+#endif
+
addrOffset :: MachRegsAddr -> Int -> Maybe MachRegsAddr
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
"\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}
% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\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
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
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: **
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
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",
| 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)
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
#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"
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
#ifdef CALLER_SAVES_Sp
callerSaves Sp = True
#endif
-#ifdef CALLER_SAVES_Su
-callerSaves Su = True
-#endif
#ifdef CALLER_SAVES_SpLim
callerSaves SpLim = True
#endif
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)
#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
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.
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 ??
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}