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