Remove CPP from nativeGen/RegAlloc/Graph/TrivColorable.hs
[ghc-hetmet.git] / compiler / nativeGen / RegAlloc / Graph / ArchX86.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
9 module RegAlloc.Graph.ArchX86 (
10         classOfReg,
11         regsOfClass,
12         regName,
13         regAlias,
14         worst,
15         squeese,
16 ) where
17
18 import RegAlloc.Graph.ArchBase  (Reg(..), RegSub(..), RegClass(..))
19
20 import UniqSet
21
22 -- | Determine the class of a register
23 classOfReg :: Reg -> RegClass
24 classOfReg reg
25  = case reg of
26         Reg c _         -> c
27         
28         RegSub SubL16 _ -> ClassG16
29         RegSub SubL8  _ -> ClassG8
30         RegSub SubL8H _ -> ClassG8
31
32         
33 -- | Determine all the regs that make up a certain class.
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 regName :: Reg -> Maybe String
55 regName reg
56  = case reg of
57         Reg ClassG32 i  
58          | i <= 7       -> Just ([ "eax", "ebx", "ecx", "edx", "ebp", "esi", "edi", "esp" ] !! i)
59
60         RegSub SubL16 (Reg ClassG32 i)
61          | i <= 7       -> Just ([ "ax", "bx", "cx", "dx", "bp", "si", "di", "sp"] !! i)
62          
63         RegSub SubL8  (Reg ClassG32 i)
64          | i <= 3       -> Just ([ "al", "bl", "cl", "dl"] !! i)
65          
66         RegSub SubL8H (Reg ClassG32 i)
67          | i <= 3       -> Just ([ "ah", "bh", "ch", "dh"] !! i)
68
69         _               -> Nothing
70
71         
72 -- | Which regs alias what other regs
73 regAlias :: Reg -> UniqSet Reg
74 regAlias reg
75  = case reg of
76
77         -- 32 bit regs alias all of the subregs
78         Reg ClassG32 i
79          
80          -- for eax, ebx, ecx, eds
81          |  i <= 3              
82          -> mkUniqSet $ [ Reg ClassG32 i, RegSub SubL16 reg, RegSub SubL8 reg, RegSub SubL8H reg ]
83          
84          -- for esi, edi, esp, ebp
85          | 4 <= i && i <= 7     
86          -> mkUniqSet $ [ Reg ClassG32 i, RegSub SubL16 reg ]
87         
88         
89         -- 16 bit subregs alias the whole reg
90         RegSub SubL16 r@(Reg ClassG32 _)        
91          ->     regAlias r
92         
93         -- 8 bit subregs alias the 32 and 16, but not the other 8 bit subreg
94         RegSub SubL8  r@(Reg ClassG32 _)
95          -> mkUniqSet $ [ r, RegSub SubL16 r, RegSub SubL8 r ]
96
97         RegSub SubL8H r@(Reg ClassG32 _)
98          -> mkUniqSet $ [ r, RegSub SubL16 r, RegSub SubL8H r ]
99         
100         -- fp
101         Reg ClassF64 _  
102          -> unitUniqSet reg
103
104         _ -> error "regAlias: invalid register"
105
106
107 -- | Optimised versions of RegColorBase.{worst, squeese} specific to x86
108
109 worst :: Int -> RegClass -> RegClass -> Int
110 worst n classN classC
111  = case classN of
112         ClassG32
113          -> case classC of
114                 ClassG32        -> min n 8
115                 ClassG16        -> min n 8
116                 ClassG8         -> min n 4
117                 ClassF64        -> 0
118                 
119         ClassG16
120          -> case classC of
121                 ClassG32        -> min n 8
122                 ClassG16        -> min n 8
123                 ClassG8         -> min n 4
124                 ClassF64        -> 0
125                 
126         ClassG8
127          -> case classC of
128                 ClassG32        -> min (n*2) 8
129                 ClassG16        -> min (n*2) 8
130                 ClassG8         -> min n 8
131                 ClassF64        -> 0
132                 
133         ClassF64
134          -> case classC of
135                 ClassF64        -> min n 6
136                 _               -> 0
137                 
138 squeese :: RegClass -> [(Int, RegClass)] -> Int
139 squeese classN countCs
140         = sum (map (\(i, classC) -> worst i classN classC) countCs)
141         
142
143
144
145