NCG: Split up the native code generator into arch specific modules
[ghc-hetmet.git] / compiler / nativeGen / Reg.hs
diff --git a/compiler/nativeGen/Reg.hs b/compiler/nativeGen/Reg.hs
new file mode 100644 (file)
index 0000000..1a341bb
--- /dev/null
@@ -0,0 +1,113 @@
+
+-- | An architecture independent description of a register.
+--     This needs to stay architecture independent because it is used
+--     by NCGMonad and the register allocators, which are shared
+--     by all architectures.
+--
+module Reg (
+       RegNo,
+       Reg(..),
+       isRealReg,
+       unRealReg,
+       isVirtualReg,
+       renameVirtualReg,
+       getHiVRegFromLo
+)
+
+where
+
+import Outputable
+import Unique
+import Panic
+
+-- | An identifier for a real machine register.
+type RegNo 
+       = Int
+
+-- 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.
+
+-- 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.
+
+--     Virtual regs can be of either class, so that info is attached.
+data Reg
+       = RealReg      {-# UNPACK #-} !RegNo
+       | VirtualRegI  {-# UNPACK #-} !Unique
+       | VirtualRegHi {-# UNPACK #-} !Unique  -- High part of 2-word register
+       | VirtualRegF  {-# UNPACK #-} !Unique
+       | VirtualRegD  {-# UNPACK #-} !Unique
+       deriving (Eq, Ord)
+
+
+-- We like to have Uniques for Reg so that we can make UniqFM and UniqSets 
+-- in the register allocator.
+instance Uniquable Reg where
+       getUnique (RealReg i)      = mkUnique 'C' i
+       getUnique (VirtualRegI u)  = u
+       getUnique (VirtualRegHi u) = u
+       getUnique (VirtualRegF u)  = u
+       getUnique (VirtualRegD u)  = u
+
+
+-- | Print a reg in a generic manner
+--     If you want the architecture specific names, then use the pprReg 
+--     function from the appropriate Ppr module.
+instance Outputable Reg where
+       ppr reg
+        = case reg of
+               RealReg i       -> text "%r"    <> int i
+               VirtualRegI  u  -> text "%vI_"  <> pprUnique u
+               VirtualRegHi u  -> text "%vHi_" <> pprUnique u
+               VirtualRegF  u  -> text "%vF_"  <> pprUnique u
+               VirtualRegD  u  -> text "%vD_"  <> pprUnique u
+
+
+
+isRealReg :: Reg -> Bool
+isRealReg = not . isVirtualReg
+
+-- | Take the RegNo from a real reg
+unRealReg :: Reg -> RegNo
+unRealReg (RealReg i)  = i
+unRealReg _            = panic "unRealReg on VirtualReg"
+
+isVirtualReg :: Reg -> Bool
+isVirtualReg (RealReg _)      = False
+isVirtualReg (VirtualRegI _)  = True
+isVirtualReg (VirtualRegHi _) = True
+isVirtualReg (VirtualRegF _)  = True
+isVirtualReg (VirtualRegD _)  = True
+
+
+renameVirtualReg :: Unique -> Reg -> Reg
+renameVirtualReg u r
+ = case r of
+       RealReg _       -> error "renameVirtualReg: can't change unique on a real reg"
+       VirtualRegI _   -> VirtualRegI  u
+       VirtualRegHi _  -> VirtualRegHi u
+       VirtualRegF _   -> VirtualRegF  u
+       VirtualRegD _   -> VirtualRegD  u
+
+-- 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.
+-- (NB. Not reversible).
+getHiVRegFromLo :: Reg -> Reg
+getHiVRegFromLo (VirtualRegI u) 
+   = VirtualRegHi (newTagUnique u 'H') -- makes a pseudo-unique with tag 'H'
+
+getHiVRegFromLo _ 
+   = panic "RegsBase.getHiVRegFromLo"
+
+