1a341bbddabc8b321fba90bcf09cb6e9dd7c1459
[ghc-hetmet.git] / compiler / nativeGen / Reg.hs
1
2 -- | An architecture independent description of a register.
3 --      This needs to stay architecture independent because it is used
4 --      by NCGMonad and the register allocators, which are shared
5 --      by all architectures.
6 --
7 module Reg (
8         RegNo,
9         Reg(..),
10         isRealReg,
11         unRealReg,
12         isVirtualReg,
13         renameVirtualReg,
14         getHiVRegFromLo
15 )
16
17 where
18
19 import Outputable
20 import Unique
21 import Panic
22
23 -- | An identifier for a real machine register.
24 type RegNo 
25         = Int
26
27 -- RealRegs are machine regs which are available for allocation, in
28 --      the usual way.  We know what class they are, because that's part of
29 --      the processor's architecture.
30
31 -- VirtualRegs are virtual registers.  The register allocator will
32 --      eventually have to map them into RealRegs, or into spill slots.
33 --
34 --      VirtualRegs are allocated on the fly, usually to represent a single
35 --      value in the abstract assembly code (i.e. dynamic registers are
36 --      usually single assignment).  
37 --
38 --      With the new register allocator, the
39 --      single assignment restriction isn't necessary to get correct code,
40 --      although a better register allocation will result if single
41 --      assignment is used -- because the allocator maps a VirtualReg into
42 --      a single RealReg, even if the VirtualReg has multiple live ranges.
43
44 --      Virtual regs can be of either class, so that info is attached.
45 data Reg
46         = RealReg      {-# UNPACK #-} !RegNo
47         | VirtualRegI  {-# UNPACK #-} !Unique
48         | VirtualRegHi {-# UNPACK #-} !Unique  -- High part of 2-word register
49         | VirtualRegF  {-# UNPACK #-} !Unique
50         | VirtualRegD  {-# UNPACK #-} !Unique
51         deriving (Eq, Ord)
52
53
54 -- We like to have Uniques for Reg so that we can make UniqFM and UniqSets 
55 -- in the register allocator.
56 instance Uniquable Reg where
57         getUnique (RealReg i)      = mkUnique 'C' i
58         getUnique (VirtualRegI u)  = u
59         getUnique (VirtualRegHi u) = u
60         getUnique (VirtualRegF u)  = u
61         getUnique (VirtualRegD u)  = u
62
63
64 -- | Print a reg in a generic manner
65 --      If you want the architecture specific names, then use the pprReg 
66 --      function from the appropriate Ppr module.
67 instance Outputable Reg where
68         ppr reg
69          = case reg of
70                 RealReg i       -> text "%r"    <> int i
71                 VirtualRegI  u  -> text "%vI_"  <> pprUnique u
72                 VirtualRegHi u  -> text "%vHi_" <> pprUnique u
73                 VirtualRegF  u  -> text "%vF_"  <> pprUnique u
74                 VirtualRegD  u  -> text "%vD_"  <> pprUnique u
75
76
77
78 isRealReg :: Reg -> Bool
79 isRealReg = not . isVirtualReg
80
81 -- | Take the RegNo from a real reg
82 unRealReg :: Reg -> RegNo
83 unRealReg (RealReg i)   = i
84 unRealReg _             = panic "unRealReg on VirtualReg"
85
86 isVirtualReg :: Reg -> Bool
87 isVirtualReg (RealReg _)      = False
88 isVirtualReg (VirtualRegI _)  = True
89 isVirtualReg (VirtualRegHi _) = True
90 isVirtualReg (VirtualRegF _)  = True
91 isVirtualReg (VirtualRegD _)  = True
92
93
94 renameVirtualReg :: Unique -> Reg -> Reg
95 renameVirtualReg u r
96  = case r of
97         RealReg _       -> error "renameVirtualReg: can't change unique on a real reg"
98         VirtualRegI _   -> VirtualRegI  u
99         VirtualRegHi _  -> VirtualRegHi u
100         VirtualRegF _   -> VirtualRegF  u
101         VirtualRegD _   -> VirtualRegD  u
102
103 -- Determine the upper-half vreg for a 64-bit quantity on a 32-bit platform
104 -- when supplied with the vreg for the lower-half of the quantity.
105 -- (NB. Not reversible).
106 getHiVRegFromLo :: Reg -> Reg
107 getHiVRegFromLo (VirtualRegI u) 
108    = VirtualRegHi (newTagUnique u 'H') -- makes a pseudo-unique with tag 'H'
109
110 getHiVRegFromLo _ 
111    = panic "RegsBase.getHiVRegFromLo"
112
113