Add new LLVM code generator to GHC. (Version 2)
[ghc-hetmet.git] / compiler / nativeGen / PPC / Regs.hs
1 -- -----------------------------------------------------------------------------
2 --
3 -- (c) The University of Glasgow 1994-2004
4 -- 
5 -- -----------------------------------------------------------------------------
6
7 module PPC.Regs (
8         -- squeeze functions
9         virtualRegSqueeze,
10         realRegSqueeze,
11
12         mkVirtualReg,
13         regDotColor,
14
15         -- immediates
16         Imm(..),
17         strImmLit,
18         litToImm,
19
20         -- addressing modes
21         AddrMode(..),
22         addrOffset,
23
24         -- registers
25         spRel,
26         argRegs,
27         allArgRegs,
28         callClobberedRegs,
29         allMachRegNos,
30         classOfRealReg,
31         showReg,
32         
33         -- machine specific
34         allFPArgRegs,
35         fits16Bits,
36         makeImmediate,
37         fReg,
38         sp, r3, r4, r27, r28, f1, f20, f21,
39
40         -- horrow show
41         freeReg,
42         globalRegMaybe,
43         allocatableRegs
44
45 )
46
47 where
48
49 #include "nativeGen/NCG.h"
50 #include "HsVersions.h"
51 #include "../includes/stg/MachRegs.h"
52
53 import Reg
54 import RegClass
55 import Size
56
57 import BlockId
58 import Cmm
59 import CLabel           ( CLabel )
60 import Unique
61
62 import Pretty
63 import Outputable       ( panic, SDoc ) 
64 import qualified Outputable
65 import Constants
66 import FastBool
67 import FastTypes
68
69 import Data.Word        ( Word8, Word16, Word32 )
70 import Data.Int         ( Int8, Int16, Int32 )
71
72
73 -- squeese functions for the graph allocator -----------------------------------
74
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 
78 --      as a neighbour.
79 --
80 {-# INLINE virtualRegSqueeze #-}
81 virtualRegSqueeze :: RegClass -> VirtualReg -> FastInt
82 virtualRegSqueeze cls vr
83  = case cls of
84         RcInteger
85          -> case vr of
86                 VirtualRegI{}           -> _ILIT(1)
87                 VirtualRegHi{}          -> _ILIT(1)
88                 _other                  -> _ILIT(0)
89
90         RcDouble
91          -> case vr of
92                 VirtualRegD{}           -> _ILIT(1)
93                 VirtualRegF{}           -> _ILIT(0)
94                 _other                  -> _ILIT(0)
95
96         _other -> _ILIT(0)
97
98 {-# INLINE realRegSqueeze #-}
99 realRegSqueeze :: RegClass -> RealReg -> FastInt
100 realRegSqueeze cls rr
101  = case cls of
102         RcInteger
103          -> case rr of
104                 RealRegSingle regNo
105                         | regNo < 32    -> _ILIT(1)     -- first fp reg is 32 
106                         | otherwise     -> _ILIT(0)
107                         
108                 RealRegPair{}           -> _ILIT(0)
109
110         RcDouble
111          -> case rr of
112                 RealRegSingle regNo
113                         | regNo < 32    -> _ILIT(0)
114                         | otherwise     -> _ILIT(1)
115                         
116                 RealRegPair{}           -> _ILIT(0)
117
118         _other -> _ILIT(0)
119
120 mkVirtualReg :: Unique -> Size -> VirtualReg
121 mkVirtualReg u size
122    | not (isFloatSize size) = VirtualRegI u
123    | otherwise
124    = case size of
125         FF32    -> VirtualRegD u
126         FF64    -> VirtualRegD u
127         _       -> panic "mkVirtualReg"
128
129 regDotColor :: RealReg -> SDoc
130 regDotColor reg
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"
136
137
138 -- immediates ------------------------------------------------------------------
139 data Imm
140         = ImmInt        Int
141         | ImmInteger    Integer     -- Sigh.
142         | ImmCLbl       CLabel      -- AbstractC Label (with baggage)
143         | ImmLit        Doc         -- Simple string
144         | ImmIndex    CLabel Int
145         | ImmFloat      Rational
146         | ImmDouble     Rational
147         | ImmConstantSum Imm Imm
148         | ImmConstantDiff Imm Imm
149         | LO Imm
150         | HI Imm
151         | HA Imm        {- high halfword adjusted -}
152
153
154 strImmLit :: String -> Imm
155 strImmLit s = ImmLit (text s)
156
157
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)
168                              = ImmConstantSum
169                                (ImmConstantDiff (ImmCLbl l1) (ImmCLbl l2))
170                                (ImmInt off)
171 litToImm (CmmBlock id)       = ImmCLbl (infoTblLbl id)
172 litToImm _                   = panic "PPC.Regs.litToImm: no match"
173
174
175 -- addressing modes ------------------------------------------------------------
176
177 data AddrMode
178         = AddrRegReg    Reg Reg
179         | AddrRegImm    Reg Imm
180
181
182 addrOffset :: AddrMode -> Int -> Maybe AddrMode
183 addrOffset addr off
184   = case addr of
185       AddrRegImm r (ImmInt n)
186        | fits16Bits n2 -> Just (AddrRegImm r (ImmInt n2))
187        | otherwise     -> Nothing
188        where n2 = n + off
189
190       AddrRegImm r (ImmInteger n)
191        | fits16Bits n2 -> Just (AddrRegImm r (ImmInt (fromInteger n2)))
192        | otherwise     -> Nothing
193        where n2 = n + toInteger off
194        
195       _ -> Nothing
196
197
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.
202
203 spRel :: Int    -- desired stack offset in words, positive or negative
204       -> AddrMode
205
206 spRel n = AddrRegImm sp (ImmInt (n * wORD_SIZE))
207
208
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]
214 argRegs 0 = []
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!"
224
225
226 allArgRegs :: [Reg]
227 allArgRegs = map regSingle [3..10]
228
229
230 -- these are the regs which we cannot assume stay alive over a C call.  
231 callClobberedRegs :: [Reg]
232 #if   defined(darwin_TARGET_OS)
233 callClobberedRegs
234   = map regSingle (0:[2..12] ++ map fReg [0..13])
235
236 #elif defined(linux_TARGET_OS)
237 callClobberedRegs
238   = map regSingle (0:[2..13] ++ map fReg [0..13])
239
240 #else
241 callClobberedRegs
242         = panic "PPC.Regs.callClobberedRegs: not defined for this architecture"
243 #endif
244
245
246 allMachRegNos   :: [RegNo]
247 allMachRegNos   = [0..63]
248
249
250 {-# INLINE classOfRealReg      #-}
251 classOfRealReg :: RealReg -> RegClass
252 classOfRealReg (RealRegSingle i)
253         | i < 32        = RcInteger 
254         | otherwise     = RcDouble
255
256 classOfRealReg (RealRegPair{})
257         = panic "regClass(ppr): no reg pairs on this architecture"
258
259 showReg :: RegNo -> String
260 showReg n
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
264
265
266
267 -- machine specific ------------------------------------------------------------
268
269 allFPArgRegs :: [Reg]
270 #if    defined(darwin_TARGET_OS)
271 allFPArgRegs = map (regSingle . fReg) [1..13]
272
273 #elif  defined(linux_TARGET_OS)
274 allFPArgRegs = map (regSingle . fReg) [1..8]
275
276 #else
277 allFPArgRegs = panic "PPC.Regs.allFPArgRegs: not defined for this architecture"
278
279 #endif
280
281 fits16Bits :: Integral a => a -> Bool
282 fits16Bits x = x >= -32768 && x < 32768
283
284 makeImmediate :: Integral a => Width -> Bool -> a -> Maybe Imm
285 makeImmediate rep signed x = fmap ImmInt (toI16 rep signed)
286     where
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"
294         
295         narrowed = narrow rep signed
296         
297         toI16 W32 True
298             | narrowed >= -32768 && narrowed < 32768 = Just narrowed
299             | otherwise = Nothing
300         toI16 W32 False
301             | narrowed >= 0 && narrowed < 65536 = Just narrowed
302             | otherwise = Nothing
303         toI16 _ _  = Just narrowed
304
305
306 {-
307 The PowerPC has 64 registers of interest; 32 integer registers and 32 floating
308 point registers.
309 -}
310
311 fReg :: Int -> RegNo
312 fReg x = (32 + x)
313
314 sp, r3, r4, r27, r28, f1, f20, f21 :: Reg
315 sp      = regSingle 1
316 r3      = regSingle 3
317 r4      = regSingle 4
318 r27     = regSingle 27
319 r28     = regSingle 28
320 f1      = regSingle $ fReg 1
321 f20     = regSingle $ fReg 20
322 f21     = regSingle $ fReg 21
323
324
325
326 -- horror show -----------------------------------------------------------------
327 freeReg :: RegNo -> FastBool
328 globalRegMaybe :: GlobalReg -> Maybe Reg
329
330
331 #if powerpc_TARGET_ARCH
332 #define r0 0
333 #define r1 1
334 #define r2 2
335 #define r3 3
336 #define r4 4
337 #define r5 5
338 #define r6 6
339 #define r7 7
340 #define r8 8
341 #define r9 9
342 #define r10 10
343 #define r11 11
344 #define r12 12
345 #define r13 13
346 #define r14 14
347 #define r15 15
348 #define r16 16
349 #define r17 17
350 #define r18 18
351 #define r19 19
352 #define r20 20
353 #define r21 21
354 #define r22 22
355 #define r23 23
356 #define r24 24
357 #define r25 25
358 #define r26 26
359 #define r27 27
360 #define r28 28
361 #define r29 29
362 #define r30 30
363 #define r31 31
364
365 #ifdef darwin_TARGET_OS
366 #define f0  32
367 #define f1  33
368 #define f2  34
369 #define f3  35
370 #define f4  36
371 #define f5  37
372 #define f6  38
373 #define f7  39
374 #define f8  40
375 #define f9  41
376 #define f10 42
377 #define f11 43
378 #define f12 44
379 #define f13 45
380 #define f14 46
381 #define f15 47
382 #define f16 48
383 #define f17 49
384 #define f18 50
385 #define f19 51
386 #define f20 52
387 #define f21 53
388 #define f22 54
389 #define f23 55
390 #define f24 56
391 #define f25 57
392 #define f26 58
393 #define f27 59
394 #define f28 60
395 #define f29 61
396 #define f30 62
397 #define f31 63
398 #else
399 #define fr0  32
400 #define fr1  33
401 #define fr2  34
402 #define fr3  35
403 #define fr4  36
404 #define fr5  37
405 #define fr6  38
406 #define fr7  39
407 #define fr8  40
408 #define fr9  41
409 #define fr10 42
410 #define fr11 43
411 #define fr12 44
412 #define fr13 45
413 #define fr14 46
414 #define fr15 47
415 #define fr16 48
416 #define fr17 49
417 #define fr18 50
418 #define fr19 51
419 #define fr20 52
420 #define fr21 53
421 #define fr22 54
422 #define fr23 55
423 #define fr24 56
424 #define fr25 57
425 #define fr26 58
426 #define fr27 59
427 #define fr28 60
428 #define fr29 61
429 #define fr30 62
430 #define fr31 63
431 #endif
432
433
434
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
440 #endif
441
442 #ifdef REG_Base
443 freeReg REG_Base = fastBool False
444 #endif
445 #ifdef REG_R1
446 freeReg REG_R1   = fastBool False
447 #endif  
448 #ifdef REG_R2  
449 freeReg REG_R2   = fastBool False
450 #endif  
451 #ifdef REG_R3  
452 freeReg REG_R3   = fastBool False
453 #endif  
454 #ifdef REG_R4  
455 freeReg REG_R4   = fastBool False
456 #endif  
457 #ifdef REG_R5  
458 freeReg REG_R5   = fastBool False
459 #endif  
460 #ifdef REG_R6  
461 freeReg REG_R6   = fastBool False
462 #endif  
463 #ifdef REG_R7  
464 freeReg REG_R7   = fastBool False
465 #endif  
466 #ifdef REG_R8  
467 freeReg REG_R8   = fastBool False
468 #endif
469 #ifdef REG_F1
470 freeReg REG_F1 = fastBool False
471 #endif
472 #ifdef REG_F2
473 freeReg REG_F2 = fastBool False
474 #endif
475 #ifdef REG_F3
476 freeReg REG_F3 = fastBool False
477 #endif
478 #ifdef REG_F4
479 freeReg REG_F4 = fastBool False
480 #endif
481 #ifdef REG_D1
482 freeReg REG_D1 = fastBool False
483 #endif
484 #ifdef REG_D2
485 freeReg REG_D2 = fastBool False
486 #endif
487 #ifdef REG_Sp 
488 freeReg REG_Sp   = fastBool False
489 #endif 
490 #ifdef REG_Su
491 freeReg REG_Su   = fastBool False
492 #endif 
493 #ifdef REG_SpLim 
494 freeReg REG_SpLim = fastBool False
495 #endif 
496 #ifdef REG_Hp 
497 freeReg REG_Hp   = fastBool False
498 #endif
499 #ifdef REG_HpLim
500 freeReg REG_HpLim = fastBool False
501 #endif
502 freeReg _               = fastBool True
503
504
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.
508
509
510 #ifdef REG_Base
511 globalRegMaybe BaseReg                  = Just (regSingle REG_Base)
512 #endif
513 #ifdef REG_R1
514 globalRegMaybe (VanillaReg 1 _)         = Just (regSingle REG_R1)
515 #endif 
516 #ifdef REG_R2 
517 globalRegMaybe (VanillaReg 2 _)         = Just (regSingle REG_R2)
518 #endif 
519 #ifdef REG_R3 
520 globalRegMaybe (VanillaReg 3 _)         = Just (regSingle REG_R3)
521 #endif 
522 #ifdef REG_R4 
523 globalRegMaybe (VanillaReg 4 _)         = Just (regSingle REG_R4)
524 #endif 
525 #ifdef REG_R5 
526 globalRegMaybe (VanillaReg 5 _)         = Just (regSingle REG_R5)
527 #endif 
528 #ifdef REG_R6 
529 globalRegMaybe (VanillaReg 6 _)         = Just (regSingle REG_R6)
530 #endif 
531 #ifdef REG_R7 
532 globalRegMaybe (VanillaReg 7 _)         = Just (regSingle REG_R7)
533 #endif 
534 #ifdef REG_R8 
535 globalRegMaybe (VanillaReg 8 _)         = Just (regSingle REG_R8)
536 #endif
537 #ifdef REG_R9 
538 globalRegMaybe (VanillaReg 9 _)         = Just (regSingle REG_R9)
539 #endif
540 #ifdef REG_R10 
541 globalRegMaybe (VanillaReg 10 _)        = Just (regSingle REG_R10)
542 #endif
543 #ifdef REG_F1
544 globalRegMaybe (FloatReg 1)             = Just (regSingle REG_F1)
545 #endif                                  
546 #ifdef REG_F2                           
547 globalRegMaybe (FloatReg 2)             = Just (regSingle REG_F2)
548 #endif                                  
549 #ifdef REG_F3                           
550 globalRegMaybe (FloatReg 3)             = Just (regSingle REG_F3)
551 #endif                                  
552 #ifdef REG_F4                           
553 globalRegMaybe (FloatReg 4)             = Just (regSingle REG_F4)
554 #endif                                  
555 #ifdef REG_D1                           
556 globalRegMaybe (DoubleReg 1)            = Just (regSingle REG_D1)
557 #endif                                  
558 #ifdef REG_D2                           
559 globalRegMaybe (DoubleReg 2)            = Just (regSingle REG_D2)
560 #endif
561 #ifdef REG_Sp       
562 globalRegMaybe Sp                       = Just (regSingle REG_Sp)
563 #endif
564 #ifdef REG_Lng1                         
565 globalRegMaybe (LongReg 1)              = Just (regSingle REG_Lng1)
566 #endif                                  
567 #ifdef REG_Lng2                         
568 globalRegMaybe (LongReg 2)              = Just (regSingle REG_Lng2)
569 #endif
570 #ifdef REG_SpLim                                
571 globalRegMaybe SpLim                    = Just (regSingle REG_SpLim)
572 #endif                                  
573 #ifdef REG_Hp                           
574 globalRegMaybe Hp                       = Just (regSingle REG_Hp)
575 #endif                                  
576 #ifdef REG_HpLim                        
577 globalRegMaybe HpLim                    = Just (regSingle REG_HpLim)
578 #endif                                  
579 #ifdef REG_CurrentTSO                           
580 globalRegMaybe CurrentTSO               = Just (regSingle REG_CurrentTSO)
581 #endif                                  
582 #ifdef REG_CurrentNursery                       
583 globalRegMaybe CurrentNursery           = Just (regSingle REG_CurrentNursery)
584 #endif                                  
585 globalRegMaybe _                        = Nothing
586
587
588 #else  /* powerpc_TARGET_ARCH */
589
590 freeReg _               = 0#
591 globalRegMaybe _        = panic "PPC.Regs.globalRegMaybe: not defined"
592
593 #endif /* powerpc_TARGET_ARCH */
594
595
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]
600 allocatableRegs
601    = let isFree i = isFastTrue (freeReg i)
602      in  map RealRegSingle $ filter isFree allMachRegNos