[project @ 2003-06-27 21:17:24 by simonpj]
[ghc-hetmet.git] / ghc / compiler / nativeGen / MachRegs.lhs
index 5e7e586..db202fe 100644 (file)
@@ -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,30 @@ 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 PrimRep         ( PrimRep(..), isFloatingRep )
-import Stix            ( StixTree(..), StixReg(..),
+import Stix            ( StixExpr(..), StixReg(..),
                           getUniqueNat, returnNat, thenNat, NatM )
-import Unique          ( mkPseudoUnique2, Uniquable(..), Unique )
-import Outputable
+import Unique          ( Unique )
+import Pretty
+import Outputable      ( Outputable(..), pprPanic, panic )
+import qualified Outputable
+import FastTypes
 \end{code}
 
 % - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -72,16 +80,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 +121,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
@@ -140,7 +157,24 @@ addrOffset addr off
        
       _ -> Nothing
 
-#endif {-sparc-}
+#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
@@ -162,47 +196,54 @@ largeOffsetError i
            ++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.
+#endif /* sparc */
 
-\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 -> 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 +296,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 +324,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 +389,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 +434,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 +460,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 +515,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 +533,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 +691,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 +828,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 +851,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 +876,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 +932,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 +960,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.
@@ -853,7 +1018,7 @@ 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 -}
+#endif /* alpha_TARGET_ARCH */
 
 #if sparc_TARGET_ARCH
 argRegs 0 = []
@@ -864,114 +1029,143 @@ 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 -}
-
+#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 ??
 #if alpha_TARGET_ARCH
 allArgRegs :: [(Reg, Reg)]
 allArgRegs = [(realReg i, realReg (fReg i)) | i <- [16..21]]
-#endif {- alpha_TARGET_ARCH -}
+#endif /* alpha_TARGET_ARCH */
 
 #if sparc_TARGET_ARCH
 allArgRegs :: [Reg]
 allArgRegs = map RealReg [oReg i | i <- [0..5]]
-#endif {- sparc_TARGET_ARCH -}
+#endif /* sparc_TARGET_ARCH */
 
 #if i386_TARGET_ARCH
 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}