1 -- -----------------------------------------------------------------------------
3 -- (c) The University of Glasgow 1994-2004
5 -- -----------------------------------------------------------------------------
37 -- machine specific info
41 gReg, iReg, lReg, oReg, fReg,
42 fp, sp, g0, g1, g2, o0, o1, f0, f6, f8, f26, f27,
52 #include "nativeGen/NCG.h"
53 #include "HsVersions.h"
54 #include "../includes/MachRegs.h"
60 import CLabel ( CLabel )
62 import Outputable ( Outputable(..), pprPanic, panic )
63 import qualified Outputable
68 -- sizes -----------------------------------------------------------------------
70 -- | A 'Size' also includes format information, such as whether
71 -- the word is signed or unsigned.
74 = II8 -- byte (signed)
75 | II16 -- halfword (signed, 2 bytes)
76 | II32 -- word (4 bytes)
77 | II64 -- word (8 bytes)
78 | FF32 -- IEEE single-precision floating pt
79 | FF64 -- IEEE single-precision floating pt
83 -- | Get the integer size of this width.
84 intSize :: Width -> Size
91 other -> pprPanic "SPARC.Regs.intSize" (ppr other)
94 -- | Get the float size of this width.
95 floatSize :: Width -> Size
100 other -> pprPanic "SPARC.Regs.intSize" (ppr other)
103 -- | Check if a size represents a floating point value.
104 isFloatSize :: Size -> Bool
112 -- | Size of a machine word.
113 -- This is big enough to hold a pointer.
115 wordSize = intSize wordWidth
118 -- | Convert a Cmm type to a Size.
119 cmmTypeSize :: CmmType -> Size
121 | isFloatType ty = floatSize (typeWidth ty)
122 | otherwise = intSize (typeWidth ty)
125 -- | Get the Width of a Size.
126 sizeToWidth :: Size -> Width
137 -- | Make a virtual reg with this size.
138 mkVReg :: Unique -> Size -> Reg
140 | not (isFloatSize size)
145 FF32 -> VirtualRegF u
146 FF64 -> VirtualRegD u
150 -- immediates ------------------------------------------------------------------
152 -- | An immediate value.
153 -- Not all of these are directly representable by the machine.
154 -- Things like ImmLit are slurped out and put in a data segment instead.
162 -- AbstractC Label (with baggage)
167 | ImmIndex CLabel Int
171 | ImmConstantSum Imm Imm
172 | ImmConstantDiff Imm Imm
178 -- | Create a ImmLit containing this string.
179 strImmLit :: String -> Imm
180 strImmLit s = ImmLit (text s)
183 -- | Convert a CmmLit to an Imm.
184 -- Narrow to the width: a CmmInt might be out of
185 -- range, but we assume that ImmInteger only contains
186 -- in-range values. A signed value should be fine here.
188 litToImm :: CmmLit -> Imm
191 CmmInt i w -> ImmInteger (narrowS w i)
192 CmmFloat f W32 -> ImmFloat f
193 CmmFloat f W64 -> ImmDouble f
194 CmmLabel l -> ImmCLbl l
195 CmmLabelOff l off -> ImmIndex l off
197 CmmLabelDiffOff l1 l2 off
199 (ImmConstantDiff (ImmCLbl l1) (ImmCLbl l2))
202 CmmBlock id -> ImmCLbl (infoTblLbl id)
203 _ -> panic "SPARC.Regs.litToImm: no match"
207 -- addressing modes ------------------------------------------------------------
209 -- | Represents a memory address in an instruction.
210 -- Being a RISC machine, the SPARC addressing modes are very regular.
213 = AddrRegReg Reg Reg -- addr = r1 + r2
214 | AddrRegImm Reg Imm -- addr = r1 + imm
217 -- | Add an integer offset to the address in an AddrMode.
219 addrOffset :: AddrMode -> Int -> Maybe AddrMode
222 AddrRegImm r (ImmInt n)
223 | fits13Bits n2 -> Just (AddrRegImm r (ImmInt n2))
224 | otherwise -> Nothing
227 AddrRegImm r (ImmInteger n)
228 | fits13Bits n2 -> Just (AddrRegImm r (ImmInt (fromInteger n2)))
229 | otherwise -> Nothing
230 where n2 = n + toInteger off
232 AddrRegReg r (RealReg 0)
233 | fits13Bits off -> Just (AddrRegImm r (ImmInt off))
234 | otherwise -> Nothing
240 -- registers -------------------------------------------------------------------
242 -- | Get an AddrMode relative to the address in sp.
243 -- This gives us a stack relative addressing mode for volatile
244 -- temporaries and for excess call arguments.
246 spRel :: Int -- ^ stack offset in words, positive or negative
249 spRel n = AddrRegImm sp (ImmInt (n * wORD_SIZE))
252 -- | The registers to place arguments for function calls,
253 -- for some number of arguments.
255 argRegs :: RegNo -> [Reg]
259 1 -> map (RealReg . oReg) [0]
260 2 -> map (RealReg . oReg) [0,1]
261 3 -> map (RealReg . oReg) [0,1,2]
262 4 -> map (RealReg . oReg) [0,1,2,3]
263 5 -> map (RealReg . oReg) [0,1,2,3,4]
264 6 -> map (RealReg . oReg) [0,1,2,3,4,5]
265 _ -> panic "MachRegs.argRegs(sparc): don't know about >6 arguments!"
268 -- | All all the regs that could possibly be returned by argRegs
272 = map RealReg [oReg i | i <- [0..5]]
275 -- These are the regs that we cannot assume stay alive over a C call.
276 -- TODO: Why can we assume that o6 isn't clobbered? -- BL 2009/02
278 callClobberedRegs :: [Reg]
282 [oReg i | i <- [0..5]] ++
283 [gReg i | i <- [1..7]] ++
284 [fReg i | i <- [0..31]] )
287 -- | The RegNos corresponding to all the registers in the machine.
288 -- For SPARC we use f0-f22 as doubles, so pretend that the high halves
289 -- of these, ie f23, f25 .. don't exist.
291 allMachRegNos :: [RegNo]
294 ++ [32,34 .. nCG_FirstFloatReg-1]
295 ++ [nCG_FirstFloatReg .. 63])
298 -- | Get the class of a register.
299 {-# INLINE regClass #-}
300 regClass :: Reg -> RegClass
303 VirtualRegI _ -> RcInteger
304 VirtualRegHi _ -> RcInteger
305 VirtualRegF _ -> RcFloat
306 VirtualRegD _ -> RcDouble
308 | i < 32 -> RcInteger
309 | i < nCG_FirstFloatReg -> RcDouble
310 | otherwise -> RcFloat
313 -- | Get the standard name for the register with this number.
314 showReg :: RegNo -> String
316 | n >= 0 && n < 8 = "%g" ++ show n
317 | n >= 8 && n < 16 = "%o" ++ show (n-8)
318 | n >= 16 && n < 24 = "%l" ++ show (n-16)
319 | n >= 24 && n < 32 = "%i" ++ show (n-24)
320 | n >= 32 && n < 64 = "%f" ++ show (n-32)
321 | otherwise = panic "SPARC.Regs.showReg: unknown sparc register"
324 -- machine specific ------------------------------------------------------------
326 -- | Get an address relative to the frame pointer.
327 -- This doesn't work work for offsets greater than 13 bits; we just hope for the best
329 fpRel :: Int -> AddrMode
331 = AddrRegImm fp (ImmInt (n * wORD_SIZE))
334 -- | Check whether an offset is representable with 13 bits.
335 fits13Bits :: Integral a => a -> Bool
336 fits13Bits x = x >= -4096 && x < 4096
338 {-# SPECIALIZE fits13Bits :: Int -> Bool, Integer -> Bool #-}
342 largeOffsetError :: Integral a => a -> b
344 = panic ("ERROR: SPARC native-code generator cannot handle large offset ("
345 ++ show i ++ ");\nprobably because of large constant data structures;" ++
346 "\nworkaround: use -fvia-C on this module.\n")
351 The SPARC has 64 registers of interest; 32 integer registers and 32
352 floating point registers. The mapping of STG registers to SPARC
353 machine registers is defined in StgRegs.h. We are, of course,
354 prepared for any eventuality.
356 The whole fp-register pairing thing on sparcs is a huge nuisance. See
357 fptools/ghc/includes/MachRegs.h for a description of what's going on
362 -- | Get the regno for this sort of reg
363 gReg, lReg, iReg, oReg, fReg :: Int -> RegNo
365 gReg x = x -- global regs
366 oReg x = (8 + x) -- output regs
367 lReg x = (16 + x) -- local regs
368 iReg x = (24 + x) -- input regs
369 fReg x = (32 + x) -- float regs
372 -- | Some specific regs used by the code generator.
373 g0, g1, g2, fp, sp, o0, o1, f0, f6, f8, f22, f26, f27 :: Reg
375 f6 = RealReg (fReg 6)
376 f8 = RealReg (fReg 8)
377 f22 = RealReg (fReg 22)
378 f26 = RealReg (fReg 26)
379 f27 = RealReg (fReg 27)
381 g0 = RealReg (gReg 0) -- g0 is always zero, and writes to it vanish.
382 g1 = RealReg (gReg 1)
383 g2 = RealReg (gReg 2)
385 -- FP, SP, int and float return (from C) regs.
386 fp = RealReg (iReg 6)
387 sp = RealReg (oReg 6)
388 o0 = RealReg (oReg 0)
389 o1 = RealReg (oReg 1)
390 f0 = RealReg (fReg 0)
393 nCG_FirstFloatReg :: RegNo
394 nCG_FirstFloatReg = unRealReg NCG_FirstFloatReg
396 nCG_FirstFloatReg :: RegNo
397 nCG_FirstFloatReg = unRealReg f22
401 -- horror show -----------------------------------------------------------------
402 #if sparc_TARGET_ARCH
436 -- | Check whether a machine register is free for allocation.
437 -- This needs to match the info in includes/MachRegs.h otherwise modules
438 -- compiled with the NCG won't be compatible with via-C ones.
440 freeReg :: RegNo -> FastBool
443 -- %g0(r0) is always 0.
446 -- %g1(r1) - %g4(r4) are allocable -----------------
448 freeReg :: RegNo -> FastBool
450 -- %o0(r8) - %o5(r13) are allocable ----------------
453 -- is the C stack pointer
457 -- holds C return addresses (???)
460 -- %l0(r16) is allocable ---------------------------
462 -- %l1(r17) - %l5(r21)
463 -- are STG regs R1 - R5
470 -- %l6(r22) - %l7(r23) are allocable --------------
472 -- %i0(r24) - %i5(r29)
473 -- are STG regs Sp, Base, SpLim, Hp, HpLim, R6
482 -- is the C frame pointer
486 -- is used for C return addresses
489 -- %f0(r32) - %f1(r33)
490 -- are C fp return registers
494 -- %f2(r34) - %f5(r37)
495 -- are STG regs D1 - D2
501 -- %f22(r54) - %f25(r57)
502 -- are STG regs F1 - F4
508 -- regs not matched above are allocable.
513 -- | Returns Just the real register that a global register is stored in.
514 -- Returns Nothing if the global has no real register, and is stored
515 -- in the in-memory register table instead.
517 globalRegMaybe :: GlobalReg -> Maybe Reg
520 -- Argument and return regs
521 VanillaReg 1 _ -> Just (RealReg 17) -- %l1
522 VanillaReg 2 _ -> Just (RealReg 18) -- %l2
523 VanillaReg 3 _ -> Just (RealReg 19) -- %l3
524 VanillaReg 4 _ -> Just (RealReg 20) -- %l4
525 VanillaReg 5 _ -> Just (RealReg 21) -- %l5
526 VanillaReg 6 _ -> Just (RealReg 29) -- %i5
528 FloatReg 1 -> Just (RealReg 54) -- %f22
529 FloatReg 2 -> Just (RealReg 55) -- %f23
530 FloatReg 3 -> Just (RealReg 56) -- %f24
531 FloatReg 4 -> Just (RealReg 57) -- %f25
533 DoubleReg 1 -> Just (RealReg 34) -- %f2
534 DoubleReg 2 -> Just (RealReg 36) -- %f4
537 Sp -> Just (RealReg 24) -- %i0
538 SpLim -> Just (RealReg 26) -- %i2
539 Hp -> Just (RealReg 27) -- %i3
540 HpLim -> Just (RealReg 28) -- %i4
542 globalRegMaybe :: GlobalReg -> Maybe Reg
549 globalRegMaybe = panic "SPARC.Regs.globalRegMaybe: not defined"