1 -- -----------------------------------------------------------------------------
3 -- (c) The University of Glasgow 1994-2004
5 -- Machine-specific info about registers.
7 -- Also includes stuff about immediate operands, which are
8 -- often/usually quite entangled with registers.
10 -- -----------------------------------------------------------------------------
12 #include "nativeGen/NCG.h"
15 --------------------------------
16 -- Generic things, shared by all architectures.
19 get_GlobalReg_reg_or_addr,
21 allocatableRegsInClass,
24 --------------------------------
25 -- Things that are defined by the arch specific module.
56 -- machine specific things
57 #if powerpc_TARGET_ARCH
62 sp, r3, r4, r27, r28, f1, f20, f21,
64 #elif i386_TARGET_ARCH
65 EABase(..), EAIndex(..), addrModeRegs,
67 eax, ebx, ecx, edx, esi, edi, ebp, esp,
68 fake0, fake1, fake2, fake3, fake4, fake5,
70 #elif i386_64_TARGET_ARCH
71 EABase(..), EAIndex(..), addrModeRegs,
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,
83 #elif sparc_TARGET_ARCH
87 gReg, iReg, lReg, oReg, fReg,
88 fp, sp, g0, g1, g2, o0, o1, f0, f6, f8, f26, f27,
98 #include "HsVersions.h"
99 #include "../includes/MachRegs.h"
102 import CgUtils ( get_GlobalReg_addr )
103 import Outputable ( Outputable(..), pprPanic )
104 import qualified Outputable
115 #if alpha_TARGET_ARCH
117 #elif powerpc_TARGET_ARCH
119 #elif i386_TARGET_ARCH || x86_64_TARGET_ARCH
121 #elif sparc_TARGET_ARCH
124 #error "MachRegs: not defined for this architecture"
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
136 instance Outputable Reg where
137 ppr r = Outputable.text (show r)
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'
147 getHiVRegFromLo other
148 = pprPanic "getHiVRegFromLo" (ppr other)
150 -- -----------------------------------------------------------------------------
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.)
160 get_GlobalReg_reg_or_addr :: GlobalReg -> Either Reg CmmExpr
161 get_GlobalReg_reg_or_addr mid
162 = case globalRegMaybe mid of
164 Nothing -> Right (get_GlobalReg_addr mid)
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]
172 = let isFree i = isFastTrue (freeReg i)
173 in filter isFree allMachRegNos
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
182 RcInteger -> allocatableRegsInteger
183 RcDouble -> allocatableRegsDouble
184 RcFloat -> panic "MachRegs.allocatableRegsInClass: no match\n"
186 allocatableRegsInteger :: Int
187 allocatableRegsInteger
188 = length $ filter (\r -> regClass r == RcInteger)
189 $ map RealReg allocatableRegs
191 allocatableRegsDouble :: Int
192 allocatableRegsDouble
193 = length $ filter (\r -> regClass r == RcDouble)
194 $ map RealReg allocatableRegs
198 -- trivColorable ---------------------------------------------------------------
200 -- trivColorable function for the graph coloring allocator
201 -- This gets hammered by scanGraph during register allocation,
202 -- so needs to be fairly efficient.
204 -- NOTE: This only works for arcitectures with just RcInteger and RcDouble
205 -- (which are disjoint) ie. x86, x86_64 and ppc
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.
212 trivColorable :: RegClass -> UniqSet Reg -> UniqSet Reg -> Bool
213 trivColorable classN conflicts exclusions
216 acc :: Reg -> (Int, Int) -> (Int, Int)
219 RcInteger -> (cd+1, cf)
220 RcDouble -> (cd, cf+1)
221 _ -> panic "MachRegs.trivColorable: reg class not handled"
223 tmp = foldUniqSet acc (0, 0) conflicts
224 (countInt, countFloat) = foldUniqSet acc tmp exclusions
226 squeese = worst countInt classN RcInteger
227 + worst countFloat classN RcDouble
229 in squeese < allocatableRegsInClass classN
231 -- | Worst case displacement
232 -- node N of classN has n neighbors of class C.
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.
237 worst :: Int -> RegClass -> RegClass -> Int
238 worst n classN classC
242 RcInteger -> min n (allocatableRegsInClass RcInteger)
247 RcDouble -> min n (allocatableRegsInClass RcDouble)
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.
256 -- There is an allocatableRegsInClass :: RegClass -> Int, but doing the unboxing
257 -- is too slow for us here.
259 -- Compare MachRegs.freeRegs and MachRegs.h to get these numbers.
262 #define ALLOCATABLE_REGS_INTEGER (_ILIT(3))
263 #define ALLOCATABLE_REGS_DOUBLE (_ILIT(6))
264 #define ALLOCATABLE_REGS_FLOAT (_ILIT(0))
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))
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))
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))
282 #error ToDo: define ALLOCATABLE_REGS_INTEGER and ALLOCATABLE_REGS_DOUBLE
285 trivColorable :: RegClass -> UniqSet Reg -> UniqSet Reg -> Bool
286 trivColorable _ conflicts exclusions
287 = {-# SCC "trivColorable" #-}
291 NodeUFM _ _ left right
292 -> case isSqueesed cI cF right of
295 False -> isSqueesed cI' cF' left
296 True -> (# True, cI', cF' #)
299 -> case regClass reg of
301 -> case cI +# _ILIT(1) of
302 cI' -> (# cI' >=# ALLOCATABLE_REGS_INTEGER, cI', cF #)
305 -> case cF +# _ILIT(1) of
306 cF' -> (# cF' >=# ALLOCATABLE_REGS_DOUBLE, cI, cF' #)
309 -> case cF +# _ILIT(1) of
310 cF' -> (# cF' >=# ALLOCATABLE_REGS_FLOAT, cI, cF' #)
313 -> (# False, cI, cF #)
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