1 -- -----------------------------------------------------------------------------
3 -- (c) The University of Glasgow 1994-2004
5 -- -----------------------------------------------------------------------------
38 sp, r3, r4, r27, r28, f1, f20, f21,
43 get_GlobalReg_reg_or_addr,
50 #include "nativeGen/NCG.h"
51 #include "HsVersions.h"
52 #include "../includes/stg/MachRegs.h"
58 import CgUtils ( get_GlobalReg_addr )
61 import CLabel ( CLabel )
65 import Outputable ( panic, SDoc )
66 import qualified Outputable
71 import Data.Word ( Word8, Word16, Word32 )
72 import Data.Int ( Int8, Int16, Int32 )
75 -- squeese functions for the graph allocator -----------------------------------
77 -- | regSqueeze_class reg
78 -- Calculuate the maximum number of register colors that could be
79 -- denied to a node of this class due to having this reg
82 {-# INLINE virtualRegSqueeze #-}
83 virtualRegSqueeze :: RegClass -> VirtualReg -> FastInt
84 virtualRegSqueeze cls vr
88 VirtualRegI{} -> _ILIT(1)
89 VirtualRegHi{} -> _ILIT(1)
90 VirtualRegD{} -> _ILIT(0)
91 VirtualRegF{} -> _ILIT(0)
93 -- We don't use floats on this arch, but we can't
94 -- return error because the return type is unboxed...
97 VirtualRegI{} -> _ILIT(0)
98 VirtualRegHi{} -> _ILIT(0)
99 VirtualRegD{} -> _ILIT(0)
100 VirtualRegF{} -> _ILIT(0)
104 VirtualRegI{} -> _ILIT(0)
105 VirtualRegHi{} -> _ILIT(0)
106 VirtualRegD{} -> _ILIT(1)
107 VirtualRegF{} -> _ILIT(0)
110 {-# INLINE realRegSqueeze #-}
111 realRegSqueeze :: RegClass -> RealReg -> FastInt
112 realRegSqueeze cls rr
117 | regNo < 32 -> _ILIT(1) -- first fp reg is 32
118 | otherwise -> _ILIT(0)
120 RealRegPair{} -> _ILIT(0)
122 -- We don't use floats on this arch, but we can't
123 -- return error because the return type is unboxed...
127 | regNo < 32 -> _ILIT(0)
128 | otherwise -> _ILIT(0)
130 RealRegPair{} -> _ILIT(0)
135 | regNo < 32 -> _ILIT(0)
136 | otherwise -> _ILIT(1)
138 RealRegPair{} -> _ILIT(0)
140 mkVirtualReg :: Unique -> Size -> VirtualReg
142 | not (isFloatSize size) = VirtualRegI u
145 FF32 -> VirtualRegD u
146 FF64 -> VirtualRegD u
147 _ -> panic "mkVirtualReg"
149 regDotColor :: RealReg -> SDoc
151 = case classOfRealReg reg of
152 RcInteger -> Outputable.text "blue"
153 RcFloat -> Outputable.text "red"
154 RcDouble -> Outputable.text "green"
157 -- immediates ------------------------------------------------------------------
160 | ImmInteger Integer -- Sigh.
161 | ImmCLbl CLabel -- AbstractC Label (with baggage)
162 | ImmLit Doc -- Simple string
163 | ImmIndex CLabel Int
166 | ImmConstantSum Imm Imm
167 | ImmConstantDiff Imm Imm
170 | HA Imm {- high halfword adjusted -}
173 strImmLit :: String -> Imm
174 strImmLit s = ImmLit (text s)
177 litToImm :: CmmLit -> Imm
178 litToImm (CmmInt i w) = ImmInteger (narrowS w i)
179 -- narrow to the width: a CmmInt might be out of
180 -- range, but we assume that ImmInteger only contains
181 -- in-range values. A signed value should be fine here.
182 litToImm (CmmFloat f W32) = ImmFloat f
183 litToImm (CmmFloat f W64) = ImmDouble f
184 litToImm (CmmLabel l) = ImmCLbl l
185 litToImm (CmmLabelOff l off) = ImmIndex l off
186 litToImm (CmmLabelDiffOff l1 l2 off)
188 (ImmConstantDiff (ImmCLbl l1) (ImmCLbl l2))
190 litToImm (CmmBlock id) = ImmCLbl (infoTblLbl id)
191 litToImm _ = panic "PPC.Regs.litToImm: no match"
194 -- addressing modes ------------------------------------------------------------
201 addrOffset :: AddrMode -> Int -> Maybe AddrMode
204 AddrRegImm r (ImmInt n)
205 | fits16Bits n2 -> Just (AddrRegImm r (ImmInt n2))
206 | otherwise -> Nothing
209 AddrRegImm r (ImmInteger n)
210 | fits16Bits n2 -> Just (AddrRegImm r (ImmInt (fromInteger n2)))
211 | otherwise -> Nothing
212 where n2 = n + toInteger off
217 -- registers -------------------------------------------------------------------
218 -- @spRel@ gives us a stack relative addressing mode for volatile
219 -- temporaries and for excess call arguments. @fpRel@, where
220 -- applicable, is the same but for the frame pointer.
222 spRel :: Int -- desired stack offset in words, positive or negative
225 spRel n = AddrRegImm sp (ImmInt (n * wORD_SIZE))
228 -- argRegs is the set of regs which are read for an n-argument call to C.
229 -- For archs which pass all args on the stack (x86), is empty.
230 -- Sparc passes up to the first 6 args in regs.
231 -- Dunno about Alpha.
232 argRegs :: RegNo -> [Reg]
234 argRegs 1 = map regSingle [3]
235 argRegs 2 = map regSingle [3,4]
236 argRegs 3 = map regSingle [3..5]
237 argRegs 4 = map regSingle [3..6]
238 argRegs 5 = map regSingle [3..7]
239 argRegs 6 = map regSingle [3..8]
240 argRegs 7 = map regSingle [3..9]
241 argRegs 8 = map regSingle [3..10]
242 argRegs _ = panic "MachRegs.argRegs(powerpc): don't know about >8 arguments!"
246 allArgRegs = map regSingle [3..10]
249 -- these are the regs which we cannot assume stay alive over a C call.
250 callClobberedRegs :: [Reg]
251 #if defined(darwin_TARGET_OS)
253 = map regSingle (0:[2..12] ++ map fReg [0..13])
255 #elif defined(linux_TARGET_OS)
257 = map regSingle (0:[2..13] ++ map fReg [0..13])
261 = panic "PPC.Regs.callClobberedRegs: not defined for this architecture"
265 allMachRegNos :: [RegNo]
266 allMachRegNos = [0..63]
269 {-# INLINE classOfRealReg #-}
270 classOfRealReg :: RealReg -> RegClass
271 classOfRealReg (RealRegSingle i)
273 | otherwise = RcDouble
275 classOfRealReg (RealRegPair{})
276 = panic "regClass(ppr): no reg pairs on this architecture"
278 showReg :: RegNo -> String
280 | n >= 0 && n <= 31 = "%r" ++ show n
281 | n >= 32 && n <= 63 = "%f" ++ show (n - 32)
282 | otherwise = "%unknown_powerpc_real_reg_" ++ show n
286 -- machine specific ------------------------------------------------------------
288 allFPArgRegs :: [Reg]
289 #if defined(darwin_TARGET_OS)
290 allFPArgRegs = map (regSingle . fReg) [1..13]
292 #elif defined(linux_TARGET_OS)
293 allFPArgRegs = map (regSingle . fReg) [1..8]
296 allFPArgRegs = panic "PPC.Regs.allFPArgRegs: not defined for this architecture"
300 fits16Bits :: Integral a => a -> Bool
301 fits16Bits x = x >= -32768 && x < 32768
303 makeImmediate :: Integral a => Width -> Bool -> a -> Maybe Imm
304 makeImmediate rep signed x = fmap ImmInt (toI16 rep signed)
306 narrow W32 False = fromIntegral (fromIntegral x :: Word32)
307 narrow W16 False = fromIntegral (fromIntegral x :: Word16)
308 narrow W8 False = fromIntegral (fromIntegral x :: Word8)
309 narrow W32 True = fromIntegral (fromIntegral x :: Int32)
310 narrow W16 True = fromIntegral (fromIntegral x :: Int16)
311 narrow W8 True = fromIntegral (fromIntegral x :: Int8)
312 narrow _ _ = panic "PPC.Regs.narrow: no match"
314 narrowed = narrow rep signed
317 | narrowed >= -32768 && narrowed < 32768 = Just narrowed
318 | otherwise = Nothing
320 | narrowed >= 0 && narrowed < 65536 = Just narrowed
321 | otherwise = Nothing
322 toI16 _ _ = Just narrowed
326 The PowerPC has 64 registers of interest; 32 integer registers and 32 floating
333 sp, r3, r4, r27, r28, f1, f20, f21 :: Reg
339 f1 = regSingle $ fReg 1
340 f20 = regSingle $ fReg 20
341 f21 = regSingle $ fReg 21
345 -- horror show -----------------------------------------------------------------
346 freeReg :: RegNo -> FastBool
347 globalRegMaybe :: GlobalReg -> Maybe Reg
350 #if powerpc_TARGET_ARCH
384 #ifdef darwin_TARGET_OS
454 freeReg 0 = fastBool False -- Hack: r0 can't be used in all insns, but it's actually free
455 freeReg 1 = fastBool False -- The Stack Pointer
456 #if !darwin_TARGET_OS
457 -- most non-darwin powerpc OSes use r2 as a TOC pointer or something like that
458 freeReg 2 = fastBool False
462 freeReg REG_Base = fastBool False
465 freeReg REG_R1 = fastBool False
468 freeReg REG_R2 = fastBool False
471 freeReg REG_R3 = fastBool False
474 freeReg REG_R4 = fastBool False
477 freeReg REG_R5 = fastBool False
480 freeReg REG_R6 = fastBool False
483 freeReg REG_R7 = fastBool False
486 freeReg REG_R8 = fastBool False
489 freeReg REG_F1 = fastBool False
492 freeReg REG_F2 = fastBool False
495 freeReg REG_F3 = fastBool False
498 freeReg REG_F4 = fastBool False
501 freeReg REG_D1 = fastBool False
504 freeReg REG_D2 = fastBool False
507 freeReg REG_Sp = fastBool False
510 freeReg REG_Su = fastBool False
513 freeReg REG_SpLim = fastBool False
516 freeReg REG_Hp = fastBool False
519 freeReg REG_HpLim = fastBool False
521 freeReg _ = fastBool True
524 -- | Returns 'Nothing' if this global register is not stored
525 -- in a real machine register, otherwise returns @'Just' reg@, where
526 -- reg is the machine register it is stored in.
530 globalRegMaybe BaseReg = Just (regSingle REG_Base)
533 globalRegMaybe (VanillaReg 1 _) = Just (regSingle REG_R1)
536 globalRegMaybe (VanillaReg 2 _) = Just (regSingle REG_R2)
539 globalRegMaybe (VanillaReg 3 _) = Just (regSingle REG_R3)
542 globalRegMaybe (VanillaReg 4 _) = Just (regSingle REG_R4)
545 globalRegMaybe (VanillaReg 5 _) = Just (regSingle REG_R5)
548 globalRegMaybe (VanillaReg 6 _) = Just (regSingle REG_R6)
551 globalRegMaybe (VanillaReg 7 _) = Just (regSingle REG_R7)
554 globalRegMaybe (VanillaReg 8 _) = Just (regSingle REG_R8)
557 globalRegMaybe (VanillaReg 9 _) = Just (regSingle REG_R9)
560 globalRegMaybe (VanillaReg 10 _) = Just (regSingle REG_R10)
563 globalRegMaybe (FloatReg 1) = Just (regSingle REG_F1)
566 globalRegMaybe (FloatReg 2) = Just (regSingle REG_F2)
569 globalRegMaybe (FloatReg 3) = Just (regSingle REG_F3)
572 globalRegMaybe (FloatReg 4) = Just (regSingle REG_F4)
575 globalRegMaybe (DoubleReg 1) = Just (regSingle REG_D1)
578 globalRegMaybe (DoubleReg 2) = Just (regSingle REG_D2)
581 globalRegMaybe Sp = Just (regSingle REG_Sp)
584 globalRegMaybe (LongReg 1) = Just (regSingle REG_Lng1)
587 globalRegMaybe (LongReg 2) = Just (regSingle REG_Lng2)
590 globalRegMaybe SpLim = Just (regSingle REG_SpLim)
593 globalRegMaybe Hp = Just (regSingle REG_Hp)
596 globalRegMaybe HpLim = Just (regSingle REG_HpLim)
598 #ifdef REG_CurrentTSO
599 globalRegMaybe CurrentTSO = Just (regSingle REG_CurrentTSO)
601 #ifdef REG_CurrentNursery
602 globalRegMaybe CurrentNursery = Just (regSingle REG_CurrentNursery)
604 globalRegMaybe _ = Nothing
607 #else /* powerpc_TARGET_ARCH */
610 globalRegMaybe _ = panic "PPC.Regs.globalRegMaybe: not defined"
612 #endif /* powerpc_TARGET_ARCH */
615 -- We map STG registers onto appropriate CmmExprs. Either they map
616 -- to real machine registers or stored as offsets from BaseReg. Given
617 -- a GlobalReg, get_GlobalReg_reg_or_addr produces either the real
618 -- register it is in, on this platform, or a CmmExpr denoting the
619 -- address in the register table holding it.
620 -- (See also get_GlobalReg_addr in CgUtils.)
622 get_GlobalReg_reg_or_addr :: GlobalReg -> Either Reg CmmExpr
623 get_GlobalReg_reg_or_addr mid
624 = case globalRegMaybe mid of
626 Nothing -> Right (get_GlobalReg_addr mid)
629 -- allocatableRegs is allMachRegNos with the fixed-use regs removed.
630 -- i.e., these are the regs for which we are prepared to allow the
631 -- register allocator to attempt to map VRegs to.
632 allocatableRegs :: [RealReg]
634 = let isFree i = isFastTrue (freeReg i)
635 in map RealRegSingle $ filter isFree allMachRegNos