[project @ 2003-12-10 11:35:24 by wolfgang]
[ghc-hetmet.git] / ghc / compiler / nativeGen / MachRegs.lhs
index 2417cb9..b7c1680 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,29 @@ 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}
 
@@ -73,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...
+  | 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}
 
@@ -110,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
@@ -141,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
@@ -163,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}
-
-% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+#endif /* sparc */
 
-@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 -> 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}
 
 % - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -256,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
@@ -264,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
@@ -322,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: **
@@ -454,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)
@@ -472,12 +533,45 @@ 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}
 
+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
 names in the header files.  Gag me with a spoon, eh?
 \begin{code}
@@ -597,7 +691,109 @@ 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
+
+#ifdef darwin_TARGET_OS
+#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
+#else
+#define fr0  32
+#define fr1  33
+#define fr2  34
+#define fr3  35
+#define fr4  36
+#define fr5  37
+#define fr6  38
+#define fr7  39
+#define fr8  40
+#define fr9  41
+#define fr10 42
+#define fr11 43
+#define fr12 44
+#define fr13 45
+#define fr14 46
+#define fr15 47
+#define fr16 48
+#define fr17 49
+#define fr18 50
+#define fr19 51
+#define fr20 52
+#define fr21 53
+#define fr22 54
+#define fr23 55
+#define fr24 56
+#define fr25 57
+#define fr26 58
+#define fr27 59
+#define fr28 60
+#define fr29 61
+#define fr30 62
+#define fr31 63
+#endif
 #endif
 \end{code}
 
@@ -621,7 +817,6 @@ 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_L1
 baseRegOffset (LongReg _ 1#)         = OFFSET_L1
@@ -630,6 +825,7 @@ baseRegOffset Hp                 = OFFSET_Hp
 baseRegOffset HpLim                 = OFFSET_HpLim
 baseRegOffset CurrentTSO            = OFFSET_CurrentTSO
 baseRegOffset CurrentNursery        = OFFSET_CurrentNursery
+baseRegOffset HpAlloc               = OFFSET_HpAlloc
 #ifdef NCG_DEBUG
 baseRegOffset BaseReg               = panic "baseRegOffset:BaseReg"
 baseRegOffset CurCostCentre         = panic "baseRegOffset:CurCostCentre"
@@ -668,22 +864,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
@@ -691,9 +887,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
@@ -722,49 +915,49 @@ magicIdRegMaybe BaseReg                   = Just (RealReg REG_Base)
 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)
@@ -775,9 +968,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                                 
@@ -806,7 +996,8 @@ 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.
@@ -827,18 +1018,21 @@ callClobberedRegs
      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 -}
+#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 -}
+#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 -}
+#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.
@@ -860,7 +1054,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 = []
@@ -871,24 +1065,44 @@ 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}
@@ -913,11 +1127,22 @@ 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 REG_Base = fastBool False
 #endif