1 -- -----------------------------------------------------------------------------
3 -- (c) The University of Glasgow 1994-2004
5 -- -----------------------------------------------------------------------------
41 sp, r3, r4, r27, r28, f1, f20, f21,
50 #include "nativeGen/NCG.h"
51 #include "HsVersions.h"
52 #include "../includes/MachRegs.h"
58 import CLabel ( CLabel )
60 import Outputable ( Outputable(..), pprPanic, panic )
61 import qualified Outputable
66 import Data.Word ( Word8, Word16, Word32 )
67 import Data.Int ( Int8, Int16, Int32 )
69 -- sizes -----------------------------------------------------------------------
70 -- For these three, the "size" also gives the int/float
71 -- distinction, because the instructions for int/float
72 -- differ only in their suffices
74 = II8 | II16 | II32 | II64 | FF32 | FF64 | FF80
77 intSize, floatSize :: Width -> Size
82 intSize other = pprPanic "MachInstrs.intSize" (ppr other)
86 floatSize other = pprPanic "MachInstrs.intSize" (ppr other)
89 isFloatSize :: Size -> Bool
90 isFloatSize FF32 = True
91 isFloatSize FF64 = True
92 isFloatSize FF80 = True
97 wordSize = intSize wordWidth
100 cmmTypeSize :: CmmType -> Size
102 | isFloatType ty = floatSize (typeWidth ty)
103 | otherwise = intSize (typeWidth ty)
106 sizeToWidth :: Size -> Width
108 sizeToWidth II16 = W16
109 sizeToWidth II32 = W32
110 sizeToWidth II64 = W64
111 sizeToWidth FF32 = W32
112 sizeToWidth FF64 = W64
113 sizeToWidth _ = panic "MachInstrs.sizeToWidth"
116 mkVReg :: Unique -> Size -> Reg
118 | not (isFloatSize size) = VirtualRegI u
121 FF32 -> VirtualRegD u
122 FF64 -> VirtualRegD u
127 -- immediates ------------------------------------------------------------------
130 | ImmInteger Integer -- Sigh.
131 | ImmCLbl CLabel -- AbstractC Label (with baggage)
132 | ImmLit Doc -- Simple string
133 | ImmIndex CLabel Int
136 | ImmConstantSum Imm Imm
137 | ImmConstantDiff Imm Imm
140 | HA Imm {- high halfword adjusted -}
143 strImmLit :: String -> Imm
144 strImmLit s = ImmLit (text s)
147 litToImm :: CmmLit -> Imm
148 litToImm (CmmInt i w) = ImmInteger (narrowS w i)
149 -- narrow to the width: a CmmInt might be out of
150 -- range, but we assume that ImmInteger only contains
151 -- in-range values. A signed value should be fine here.
152 litToImm (CmmFloat f W32) = ImmFloat f
153 litToImm (CmmFloat f W64) = ImmDouble f
154 litToImm (CmmLabel l) = ImmCLbl l
155 litToImm (CmmLabelOff l off) = ImmIndex l off
156 litToImm (CmmLabelDiffOff l1 l2 off)
158 (ImmConstantDiff (ImmCLbl l1) (ImmCLbl l2))
160 litToImm (CmmBlock id) = ImmCLbl (infoTblLbl id)
161 litToImm _ = panic "PPC.Regs.litToImm: no match"
164 -- addressing modes ------------------------------------------------------------
171 addrOffset :: AddrMode -> Int -> Maybe AddrMode
174 AddrRegImm r (ImmInt n)
175 | fits16Bits n2 -> Just (AddrRegImm r (ImmInt n2))
176 | otherwise -> Nothing
179 AddrRegImm r (ImmInteger n)
180 | fits16Bits n2 -> Just (AddrRegImm r (ImmInt (fromInteger n2)))
181 | otherwise -> Nothing
182 where n2 = n + toInteger off
187 -- registers -------------------------------------------------------------------
188 -- @spRel@ gives us a stack relative addressing mode for volatile
189 -- temporaries and for excess call arguments. @fpRel@, where
190 -- applicable, is the same but for the frame pointer.
192 spRel :: Int -- desired stack offset in words, positive or negative
195 spRel n = AddrRegImm sp (ImmInt (n * wORD_SIZE))
198 -- argRegs is the set of regs which are read for an n-argument call to C.
199 -- For archs which pass all args on the stack (x86), is empty.
200 -- Sparc passes up to the first 6 args in regs.
201 -- Dunno about Alpha.
202 argRegs :: RegNo -> [Reg]
204 argRegs 1 = map RealReg [3]
205 argRegs 2 = map RealReg [3,4]
206 argRegs 3 = map RealReg [3..5]
207 argRegs 4 = map RealReg [3..6]
208 argRegs 5 = map RealReg [3..7]
209 argRegs 6 = map RealReg [3..8]
210 argRegs 7 = map RealReg [3..9]
211 argRegs 8 = map RealReg [3..10]
212 argRegs _ = panic "MachRegs.argRegs(powerpc): don't know about >8 arguments!"
216 allArgRegs = map RealReg [3..10]
219 -- these are the regs which we cannot assume stay alive over a C call.
220 callClobberedRegs :: [Reg]
221 #if defined(darwin_TARGET_OS)
223 = map RealReg (0:[2..12] ++ map fReg [0..13])
225 #elif defined(linux_TARGET_OS)
227 = map RealReg (0:[2..13] ++ map fReg [0..13])
231 = panic "PPC.Regs.callClobberedRegs: not defined for this architecture"
235 allMachRegNos :: [RegNo]
236 allMachRegNos = [0..63]
239 {-# INLINE regClass #-}
240 regClass :: Reg -> RegClass
241 regClass (VirtualRegI _) = RcInteger
242 regClass (VirtualRegHi _) = RcInteger
243 regClass (VirtualRegF u) = pprPanic ("regClass(ppc):VirtualRegF ") (ppr u)
244 regClass (VirtualRegD _) = RcDouble
247 | otherwise = RcDouble
250 showReg :: RegNo -> String
252 | n >= 0 && n <= 31 = "%r" ++ show n
253 | n >= 32 && n <= 63 = "%f" ++ show (n - 32)
254 | otherwise = "%unknown_powerpc_real_reg_" ++ show n
258 -- machine specific ------------------------------------------------------------
260 allFPArgRegs :: [Reg]
261 #if defined(darwin_TARGET_OS)
262 allFPArgRegs = map (RealReg . fReg) [1..13]
264 #elif defined(linux_TARGET_OS)
265 allFPArgRegs = map (RealReg . fReg) [1..8]
268 allFPArgRegs = panic "PPC.Regs.allFPArgRegs: not defined for this architecture"
272 fits16Bits :: Integral a => a -> Bool
273 fits16Bits x = x >= -32768 && x < 32768
275 makeImmediate :: Integral a => Width -> Bool -> a -> Maybe Imm
276 makeImmediate rep signed x = fmap ImmInt (toI16 rep signed)
278 narrow W32 False = fromIntegral (fromIntegral x :: Word32)
279 narrow W16 False = fromIntegral (fromIntegral x :: Word16)
280 narrow W8 False = fromIntegral (fromIntegral x :: Word8)
281 narrow W32 True = fromIntegral (fromIntegral x :: Int32)
282 narrow W16 True = fromIntegral (fromIntegral x :: Int16)
283 narrow W8 True = fromIntegral (fromIntegral x :: Int8)
284 narrow _ _ = panic "PPC.Regs.narrow: no match"
286 narrowed = narrow rep signed
289 | narrowed >= -32768 && narrowed < 32768 = Just narrowed
290 | otherwise = Nothing
292 | narrowed >= 0 && narrowed < 65536 = Just narrowed
293 | otherwise = Nothing
294 toI16 _ _ = Just narrowed
298 The PowerPC has 64 registers of interest; 32 integer registers and 32 floating
305 sp, r3, r4, r27, r28, f1, f20, f21 :: Reg
311 f1 = RealReg $ fReg 1
312 f20 = RealReg $ fReg 20
313 f21 = RealReg $ fReg 21
317 -- horror show -----------------------------------------------------------------
318 freeReg :: RegNo -> FastBool
319 globalRegMaybe :: GlobalReg -> Maybe Reg
322 #if powerpc_TARGET_ARCH
356 #ifdef darwin_TARGET_OS
426 freeReg 0 = fastBool False -- Hack: r0 can't be used in all insns, but it's actually free
427 freeReg 1 = fastBool False -- The Stack Pointer
428 #if !darwin_TARGET_OS
429 -- most non-darwin powerpc OSes use r2 as a TOC pointer or something like that
430 freeReg 2 = fastBool False
434 freeReg REG_Base = fastBool False
437 freeReg REG_R1 = fastBool False
440 freeReg REG_R2 = fastBool False
443 freeReg REG_R3 = fastBool False
446 freeReg REG_R4 = fastBool False
449 freeReg REG_R5 = fastBool False
452 freeReg REG_R6 = fastBool False
455 freeReg REG_R7 = fastBool False
458 freeReg REG_R8 = fastBool False
461 freeReg REG_F1 = fastBool False
464 freeReg REG_F2 = fastBool False
467 freeReg REG_F3 = fastBool False
470 freeReg REG_F4 = fastBool False
473 freeReg REG_D1 = fastBool False
476 freeReg REG_D2 = fastBool False
479 freeReg REG_Sp = fastBool False
482 freeReg REG_Su = fastBool False
485 freeReg REG_SpLim = fastBool False
488 freeReg REG_Hp = fastBool False
491 freeReg REG_HpLim = fastBool False
493 freeReg _ = fastBool True
496 -- | Returns 'Nothing' if this global register is not stored
497 -- in a real machine register, otherwise returns @'Just' reg@, where
498 -- reg is the machine register it is stored in.
502 globalRegMaybe BaseReg = Just (RealReg REG_Base)
505 globalRegMaybe (VanillaReg 1 _) = Just (RealReg REG_R1)
508 globalRegMaybe (VanillaReg 2 _) = Just (RealReg REG_R2)
511 globalRegMaybe (VanillaReg 3 _) = Just (RealReg REG_R3)
514 globalRegMaybe (VanillaReg 4 _) = Just (RealReg REG_R4)
517 globalRegMaybe (VanillaReg 5 _) = Just (RealReg REG_R5)
520 globalRegMaybe (VanillaReg 6 _) = Just (RealReg REG_R6)
523 globalRegMaybe (VanillaReg 7 _) = Just (RealReg REG_R7)
526 globalRegMaybe (VanillaReg 8 _) = Just (RealReg REG_R8)
529 globalRegMaybe (VanillaReg 9 _) = Just (RealReg REG_R9)
532 globalRegMaybe (VanillaReg 10 _) = Just (RealReg REG_R10)
535 globalRegMaybe (FloatReg 1) = Just (RealReg REG_F1)
538 globalRegMaybe (FloatReg 2) = Just (RealReg REG_F2)
541 globalRegMaybe (FloatReg 3) = Just (RealReg REG_F3)
544 globalRegMaybe (FloatReg 4) = Just (RealReg REG_F4)
547 globalRegMaybe (DoubleReg 1) = Just (RealReg REG_D1)
550 globalRegMaybe (DoubleReg 2) = Just (RealReg REG_D2)
553 globalRegMaybe Sp = Just (RealReg REG_Sp)
556 globalRegMaybe (LongReg 1) = Just (RealReg REG_Lng1)
559 globalRegMaybe (LongReg 2) = Just (RealReg REG_Lng2)
562 globalRegMaybe SpLim = Just (RealReg REG_SpLim)
565 globalRegMaybe Hp = Just (RealReg REG_Hp)
568 globalRegMaybe HpLim = Just (RealReg REG_HpLim)
570 #ifdef REG_CurrentTSO
571 globalRegMaybe CurrentTSO = Just (RealReg REG_CurrentTSO)
573 #ifdef REG_CurrentNursery
574 globalRegMaybe CurrentNursery = Just (RealReg REG_CurrentNursery)
576 globalRegMaybe _ = Nothing
579 #else /* powerpc_TARGET_ARCH */
582 globalRegMaybe _ = panic "PPC.Regs.globalRegMaybe: not defined"
584 #endif /* powerpc_TARGET_ARCH */