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 || x86_64_TARGET_ARCH
65 EABase(..), EAIndex(..), addrModeRegs,
67 eax, ebx, ecx, edx, esi, edi, ebp, esp,
68 fake0, fake1, fake2, fake3, fake4, fake5,
69 rax, rbx, rcx, rdx, rsi, rdi, rbp, rsp,
70 r8, r9, r10, r11, r12, r13, r14, r15,
71 xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7,
72 xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15,
78 #elif sparc_TARGET_ARCH
82 gReg, iReg, lReg, oReg, fReg,
83 fp, sp, g0, g1, g2, o0, o1, f0, f6, f8, f26, f27,
93 #include "HsVersions.h"
94 #include "../includes/MachRegs.h"
97 import CgUtils ( get_GlobalReg_addr )
98 import Outputable ( Outputable(..), pprPanic )
99 import qualified Outputable
110 #if alpha_TARGET_ARCH
112 #elif powerpc_TARGET_ARCH
114 #elif i386_TARGET_ARCH || x86_64_TARGET_ARCH
116 #elif sparc_TARGET_ARCH
119 #error "Regs: not defined for this architecture"
124 instance Show Reg where
125 show (RealReg i) = showReg i
126 show (VirtualRegI u) = "%vI_" ++ show u
127 show (VirtualRegHi u) = "%vHi_" ++ show u
128 show (VirtualRegF u) = "%vF_" ++ show u
129 show (VirtualRegD u) = "%vD_" ++ show u
131 instance Outputable Reg where
132 ppr r = Outputable.text (show r)
135 -- Determine the upper-half vreg for a 64-bit quantity on a 32-bit platform
136 -- when supplied with the vreg for the lower-half of the quantity.
137 -- (NB. Not reversible).
138 getHiVRegFromLo :: Reg -> Reg
139 getHiVRegFromLo (VirtualRegI u)
140 = VirtualRegHi (newTagUnique u 'H') -- makes a pseudo-unique with tag 'H'
142 getHiVRegFromLo other
143 = pprPanic "getHiVRegFromLo" (ppr other)
145 -- -----------------------------------------------------------------------------
148 -- We map STG registers onto appropriate CmmExprs. Either they map
149 -- to real machine registers or stored as offsets from BaseReg. Given
150 -- a GlobalReg, get_GlobalReg_reg_or_addr produces either the real
151 -- register it is in, on this platform, or a CmmExpr denoting the
152 -- address in the register table holding it.
153 -- (See also get_GlobalReg_addr in CgUtils.)
155 get_GlobalReg_reg_or_addr :: GlobalReg -> Either Reg CmmExpr
156 get_GlobalReg_reg_or_addr mid
157 = case globalRegMaybe mid of
159 Nothing -> Right (get_GlobalReg_addr mid)
162 -- allocatableRegs is allMachRegNos with the fixed-use regs removed.
163 -- i.e., these are the regs for which we are prepared to allow the
164 -- register allocator to attempt to map VRegs to.
165 allocatableRegs :: [RegNo]
167 = let isFree i = isFastTrue (freeReg i)
168 in filter isFree allMachRegNos
171 -- | The number of regs in each class.
172 -- We go via top level CAFs to ensure that we're not recomputing
173 -- the length of these lists each time the fn is called.
174 allocatableRegsInClass :: RegClass -> Int
175 allocatableRegsInClass cls
177 RcInteger -> allocatableRegsInteger
178 RcDouble -> allocatableRegsDouble
179 RcFloat -> panic "Regs.allocatableRegsInClass: no match\n"
181 allocatableRegsInteger :: Int
182 allocatableRegsInteger
183 = length $ filter (\r -> regClass r == RcInteger)
184 $ map RealReg allocatableRegs
186 allocatableRegsDouble :: Int
187 allocatableRegsDouble
188 = length $ filter (\r -> regClass r == RcDouble)
189 $ map RealReg allocatableRegs
193 -- trivColorable ---------------------------------------------------------------
195 -- trivColorable function for the graph coloring allocator
196 -- This gets hammered by scanGraph during register allocation,
197 -- so needs to be fairly efficient.
199 -- NOTE: This only works for arcitectures with just RcInteger and RcDouble
200 -- (which are disjoint) ie. x86, x86_64 and ppc
204 -- Doing a nice fold over the UniqSet makes trivColorable use
205 -- 32% of total compile time and 42% of total alloc when compiling SHA1.lhs from darcs.
207 trivColorable :: RegClass -> UniqSet Reg -> UniqSet Reg -> Bool
208 trivColorable classN conflicts exclusions
211 acc :: Reg -> (Int, Int) -> (Int, Int)
214 RcInteger -> (cd+1, cf)
215 RcDouble -> (cd, cf+1)
216 _ -> panic "Regs.trivColorable: reg class not handled"
218 tmp = foldUniqSet acc (0, 0) conflicts
219 (countInt, countFloat) = foldUniqSet acc tmp exclusions
221 squeese = worst countInt classN RcInteger
222 + worst countFloat classN RcDouble
224 in squeese < allocatableRegsInClass classN
226 -- | Worst case displacement
227 -- node N of classN has n neighbors of class C.
229 -- We currently only have RcInteger and RcDouble, which don't conflict at all.
230 -- This is a bit boring compared to what's in RegArchX86.
232 worst :: Int -> RegClass -> RegClass -> Int
233 worst n classN classC
237 RcInteger -> min n (allocatableRegsInClass RcInteger)
242 RcDouble -> min n (allocatableRegsInClass RcDouble)
247 -- The number of allocatable regs is hard coded here so we can do a fast comparision
248 -- in trivColorable. It's ok if these numbers are _less_ than the actual number of
249 -- free regs, but they can't be more or the register conflict graph won't color.
251 -- There is an allocatableRegsInClass :: RegClass -> Int, but doing the unboxing
252 -- is too slow for us here.
254 -- Compare Regs.freeRegs and MachRegs.h to get these numbers.
257 #define ALLOCATABLE_REGS_INTEGER (_ILIT(3))
258 #define ALLOCATABLE_REGS_DOUBLE (_ILIT(6))
259 #define ALLOCATABLE_REGS_FLOAT (_ILIT(0))
261 #elif x86_64_TARGET_ARCH
262 #define ALLOCATABLE_REGS_INTEGER (_ILIT(5))
263 #define ALLOCATABLE_REGS_DOUBLE (_ILIT(2))
264 #define ALLOCATABLE_REGS_FLOAT (_ILIT(0))
266 #elif powerpc_TARGET_ARCH
267 #define ALLOCATABLE_REGS_INTEGER (_ILIT(16))
268 #define ALLOCATABLE_REGS_DOUBLE (_ILIT(26))
269 #define ALLOCATABLE_REGS_FLOAT (_ILIT(0))
271 #elif sparc_TARGET_ARCH
272 #define ALLOCATABLE_REGS_INTEGER (_ILIT(3))
273 #define ALLOCATABLE_REGS_DOUBLE (_ILIT(6))
274 #define ALLOCATABLE_REGS_FLOAT (_ILIT(0))
277 #error ToDo: define ALLOCATABLE_REGS_INTEGER and ALLOCATABLE_REGS_DOUBLE
280 trivColorable :: RegClass -> UniqSet Reg -> UniqSet Reg -> Bool
281 trivColorable _ conflicts exclusions
282 = {-# SCC "trivColorable" #-}
286 NodeUFM _ _ left right
287 -> case isSqueesed cI cF right of
290 False -> isSqueesed cI' cF' left
291 True -> (# True, cI', cF' #)
294 -> case regClass reg of
296 -> case cI +# _ILIT(1) of
297 cI' -> (# cI' >=# ALLOCATABLE_REGS_INTEGER, cI', cF #)
300 -> case cF +# _ILIT(1) of
301 cF' -> (# cF' >=# ALLOCATABLE_REGS_DOUBLE, cI, cF' #)
304 -> case cF +# _ILIT(1) of
305 cF' -> (# cF' >=# ALLOCATABLE_REGS_FLOAT, cI, cF' #)
308 -> (# False, cI, cF #)
310 in case isSqueesed (_ILIT(0)) (_ILIT(0)) conflicts of
311 (# False, cI', cF' #)
312 -> case isSqueesed cI' cF' exclusions of
313 (# s, _, _ #) -> not s