1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
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"
|