1 -- -----------------------------------------------------------------------------
3 -- (c) The University of Glasgow 1994-2004
5 -- -----------------------------------------------------------------------------
15 -- machine specific info
16 gReg, iReg, lReg, oReg, fReg,
17 fp, sp, g0, g1, g2, o0, o1, f0, f1, f6, f8, f22, f26, f27,
21 get_GlobalReg_reg_or_addr,
43 import CgUtils ( get_GlobalReg_addr )
51 The SPARC has 64 registers of interest; 32 integer registers and 32
52 floating point registers. The mapping of STG registers to SPARC
53 machine registers is defined in StgRegs.h. We are, of course,
54 prepared for any eventuality.
56 The whole fp-register pairing thing on sparcs is a huge nuisance. See
57 includes/stg/MachRegs.h for a description of what's going on
62 -- | Get the standard name for the register with this number.
63 showReg :: RegNo -> String
65 | n >= 0 && n < 8 = "%g" ++ show n
66 | n >= 8 && n < 16 = "%o" ++ show (n-8)
67 | n >= 16 && n < 24 = "%l" ++ show (n-16)
68 | n >= 24 && n < 32 = "%i" ++ show (n-24)
69 | n >= 32 && n < 64 = "%f" ++ show (n-32)
70 | otherwise = panic "SPARC.Regs.showReg: unknown sparc register"
73 -- Get the register class of a certain real reg
74 classOfRealReg :: RealReg -> RegClass
79 | otherwise -> RcFloat
81 RealRegPair{} -> RcDouble
84 -- | regSqueeze_class reg
85 -- Calculuate the maximum number of register colors that could be
86 -- denied to a node of this class due to having this reg
89 {-# INLINE virtualRegSqueeze #-}
90 virtualRegSqueeze :: RegClass -> VirtualReg -> FastInt
92 virtualRegSqueeze cls vr
96 VirtualRegI{} -> _ILIT(1)
97 VirtualRegHi{} -> _ILIT(1)
98 VirtualRegF{} -> _ILIT(0)
99 VirtualRegD{} -> _ILIT(0)
103 VirtualRegI{} -> _ILIT(0)
104 VirtualRegHi{} -> _ILIT(0)
105 VirtualRegF{} -> _ILIT(1)
106 VirtualRegD{} -> _ILIT(2)
110 VirtualRegI{} -> _ILIT(0)
111 VirtualRegHi{} -> _ILIT(0)
112 VirtualRegF{} -> _ILIT(1)
113 VirtualRegD{} -> _ILIT(1)
115 {-# INLINE realRegSqueeze #-}
116 realRegSqueeze :: RegClass -> RealReg -> FastInt
118 realRegSqueeze cls rr
123 | regNo < 32 -> _ILIT(1)
124 | otherwise -> _ILIT(0)
126 RealRegPair{} -> _ILIT(0)
131 | regNo < 32 -> _ILIT(0)
132 | otherwise -> _ILIT(1)
134 RealRegPair{} -> _ILIT(2)
139 | regNo < 32 -> _ILIT(0)
140 | otherwise -> _ILIT(1)
142 RealRegPair{} -> _ILIT(1)
145 -- | All the allocatable registers in the machine,
146 -- including register pairs.
147 allRealRegs :: [RealReg]
149 = [ (RealRegSingle i) | i <- [0..63] ]
150 ++ [ (RealRegPair i (i+1)) | i <- [32, 34 .. 62 ] ]
153 -- | Get the regno for this sort of reg
154 gReg, lReg, iReg, oReg, fReg :: Int -> RegNo
156 gReg x = x -- global regs
157 oReg x = (8 + x) -- output regs
158 lReg x = (16 + x) -- local regs
159 iReg x = (24 + x) -- input regs
160 fReg x = (32 + x) -- float regs
163 -- | Some specific regs used by the code generator.
164 g0, g1, g2, fp, sp, o0, o1, f0, f1, f6, f8, f22, f26, f27 :: Reg
166 f6 = RegReal (RealRegSingle (fReg 6))
167 f8 = RegReal (RealRegSingle (fReg 8))
168 f22 = RegReal (RealRegSingle (fReg 22))
169 f26 = RegReal (RealRegSingle (fReg 26))
170 f27 = RegReal (RealRegSingle (fReg 27))
172 -- g0 is always zero, and writes to it vanish.
173 g0 = RegReal (RealRegSingle (gReg 0))
174 g1 = RegReal (RealRegSingle (gReg 1))
175 g2 = RegReal (RealRegSingle (gReg 2))
177 -- FP, SP, int and float return (from C) regs.
178 fp = RegReal (RealRegSingle (iReg 6))
179 sp = RegReal (RealRegSingle (oReg 6))
180 o0 = RegReal (RealRegSingle (oReg 0))
181 o1 = RegReal (RealRegSingle (oReg 1))
182 f0 = RegReal (RealRegSingle (fReg 0))
183 f1 = RegReal (RealRegSingle (fReg 1))
185 -- | Produce the second-half-of-a-double register given the first half.
187 fPair :: Reg -> Maybe Reg
189 | n >= 32 && n `mod` 2 == 0 = Just (RealReg (n+1))
191 fPair (VirtualRegD u)
192 = Just (VirtualRegHi u)
195 = trace ("MachInstrs.fPair: can't get high half of supposed double reg " ++ showPpr reg)
200 -- | All the regs that the register allocator can allocate to,
201 -- with the the fixed use regs removed.
203 allocatableRegs :: [RealReg]
208 -> isFastTrue (freeReg r)
211 -> isFastTrue (freeReg r1)
212 && isFastTrue (freeReg r2)
214 in filter isFree allRealRegs
218 -- We map STG registers onto appropriate CmmExprs. Either they map
219 -- to real machine registers or stored as offsets from BaseReg. Given
220 -- a GlobalReg, get_GlobalReg_reg_or_addr produces either the real
221 -- register it is in, on this platform, or a CmmExpr denoting the
222 -- address in the register table holding it.
223 -- (See also get_GlobalReg_addr in CgUtils.)
225 get_GlobalReg_reg_or_addr :: GlobalReg -> Either RealReg CmmExpr
226 get_GlobalReg_reg_or_addr mid
227 = case globalRegMaybe mid of
229 Nothing -> Right (get_GlobalReg_addr mid)
232 -- | The registers to place arguments for function calls,
233 -- for some number of arguments.
235 argRegs :: RegNo -> [Reg]
239 1 -> map (RegReal . RealRegSingle . oReg) [0]
240 2 -> map (RegReal . RealRegSingle . oReg) [0,1]
241 3 -> map (RegReal . RealRegSingle . oReg) [0,1,2]
242 4 -> map (RegReal . RealRegSingle . oReg) [0,1,2,3]
243 5 -> map (RegReal . RealRegSingle . oReg) [0,1,2,3,4]
244 6 -> map (RegReal . RealRegSingle . oReg) [0,1,2,3,4,5]
245 _ -> panic "MachRegs.argRegs(sparc): don't know about >6 arguments!"
248 -- | All all the regs that could possibly be returned by argRegs
252 = map (RegReal . RealRegSingle) [oReg i | i <- [0..5]]
255 -- These are the regs that we cannot assume stay alive over a C call.
256 -- TODO: Why can we assume that o6 isn't clobbered? -- BL 2009/02
258 callClobberedRegs :: [Reg]
260 = map (RegReal . RealRegSingle)
262 [oReg i | i <- [0..5]] ++
263 [gReg i | i <- [1..7]] ++
264 [fReg i | i <- [0..31]] )
268 -- | Make a virtual reg with this size.
269 mkVirtualReg :: Unique -> Size -> VirtualReg
271 | not (isFloatSize size)
276 FF32 -> VirtualRegF u
277 FF64 -> VirtualRegD u
281 regDotColor :: RealReg -> SDoc
283 = case classOfRealReg reg of
284 RcInteger -> text "blue"
285 RcFloat -> text "red"
286 RcDouble -> text "green"
291 -- Hard coded freeReg / globalRegMaybe -----------------------------------------
292 -- This isn't being used at the moment because we're generating
293 -- these functions from the information in
294 -- includes/stg/MachRegs.hs via RegPlate.hs
296 -- | Check whether a machine register is free for allocation.
297 -- This needs to match the info in includes/stg/MachRegs.h
298 -- otherwise modules compiled with the NCG won't be compatible
302 freeReg :: RegNo -> FastBool
305 -- %g0(r0) is always 0.
308 -- %g1(r1) - %g4(r4) are allocable -----------------
311 -- are reserved for the OS
316 -- %o0(r8) - %o5(r13) are allocable ----------------
319 -- is the C stack pointer
323 -- holds C return addresses (???)
326 -- %l0(r16) is allocable ---------------------------
328 -- %l1(r17) - %l5(r21)
329 -- are STG regs R1 - R5
336 -- %l6(r22) - %l7(r23) are allocable --------------
338 -- %i0(r24) - %i5(r29)
339 -- are STG regs Sp, Base, SpLim, Hp, R6
345 -- %i5(r28) is allocable --------------------------
350 -- is the C frame pointer
354 -- is used for C return addresses
357 -- %f0(r32) - %f1(r33)
358 -- are C fp return registers
362 -- %f2(r34) - %f5(r37)
363 -- are STG regs D1 - D2
369 -- %f22(r54) - %f25(r57)
370 -- are STG regs F1 - F4
376 -- regs not matched above are allocable.
381 -- | Returns Just the real register that a global register is stored in.
382 -- Returns Nothing if the global has no real register, and is stored
383 -- in the in-memory register table instead.
386 globalRegMaybe :: GlobalReg -> Maybe Reg
389 -- Argument and return regs
390 VanillaReg 1 _ -> Just (RealReg 17) -- %l1
391 VanillaReg 2 _ -> Just (RealReg 18) -- %l2
392 VanillaReg 3 _ -> Just (RealReg 19) -- %l3
393 VanillaReg 4 _ -> Just (RealReg 20) -- %l4
394 VanillaReg 5 _ -> Just (RealReg 21) -- %l5
395 VanillaReg 6 _ -> Just (RealReg 29) -- %i5
397 FloatReg 1 -> Just (RealReg 54) -- %f22
398 FloatReg 2 -> Just (RealReg 55) -- %f23
399 FloatReg 3 -> Just (RealReg 56) -- %f24
400 FloatReg 4 -> Just (RealReg 57) -- %f25
402 DoubleReg 1 -> Just (RealReg 34) -- %f2
403 DoubleReg 2 -> Just (RealReg 36) -- %f4
406 Sp -> Just (RealReg 24) -- %i0
407 SpLim -> Just (RealReg 26) -- %i2
408 Hp -> Just (RealReg 27) -- %i3
410 BaseReg -> Just (RealReg 25) -- %i1