Add new LLVM code generator to GHC. (Version 2)
[ghc-hetmet.git] / compiler / nativeGen / X86 / Regs.hs
index 1f1c724..b9a23a6 100644 (file)
@@ -1,14 +1,7 @@
 module X86.Regs (
-
-       -- sizes
-       Size(..),
-       intSize, 
-       floatSize, 
-       isFloatSize, 
-       wordSize,
-       cmmTypeSize,
-       sizeToWidth,
-       mkVReg,
+       -- squeese functions for the graph allocator
+       virtualRegSqueeze,
+       realRegSqueeze,
 
        -- immediates
        Imm(..),
@@ -25,14 +18,14 @@ module X86.Regs (
        allArgRegs,
        callClobberedRegs,
        allMachRegNos,
-       regClass,
+       classOfRealReg,
        showReg,        
 
        -- machine specific
        EABase(..), EAIndex(..), addrModeRegs,
 
        eax, ebx, ecx, edx, esi, edi, ebp, esp,
-       fake0, fake1, fake2, fake3, fake4, fake5,
+       fake0, fake1, fake2, fake3, fake4, fake5, firstfake,
 
        rax, rbx, rcx, rdx, rsi, rdi, rbp, rsp,
        r8,  r9,  r10, r11, r12, r13, r14, r15,
@@ -45,7 +38,9 @@ module X86.Regs (
 
        -- horror show
        freeReg,
-       globalRegMaybe
+       globalRegMaybe,
+       
+       allocatableRegs
 )
 
 where
@@ -53,100 +48,80 @@ where
 #include "nativeGen/NCG.h"
 #include "HsVersions.h"
 
-#if i386_TARGET_ARCH
-# define STOLEN_X86_REGS 4
--- HACK: go for the max
-#endif
+#include "../includes/stg/MachRegs.h"
 
-#include "../includes/MachRegs.h"
-
-import RegsBase
+import Reg
+import RegClass
 
 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
 
+
 #if  defined(i386_TARGET_ARCH) || defined(x86_64_TARGET_ARCH)
 import Constants
 #endif
 
--- -----------------------------------------------------------------------------
--- 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.
+-- | 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.
 --
--- 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)
-
-
-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"
-
-
-mkVReg :: Unique -> Size -> Reg
-mkVReg u size
-   | not (isFloatSize size) = VirtualRegI u
-   | otherwise
-   = case size of
-        FF32   -> VirtualRegD u
-        FF64   -> VirtualRegD u
-       _       -> panic "mkVReg"
-
+{-# INLINE virtualRegSqueeze #-}
+virtualRegSqueeze :: RegClass -> VirtualReg -> FastInt
+
+virtualRegSqueeze cls vr
+ = case cls of
+       RcInteger
+        -> case vr of
+               VirtualRegI{}           -> _ILIT(1)
+               VirtualRegHi{}          -> _ILIT(1)
+                _other                  -> _ILIT(0)
+
+       RcDouble
+        -> case vr of
+               VirtualRegD{}           -> _ILIT(1)
+               VirtualRegF{}           -> _ILIT(0)
+                _other                  -> _ILIT(0)
+
+       RcDoubleSSE
+        -> case vr of
+               VirtualRegSSE{}         -> _ILIT(1)
+                _other                  -> _ILIT(0)
+
+        _other -> _ILIT(0)
+
+{-# INLINE realRegSqueeze #-}
+realRegSqueeze :: RegClass -> RealReg -> FastInt
+realRegSqueeze cls rr
+ = case cls of
+       RcInteger
+        -> case rr of
+               RealRegSingle regNo
+                       | regNo < firstfake -> _ILIT(1)
+                       | otherwise     -> _ILIT(0)
+                       
+               RealRegPair{}           -> _ILIT(0)
+
+       RcDouble
+        -> case rr of
+               RealRegSingle regNo
+                       | regNo >= firstfake && regNo < lastfake -> _ILIT(1)
+                       | otherwise     -> _ILIT(0)
+                       
+               RealRegPair{}           -> _ILIT(0)
+
+        RcDoubleSSE
+        -> case rr of
+               RealRegSingle regNo | regNo >= firstxmm -> _ILIT(1)
+                _otherwise                        -> _ILIT(0)
+
+        _other -> _ILIT(0)
 
 -- -----------------------------------------------------------------------------
 -- Immediates
@@ -241,6 +216,35 @@ spRel _    = panic "X86.Regs.spRel: not defined for this architecture"
 
 #endif
 
+-- The register numbers must fit into 32 bits on x86, so that we can
+-- use a Word32 to represent the set of free registers in the register
+-- allocator.
+
+firstfake, lastfake :: RegNo
+firstfake = 16
+lastfake  = 21
+
+firstxmm, lastxmm :: RegNo
+firstxmm  = 24
+#if i386_TARGET_ARCH
+lastxmm   = 31
+#else
+lastxmm   = 39
+#endif
+
+lastint :: RegNo
+#if i386_TARGET_ARCH
+lastint = 7 -- not %r8..%r15
+#else
+lastint = 15
+#endif
+
+intregnos, fakeregnos, xmmregnos, floatregnos :: [RegNo]
+intregnos   = [0..lastint]
+fakeregnos  = [firstfake .. lastfake]
+xmmregnos   = [firstxmm  .. lastxmm]
+floatregnos = fakeregnos ++ xmmregnos;
+
 
 -- 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.
@@ -249,89 +253,46 @@ spRel _   = panic "X86.Regs.spRel: not defined for this architecture"
 argRegs :: RegNo -> [Reg]
 argRegs _      = panic "MachRegs.argRegs(x86): should not be used!"
 
-
-
-
-
 -- | The complete set of machine registers.
 allMachRegNos :: [RegNo]
-
-#if   i386_TARGET_ARCH
-allMachRegNos  = [0..13]
-
-#elif x86_64_TARGET_ARCH
-allMachRegNos  = [0..31]
-
-#else
-allMachRegNos  = panic "X86.Regs.callClobberedRegs: not defined for this architecture"
-
-#endif
-
+allMachRegNos  = intregnos ++ floatregnos
 
 -- | Take the class of a register.
-{-# INLINE regClass      #-}
-regClass :: Reg -> 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).
-regClass (RealReg i)     = if i < 8 then RcInteger else RcDouble
-regClass (VirtualRegI  _) = RcInteger
-regClass (VirtualRegHi _) = RcInteger
-regClass (VirtualRegD  _) = RcDouble
-regClass (VirtualRegF  u) = pprPanic ("regClass(x86):VirtualRegF") (ppr u)
-
-#elif x86_64_TARGET_ARCH
+{-# INLINE classOfRealReg      #-}
+classOfRealReg :: RealReg -> RegClass
 -- 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  _) = RcInteger
-regClass (VirtualRegHi _) = RcInteger
-regClass (VirtualRegD  _) = RcDouble
-regClass (VirtualRegF  u) = pprPanic "regClass(x86_64):VirtualRegF" (ppr u)
-
-#else
-regClass _     = panic "X86.Regs.regClass: not defined for this architecture"
-
-#endif
+classOfRealReg reg
+ = case reg of
+       RealRegSingle i
+          | i <= lastint  -> RcInteger
+          | i <= lastfake -> RcDouble
+          | otherwise     -> RcDoubleSSE
 
+       RealRegPair{}   -> panic "X86.Regs.classOfRealReg: RegPairs on this arch"
 
 -- | Get the name of the register with this number.
 showReg :: RegNo -> String
-
-#if   i386_TARGET_ARCH
 showReg n
-   = if   n >= 0 && n < 14
-     then regNames !! n
-     else "%unknown_x86_real_reg_" ++ show n
+       | n >= firstxmm  = "%xmm" ++ show (n-firstxmm)
+        | n >= firstfake = "%fake" ++ show (n-firstfake)
+       | n >= 8         = "%r" ++ show n
+       | otherwise      = regNames !! n
 
 regNames :: [String]
 regNames 
-   = ["%eax", "%ebx", "%ecx", "%edx", "%esi", "%edi", "%ebp", "%esp", 
-      "%fake0", "%fake1", "%fake2", "%fake3", "%fake4", "%fake5", "%fake6"]
-
+#if   i386_TARGET_ARCH
+   = ["%eax", "%ebx", "%ecx", "%edx", "%esi", "%edi", "%ebp", "%esp"]
 #elif x86_64_TARGET_ARCH
-showReg n
-       | n >= 16       = "%xmm" ++ show (n-16)
-       | n >= 8        = "%r" ++ show n
-       | otherwise     = regNames !! n
-
-regNames :: [String]
-regNames 
- = ["%rax", "%rbx", "%rcx", "%rdx", "%rsi", "%rdi", "%rbp", "%rsp" ]
-
+   = ["%rax", "%rbx", "%rcx", "%rdx", "%rsi", "%rdi", "%rbp", "%rsp" ]
 #else
-showReg _      = panic "X86.Regs.showReg: not defined for this architecture"
-
+   = []
 #endif
 
 
 
-
 -- machine specific ------------------------------------------------------------
 
 
@@ -341,7 +302,7 @@ 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-13 are fakes; we pretend x86 has 6 conventionally-addressable
+- Registers fake0..fake5 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.
 
@@ -353,20 +314,20 @@ never generate them.
 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
+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 16
+fake1 = regSingle 17
+fake2 = regSingle 18
+fake3 = regSingle 19
+fake4 = regSingle 20
+fake5 = regSingle 21
 
 
 
@@ -383,41 +344,41 @@ rax, rbx, rcx, rdx, rsp, rbp, rsi, rdi,
   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 24
+xmm1  = regSingle 25
+xmm2  = regSingle 26
+xmm3  = regSingle 27
+xmm4  = regSingle 28
+xmm5  = regSingle 29
+xmm6  = regSingle 30
+xmm7  = regSingle 31
+xmm8  = regSingle 32
+xmm9  = regSingle 33
+xmm10 = regSingle 34
+xmm11 = regSingle 35
+xmm12 = regSingle 36
+xmm13 = regSingle 37
+xmm14 = regSingle 38
+xmm15 = regSingle 39
 
 allFPArgRegs :: [Reg]
-allFPArgRegs   = map RealReg [16 .. 23]
+allFPArgRegs   = map regSingle [firstxmm .. firstxmm+7]
 
 ripRel :: Displacement -> AddrMode
 ripRel imm     = AddrBaseIndex EABaseRip EAIndexNone imm
@@ -436,14 +397,14 @@ esp = rsp
 -}
 
 xmm :: RegNo -> Reg
-xmm n = RealReg (16+n)
+xmm n = regSingle (firstxmm+n)
 
 
 
 
 -- horror show -----------------------------------------------------------------
 freeReg                :: RegNo -> FastBool
-globalRegMaybe                 :: GlobalReg -> Maybe Reg
+globalRegMaybe                 :: GlobalReg -> Maybe RealReg
 allArgRegs             :: [Reg]
 callClobberedRegs      :: [Reg]
 
@@ -458,12 +419,6 @@ callClobberedRegs  :: [Reg]
 #define edi 5
 #define ebp 6
 #define esp 7
-#define fake0 8
-#define fake1 9
-#define fake2 10
-#define fake3 11
-#define fake4 12
-#define fake5 13
 #endif
 
 #if x86_64_TARGET_ARCH
@@ -483,25 +438,31 @@ callClobberedRegs         :: [Reg]
 #define r13   13
 #define r14   14
 #define r15   15
-#define xmm0  16
-#define xmm1  17
-#define xmm2  18
-#define xmm3  19
-#define xmm4  20
-#define xmm5  21
-#define xmm6  22
-#define xmm7  23
-#define xmm8  24
-#define xmm9  25
-#define xmm10 26
-#define xmm11 27
-#define xmm12 28
-#define xmm13 29
-#define xmm14 30
-#define xmm15 31
 #endif
 
-
+#define fake0 16
+#define fake1 17
+#define fake2 18
+#define fake3 19
+#define fake4 20
+#define fake5 21
+
+#define xmm0  24
+#define xmm1  25
+#define xmm2  26
+#define xmm3  27
+#define xmm4  28
+#define xmm5  29
+#define xmm6  30
+#define xmm7  31
+#define xmm8  32
+#define xmm9  33
+#define xmm10 34
+#define xmm11 35
+#define xmm12 36
+#define xmm13 37
+#define xmm14 38
+#define xmm15 39
 
 #if i386_TARGET_ARCH
 freeReg esp = fastBool False  --       %esp is the C stack pointer
@@ -579,79 +540,79 @@ freeReg _               = fastBool True
 -- 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
-globalRegMaybe (VanillaReg 1 _)                = Just (RealReg REG_R1)
+globalRegMaybe (VanillaReg 1 _)                = Just (RealRegSingle REG_R1)
 #endif 
 #ifdef REG_R2 
-globalRegMaybe (VanillaReg 2 _)                = Just (RealReg REG_R2)
+globalRegMaybe (VanillaReg 2 _)                = Just (RealRegSingle REG_R2)
 #endif 
 #ifdef REG_R3 
-globalRegMaybe (VanillaReg 3 _)        = Just (RealReg REG_R3)
+globalRegMaybe (VanillaReg 3 _)        = Just (RealRegSingle REG_R3)
 #endif 
 #ifdef REG_R4 
-globalRegMaybe (VanillaReg 4 _)                = Just (RealReg REG_R4)
+globalRegMaybe (VanillaReg 4 _)                = Just (RealRegSingle REG_R4)
 #endif 
 #ifdef REG_R5 
-globalRegMaybe (VanillaReg 5 _)                = Just (RealReg REG_R5)
+globalRegMaybe (VanillaReg 5 _)                = Just (RealRegSingle REG_R5)
 #endif 
 #ifdef REG_R6 
-globalRegMaybe (VanillaReg 6 _)                = Just (RealReg REG_R6)
+globalRegMaybe (VanillaReg 6 _)                = Just (RealRegSingle REG_R6)
 #endif 
 #ifdef REG_R7 
-globalRegMaybe (VanillaReg 7 _)                = Just (RealReg REG_R7)
+globalRegMaybe (VanillaReg 7 _)                = Just (RealRegSingle REG_R7)
 #endif 
 #ifdef REG_R8 
-globalRegMaybe (VanillaReg 8 _)                = Just (RealReg REG_R8)
+globalRegMaybe (VanillaReg 8 _)                = Just (RealRegSingle REG_R8)
 #endif
 #ifdef REG_R9 
-globalRegMaybe (VanillaReg 9 _)                = Just (RealReg REG_R9)
+globalRegMaybe (VanillaReg 9 _)                = Just (RealRegSingle REG_R9)
 #endif
 #ifdef REG_R10 
-globalRegMaybe (VanillaReg 10 _)       = Just (RealReg REG_R10)
+globalRegMaybe (VanillaReg 10 _)       = Just (RealRegSingle REG_R10)
 #endif
 #ifdef REG_F1
-globalRegMaybe (FloatReg 1)            = Just (RealReg REG_F1)
+globalRegMaybe (FloatReg 1)            = Just (RealRegSingle REG_F1)
 #endif                                 
 #ifdef REG_F2                          
-globalRegMaybe (FloatReg 2)            = Just (RealReg REG_F2)
+globalRegMaybe (FloatReg 2)            = Just (RealRegSingle REG_F2)
 #endif                                 
 #ifdef REG_F3                          
-globalRegMaybe (FloatReg 3)            = Just (RealReg REG_F3)
+globalRegMaybe (FloatReg 3)            = Just (RealRegSingle REG_F3)
 #endif                                 
 #ifdef REG_F4                          
-globalRegMaybe (FloatReg 4)            = Just (RealReg REG_F4)
+globalRegMaybe (FloatReg 4)            = Just (RealRegSingle REG_F4)
 #endif                                 
 #ifdef REG_D1                          
-globalRegMaybe (DoubleReg 1)           = Just (RealReg REG_D1)
+globalRegMaybe (DoubleReg 1)           = Just (RealRegSingle REG_D1)
 #endif                                 
 #ifdef REG_D2                          
-globalRegMaybe (DoubleReg 2)           = Just (RealReg REG_D2)
+globalRegMaybe (DoubleReg 2)           = Just (RealRegSingle REG_D2)
 #endif
 #ifdef REG_Sp      
-globalRegMaybe Sp                      = Just (RealReg REG_Sp)
+globalRegMaybe Sp                      = Just (RealRegSingle REG_Sp)
 #endif
 #ifdef REG_Lng1                                
-globalRegMaybe (LongReg 1)             = Just (RealReg REG_Lng1)
+globalRegMaybe (LongReg 1)             = Just (RealRegSingle REG_Lng1)
 #endif                                 
 #ifdef REG_Lng2                                
-globalRegMaybe (LongReg 2)             = Just (RealReg REG_Lng2)
+globalRegMaybe (LongReg 2)             = Just (RealRegSingle REG_Lng2)
 #endif
 #ifdef REG_SpLim                               
-globalRegMaybe SpLim                   = Just (RealReg REG_SpLim)
+globalRegMaybe SpLim                   = Just (RealRegSingle REG_SpLim)
 #endif                                 
 #ifdef REG_Hp                          
-globalRegMaybe Hp                      = Just (RealReg REG_Hp)
+globalRegMaybe Hp                      = Just (RealRegSingle REG_Hp)
 #endif                                 
 #ifdef REG_HpLim                       
-globalRegMaybe HpLim                   = Just (RealReg REG_HpLim)
+globalRegMaybe HpLim                   = Just (RealRegSingle REG_HpLim)
 #endif                                 
 #ifdef REG_CurrentTSO                          
-globalRegMaybe CurrentTSO              = Just (RealReg REG_CurrentTSO)
+globalRegMaybe CurrentTSO              = Just (RealRegSingle REG_CurrentTSO)
 #endif                                 
 #ifdef REG_CurrentNursery                              
-globalRegMaybe CurrentNursery          = Just (RealReg REG_CurrentNursery)
+globalRegMaybe CurrentNursery          = Just (RealRegSingle REG_CurrentNursery)
 #endif                                 
 globalRegMaybe _                       = Nothing
 
@@ -661,7 +622,7 @@ globalRegMaybe _                    = Nothing
 allArgRegs = panic "X86.Regs.allArgRegs: should not be used!"
 
 #elif x86_64_TARGET_ARCH
-allArgRegs = map RealReg [rdi,rsi,rdx,rcx,r8,r9]
+allArgRegs = map regSingle [rdi,rsi,rdx,rcx,r8,r9]
 
 #else
 allArgRegs  = panic "X86.Regs.allArgRegs: not defined for this architecture"
@@ -673,13 +634,13 @@ allArgRegs  = panic "X86.Regs.allArgRegs: not defined for this architecture"
 #if   i386_TARGET_ARCH
 -- caller-saves registers
 callClobberedRegs
-  = map RealReg [eax,ecx,edx,fake0,fake1,fake2,fake3,fake4,fake5]
+  = map regSingle ([eax,ecx,edx]  ++ floatregnos)
 
 #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])
+  = map regSingle ([rax,rcx,rdx,rsi,rdi,r8,r9,r10,r11] ++ floatregnos)
 
 #else
 callClobberedRegs
@@ -699,4 +660,12 @@ callClobberedRegs  = panic "X86.Regs.globalRegMaybe: not defined"
 
 #endif
 
+-- 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
+