RTS tidyup sweep, first phase
[ghc-hetmet.git] / compiler / nativeGen / X86 / Regs.hs
index 3432090..64d835b 100644 (file)
@@ -1,14 +1,7 @@
 module X86.Regs (
 module X86.Regs (
-
-       -- sizes
-       Size(..),
-       intSize, 
-       floatSize, 
-       isFloatSize, 
-       wordSize,
-       cmmTypeSize,
-       sizeToWidth,
-       mkVReg,
+       -- squeese functions for the graph allocator
+       virtualRegSqueeze,
+       realRegSqueeze,
 
        -- immediates
        Imm(..),
 
        -- immediates
        Imm(..),
@@ -25,33 +18,30 @@ module X86.Regs (
        allArgRegs,
        callClobberedRegs,
        allMachRegNos,
        allArgRegs,
        callClobberedRegs,
        allMachRegNos,
-       regClass,
+       classOfRealReg,
        showReg,        
 
        -- machine specific
        EABase(..), EAIndex(..), addrModeRegs,
 
        showReg,        
 
        -- machine specific
        EABase(..), EAIndex(..), addrModeRegs,
 
-#if i386_TARGET_ARCH
-       -- part of address mode. shared for both arches.
        eax, ebx, ecx, edx, esi, edi, ebp, esp,
        fake0, fake1, fake2, fake3, fake4, fake5,
        eax, ebx, ecx, edx, esi, edi, ebp, esp,
        fake0, fake1, fake2, fake3, fake4, fake5,
-#endif
-#if x86_64_TARGET_ARCH
-       -- part of address mode. shared for both arches.
-       ripRel,
-       allFPArgRegs,
-       
+
        rax, rbx, rcx, rdx, rsi, rdi, rbp, rsp,
        rax, rbx, rcx, rdx, rsi, rdi, rbp, rsp,
-       eax, ebx, ecx, edx, esi, edi, ebp, esp,
-       r8, r9, r10, r11, r12, r13, r14, r15,
+       r8,  r9,  r10, r11, r12, r13, r14, r15,
        xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7,
        xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15,
        xmm,
        xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7,
        xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15,
        xmm,
-#endif
+
+       ripRel,
+       allFPArgRegs,
 
        -- horror show
        freeReg,
 
        -- horror show
        freeReg,
-       globalRegMaybe
+       globalRegMaybe,
+       
+       get_GlobalReg_reg_or_addr,
+       allocatableRegs
 )
 
 where
 )
 
 where
@@ -64,90 +54,124 @@ where
 -- HACK: go for the max
 #endif
 
 -- HACK: go for the max
 #endif
 
-#include "../includes/MachRegs.h"
+#include "../includes/stg/MachRegs.h"
 
 
-import RegsBase
+import Reg
+import RegClass
 
 
+import CgUtils          ( get_GlobalReg_addr )
 import BlockId
 import Cmm
 import CLabel           ( CLabel )
 import Pretty
 import BlockId
 import Cmm
 import CLabel           ( CLabel )
 import Pretty
-import Outputable      ( Outputable(..), pprPanic, panic )
-import qualified Outputable
-import Unique
+import Outputable      ( panic )
+import FastTypes
 import FastBool
 
 import FastBool
 
--- -----------------------------------------------------------------------------
--- Sizes on this architecture
--- 
--- A Size is usually a combination of width and class
-
--- It looks very like the old MachRep, but it's now of purely local
--- significance, here in the native code generator.  You can change it
--- without global consequences.
---
--- A major use is as an opcode qualifier; thus the opcode 
---     mov.l a b
--- might be encoded 
---     MOV II32 a b
--- where the Size field encodes the ".l" part.
-
--- ToDo: it's not clear to me that we need separate signed-vs-unsigned sizes
--- here.  I've removed them from the x86 version, we'll see what happens --SDM
-
--- ToDo: quite a few occurrences of Size could usefully be replaced by Width
-
-data Size
-       = II8 | II16 | II32 | II64 | FF32 | FF64 | FF80
-       deriving Eq
-
-intSize, floatSize :: Width -> Size
-intSize W8 = II8
-intSize W16 = II16
-intSize W32 = II32
-intSize W64 = II64
-intSize other = pprPanic "MachInstrs.intSize" (ppr other)
-
-
-floatSize W32 = FF32
-floatSize W64 = FF64
-floatSize other = pprPanic "MachInstrs.intSize" (ppr other)
-
-
-isFloatSize :: Size -> Bool
-isFloatSize FF32 = True
-isFloatSize FF64 = True
-isFloatSize FF80 = True
-isFloatSize _    = False
-
-
-wordSize :: Size
-wordSize = intSize wordWidth
-
 
 
-cmmTypeSize :: CmmType -> Size
-cmmTypeSize ty | isFloatType ty = floatSize (typeWidth ty)
-              | otherwise      = intSize (typeWidth ty)
+#if  defined(i386_TARGET_ARCH) || defined(x86_64_TARGET_ARCH)
+import Constants
+#endif
 
 
 
 
-sizeToWidth :: Size -> Width
-sizeToWidth II8  = W8
-sizeToWidth II16 = W16
-sizeToWidth II32 = W32
-sizeToWidth II64 = W64
-sizeToWidth FF32 = W32
-sizeToWidth FF64 = W64
-sizeToWidth _ = panic "MachInstrs.sizeToWidth"
+-- | regSqueeze_class reg
+--     Calculuate the maximum number of register colors that could be
+--     denied to a node of this class due to having this reg 
+--     as a neighbour.
+--
+{-# INLINE virtualRegSqueeze #-}
+virtualRegSqueeze :: RegClass -> VirtualReg -> FastInt
+
+virtualRegSqueeze cls vr
+ = case cls of
+       RcInteger
+        -> case vr of
+               VirtualRegI{}           -> _ILIT(1)
+               VirtualRegHi{}          -> _ILIT(1)
+               VirtualRegD{}           -> _ILIT(0)
+               VirtualRegF{}           -> _ILIT(0)
+
+       -- We don't use floats on this arch, but we can't
+       --      return error because the return type is unboxed...
+       RcFloat
+        -> case vr of
+               VirtualRegI{}           -> _ILIT(0)
+               VirtualRegHi{}          -> _ILIT(0)
+               VirtualRegD{}           -> _ILIT(0)
+               VirtualRegF{}           -> _ILIT(0)
+
+       RcDouble
+        -> case vr of
+               VirtualRegI{}           -> _ILIT(0)
+               VirtualRegHi{}          -> _ILIT(0)
+               VirtualRegD{}           -> _ILIT(1)
+               VirtualRegF{}           -> _ILIT(0)
+
+{-# INLINE realRegSqueeze #-}
+realRegSqueeze :: RegClass -> RealReg -> FastInt
+
+#if defined(i386_TARGET_ARCH)
+realRegSqueeze cls rr
+ = case cls of
+       RcInteger
+        -> case rr of
+               RealRegSingle regNo
+                       | regNo < 8     -> _ILIT(1)     -- first fp reg is 8
+                       | otherwise     -> _ILIT(0)
+                       
+               RealRegPair{}           -> _ILIT(0)
+
+       -- We don't use floats on this arch, but we can't
+       --      return error because the return type is unboxed...
+       RcFloat
+        -> case rr of
+               RealRegSingle regNo
+                       | regNo < 8     -> _ILIT(0)
+                       | otherwise     -> _ILIT(0)
+                       
+               RealRegPair{}           -> _ILIT(0)
+
+       RcDouble
+        -> case rr of
+               RealRegSingle regNo
+                       | regNo < 8     -> _ILIT(0)
+                       | otherwise     -> _ILIT(1)
+                       
+               RealRegPair{}           -> _ILIT(0)
+
+#elif defined(x86_64_TARGET_ARCH)
+realRegSqueeze cls rr
+ = case cls of
+       RcInteger
+        -> case rr of
+               RealRegSingle regNo
+                       | regNo < 16    -> _ILIT(1)     -- first xmm reg is 16
+                       | otherwise     -> _ILIT(0)
+                       
+               RealRegPair{}           -> _ILIT(0)
+
+       -- We don't use floats on this arch, but we can't
+       --      return error because the return type is unboxed...
+       RcFloat
+        -> case rr of
+               RealRegSingle regNo
+                       | regNo < 16    -> _ILIT(0)
+                       | otherwise     -> _ILIT(0)
+                       
+               RealRegPair{}           -> _ILIT(0)
+
+       RcDouble
+        -> case rr of
+               RealRegSingle regNo
+                       | regNo < 16    -> _ILIT(0)
+                       | otherwise     -> _ILIT(1)
+                       
+               RealRegPair{}           -> _ILIT(0)
 
 
+#else
+realRegSqueeze _ _     = _ILIT(0)
+#endif
 
 
-mkVReg :: Unique -> Size -> Reg
-mkVReg u size
-   | not (isFloatSize size) = VirtualRegI u
-   | otherwise
-   = case size of
-        FF32   -> VirtualRegD u
-        FF64   -> VirtualRegD u
-       _       -> panic "mkVReg"
 
 
 -- -----------------------------------------------------------------------------
 
 
 -- -----------------------------------------------------------------------------
@@ -253,38 +277,6 @@ argRegs _  = panic "MachRegs.argRegs(x86): should not be used!"
 
 
 
 
 
 
--- 
-allArgRegs :: [Reg]
-
-#if   i386_TARGET_ARCH
-allArgRegs = panic "X86.Regs.allArgRegs: should not be used!"
-
-#elif x86_64_TARGET_ARCH
-allArgRegs = map RealReg [rdi,rsi,rdx,rcx,r8,r9]
-
-#else
-allArgRegs  = panic "X86.Regs.allArgRegs: not defined for this architecture"
-#endif
-
-
--- | these are the regs which we cannot assume stay alive over a C call.  
-callClobberedRegs :: [Reg]
-
-#if   i386_TARGET_ARCH
--- caller-saves registers
-callClobberedRegs
-  = map RealReg [eax,ecx,edx,fake0,fake1,fake2,fake3,fake4,fake5]
-
-#elif x86_64_TARGET_ARCH
--- all xmm regs are caller-saves
--- caller-saves registers
-callClobberedRegs    
-  = map RealReg ([rax,rcx,rdx,rsi,rdi,r8,r9,r10,r11] ++ [16..31])
-
-#else
-callClobberedRegs
-  = panic "X86.Regs.callClobberedRegs: not defined for this architecture"
-#endif
 
 
 -- | The complete set of machine registers.
 
 
 -- | The complete set of machine registers.
@@ -303,35 +295,31 @@ allMachRegNos     = panic "X86.Regs.callClobberedRegs: not defined for this architec
 
 
 -- | Take the class of a register.
 
 
 -- | Take the class of a register.
-{-# INLINE regClass      #-}
-regClass :: Reg -> RegClass
+{-# INLINE classOfRealReg      #-}
+classOfRealReg :: RealReg -> RegClass
 
 #if   i386_TARGET_ARCH
 -- On x86, we might want to have an 8-bit RegClass, which would
 -- contain just regs 1-4 (the others don't have 8-bit versions).
 -- However, we can get away without this at the moment because the
 -- only allocatable integer regs are also 8-bit compatible (1, 3, 4).
 
 #if   i386_TARGET_ARCH
 -- On x86, we might want to have an 8-bit RegClass, which would
 -- contain just regs 1-4 (the others don't have 8-bit versions).
 -- However, we can get away without this at the moment because the
 -- only allocatable integer regs are also 8-bit compatible (1, 3, 4).
-regClass (RealReg i)     = if i < 8 then RcInteger else RcDouble
-regClass (VirtualRegI  u) = RcInteger
-regClass (VirtualRegHi u) = RcInteger
-regClass (VirtualRegD  u) = RcDouble
-regClass (VirtualRegF  u) = pprPanic "regClass(x86):VirtualRegF" 
-                                    (ppr (VirtualRegF u))
+classOfRealReg reg
+ = case reg of
+       RealRegSingle i -> if i < 8 then RcInteger else RcDouble
+       RealRegPair{}   -> panic "X86.Regs.classOfRealReg: RegPairs on this arch"
 
 #elif x86_64_TARGET_ARCH
 -- On x86, we might want to have an 8-bit RegClass, which would
 -- contain just regs 1-4 (the others don't have 8-bit versions).
 -- However, we can get away without this at the moment because the
 -- only allocatable integer regs are also 8-bit compatible (1, 3, 4).
 
 #elif x86_64_TARGET_ARCH
 -- On x86, we might want to have an 8-bit RegClass, which would
 -- contain just regs 1-4 (the others don't have 8-bit versions).
 -- However, we can get away without this at the moment because the
 -- only allocatable integer regs are also 8-bit compatible (1, 3, 4).
-regClass (RealReg i)     = if i < 16 then RcInteger else RcDouble
-regClass (VirtualRegI  u) = RcInteger
-regClass (VirtualRegHi u) = RcInteger
-regClass (VirtualRegD  u) = RcDouble
-regClass (VirtualRegF  u) = pprPanic "regClass(x86_64):VirtualRegF" 
-                                    (ppr (VirtualRegF u))
+classOfRealReg reg
+ = case reg of
+       RealRegSingle i -> if i < 16 then RcInteger else RcDouble
+       RealRegPair{}   -> panic "X86.Regs.classOfRealReg: RegPairs on this arch"
 
 #else
 
 #else
-regClass _     = panic "X86.Regs.regClass: not defined for this architecture"
+classOfRealReg _       = panic "X86.Regs.regClass: not defined for this architecture"
 
 #endif
 
 
 #endif
 
@@ -345,6 +333,7 @@ showReg n
      then regNames !! n
      else "%unknown_x86_real_reg_" ++ show n
 
      then regNames !! n
      else "%unknown_x86_real_reg_" ++ show n
 
+regNames :: [String]
 regNames 
    = ["%eax", "%ebx", "%ecx", "%edx", "%esi", "%edi", "%ebp", "%esp", 
       "%fake0", "%fake1", "%fake2", "%fake3", "%fake4", "%fake5", "%fake6"]
 regNames 
    = ["%eax", "%ebx", "%ecx", "%edx", "%esi", "%edi", "%ebp", "%esp", 
       "%fake0", "%fake1", "%fake2", "%fake3", "%fake4", "%fake5", "%fake6"]
@@ -355,6 +344,7 @@ showReg n
        | n >= 8        = "%r" ++ show n
        | otherwise     = regNames !! n
 
        | n >= 8        = "%r" ++ show n
        | otherwise     = regNames !! n
 
+regNames :: [String]
 regNames 
  = ["%rax", "%rbx", "%rcx", "%rdx", "%rsi", "%rdi", "%rbp", "%rsp" ]
 
 regNames 
  = ["%rax", "%rbx", "%rcx", "%rdx", "%rsi", "%rdi", "%rbp", "%rsp" ]
 
@@ -384,25 +374,24 @@ regs.  @regClass@ barfs if you give it a VirtualRegF, and mkVReg above should
 never generate them.
 -}
 
 never generate them.
 -}
 
-#if   i386_TARGET_ARCH
 fake0, fake1, fake2, fake3, fake4, fake5, 
        eax, ebx, ecx, edx, esp, ebp, esi, edi :: Reg
 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
 
 
-#endif
+eax   = regSingle 0
+ebx   = regSingle 1
+ecx   = regSingle 2
+edx   = regSingle 3
+esi   = regSingle 4
+edi   = regSingle 5
+ebp   = regSingle 6
+esp   = regSingle 7
+fake0 = regSingle 8
+fake1 = regSingle 9
+fake2 = regSingle 10
+fake3 = regSingle 11
+fake4 = regSingle 12
+fake5 = regSingle 13
+
 
 
 {-
 
 
 {-
@@ -413,52 +402,53 @@ AMD x86_64 architecture:
 
 -}
 
 
 -}
 
-#if   x86_64_TARGET_ARCH
-allFPArgRegs :: [Reg]
-allFPArgRegs   = map RealReg [xmm0 .. xmm7]
-
-ripRel imm     = AddrBaseIndex EABaseRip EAIndexNone imm
-
-
 rax, rbx, rcx, rdx, rsp, rbp, rsi, rdi, 
   r8, r9, r10, r11, r12, r13, r14, r15,
   xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7,
   xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15 :: Reg
 
 rax, rbx, rcx, rdx, rsp, rbp, rsi, rdi, 
   r8, r9, r10, r11, r12, r13, r14, r15,
   xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7,
   xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15 :: Reg
 
-rax   = RealReg 0
-rbx   = RealReg 1
-rcx   = RealReg 2
-rdx   = RealReg 3
-rsi   = RealReg 4
-rdi   = RealReg 5
-rbp   = RealReg 6
-rsp   = RealReg 7
-r8    = RealReg 8
-r9    = RealReg 9
-r10   = RealReg 10
-r11   = RealReg 11
-r12   = RealReg 12
-r13   = RealReg 13
-r14   = RealReg 14
-r15   = RealReg 15
-xmm0  = RealReg 16
-xmm1  = RealReg 17
-xmm2  = RealReg 18
-xmm3  = RealReg 19
-xmm4  = RealReg 20
-xmm5  = RealReg 21
-xmm6  = RealReg 22
-xmm7  = RealReg 23
-xmm8  = RealReg 24
-xmm9  = RealReg 25
-xmm10 = RealReg 26
-xmm11 = RealReg 27
-xmm12 = RealReg 28
-xmm13 = RealReg 29
-xmm14 = RealReg 30
-xmm15 = RealReg 31
+rax   = regSingle 0
+rbx   = regSingle 1
+rcx   = regSingle 2
+rdx   = regSingle 3
+rsi   = regSingle 4
+rdi   = regSingle 5
+rbp   = regSingle 6
+rsp   = regSingle 7
+r8    = regSingle 8
+r9    = regSingle 9
+r10   = regSingle 10
+r11   = regSingle 11
+r12   = regSingle 12
+r13   = regSingle 13
+r14   = regSingle 14
+r15   = regSingle 15
+xmm0  = regSingle 16
+xmm1  = regSingle 17
+xmm2  = regSingle 18
+xmm3  = regSingle 19
+xmm4  = regSingle 20
+xmm5  = regSingle 21
+xmm6  = regSingle 22
+xmm7  = regSingle 23
+xmm8  = regSingle 24
+xmm9  = regSingle 25
+xmm10 = regSingle 26
+xmm11 = regSingle 27
+xmm12 = regSingle 28
+xmm13 = regSingle 29
+xmm14 = regSingle 30
+xmm15 = regSingle 31
+
+allFPArgRegs :: [Reg]
+allFPArgRegs   = map regSingle [16 .. 23]
+
+ripRel :: Displacement -> AddrMode
+ripRel imm     = AddrBaseIndex EABaseRip EAIndexNone imm
+
 
  -- so we can re-use some x86 code:
 
  -- so we can re-use some x86 code:
+{-
 eax = rax
 ebx = rbx
 ecx = rcx
 eax = rax
 ebx = rbx
 ecx = rcx
@@ -467,16 +457,19 @@ esi = rsi
 edi = rdi
 ebp = rbp
 esp = rsp
 edi = rdi
 ebp = rbp
 esp = rsp
+-}
 
 
-xmm n = RealReg (16+n)
+xmm :: RegNo -> Reg
+xmm n = regSingle (16+n)
 
 
-#endif
 
 
 
 -- horror show -----------------------------------------------------------------
 
 
 
 -- horror show -----------------------------------------------------------------
-freeReg :: RegNo -> FastBool
-globalRegMaybe :: GlobalReg -> Maybe Reg
+freeReg                :: RegNo -> FastBool
+globalRegMaybe                 :: GlobalReg -> Maybe RealReg
+allArgRegs             :: [Reg]
+callClobberedRegs      :: [Reg]
 
 #if defined(i386_TARGET_ARCH) || defined(x86_64_TARGET_ARCH)
 
 
 #if defined(i386_TARGET_ARCH) || defined(x86_64_TARGET_ARCH)
 
@@ -602,7 +595,7 @@ freeReg REG_Hp   = fastBool False
 #ifdef REG_HpLim
 freeReg REG_HpLim = fastBool False
 #endif
 #ifdef REG_HpLim
 freeReg REG_HpLim = fastBool False
 #endif
-freeReg n               = fastBool True
+freeReg _               = fastBool True
 
 
 --  | Returns 'Nothing' if this global register is not stored
 
 
 --  | Returns 'Nothing' if this global register is not stored
@@ -610,85 +603,146 @@ freeReg n               = fastBool True
 -- reg is the machine register it is stored in.
 
 #ifdef REG_Base
 -- reg is the machine register it is stored in.
 
 #ifdef REG_Base
-globalRegMaybe BaseReg                 = Just (RealReg REG_Base)
+globalRegMaybe BaseReg                 = Just (RealRegSingle REG_Base)
 #endif
 #ifdef REG_R1
 #endif
 #ifdef REG_R1
-globalRegMaybe (VanillaReg 1 _)                = Just (RealReg REG_R1)
+globalRegMaybe (VanillaReg 1 _)                = Just (RealRegSingle REG_R1)
 #endif 
 #ifdef REG_R2 
 #endif 
 #ifdef REG_R2 
-globalRegMaybe (VanillaReg 2 _)                = Just (RealReg REG_R2)
+globalRegMaybe (VanillaReg 2 _)                = Just (RealRegSingle REG_R2)
 #endif 
 #ifdef REG_R3 
 #endif 
 #ifdef REG_R3 
-globalRegMaybe (VanillaReg 3 _)        = Just (RealReg REG_R3)
+globalRegMaybe (VanillaReg 3 _)        = Just (RealRegSingle REG_R3)
 #endif 
 #ifdef REG_R4 
 #endif 
 #ifdef REG_R4 
-globalRegMaybe (VanillaReg 4 _)                = Just (RealReg REG_R4)
+globalRegMaybe (VanillaReg 4 _)                = Just (RealRegSingle REG_R4)
 #endif 
 #ifdef REG_R5 
 #endif 
 #ifdef REG_R5 
-globalRegMaybe (VanillaReg 5 _)                = Just (RealReg REG_R5)
+globalRegMaybe (VanillaReg 5 _)                = Just (RealRegSingle REG_R5)
 #endif 
 #ifdef REG_R6 
 #endif 
 #ifdef REG_R6 
-globalRegMaybe (VanillaReg 6 _)                = Just (RealReg REG_R6)
+globalRegMaybe (VanillaReg 6 _)                = Just (RealRegSingle REG_R6)
 #endif 
 #ifdef REG_R7 
 #endif 
 #ifdef REG_R7 
-globalRegMaybe (VanillaReg 7 _)                = Just (RealReg REG_R7)
+globalRegMaybe (VanillaReg 7 _)                = Just (RealRegSingle REG_R7)
 #endif 
 #ifdef REG_R8 
 #endif 
 #ifdef REG_R8 
-globalRegMaybe (VanillaReg 8 _)                = Just (RealReg REG_R8)
+globalRegMaybe (VanillaReg 8 _)                = Just (RealRegSingle REG_R8)
 #endif
 #ifdef REG_R9 
 #endif
 #ifdef REG_R9 
-globalRegMaybe (VanillaReg 9 _)                = Just (RealReg REG_R9)
+globalRegMaybe (VanillaReg 9 _)                = Just (RealRegSingle REG_R9)
 #endif
 #ifdef REG_R10 
 #endif
 #ifdef REG_R10 
-globalRegMaybe (VanillaReg 10 _)       = Just (RealReg REG_R10)
+globalRegMaybe (VanillaReg 10 _)       = Just (RealRegSingle REG_R10)
 #endif
 #ifdef REG_F1
 #endif
 #ifdef REG_F1
-globalRegMaybe (FloatReg 1)            = Just (RealReg REG_F1)
+globalRegMaybe (FloatReg 1)            = Just (RealRegSingle REG_F1)
 #endif                                 
 #ifdef REG_F2                          
 #endif                                 
 #ifdef REG_F2                          
-globalRegMaybe (FloatReg 2)            = Just (RealReg REG_F2)
+globalRegMaybe (FloatReg 2)            = Just (RealRegSingle REG_F2)
 #endif                                 
 #ifdef REG_F3                          
 #endif                                 
 #ifdef REG_F3                          
-globalRegMaybe (FloatReg 3)            = Just (RealReg REG_F3)
+globalRegMaybe (FloatReg 3)            = Just (RealRegSingle REG_F3)
 #endif                                 
 #ifdef REG_F4                          
 #endif                                 
 #ifdef REG_F4                          
-globalRegMaybe (FloatReg 4)            = Just (RealReg REG_F4)
+globalRegMaybe (FloatReg 4)            = Just (RealRegSingle REG_F4)
 #endif                                 
 #ifdef REG_D1                          
 #endif                                 
 #ifdef REG_D1                          
-globalRegMaybe (DoubleReg 1)           = Just (RealReg REG_D1)
+globalRegMaybe (DoubleReg 1)           = Just (RealRegSingle REG_D1)
 #endif                                 
 #ifdef REG_D2                          
 #endif                                 
 #ifdef REG_D2                          
-globalRegMaybe (DoubleReg 2)           = Just (RealReg REG_D2)
+globalRegMaybe (DoubleReg 2)           = Just (RealRegSingle REG_D2)
 #endif
 #ifdef REG_Sp      
 #endif
 #ifdef REG_Sp      
-globalRegMaybe Sp                      = Just (RealReg REG_Sp)
+globalRegMaybe Sp                      = Just (RealRegSingle REG_Sp)
 #endif
 #ifdef REG_Lng1                                
 #endif
 #ifdef REG_Lng1                                
-globalRegMaybe (LongReg 1)             = Just (RealReg REG_Lng1)
+globalRegMaybe (LongReg 1)             = Just (RealRegSingle REG_Lng1)
 #endif                                 
 #ifdef REG_Lng2                                
 #endif                                 
 #ifdef REG_Lng2                                
-globalRegMaybe (LongReg 2)             = Just (RealReg REG_Lng2)
+globalRegMaybe (LongReg 2)             = Just (RealRegSingle REG_Lng2)
 #endif
 #ifdef REG_SpLim                               
 #endif
 #ifdef REG_SpLim                               
-globalRegMaybe SpLim                   = Just (RealReg REG_SpLim)
+globalRegMaybe SpLim                   = Just (RealRegSingle REG_SpLim)
 #endif                                 
 #ifdef REG_Hp                          
 #endif                                 
 #ifdef REG_Hp                          
-globalRegMaybe Hp                      = Just (RealReg REG_Hp)
+globalRegMaybe Hp                      = Just (RealRegSingle REG_Hp)
 #endif                                 
 #ifdef REG_HpLim                       
 #endif                                 
 #ifdef REG_HpLim                       
-globalRegMaybe HpLim                   = Just (RealReg REG_HpLim)
+globalRegMaybe HpLim                   = Just (RealRegSingle REG_HpLim)
 #endif                                 
 #ifdef REG_CurrentTSO                          
 #endif                                 
 #ifdef REG_CurrentTSO                          
-globalRegMaybe CurrentTSO              = Just (RealReg REG_CurrentTSO)
+globalRegMaybe CurrentTSO              = Just (RealRegSingle REG_CurrentTSO)
 #endif                                 
 #ifdef REG_CurrentNursery                              
 #endif                                 
 #ifdef REG_CurrentNursery                              
-globalRegMaybe CurrentNursery          = Just (RealReg REG_CurrentNursery)
+globalRegMaybe CurrentNursery          = Just (RealRegSingle REG_CurrentNursery)
 #endif                                 
 globalRegMaybe _                       = Nothing
 
 #endif                                 
 globalRegMaybe _                       = Nothing
 
+-- 
+
+#if   i386_TARGET_ARCH
+allArgRegs = panic "X86.Regs.allArgRegs: should not be used!"
+
+#elif x86_64_TARGET_ARCH
+allArgRegs = map regSingle [rdi,rsi,rdx,rcx,r8,r9]
+
+#else
+allArgRegs  = panic "X86.Regs.allArgRegs: not defined for this architecture"
+#endif
+
+
+-- | these are the regs which we cannot assume stay alive over a C call.  
+
+#if   i386_TARGET_ARCH
+-- caller-saves registers
+callClobberedRegs
+  = map regSingle [eax,ecx,edx,fake0,fake1,fake2,fake3,fake4,fake5]
+
+#elif x86_64_TARGET_ARCH
+-- all xmm regs are caller-saves
+-- caller-saves registers
+callClobberedRegs    
+  = map regSingle ([rax,rcx,rdx,rsi,rdi,r8,r9,r10,r11] ++ [16..31])
+
+#else
+callClobberedRegs
+  = panic "X86.Regs.callClobberedRegs: not defined for this architecture"
+#endif
+
 #else /* i386_TARGET_ARCH || x86_64_TARGET_ARCH */
 
 #else /* i386_TARGET_ARCH || x86_64_TARGET_ARCH */
 
+
+
 freeReg        _               = 0#
 globalRegMaybe _       = panic "X86.Regs.globalRegMaybe: not defined"
 
 freeReg        _               = 0#
 globalRegMaybe _       = panic "X86.Regs.globalRegMaybe: not defined"
 
+allArgRegs             = panic "X86.Regs.globalRegMaybe: not defined"
+callClobberedRegs      = panic "X86.Regs.globalRegMaybe: not defined"
+
+
 #endif
 #endif
+
+-- We map STG registers onto appropriate CmmExprs.  Either they map
+-- to real machine registers or stored as offsets from BaseReg.  Given
+-- a GlobalReg, get_GlobalReg_reg_or_addr produces either the real
+-- register it is in, on this platform, or a CmmExpr denoting the
+-- address in the register table holding it.
+-- (See also get_GlobalReg_addr in CgUtils.)
+
+get_GlobalReg_reg_or_addr :: GlobalReg -> Either RealReg CmmExpr
+get_GlobalReg_reg_or_addr mid
+   = case globalRegMaybe mid of
+        Just rr -> Left rr
+        Nothing -> Right (get_GlobalReg_addr mid)
+
+
+-- 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 :: [RealReg]
+allocatableRegs
+   = let isFree i = isFastTrue (freeReg i)
+     in  map RealRegSingle $ filter isFree allMachRegNos
+
+