1 -- -----------------------------------------------------------------------------
3 -- (c) The University of Glasgow 1994-2004
5 -- -----------------------------------------------------------------------------
38 sp, r3, r4, r27, r28, f1, f20, f21,
49 #include "nativeGen/NCG.h"
50 #include "HsVersions.h"
51 #include "../includes/stg/MachRegs.h"
59 import CLabel ( CLabel )
63 import Outputable ( panic, SDoc )
64 import qualified Outputable
69 import Data.Word ( Word8, Word16, Word32 )
70 import Data.Int ( Int8, Int16, Int32 )
73 -- squeese functions for the graph allocator -----------------------------------
75 -- | regSqueeze_class reg
76 -- Calculuate the maximum number of register colors that could be
77 -- denied to a node of this class due to having this reg
80 {-# INLINE virtualRegSqueeze #-}
81 virtualRegSqueeze :: RegClass -> VirtualReg -> FastInt
82 virtualRegSqueeze cls vr
86 VirtualRegI{} -> _ILIT(1)
87 VirtualRegHi{} -> _ILIT(1)
92 VirtualRegD{} -> _ILIT(1)
93 VirtualRegF{} -> _ILIT(0)
98 {-# INLINE realRegSqueeze #-}
99 realRegSqueeze :: RegClass -> RealReg -> FastInt
100 realRegSqueeze cls rr
105 | regNo < 32 -> _ILIT(1) -- first fp reg is 32
106 | otherwise -> _ILIT(0)
108 RealRegPair{} -> _ILIT(0)
113 | regNo < 32 -> _ILIT(0)
114 | otherwise -> _ILIT(1)
116 RealRegPair{} -> _ILIT(0)
120 mkVirtualReg :: Unique -> Size -> VirtualReg
122 | not (isFloatSize size) = VirtualRegI u
125 FF32 -> VirtualRegD u
126 FF64 -> VirtualRegD u
127 _ -> panic "mkVirtualReg"
129 regDotColor :: RealReg -> SDoc
131 = case classOfRealReg reg of
132 RcInteger -> Outputable.text "blue"
133 RcFloat -> Outputable.text "red"
134 RcDouble -> Outputable.text "green"
135 RcDoubleSSE -> Outputable.text "yellow"
138 -- immediates ------------------------------------------------------------------
141 | ImmInteger Integer -- Sigh.
142 | ImmCLbl CLabel -- AbstractC Label (with baggage)
143 | ImmLit Doc -- Simple string
144 | ImmIndex CLabel Int
147 | ImmConstantSum Imm Imm
148 | ImmConstantDiff Imm Imm
151 | HA Imm {- high halfword adjusted -}
154 strImmLit :: String -> Imm
155 strImmLit s = ImmLit (text s)
158 litToImm :: CmmLit -> Imm
159 litToImm (CmmInt i w) = ImmInteger (narrowS w i)
160 -- narrow to the width: a CmmInt might be out of
161 -- range, but we assume that ImmInteger only contains
162 -- in-range values. A signed value should be fine here.
163 litToImm (CmmFloat f W32) = ImmFloat f
164 litToImm (CmmFloat f W64) = ImmDouble f
165 litToImm (CmmLabel l) = ImmCLbl l
166 litToImm (CmmLabelOff l off) = ImmIndex l off
167 litToImm (CmmLabelDiffOff l1 l2 off)
169 (ImmConstantDiff (ImmCLbl l1) (ImmCLbl l2))
171 litToImm (CmmBlock id) = ImmCLbl (infoTblLbl id)
172 litToImm _ = panic "PPC.Regs.litToImm: no match"
175 -- addressing modes ------------------------------------------------------------
182 addrOffset :: AddrMode -> Int -> Maybe AddrMode
185 AddrRegImm r (ImmInt n)
186 | fits16Bits n2 -> Just (AddrRegImm r (ImmInt n2))
187 | otherwise -> Nothing
190 AddrRegImm r (ImmInteger n)
191 | fits16Bits n2 -> Just (AddrRegImm r (ImmInt (fromInteger n2)))
192 | otherwise -> Nothing
193 where n2 = n + toInteger off
198 -- registers -------------------------------------------------------------------
199 -- @spRel@ gives us a stack relative addressing mode for volatile
200 -- temporaries and for excess call arguments. @fpRel@, where
201 -- applicable, is the same but for the frame pointer.
203 spRel :: Int -- desired stack offset in words, positive or negative
206 spRel n = AddrRegImm sp (ImmInt (n * wORD_SIZE))
209 -- argRegs is the set of regs which are read for an n-argument call to C.
210 -- For archs which pass all args on the stack (x86), is empty.
211 -- Sparc passes up to the first 6 args in regs.
212 -- Dunno about Alpha.
213 argRegs :: RegNo -> [Reg]
215 argRegs 1 = map regSingle [3]
216 argRegs 2 = map regSingle [3,4]
217 argRegs 3 = map regSingle [3..5]
218 argRegs 4 = map regSingle [3..6]
219 argRegs 5 = map regSingle [3..7]
220 argRegs 6 = map regSingle [3..8]
221 argRegs 7 = map regSingle [3..9]
222 argRegs 8 = map regSingle [3..10]
223 argRegs _ = panic "MachRegs.argRegs(powerpc): don't know about >8 arguments!"
227 allArgRegs = map regSingle [3..10]
230 -- these are the regs which we cannot assume stay alive over a C call.
231 callClobberedRegs :: [Reg]
232 #if defined(darwin_TARGET_OS)
234 = map regSingle (0:[2..12] ++ map fReg [0..13])
236 #elif defined(linux_TARGET_OS)
238 = map regSingle (0:[2..13] ++ map fReg [0..13])
242 = panic "PPC.Regs.callClobberedRegs: not defined for this architecture"
246 allMachRegNos :: [RegNo]
247 allMachRegNos = [0..63]
250 {-# INLINE classOfRealReg #-}
251 classOfRealReg :: RealReg -> RegClass
252 classOfRealReg (RealRegSingle i)
254 | otherwise = RcDouble
256 classOfRealReg (RealRegPair{})
257 = panic "regClass(ppr): no reg pairs on this architecture"
259 showReg :: RegNo -> String
261 | n >= 0 && n <= 31 = "%r" ++ show n
262 | n >= 32 && n <= 63 = "%f" ++ show (n - 32)
263 | otherwise = "%unknown_powerpc_real_reg_" ++ show n
267 -- machine specific ------------------------------------------------------------
269 allFPArgRegs :: [Reg]
270 #if defined(darwin_TARGET_OS)
271 allFPArgRegs = map (regSingle . fReg) [1..13]
273 #elif defined(linux_TARGET_OS)
274 allFPArgRegs = map (regSingle . fReg) [1..8]
277 allFPArgRegs = panic "PPC.Regs.allFPArgRegs: not defined for this architecture"
281 fits16Bits :: Integral a => a -> Bool
282 fits16Bits x = x >= -32768 && x < 32768
284 makeImmediate :: Integral a => Width -> Bool -> a -> Maybe Imm
285 makeImmediate rep signed x = fmap ImmInt (toI16 rep signed)
287 narrow W32 False = fromIntegral (fromIntegral x :: Word32)
288 narrow W16 False = fromIntegral (fromIntegral x :: Word16)
289 narrow W8 False = fromIntegral (fromIntegral x :: Word8)
290 narrow W32 True = fromIntegral (fromIntegral x :: Int32)
291 narrow W16 True = fromIntegral (fromIntegral x :: Int16)
292 narrow W8 True = fromIntegral (fromIntegral x :: Int8)
293 narrow _ _ = panic "PPC.Regs.narrow: no match"
295 narrowed = narrow rep signed
298 | narrowed >= -32768 && narrowed < 32768 = Just narrowed
299 | otherwise = Nothing
301 | narrowed >= 0 && narrowed < 65536 = Just narrowed
302 | otherwise = Nothing
303 toI16 _ _ = Just narrowed
307 The PowerPC has 64 registers of interest; 32 integer registers and 32 floating
314 sp, r3, r4, r27, r28, f1, f20, f21 :: Reg
320 f1 = regSingle $ fReg 1
321 f20 = regSingle $ fReg 20
322 f21 = regSingle $ fReg 21
326 -- horror show -----------------------------------------------------------------
327 freeReg :: RegNo -> FastBool
328 globalRegMaybe :: GlobalReg -> Maybe Reg
331 #if powerpc_TARGET_ARCH
365 #ifdef darwin_TARGET_OS
435 freeReg 0 = fastBool False -- Hack: r0 can't be used in all insns, but it's actually free
436 freeReg 1 = fastBool False -- The Stack Pointer
437 #if !darwin_TARGET_OS
438 -- most non-darwin powerpc OSes use r2 as a TOC pointer or something like that
439 freeReg 2 = fastBool False
443 freeReg REG_Base = fastBool False
446 freeReg REG_R1 = fastBool False
449 freeReg REG_R2 = fastBool False
452 freeReg REG_R3 = fastBool False
455 freeReg REG_R4 = fastBool False
458 freeReg REG_R5 = fastBool False
461 freeReg REG_R6 = fastBool False
464 freeReg REG_R7 = fastBool False
467 freeReg REG_R8 = fastBool False
470 freeReg REG_F1 = fastBool False
473 freeReg REG_F2 = fastBool False
476 freeReg REG_F3 = fastBool False
479 freeReg REG_F4 = fastBool False
482 freeReg REG_D1 = fastBool False
485 freeReg REG_D2 = fastBool False
488 freeReg REG_Sp = fastBool False
491 freeReg REG_Su = fastBool False
494 freeReg REG_SpLim = fastBool False
497 freeReg REG_Hp = fastBool False
500 freeReg REG_HpLim = fastBool False
502 freeReg _ = fastBool True
505 -- | Returns 'Nothing' if this global register is not stored
506 -- in a real machine register, otherwise returns @'Just' reg@, where
507 -- reg is the machine register it is stored in.
511 globalRegMaybe BaseReg = Just (regSingle REG_Base)
514 globalRegMaybe (VanillaReg 1 _) = Just (regSingle REG_R1)
517 globalRegMaybe (VanillaReg 2 _) = Just (regSingle REG_R2)
520 globalRegMaybe (VanillaReg 3 _) = Just (regSingle REG_R3)
523 globalRegMaybe (VanillaReg 4 _) = Just (regSingle REG_R4)
526 globalRegMaybe (VanillaReg 5 _) = Just (regSingle REG_R5)
529 globalRegMaybe (VanillaReg 6 _) = Just (regSingle REG_R6)
532 globalRegMaybe (VanillaReg 7 _) = Just (regSingle REG_R7)
535 globalRegMaybe (VanillaReg 8 _) = Just (regSingle REG_R8)
538 globalRegMaybe (VanillaReg 9 _) = Just (regSingle REG_R9)
541 globalRegMaybe (VanillaReg 10 _) = Just (regSingle REG_R10)
544 globalRegMaybe (FloatReg 1) = Just (regSingle REG_F1)
547 globalRegMaybe (FloatReg 2) = Just (regSingle REG_F2)
550 globalRegMaybe (FloatReg 3) = Just (regSingle REG_F3)
553 globalRegMaybe (FloatReg 4) = Just (regSingle REG_F4)
556 globalRegMaybe (DoubleReg 1) = Just (regSingle REG_D1)
559 globalRegMaybe (DoubleReg 2) = Just (regSingle REG_D2)
562 globalRegMaybe Sp = Just (regSingle REG_Sp)
565 globalRegMaybe (LongReg 1) = Just (regSingle REG_Lng1)
568 globalRegMaybe (LongReg 2) = Just (regSingle REG_Lng2)
571 globalRegMaybe SpLim = Just (regSingle REG_SpLim)
574 globalRegMaybe Hp = Just (regSingle REG_Hp)
577 globalRegMaybe HpLim = Just (regSingle REG_HpLim)
579 #ifdef REG_CurrentTSO
580 globalRegMaybe CurrentTSO = Just (regSingle REG_CurrentTSO)
582 #ifdef REG_CurrentNursery
583 globalRegMaybe CurrentNursery = Just (regSingle REG_CurrentNursery)
585 globalRegMaybe _ = Nothing
588 #else /* powerpc_TARGET_ARCH */
591 globalRegMaybe _ = panic "PPC.Regs.globalRegMaybe: not defined"
593 #endif /* powerpc_TARGET_ARCH */
596 -- allocatableRegs is allMachRegNos with the fixed-use regs removed.
597 -- i.e., these are the regs for which we are prepared to allow the
598 -- register allocator to attempt to map VRegs to.
599 allocatableRegs :: [RealReg]
601 = let isFree i = isFastTrue (freeReg i)
602 in map RealRegSingle $ filter isFree allMachRegNos