never executed always true always false
1
2 -- | A description of the register set of the X86.
3 --
4 -- This isn't used directly in GHC proper.
5 --
6 -- See RegArchBase.hs for the reference.
7 -- See MachRegs.hs for the actual trivColorable function used in GHC.
8 --
9 module GHC.CmmToAsm.Reg.Graph.X86 (
10 classOfReg,
11 regsOfClass,
12 regName,
13 regAlias,
14 worst,
15 squeese,
16 ) where
17
18 import GHC.Prelude
19
20 import GHC.CmmToAsm.Reg.Graph.Base (Reg(..), RegSub(..), RegClass(..))
21 import GHC.Types.Unique.Set
22
23 import qualified Data.Array as A
24
25
26 -- | Determine the class of a register
27 classOfReg :: Reg -> RegClass
28 classOfReg reg
29 = case reg of
30 Reg c _ -> c
31
32 RegSub SubL16 _ -> ClassG16
33 RegSub SubL8 _ -> ClassG8
34 RegSub SubL8H _ -> ClassG8
35
36
37 -- | Determine all the regs that make up a certain class.
38 regsOfClass :: RegClass -> UniqSet Reg
39 regsOfClass c
40 = case c of
41 ClassG32
42 -> mkUniqSet [ Reg ClassG32 i
43 | i <- [0..7] ]
44
45 ClassG16
46 -> mkUniqSet [ RegSub SubL16 (Reg ClassG32 i)
47 | i <- [0..7] ]
48
49 ClassG8
50 -> unionUniqSets
51 (mkUniqSet [ RegSub SubL8 (Reg ClassG32 i) | i <- [0..3] ])
52 (mkUniqSet [ RegSub SubL8H (Reg ClassG32 i) | i <- [0..3] ])
53
54 ClassF64
55 -> mkUniqSet [ Reg ClassF64 i
56 | i <- [0..5] ]
57
58
59 -- | Determine the common name of a reg
60 -- returns Nothing if this reg is not part of the machine.
61 regName :: Reg -> Maybe String
62 regName reg
63 = case reg of
64 Reg ClassG32 i
65 | i <= 7 ->
66 let names = A.listArray (0,8)
67 [ "eax", "ebx", "ecx", "edx"
68 , "ebp", "esi", "edi", "esp" ]
69 in Just $ names A.! i
70
71 RegSub SubL16 (Reg ClassG32 i)
72 | i <= 7 ->
73 let names = A.listArray (0,8)
74 [ "ax", "bx", "cx", "dx"
75 , "bp", "si", "di", "sp"]
76 in Just $ names A.! i
77
78 RegSub SubL8 (Reg ClassG32 i)
79 | i <= 3 ->
80 let names = A.listArray (0,4) [ "al", "bl", "cl", "dl"]
81 in Just $ names A.! i
82
83 RegSub SubL8H (Reg ClassG32 i)
84 | i <= 3 ->
85 let names = A.listArray (0,4) [ "ah", "bh", "ch", "dh"]
86 in Just $ names A.! i
87
88 _ -> Nothing
89
90
91 -- | Which regs alias what other regs.
92 regAlias :: Reg -> UniqSet Reg
93 regAlias reg
94 = case reg of
95
96 -- 32 bit regs alias all of the subregs
97 Reg ClassG32 i
98
99 -- for eax, ebx, ecx, eds
100 | i <= 3
101 -> mkUniqSet
102 $ [ Reg ClassG32 i, RegSub SubL16 reg
103 , RegSub SubL8 reg, RegSub SubL8H reg ]
104
105 -- for esi, edi, esp, ebp
106 | 4 <= i && i <= 7
107 -> mkUniqSet
108 $ [ Reg ClassG32 i, RegSub SubL16 reg ]
109
110 -- 16 bit subregs alias the whole reg
111 RegSub SubL16 r@(Reg ClassG32 _)
112 -> regAlias r
113
114 -- 8 bit subregs alias the 32 and 16, but not the other 8 bit subreg
115 RegSub SubL8 r@(Reg ClassG32 _)
116 -> mkUniqSet $ [ r, RegSub SubL16 r, RegSub SubL8 r ]
117
118 RegSub SubL8H r@(Reg ClassG32 _)
119 -> mkUniqSet $ [ r, RegSub SubL16 r, RegSub SubL8H r ]
120
121 -- fp
122 Reg ClassF64 _
123 -> unitUniqSet reg
124
125 _ -> error "regAlias: invalid register"
126
127
128 -- | Optimised versions of RegColorBase.{worst, squeese} specific to x86
129 worst :: Int -> RegClass -> RegClass -> Int
130 worst n classN classC
131 = case classN of
132 ClassG32
133 -> case classC of
134 ClassG32 -> min n 8
135 ClassG16 -> min n 8
136 ClassG8 -> min n 4
137 ClassF64 -> 0
138
139 ClassG16
140 -> case classC of
141 ClassG32 -> min n 8
142 ClassG16 -> min n 8
143 ClassG8 -> min n 4
144 ClassF64 -> 0
145
146 ClassG8
147 -> case classC of
148 ClassG32 -> min (n*2) 8
149 ClassG16 -> min (n*2) 8
150 ClassG8 -> min n 8
151 ClassF64 -> 0
152
153 ClassF64
154 -> case classC of
155 ClassF64 -> min n 6
156 _ -> 0
157
158 squeese :: RegClass -> [(Int, RegClass)] -> Int
159 squeese classN countCs
160 = sum (map (\(i, classC) -> worst i classN classC) countCs)
161