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
70 = II8 -- byte (signed)
71 -- | II8u -- byte (unsigned)
72 | II16 -- halfword (signed, 2 bytes)
73 -- | II16u -- halfword (unsigned, 2 bytes)
74 | II32 -- word (4 bytes)
75 | II64 -- word (8 bytes)
76 | FF32 -- IEEE single-precision floating pt
77 | FF64 -- IEEE single-precision floating pt
81 intSize, floatSize :: Width -> Size
87 intSize other = pprPanic "MachInstrs.intSize" (ppr other)
91 floatSize other = pprPanic "MachInstrs.intSize" (ppr other)
94 isFloatSize :: Size -> Bool
95 isFloatSize FF32 = True
96 isFloatSize FF64 = True
101 wordSize = intSize wordWidth
104 cmmTypeSize :: CmmType -> Size
106 | isFloatType ty = floatSize (typeWidth ty)
107 | otherwise = intSize (typeWidth ty)
110 sizeToWidth :: Size -> Width
123 mkVReg :: Unique -> Size -> Reg
125 | not (isFloatSize size)
130 FF32 -> VirtualRegF u
131 FF64 -> VirtualRegD u
135 -- immediates ------------------------------------------------------------------
138 | ImmInteger Integer -- Sigh.
139 | ImmCLbl CLabel -- AbstractC Label (with baggage)
140 | ImmLit Doc -- Simple string
141 | ImmIndex CLabel Int
144 | ImmConstantSum Imm Imm
145 | ImmConstantDiff Imm Imm
146 | LO Imm {- Possible restrictions... -}
150 strImmLit :: String -> Imm
151 strImmLit s = ImmLit (text s)
154 -- narrow to the width: a CmmInt might be out of
155 -- range, but we assume that ImmInteger only contains
156 -- in-range values. A signed value should be fine here.
157 litToImm :: CmmLit -> Imm
158 litToImm (CmmInt i w) = ImmInteger (narrowS w i)
159 litToImm (CmmFloat f W32) = ImmFloat f
160 litToImm (CmmFloat f W64) = ImmDouble f
161 litToImm (CmmLabel l) = ImmCLbl l
162 litToImm (CmmLabelOff l off) = ImmIndex l off
164 litToImm (CmmLabelDiffOff l1 l2 off)
166 (ImmConstantDiff (ImmCLbl l1) (ImmCLbl l2))
168 litToImm (CmmBlock id) = ImmCLbl (infoTblLbl id)
170 = panic "SPARC.Regs.litToImm: no match"
172 -- addressing modes ------------------------------------------------------------
178 addrOffset :: AddrMode -> Int -> Maybe AddrMode
181 AddrRegImm r (ImmInt n)
182 | fits13Bits n2 -> Just (AddrRegImm r (ImmInt n2))
183 | otherwise -> Nothing
186 AddrRegImm r (ImmInteger n)
187 | fits13Bits n2 -> Just (AddrRegImm r (ImmInt (fromInteger n2)))
188 | otherwise -> Nothing
189 where n2 = n + toInteger off
191 AddrRegReg r (RealReg 0)
192 | fits13Bits off -> Just (AddrRegImm r (ImmInt off))
193 | otherwise -> Nothing
199 -- registers -------------------------------------------------------------------
201 -- @spRel@ gives us a stack relative addressing mode for volatile
202 -- temporaries and for excess call arguments. @fpRel@, where
203 -- applicable, is the same but for the frame pointer.
204 spRel :: Int -- desired stack offset in words, positive or negative
207 spRel n = AddrRegImm sp (ImmInt (n * wORD_SIZE))
210 argRegs :: RegNo -> [Reg]
212 argRegs 1 = map (RealReg . oReg) [0]
213 argRegs 2 = map (RealReg . oReg) [0,1]
214 argRegs 3 = map (RealReg . oReg) [0,1,2]
215 argRegs 4 = map (RealReg . oReg) [0,1,2,3]
216 argRegs 5 = map (RealReg . oReg) [0,1,2,3,4]
217 argRegs 6 = map (RealReg . oReg) [0,1,2,3,4,5]
218 argRegs _ = panic "MachRegs.argRegs(sparc): don't know about >6 arguments!"
222 allArgRegs = map RealReg [oReg i | i <- [0..5]]
225 -- These are the regs which we cannot assume stay alive over a C call.
226 callClobberedRegs :: [Reg]
230 [oReg i | i <- [0..5]] ++
231 [gReg i | i <- [1..7]] ++
232 [fReg i | i <- [0..31]] )
235 allMachRegNos :: [RegNo]
238 ++ [32,34 .. nCG_FirstFloatReg-1]
239 ++ [nCG_FirstFloatReg .. 63])
242 -- | Get the class of a register.
243 {-# INLINE regClass #-}
244 regClass :: Reg -> RegClass
245 regClass (VirtualRegI _) = RcInteger
246 regClass (VirtualRegHi _) = RcInteger
247 regClass (VirtualRegF _) = RcFloat
248 regClass (VirtualRegD _) = RcDouble
251 | i < nCG_FirstFloatReg = RcDouble
252 | otherwise = RcFloat
255 showReg :: RegNo -> String
257 | n >= 0 && n < 8 = "%g" ++ show n
258 | n >= 8 && n < 16 = "%o" ++ show (n-8)
259 | n >= 16 && n < 24 = "%l" ++ show (n-16)
260 | n >= 24 && n < 32 = "%i" ++ show (n-24)
261 | n >= 32 && n < 64 = "%f" ++ show (n-32)
262 | otherwise = "%unknown_sparc_real_reg_" ++ show n
265 -- machine specific ------------------------------------------------------------
267 -- Duznae work for offsets greater than 13 bits; we just hope for the best
268 fpRel :: Int -> AddrMode
270 = AddrRegImm fp (ImmInt (n * wORD_SIZE))
273 {-# SPECIALIZE fits13Bits :: Int -> Bool, Integer -> Bool #-}
274 fits13Bits :: Integral a => a -> Bool
275 fits13Bits x = x >= -4096 && x < 4096
278 largeOffsetError :: Integral a => a -> b
280 = error ("ERROR: SPARC native-code generator cannot handle large offset ("
281 ++ show i ++ ");\nprobably because of large constant data structures;" ++
282 "\nworkaround: use -fvia-C on this module.\n")
286 The SPARC has 64 registers of interest; 32 integer registers and 32
287 floating point registers. The mapping of STG registers to SPARC
288 machine registers is defined in StgRegs.h. We are, of course,
289 prepared for any eventuality.
291 The whole fp-register pairing thing on sparcs is a huge nuisance. See
292 fptools/ghc/includes/MachRegs.h for a description of what's going on
297 gReg,lReg,iReg,oReg,fReg :: Int -> RegNo
305 g0, g1, g2, fp, sp, o0, o1, f0, f6, f8, f22, f26, f27 :: Reg
306 f6 = RealReg (fReg 6)
307 f8 = RealReg (fReg 8)
308 f22 = RealReg (fReg 22)
309 f26 = RealReg (fReg 26)
310 f27 = RealReg (fReg 27)
313 -- g0 is useful for codegen; is always zero, and writes to it vanish.
314 g0 = RealReg (gReg 0)
315 g1 = RealReg (gReg 1)
316 g2 = RealReg (gReg 2)
319 -- FP, SP, int and float return (from C) regs.
320 fp = RealReg (iReg 6)
321 sp = RealReg (oReg 6)
322 o0 = RealReg (oReg 0)
323 o1 = RealReg (oReg 1)
324 f0 = RealReg (fReg 0)
327 #if sparc_TARGET_ARCH
328 nCG_FirstFloatReg :: RegNo
329 nCG_FirstFloatReg = unRealReg NCG_FirstFloatReg
331 nCG_FirstFloatReg :: RegNo
332 nCG_FirstFloatReg = unRealReg f22
336 -- horror show -----------------------------------------------------------------
337 #if sparc_TARGET_ARCH
407 freeReg :: RegNo -> FastBool
408 globalRegMaybe :: GlobalReg -> Maybe Reg
410 #if defined(sparc_TARGET_ARCH)
413 freeReg g0 = fastBool False -- %g0 is always 0.
415 freeReg g5 = fastBool False -- %g5 is reserved (ABI).
416 freeReg g6 = fastBool False -- %g6 is reserved (ABI).
417 freeReg g7 = fastBool False -- %g7 is reserved (ABI).
418 freeReg i6 = fastBool False -- %i6 is our frame pointer.
419 freeReg i7 = fastBool False -- %i7 tends to have ret-addr-ish things
420 freeReg o6 = fastBool False -- %o6 is our stack pointer.
421 freeReg o7 = fastBool False -- %o7 holds ret addrs (???)
422 freeReg f0 = fastBool False -- %f0/%f1 are the C fp return registers.
423 freeReg f1 = fastBool False
425 -- TODO: Not sure about these BL 2009/01/10
426 -- Used for NCG spill tmps? what is this?
429 freeReg g1 = fastBool False -- %g1 is used for NCG spill tmp
430 freeReg g2 = fastBool False
431 freeReg f6 = fastBool False
432 freeReg f8 = fastBool False
433 freeReg f26 = fastBool False
434 freeReg f27 = fastBool False
438 freeReg REG_Base = fastBool False
441 freeReg REG_R1 = fastBool False
444 freeReg REG_R2 = fastBool False
447 freeReg REG_R3 = fastBool False
450 freeReg REG_R4 = fastBool False
453 freeReg REG_R5 = fastBool False
456 freeReg REG_R6 = fastBool False
459 freeReg REG_R7 = fastBool False
462 freeReg REG_R8 = fastBool False
465 freeReg REG_F1 = fastBool False
468 freeReg REG_F2 = fastBool False
471 freeReg REG_F3 = fastBool False
474 freeReg REG_F4 = fastBool False
477 freeReg REG_D1 = fastBool False
480 freeReg REG_D2 = fastBool False
483 freeReg REG_Sp = fastBool False
486 freeReg REG_Su = fastBool False
489 freeReg REG_SpLim = fastBool False
492 freeReg REG_Hp = fastBool False
495 freeReg REG_HpLim = fastBool False
497 freeReg _ = fastBool True
501 -- | Returns 'Nothing' if this global register is not stored
502 -- in a real machine register, otherwise returns @'Just' reg@, where
503 -- reg is the machine register it is stored in.
507 globalRegMaybe BaseReg = Just (RealReg REG_Base)
510 globalRegMaybe (VanillaReg 1 _) = Just (RealReg REG_R1)
513 globalRegMaybe (VanillaReg 2 _) = Just (RealReg REG_R2)
516 globalRegMaybe (VanillaReg 3 _) = Just (RealReg REG_R3)
519 globalRegMaybe (VanillaReg 4 _) = Just (RealReg REG_R4)
522 globalRegMaybe (VanillaReg 5 _) = Just (RealReg REG_R5)
525 globalRegMaybe (VanillaReg 6 _) = Just (RealReg REG_R6)
528 globalRegMaybe (VanillaReg 7 _) = Just (RealReg REG_R7)
531 globalRegMaybe (VanillaReg 8 _) = Just (RealReg REG_R8)
534 globalRegMaybe (VanillaReg 9 _) = Just (RealReg REG_R9)
537 globalRegMaybe (VanillaReg 10 _) = Just (RealReg REG_R10)
540 globalRegMaybe (FloatReg 1) = Just (RealReg REG_F1)
543 globalRegMaybe (FloatReg 2) = Just (RealReg REG_F2)
546 globalRegMaybe (FloatReg 3) = Just (RealReg REG_F3)
549 globalRegMaybe (FloatReg 4) = Just (RealReg REG_F4)
552 globalRegMaybe (DoubleReg 1) = Just (RealReg REG_D1)
555 globalRegMaybe (DoubleReg 2) = Just (RealReg REG_D2)
558 globalRegMaybe Sp = Just (RealReg REG_Sp)
561 globalRegMaybe (LongReg 1) = Just (RealReg REG_Lng1)
564 globalRegMaybe (LongReg 2) = Just (RealReg REG_Lng2)
567 globalRegMaybe SpLim = Just (RealReg REG_SpLim)
570 globalRegMaybe Hp = Just (RealReg REG_Hp)
573 globalRegMaybe HpLim = Just (RealReg REG_HpLim)
575 #ifdef REG_CurrentTSO
576 globalRegMaybe CurrentTSO = Just (RealReg REG_CurrentTSO)
578 #ifdef REG_CurrentNursery
579 globalRegMaybe CurrentNursery = Just (RealReg REG_CurrentNursery)
581 globalRegMaybe _ = Nothing
587 globalRegMaybe = panic "SPARC.Regs.globalRegMaybe: not defined"