[project @ 2000-10-24 10:12:16 by sewardj]
[ghc-hetmet.git] / ghc / compiler / nativeGen / MachRegs.lhs
index 13897a8..f54401e 100644 (file)
@@ -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}
 
@@ -10,31 +10,25 @@ often/usually quite entangled with registers.
 modules --- the pleasure has been foregone.)
 
 \begin{code}
-#include "HsVersions.h"
 #include "nativeGen/NCG.h"
 
 module MachRegs (
 
-       Reg(..),
+        RegClass(..), regClass,
+       Reg(..), isRealReg, isVirtualReg,
+        allocatableRegs, argRegs, allArgRegs, callClobberedRegs,
+
        Imm(..),
-       Addr(..),
+       MachRegsAddr(..),
        RegLoc(..),
-       SYN_IE(RegNo),
 
        addrOffset,
-       argRegs,
        baseRegOffset,
-       callClobberedRegs,
        callerSaves,
-       dblImmLit,
-       extractMappedRegNos,
-       freeMappedRegs,
-       freeReg, freeRegs,
+       freeReg,
        getNewRegNCG,
+       mkVReg,
        magicIdRegMaybe,
-       mkReg,
-       realReg,
-       reservedRegs,
        saveLoc,
        spRel,
        stgReg,
@@ -48,39 +42,28 @@ 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, f0, f6, f8, f26, f27
        
 #endif
     ) where
 
-#if __GLASGOW_HASKELL__ >= 202
-import GlaExts hiding (Addr)
-import FastString
-#else
-IMP_Ubiq(){-uitous-}
-#endif
+#include "HsVersions.h"
 
 import AbsCSyn         ( MagicId(..) )
 import AbsCUtils       ( magicIdPrimRep )
-import CLabel           ( CLabel )
-import Outputable       ( Outputable(..) )
-import Pretty          ( Doc, text, rational )
+import CLabel           ( CLabel, mkMainRegTableLabel )
 import PrimOp          ( PrimOp(..) )
-import PrimRep         ( PrimRep(..) )
-import Stix            ( sStLitLbl, StixTree(..), StixReg(..),
-                         CodeSegment
-                       )
-import Unique          ( mkPseudoUnique1, mkPseudoUnique2, mkPseudoUnique3,
-                         Unique{-instance Ord3-}, Uniquable(..)
-                       )
-import UniqSupply      ( getUnique, returnUs, thenUs, SYN_IE(UniqSM) )
-import Util            ( panic, Ord3(..) )
+import PrimRep         ( PrimRep(..), isFloatingRep )
+import Stix            ( StixTree(..), StixReg(..),
+                          getUniqueNat, returnNat, thenNat, NatM )
+import Unique          ( mkPseudoUnique2, Uniquable(..), Unique )
+import Outputable
+import FastTypes
 \end{code}
 
 % - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -90,26 +73,23 @@ data Imm
   = ImmInt     Int
   | ImmInteger Integer     -- Sigh.
   | ImmCLbl    CLabel      -- AbstractC Label (with baggage)
-  | ImmLab     Doc    -- Simple string label (underscore-able)
-  | ImmLit     Doc    -- Simple string
+  | ImmLab     Bool SDoc    -- Simple string label (underscore-able)
+                             -- Bool==True ==> in a different DLL
+  | ImmLit     SDoc    -- Simple string
+  | ImmIndex    CLabel Int
+  | ImmFloat   Rational
+  | ImmDouble  Rational
   IF_ARCH_sparc(
   | LO Imm                 -- Possible restrictions...
   | HI Imm
   ,)
-
 strImmLit s = ImmLit (text s)
-dblImmLit r
-  = strImmLit (
-        IF_ARCH_alpha({-prepend nothing-}
-       ,IF_ARCH_i386( '0' : 'd' :
-       ,IF_ARCH_sparc('0' : 'r' :,)))
-       show (rational r))
 \end{code}
 
 % - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
 \begin{code}
-data Addr
+data MachRegsAddr
 #if alpha_TARGET_ARCH
   = AddrImm    Imm
   | AddrReg    Reg
@@ -117,8 +97,8 @@ data Addr
 #endif
 
 #if i386_TARGET_ARCH
-  = Addr       Base Index Displacement
-  | ImmAddr    Imm Int
+  = AddrBaseIndex      Base Index Displacement
+  | ImmAddr            Imm Int
 
 type Base         = Maybe Reg
 type Index        = Maybe (Reg, Int)   -- Int is 2, 4 or 8
@@ -130,7 +110,7 @@ type Displacement = Imm
   | AddrRegImm Reg Imm
 #endif
 
-addrOffset :: Addr -> Int -> Maybe Addr
+addrOffset :: MachRegsAddr -> Int -> Maybe MachRegsAddr
 
 addrOffset addr off
   = case addr of
@@ -139,9 +119,9 @@ addrOffset addr off
 #endif
 #if i386_TARGET_ARCH
       ImmAddr i off0     -> Just (ImmAddr i (off0 + off))
-      Addr r i (ImmInt n) -> Just (Addr r i (ImmInt (n + off)))
-      Addr r i (ImmInteger n)
-       -> Just (Addr r i (ImmInt (fromInteger (n + toInteger off))))
+      AddrBaseIndex r i (ImmInt n) -> Just (AddrBaseIndex r i (ImmInt (n + off)))
+      AddrBaseIndex r i (ImmInteger n)
+       -> Just (AddrBaseIndex r i (ImmInt (fromInteger (n + toInteger off))))
       _ -> Nothing
 #endif
 #if sparc_TARGET_ARCH
@@ -155,7 +135,7 @@ 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
        
@@ -172,19 +152,16 @@ 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}
@@ -219,24 +196,11 @@ stgReg x
 
     baseLoc = case (magicIdRegMaybe BaseReg) of
       Just _  -> StReg (StixMagicId BaseReg)
-      Nothing -> sStLitLbl SLIT("MainRegTable")
+      Nothing -> StCLbl mkMainRegTableLabel
 
     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
-      Hp               -> StInd PtrRep (sStLitLbl SLIT("StorageMgrInfo"))
-      HpLim            -> StInd PtrRep (sStLitLbl
-                               (_PK_ ("StorageMgrInfo+" ++ BYTES_PER_WORD_STR)))
-      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)
+      BaseReg -> StCLbl mkMainRegTableLabel
+
       _ -> StInd (magicIdPrimRep x)
                 (StPrim IntAddOp [baseLoc,
                        StInt (toInteger (offset*BYTES_PER_WORD))])
@@ -250,17 +214,17 @@ applicable, is the same but for the frame pointer.
 
 \begin{code}
 spRel :: Int   -- desired stack offset in words, positive or negative
-      -> Addr
+      -> MachRegsAddr
 
 spRel n
 #if i386_TARGET_ARCH
-  = Addr (Just esp) Nothing (ImmInt (n * BYTES_PER_WORD))
+  = AddrBaseIndex (Just esp) Nothing (ImmInt (n * BYTES_PER_WORD))
 #else
   = AddrRegImm sp (ImmInt (n * BYTES_PER_WORD))
 #endif
 
 #if sparc_TARGET_ARCH
-fpRel :: Int -> Addr
+fpRel :: Int -> MachRegsAddr
     -- Duznae work for offsets greater than 13 bits; we just hope for
     -- the best
 fpRel n
@@ -274,104 +238,103 @@ fpRel n
 %*                                                                     *
 %************************************************************************
 
-Static Registers correspond to actual machine registers.  These should
-be avoided until the last possible moment.
-
-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.
+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.
 
-\begin{code}
-data Reg
-  = FixedReg  FAST_INT         -- A pre-allocated machine register
+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.
 
-  | MappedReg FAST_INT         -- A dynamically allocated machine register
+Virtual regs can be of either class, so that info is attached.
 
-  | MemoryReg Int PrimRep      -- A machine "register" actually held in
-                               -- a memory allocated table of
-                               -- registers which didn't fit in real
-                               -- registers.
-
-  | UnmappedReg Unique PrimRep -- One of an infinite supply of registers,
-                               -- always mapped to one of the earlier
-                               -- two (?)  before we're done.
+\begin{code}
 
-mkReg :: Unique -> PrimRep -> Reg
-mkReg = UnmappedReg
+data RegClass 
+   = RcInteger 
+   | RcFloat
+   | RcDouble
+     deriving Eq
 
-getNewRegNCG :: PrimRep -> UniqSM Reg
-getNewRegNCG pk
-  = getUnique  `thenUs` \ u ->
-    returnUs (UnmappedReg u pk)
+data Reg
+   = RealReg     Int
+   | VirtualRegI Unique
+   | VirtualRegF Unique
+   | VirtualRegD Unique
 
-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
+unRealReg (RealReg i) = i
+unRealReg vreg        = pprPanic "unRealReg on VirtualReg" (ppr vreg)
 
-#ifdef DEBUG
-instance Outputable Reg where
-    ppr sty r = text (show r)
+mkVReg :: Unique -> PrimRep -> Reg
+mkVReg u pk
+#if sparc_TARGET_ARCH
+   = case pk of
+        FloatRep  -> VirtualRegF u
+        DoubleRep -> VirtualRegD u
+        other     -> VirtualRegI u
+#else
+   = if isFloatingRep pk then VirtualRegD u else VirtualRegI u
 #endif
 
-cmpReg (FixedReg i)      (FixedReg i')      = cmp_ihash i i'
-cmpReg (MappedReg i)     (MappedReg i')     = cmp_ihash i i'
-cmpReg (MemoryReg i _)   (MemoryReg i' _)   = cmp_i i i'
-cmpReg (UnmappedReg u _) (UnmappedReg u' _) = cmp 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)
+isVirtualReg (RealReg _)     = False
+isVirtualReg (VirtualRegI _) = True
+isVirtualReg (VirtualRegF _) = True
+isVirtualReg (VirtualRegD _) = True
+isRealReg = not . isVirtualReg
 
-cmp_i :: Int -> Int -> TAG_
-cmp_i a1 a2 = if a1 == a2 then EQ_ else if a1 < a2 then LT_ else GT_
-
-cmp_ihash :: FAST_INT -> FAST_INT -> TAG_
-cmp_ihash a1 a2 = if a1 _EQ_ a2 then EQ_ else if a1 _LT_ a2 then LT_ else GT_
-
-instance Ord3 Reg where
-    cmp = cmpReg
+getNewRegNCG :: PrimRep -> NatM Reg
+getNewRegNCG pk
+   = getUniqueNat `thenNat` \ u -> returnNat (mkVReg u pk)
 
 instance Eq Reg where
-    a == b = case (a `cmp` b) of { EQ_ -> True;  _ -> False }
-    a /= b = case (a `cmp` 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 `cmp` b) of { LT_ -> True;        EQ_ -> True;  GT__ -> False }
-    a <         b = case (a `cmp` b) of { LT_ -> True; EQ_ -> False; GT__ -> False }
-    a >= b = case (a `cmp` b) of { LT_ -> False; EQ_ -> True;  GT__ -> True  }
-    a >         b = case (a `cmp` b) of { LT_ -> False; EQ_ -> False; GT__ -> True  }
-    _tagCmp a b = case (a `cmp` b) of { LT_ -> _LT; EQ_ -> _EQ; GT__ -> _GT }
+   compare (RealReg i1)     (RealReg i2)     = compare i1 i2
+   compare (RealReg _)      (VirtualRegI _)  = LT
+   compare (RealReg _)      (VirtualRegF _)  = LT
+   compare (RealReg _)      (VirtualRegD _)  = LT
 
-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 (VirtualRegI _)  (RealReg _)      = GT
+   compare (VirtualRegI u1) (VirtualRegI u2) = compare u1 u2
+   compare (VirtualRegI _)  (VirtualRegF _)  = LT
+   compare (VirtualRegI _)  (VirtualRegD _)  = LT
 
-\begin{code}
-type RegNo = Int
+   compare (VirtualRegF _)  (RealReg _)      = GT
+   compare (VirtualRegF _)  (VirtualRegI _)  = GT
+   compare (VirtualRegF u1) (VirtualRegF u2) = compare u1 u2
+   compare (VirtualRegF _)  (VirtualRegD _)  = LT
 
-realReg :: RegNo -> Reg
-realReg n@IBOX(i)
-  = if _IS_TRUE_(freeReg i) then MappedReg i else FixedReg i
+   compare (VirtualRegD _)  (RealReg _)      = GT
+   compare (VirtualRegD _)  (VirtualRegI _)  = GT
+   compare (VirtualRegD _)  (VirtualRegF _)  = GT
+   compare (VirtualRegD u1) (VirtualRegD u2) = compare u1 u2
 
-extractMappedRegNos :: [Reg] -> [RegNo]
 
-extractMappedRegNos regs
-  = foldr ex [] regs
-  where
-    ex (MappedReg i) acc = IBOX(i) : acc  -- we'll take it
-    ex _            acc = acc            -- leave it out
+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
+
+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
 \end{code}
 
 ** Machine-specific Reg stuff: **
@@ -406,31 +369,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}
@@ -440,6 +421,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
 
@@ -450,16 +435,45 @@ 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, 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)
+f0  = RealReg (fReg 0)
+f1  = RealReg (fReg 1)
 
 #endif
 \end{code}
@@ -510,14 +524,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
@@ -552,16 +564,17 @@ 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
@@ -584,40 +597,44 @@ names in the header files.  Gag me with a spoon, eh?
 #define f29 61
 #define f30 62
 #define f31 63
+
 #endif
 \end{code}
 
 \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
-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 Su                    = OFFSET_Su
+baseRegOffset SpLim                 = OFFSET_SpLim
+#ifdef OFFSET_Lng1
+baseRegOffset (LongReg _ 1))         = OFFSET_Lng1
+#endif
+#ifdef OFFSET_Lng2
+baseRegOffset (LongReg _ 2))         = OFFSET_Lng2
+#endif
 baseRegOffset Hp                    = OFFSET_Hp
 baseRegOffset HpLim                 = OFFSET_HpLim
-baseRegOffset LivenessReg           = OFFSET_Liveness
-#ifdef DEBUG
+baseRegOffset CurrentTSO            = OFFSET_CurrentTSO
+baseRegOffset CurrentNursery        = OFFSET_CurrentNursery
+#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
@@ -629,9 +646,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
@@ -656,41 +670,35 @@ callerSaves (VanillaReg _ ILIT(7))        = True
 #ifdef CALLER_SAVES_R8
 callerSaves (VanillaReg _ ILIT(8))     = True
 #endif
-#ifdef CALLER_SAVES_FltReg1
+#ifdef CALLER_SAVES_F1
 callerSaves (FloatReg ILIT(1))         = True
 #endif
-#ifdef CALLER_SAVES_FltReg2
+#ifdef CALLER_SAVES_F2
 callerSaves (FloatReg ILIT(2))         = True
 #endif
-#ifdef CALLER_SAVES_FltReg3
+#ifdef CALLER_SAVES_F3
 callerSaves (FloatReg ILIT(3))         = True
 #endif
-#ifdef CALLER_SAVES_FltReg4
+#ifdef CALLER_SAVES_F4
 callerSaves (FloatReg ILIT(4))         = True
 #endif
-#ifdef CALLER_SAVES_DblReg1
+#ifdef CALLER_SAVES_D1
 callerSaves (DoubleReg ILIT(1))                = True
 #endif
-#ifdef CALLER_SAVES_DblReg2
+#ifdef CALLER_SAVES_D2
 callerSaves (DoubleReg ILIT(2))                = True
 #endif
-#ifdef CALLER_SAVES_Tag
-callerSaves TagReg                     = True
-#endif
-#ifdef CALLER_SAVES_Ret
-callerSaves RetReg                     = True
-#endif
-#ifdef CALLER_SAVES_SpA
-callerSaves SpA                                = True
+#ifdef CALLER_SAVES_L1
+callerSaves (LongReg _ ILIT(1))                = True
 #endif
-#ifdef CALLER_SAVES_SuA
-callerSaves SuA                                = True
+#ifdef CALLER_SAVES_Sp
+callerSaves Sp                         = True
 #endif
-#ifdef CALLER_SAVES_SpB
-callerSaves SpB                                = True
+#ifdef CALLER_SAVES_Su
+callerSaves Su                         = True
 #endif
-#ifdef CALLER_SAVES_SuB
-callerSaves SuB                                = True
+#ifdef CALLER_SAVES_SpLim
+callerSaves SpLim                      = True
 #endif
 #ifdef CALLER_SAVES_Hp
 callerSaves Hp                         = True
@@ -698,14 +706,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}
@@ -714,134 +719,111 @@ 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 _ ILIT(2))         = Just (RealReg REG_R2)
 #endif 
 #ifdef REG_R3 
-magicIdRegMaybe (VanillaReg _ ILIT(3))         = Just (FixedReg ILIT(REG_R3))
+magicIdRegMaybe (VanillaReg _ ILIT(3))         = Just (RealReg REG_R3)
 #endif 
 #ifdef REG_R4 
-magicIdRegMaybe (VanillaReg _ ILIT(4))         = Just (FixedReg ILIT(REG_R4))
+magicIdRegMaybe (VanillaReg _ ILIT(4))         = Just (RealReg REG_R4)
 #endif 
 #ifdef REG_R5 
-magicIdRegMaybe (VanillaReg _ ILIT(5))         = Just (FixedReg ILIT(REG_R5))
+magicIdRegMaybe (VanillaReg _ ILIT(5))         = Just (RealReg REG_R5)
 #endif 
 #ifdef REG_R6 
-magicIdRegMaybe (VanillaReg _ ILIT(6))         = Just (FixedReg ILIT(REG_R6))
+magicIdRegMaybe (VanillaReg _ ILIT(6))         = Just (RealReg REG_R6)
 #endif 
 #ifdef REG_R7 
-magicIdRegMaybe (VanillaReg _ ILIT(7))         = Just (FixedReg ILIT(REG_R7))
+magicIdRegMaybe (VanillaReg _ ILIT(7))         = Just (RealReg REG_R7)
 #endif 
 #ifdef REG_R8 
-magicIdRegMaybe (VanillaReg _ ILIT(8))         = Just (FixedReg ILIT(REG_R8))
+magicIdRegMaybe (VanillaReg _ ILIT(8))         = Just (RealReg REG_R8)
+#endif
+#ifdef REG_R9 
+magicIdRegMaybe (VanillaReg _ ILIT(9))         = Just (RealReg REG_R9)
+#endif
+#ifdef REG_R10 
+magicIdRegMaybe (VanillaReg _ ILIT(10))        = Just (RealReg REG_R10)
 #endif
-#ifdef REG_Flt1
-magicIdRegMaybe (FloatReg ILIT(1))     = Just (FixedReg ILIT(REG_Flt1))
+#ifdef REG_F1
+magicIdRegMaybe (FloatReg ILIT(1))     = Just (RealReg REG_F1)
 #endif                                 
-#ifdef REG_Flt2                                
-magicIdRegMaybe (FloatReg ILIT(2))     = Just (FixedReg ILIT(REG_Flt2))
+#ifdef REG_F2                          
+magicIdRegMaybe (FloatReg ILIT(2))     = Just (RealReg REG_F2)
 #endif                                 
-#ifdef REG_Flt3                                
-magicIdRegMaybe (FloatReg ILIT(3))     = Just (FixedReg ILIT(REG_Flt3))
+#ifdef REG_F3                          
+magicIdRegMaybe (FloatReg ILIT(3))     = Just (RealReg REG_F3)
 #endif                                 
-#ifdef REG_Flt4                                
-magicIdRegMaybe (FloatReg ILIT(4))     = Just (FixedReg ILIT(REG_Flt4))
+#ifdef REG_F4                          
+magicIdRegMaybe (FloatReg ILIT(4))     = Just (RealReg REG_F4)
 #endif                                 
-#ifdef REG_Dbl1                                
-magicIdRegMaybe (DoubleReg ILIT(1))    = Just (FixedReg ILIT(REG_Dbl1))
+#ifdef REG_D1                          
+magicIdRegMaybe (DoubleReg ILIT(1))    = Just (RealReg REG_D1)
 #endif                                 
-#ifdef REG_Dbl2                                
-magicIdRegMaybe (DoubleReg ILIT(2))    = Just (FixedReg ILIT(REG_Dbl2))
-#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))
+#ifdef REG_D2                          
+magicIdRegMaybe (DoubleReg ILIT(2))    = Just (RealReg REG_D2)
+#endif
+#ifdef REG_Sp      
+magicIdRegMaybe Sp                     = Just (RealReg REG_Sp)
+#endif
+#ifdef REG_Lng1                                
+magicIdRegMaybe (LongReg _ ILIT(1))    = Just (RealReg REG_Lng1)
+#endif                                 
+#ifdef REG_Lng2                                
+magicIdRegMaybe (LongReg _ ILIT(2))    = Just (RealReg REG_Lng2)
+#endif
+#ifdef REG_Su                          
+magicIdRegMaybe Su                     = Just (RealReg REG_Su)
 #endif                                 
-#ifdef REG_SuB                         
-magicIdRegMaybe SuB                    = Just (FixedReg ILIT(REG_SuB))
+#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]),
+                   )))
+-- 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 = _IS_TRUE_(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,
@@ -850,180 +832,154 @@ 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 -}
 
 -------------------------------
+-- 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!"
 
 -------------------------------
-
+-- 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]
-
-freeMappedRegs nums
-  = foldr free [] nums
-  where
-    free IBOX(i) acc
-      = if _IS_TRUE_(freeReg i) then (MappedReg i) : acc else acc
+#if i386_TARGET_ARCH
+allArgRegs :: [Reg]
+allArgRegs = panic "MachRegs.allArgRegs(x86): should not be used!"
+#endif
 \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 o6 = fastBool False  --        %o6 is our stack pointer.
+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_
-#endif
-#ifdef REG_StkO
-freeReg ILIT(REG_StkO) = _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_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_
+#ifdef REG_Sp 
+freeReg REG_Sp   = fastBool False
 #endif 
-#ifdef REG_SuA 
-freeReg ILIT(REG_SuA)  = _FALSE_
+#ifdef REG_Su
+freeReg REG_Su   = fastBool False
 #endif 
-#ifdef REG_SpB 
-freeReg ILIT(REG_SpB)  = _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}