NCG: Split MachRegs.hs into arch specific modules
[ghc-hetmet.git] / compiler / nativeGen / MachRegs.hs
1 -- -----------------------------------------------------------------------------
2 --
3 -- (c) The University of Glasgow 1994-2004
4 -- 
5 -- Machine-specific info about registers.
6 -- 
7 -- Also includes stuff about immediate operands, which are
8 -- often/usually quite entangled with registers.
9 -- 
10 -- -----------------------------------------------------------------------------
11
12 #include "nativeGen/NCG.h"
13
14 module MachRegs (
15         --------------------------------
16         -- Generic things, shared by all architectures.
17         module RegsBase,        
18         getHiVRegFromLo,
19         get_GlobalReg_reg_or_addr,
20         allocatableRegs,
21         allocatableRegsInClass,
22         trivColorable,
23
24         --------------------------------
25         -- Things that are defined by the arch specific module.
26         --
27
28         -- sizes
29         Size(..),
30         intSize, 
31         floatSize, 
32         isFloatSize, 
33         wordSize, 
34         cmmTypeSize, 
35         sizeToWidth,
36         mkVReg,
37
38         -- immediates
39         Imm(..), 
40         strImmLit, 
41         litToImm,
42
43         -- addressing modes
44         AddrMode(..),
45         addrOffset,
46
47         -- registers
48         spRel,
49         argRegs, 
50         allArgRegs, 
51         callClobberedRegs,
52         allMachRegNos,
53         regClass,
54         showReg,
55
56         -- machine specific things
57 #if   powerpc_TARGET_ARCH
58         allFPArgRegs,
59         fits16Bits,
60         makeImmediate,
61         freg,
62         sp, r3, r4, r27, r28, f1, f20, f21,
63
64 #elif i386_TARGET_ARCH
65         EABase(..), EAIndex(..), addrModeRegs,
66         
67         eax, ebx, ecx, edx, esi, edi, ebp, esp,
68         fake0, fake1, fake2, fake3, fake4, fake5,
69
70 #elif i386_64_TARGET_ARCH
71         EABase(..), EAIndex(..), addrModeRegs, 
72
73         ripRel,
74         allFPArgRegs,
75         
76         rax, rbx, rcx, rdx, rsi, rdi, rbp, rsp,
77         eax, ebx, ecx, edx, esi, edi, ebp, esp,
78         r8, r9, r10, r11, r12, r13, r14, r15,
79         xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7,
80         xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15,
81         xmm,
82
83 #elif sparc_TARGET_ARCH
84         fpRel,
85         fits13Bits, 
86         largeOffsetError,
87         gReg, iReg, lReg, oReg, fReg,
88         fp, sp, g0, g1, g2, o0, o1, f0, f6, f8, f26, f27,
89         nCG_FirstFloatReg,
90 #endif
91         -- horror show
92         freeReg,
93         globalRegMaybe  
94
95
96 where
97
98 #include "HsVersions.h"
99 #include "../includes/MachRegs.h"
100
101 import Cmm
102 import CgUtils          ( get_GlobalReg_addr )
103 import Outputable       ( Outputable(..), pprPanic )
104 import qualified Outputable
105 import Panic
106 import Unique
107 import UniqSet
108 import FastTypes
109 import FastBool
110 import UniqFM
111
112
113 import RegsBase
114
115 #if   alpha_TARGET_ARCH
116 import Alpha.Regs
117 #elif powerpc_TARGET_ARCH
118 import PPC.Regs
119 #elif i386_TARGET_ARCH || x86_64_TARGET_ARCH
120 import X86.Regs
121 #elif sparc_TARGET_ARCH
122 import SPARC.Regs
123 #else
124 #error "MachRegs: not defined for this architecture"
125 #endif
126
127
128
129 instance Show Reg where
130         show (RealReg i)      = showReg i
131         show (VirtualRegI u)  = "%vI_" ++ show u
132         show (VirtualRegHi u) = "%vHi_" ++ show u
133         show (VirtualRegF u)  = "%vF_" ++ show u
134         show (VirtualRegD u)  = "%vD_" ++ show u
135
136 instance Outputable Reg where
137         ppr r = Outputable.text (show r)
138
139
140 -- Determine the upper-half vreg for a 64-bit quantity on a 32-bit platform
141 -- when supplied with the vreg for the lower-half of the quantity.
142 -- (NB. Not reversible).
143 getHiVRegFromLo :: Reg -> Reg
144 getHiVRegFromLo (VirtualRegI u) 
145    = VirtualRegHi (newTagUnique u 'H') -- makes a pseudo-unique with tag 'H'
146
147 getHiVRegFromLo other 
148    = pprPanic "getHiVRegFromLo" (ppr other)
149
150 -- -----------------------------------------------------------------------------
151 -- Global registers
152
153 -- We map STG registers onto appropriate CmmExprs.  Either they map
154 -- to real machine registers or stored as offsets from BaseReg.  Given
155 -- a GlobalReg, get_GlobalReg_reg_or_addr produces either the real
156 -- register it is in, on this platform, or a CmmExpr denoting the
157 -- address in the register table holding it.
158 -- (See also get_GlobalReg_addr in CgUtils.)
159
160 get_GlobalReg_reg_or_addr       :: GlobalReg -> Either Reg CmmExpr
161 get_GlobalReg_reg_or_addr mid
162    = case globalRegMaybe mid of
163         Just rr -> Left rr
164         Nothing -> Right (get_GlobalReg_addr mid)
165
166
167 -- allocatableRegs is allMachRegNos with the fixed-use regs removed.
168 -- i.e., these are the regs for which we are prepared to allow the
169 -- register allocator to attempt to map VRegs to.
170 allocatableRegs :: [RegNo]
171 allocatableRegs
172    = let isFree i = isFastTrue (freeReg i)
173      in  filter isFree allMachRegNos
174
175
176 -- | The number of regs in each class.
177 --      We go via top level CAFs to ensure that we're not recomputing
178 --      the length of these lists each time the fn is called.
179 allocatableRegsInClass :: RegClass -> Int
180 allocatableRegsInClass cls
181  = case cls of
182         RcInteger       -> allocatableRegsInteger
183         RcDouble        -> allocatableRegsDouble
184         RcFloat         -> panic "MachRegs.allocatableRegsInClass: no match\n"
185
186 allocatableRegsInteger :: Int
187 allocatableRegsInteger  
188         = length $ filter (\r -> regClass r == RcInteger) 
189                  $ map RealReg allocatableRegs
190
191 allocatableRegsDouble :: Int
192 allocatableRegsDouble
193         = length $ filter (\r -> regClass r == RcDouble) 
194                  $ map RealReg allocatableRegs
195
196
197
198 -- trivColorable ---------------------------------------------------------------
199
200 -- trivColorable function for the graph coloring allocator
201 --      This gets hammered by scanGraph during register allocation,
202 --      so needs to be fairly efficient.
203 --
204 --      NOTE:   This only works for arcitectures with just RcInteger and RcDouble
205 --              (which are disjoint) ie. x86, x86_64 and ppc
206 --
207
208 --      BL 2007/09
209 --      Doing a nice fold over the UniqSet makes trivColorable use
210 --      32% of total compile time and 42% of total alloc when compiling SHA1.lhs from darcs.
211 {-
212 trivColorable :: RegClass -> UniqSet Reg -> UniqSet Reg -> Bool
213 trivColorable classN conflicts exclusions
214  = let
215
216         acc :: Reg -> (Int, Int) -> (Int, Int)
217         acc r (cd, cf)  
218          = case regClass r of
219                 RcInteger       -> (cd+1, cf)
220                 RcDouble        -> (cd,   cf+1)
221                 _               -> panic "MachRegs.trivColorable: reg class not handled"
222
223         tmp                     = foldUniqSet acc (0, 0) conflicts
224         (countInt,  countFloat) = foldUniqSet acc tmp    exclusions
225
226         squeese         = worst countInt   classN RcInteger
227                         + worst countFloat classN RcDouble
228
229    in   squeese < allocatableRegsInClass classN
230
231 -- | Worst case displacement
232 --      node N of classN has n neighbors of class C.
233 --
234 --      We currently only have RcInteger and RcDouble, which don't conflict at all.
235 --      This is a bit boring compared to what's in RegArchX86.
236 --
237 worst :: Int -> RegClass -> RegClass -> Int
238 worst n classN classC
239  = case classN of
240         RcInteger
241          -> case classC of
242                 RcInteger       -> min n (allocatableRegsInClass RcInteger)
243                 RcDouble        -> 0
244                 
245         RcDouble
246          -> case classC of
247                 RcDouble        -> min n (allocatableRegsInClass RcDouble)
248                 RcInteger       -> 0
249 -}
250
251
252 -- The number of allocatable regs is hard coded here so we can do a fast comparision
253 -- in trivColorable. It's ok if these numbers are _less_ than the actual number of
254 -- free regs, but they can't be more or the register conflict graph won't color.
255 --
256 -- There is an allocatableRegsInClass :: RegClass -> Int, but doing the unboxing
257 -- is too slow for us here.
258 --
259 -- Compare MachRegs.freeRegs  and MachRegs.h to get these numbers.
260 --
261 #if i386_TARGET_ARCH
262 #define ALLOCATABLE_REGS_INTEGER (_ILIT(3))
263 #define ALLOCATABLE_REGS_DOUBLE  (_ILIT(6))
264 #define ALLOCATABLE_REGS_FLOAT   (_ILIT(0))
265
266 #elif x86_64_TARGET_ARCH
267 #define ALLOCATABLE_REGS_INTEGER (_ILIT(5))
268 #define ALLOCATABLE_REGS_DOUBLE  (_ILIT(2))
269 #define ALLOCATABLE_REGS_FLOAT   (_ILIT(0))
270
271 #elif powerpc_TARGET_ARCH
272 #define ALLOCATABLE_REGS_INTEGER (_ILIT(16))
273 #define ALLOCATABLE_REGS_DOUBLE  (_ILIT(26))
274 #define ALLOCATABLE_REGS_FLOAT   (_ILIT(0))
275
276 #elif sparc_TARGET_ARCH
277 #define ALLOCATABLE_REGS_INTEGER (_ILIT(3))
278 #define ALLOCATABLE_REGS_DOUBLE  (_ILIT(6))
279 #define ALLOCATABLE_REGS_FLOAT   (_ILIT(0))
280
281 #else
282 #error ToDo: define ALLOCATABLE_REGS_INTEGER and ALLOCATABLE_REGS_DOUBLE
283 #endif
284
285 trivColorable :: RegClass -> UniqSet Reg -> UniqSet Reg -> Bool
286 trivColorable _ conflicts exclusions
287  = {-# SCC "trivColorable" #-}
288    let
289         isSqueesed cI cF ufm
290           = case ufm of
291                 NodeUFM _ _ left right
292                  -> case isSqueesed cI cF right of
293                         (# s, cI', cF' #)
294                          -> case s of
295                                 False   -> isSqueesed cI' cF' left
296                                 True    -> (# True, cI', cF' #)
297
298                 LeafUFM _ reg
299                  -> case regClass reg of
300                         RcInteger
301                          -> case cI +# _ILIT(1) of
302                                 cI' -> (# cI' >=# ALLOCATABLE_REGS_INTEGER, cI', cF #)
303
304                         RcDouble
305                          -> case cF +# _ILIT(1) of
306                                 cF' -> (# cF' >=# ALLOCATABLE_REGS_DOUBLE,  cI, cF' #)
307
308                         RcFloat 
309                          -> case cF +# _ILIT(1) of
310                                 cF' -> (# cF' >=# ALLOCATABLE_REGS_FLOAT,   cI, cF' #)
311
312                 EmptyUFM
313                  ->     (# False, cI, cF #)
314
315    in case isSqueesed (_ILIT(0)) (_ILIT(0)) conflicts of
316         (# False, cI', cF' #)
317          -> case isSqueesed cI' cF' exclusions of
318                 (# s, _, _ #)   -> not s
319
320         (# True, _, _ #)
321          -> False
322
323