Split Reg into vreg/hreg and add register pairs
[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         -- immediates
9         Imm(..),
10         strImmLit,
11         litToImm,
12
13         -- addressing modes
14         AddrMode(..),
15         addrOffset,
16
17         -- registers
18         spRel,
19         argRegs,
20         allArgRegs,
21         callClobberedRegs,
22         allMachRegNos,
23         regClass,
24         showReg,
25         
26         -- machine specific
27         allFPArgRegs,
28         fits16Bits,
29         makeImmediate,
30         fReg,
31         sp, r3, r4, r27, r28, f1, f20, f21,
32
33         -- horrow show
34         freeReg,
35         globalRegMaybe,
36         get_GlobalReg_reg_or_addr,
37         allocatableRegs
38
39 )
40
41 where
42
43 #include "nativeGen/NCG.h"
44 #include "HsVersions.h"
45 #include "../includes/MachRegs.h"
46
47 import Reg
48 import RegClass
49
50 import CgUtils          ( get_GlobalReg_addr )
51 import BlockId
52 import Cmm
53 import CLabel           ( CLabel )
54 import Pretty
55 import Outputable       ( Outputable(..), pprPanic, panic )
56 import qualified Outputable
57 import Constants
58 import FastBool
59
60 import Data.Word        ( Word8, Word16, Word32 )
61 import Data.Int         ( Int8, Int16, Int32 )
62
63
64 -- immediates ------------------------------------------------------------------
65 data Imm
66         = ImmInt        Int
67         | ImmInteger    Integer     -- Sigh.
68         | ImmCLbl       CLabel      -- AbstractC Label (with baggage)
69         | ImmLit        Doc         -- Simple string
70         | ImmIndex    CLabel Int
71         | ImmFloat      Rational
72         | ImmDouble     Rational
73         | ImmConstantSum Imm Imm
74         | ImmConstantDiff Imm Imm
75         | LO Imm
76         | HI Imm
77         | HA Imm        {- high halfword adjusted -}
78
79
80 strImmLit :: String -> Imm
81 strImmLit s = ImmLit (text s)
82
83
84 litToImm :: CmmLit -> Imm
85 litToImm (CmmInt i w)        = ImmInteger (narrowS w i)
86                 -- narrow to the width: a CmmInt might be out of
87                 -- range, but we assume that ImmInteger only contains
88                 -- in-range values.  A signed value should be fine here.
89 litToImm (CmmFloat f W32)    = ImmFloat f
90 litToImm (CmmFloat f W64)    = ImmDouble f
91 litToImm (CmmLabel l)        = ImmCLbl l
92 litToImm (CmmLabelOff l off) = ImmIndex l off
93 litToImm (CmmLabelDiffOff l1 l2 off)
94                              = ImmConstantSum
95                                (ImmConstantDiff (ImmCLbl l1) (ImmCLbl l2))
96                                (ImmInt off)
97 litToImm (CmmBlock id)       = ImmCLbl (infoTblLbl id)
98 litToImm _                   = panic "PPC.Regs.litToImm: no match"
99
100
101 -- addressing modes ------------------------------------------------------------
102
103 data AddrMode
104         = AddrRegReg    Reg Reg
105         | AddrRegImm    Reg Imm
106
107
108 addrOffset :: AddrMode -> Int -> Maybe AddrMode
109 addrOffset addr off
110   = case addr of
111       AddrRegImm r (ImmInt n)
112        | fits16Bits n2 -> Just (AddrRegImm r (ImmInt n2))
113        | otherwise     -> Nothing
114        where n2 = n + off
115
116       AddrRegImm r (ImmInteger n)
117        | fits16Bits n2 -> Just (AddrRegImm r (ImmInt (fromInteger n2)))
118        | otherwise     -> Nothing
119        where n2 = n + toInteger off
120        
121       _ -> Nothing
122
123
124 -- registers -------------------------------------------------------------------
125 -- @spRel@ gives us a stack relative addressing mode for volatile
126 -- temporaries and for excess call arguments.  @fpRel@, where
127 -- applicable, is the same but for the frame pointer.
128
129 spRel :: Int    -- desired stack offset in words, positive or negative
130       -> AddrMode
131
132 spRel n = AddrRegImm sp (ImmInt (n * wORD_SIZE))
133
134
135 -- argRegs is the set of regs which are read for an n-argument call to C.
136 -- For archs which pass all args on the stack (x86), is empty.
137 -- Sparc passes up to the first 6 args in regs.
138 -- Dunno about Alpha.
139 argRegs :: RegNo -> [Reg]
140 argRegs 0 = []
141 argRegs 1 = map regSingle [3]
142 argRegs 2 = map regSingle [3,4]
143 argRegs 3 = map regSingle [3..5]
144 argRegs 4 = map regSingle [3..6]
145 argRegs 5 = map regSingle [3..7]
146 argRegs 6 = map regSingle [3..8]
147 argRegs 7 = map regSingle [3..9]
148 argRegs 8 = map regSingle [3..10]
149 argRegs _ = panic "MachRegs.argRegs(powerpc): don't know about >8 arguments!"
150
151
152 allArgRegs :: [Reg]
153 allArgRegs = map regSingle [3..10]
154
155
156 -- these are the regs which we cannot assume stay alive over a C call.  
157 callClobberedRegs :: [Reg]
158 #if   defined(darwin_TARGET_OS)
159 callClobberedRegs
160   = map regSingle (0:[2..12] ++ map fReg [0..13])
161
162 #elif defined(linux_TARGET_OS)
163 callClobberedRegs
164   = map regSingle (0:[2..13] ++ map fReg [0..13])
165
166 #else
167 callClobberedRegs
168         = panic "PPC.Regs.callClobberedRegs: not defined for this architecture"
169 #endif
170
171
172 allMachRegNos   :: [RegNo]
173 allMachRegNos   = [0..63]
174
175
176 {-# INLINE regClass      #-}
177 regClass :: Reg -> RegClass
178 regClass (RegVirtual (VirtualRegI  _)) = RcInteger
179 regClass (RegVirtual (VirtualRegHi _)) = RcInteger
180 regClass (RegVirtual (VirtualRegF  u)) = pprPanic ("regClass(ppc):VirtualRegF ") (ppr u)
181 regClass (RegVirtual (VirtualRegD  _)) = RcDouble
182
183 regClass (RegReal    (RealRegSingle i))
184         | i < 32        = RcInteger 
185         | otherwise     = RcDouble
186
187 regClass (RegReal    (RealRegPair{}))
188         = panic "regClass(ppr): no reg pairs on this architecture"
189
190 showReg :: RegNo -> String
191 showReg n
192     | n >= 0 && n <= 31   = "%r" ++ show n
193     | n >= 32 && n <= 63  = "%f" ++ show (n - 32)
194     | otherwise           = "%unknown_powerpc_real_reg_" ++ show n
195
196
197
198 -- machine specific ------------------------------------------------------------
199
200 allFPArgRegs :: [Reg]
201 #if    defined(darwin_TARGET_OS)
202 allFPArgRegs = map (regSingle . fReg) [1..13]
203
204 #elif  defined(linux_TARGET_OS)
205 allFPArgRegs = map (regSingle . fReg) [1..8]
206
207 #else
208 allFPArgRegs = panic "PPC.Regs.allFPArgRegs: not defined for this architecture"
209
210 #endif
211
212 fits16Bits :: Integral a => a -> Bool
213 fits16Bits x = x >= -32768 && x < 32768
214
215 makeImmediate :: Integral a => Width -> Bool -> a -> Maybe Imm
216 makeImmediate rep signed x = fmap ImmInt (toI16 rep signed)
217     where
218         narrow W32 False = fromIntegral (fromIntegral x :: Word32)
219         narrow W16 False = fromIntegral (fromIntegral x :: Word16)
220         narrow W8  False = fromIntegral (fromIntegral x :: Word8)
221         narrow W32 True  = fromIntegral (fromIntegral x :: Int32)
222         narrow W16 True  = fromIntegral (fromIntegral x :: Int16)
223         narrow W8  True  = fromIntegral (fromIntegral x :: Int8)
224         narrow _   _     = panic "PPC.Regs.narrow: no match"
225         
226         narrowed = narrow rep signed
227         
228         toI16 W32 True
229             | narrowed >= -32768 && narrowed < 32768 = Just narrowed
230             | otherwise = Nothing
231         toI16 W32 False
232             | narrowed >= 0 && narrowed < 65536 = Just narrowed
233             | otherwise = Nothing
234         toI16 _ _  = Just narrowed
235
236
237 {-
238 The PowerPC has 64 registers of interest; 32 integer registers and 32 floating
239 point registers.
240 -}
241
242 fReg :: Int -> RegNo
243 fReg x = (32 + x)
244
245 sp, r3, r4, r27, r28, f1, f20, f21 :: Reg
246 sp      = regSingle 1
247 r3      = regSingle 3
248 r4      = regSingle 4
249 r27     = regSingle 27
250 r28     = regSingle 28
251 f1      = regSingle $ fReg 1
252 f20     = regSingle $ fReg 20
253 f21     = regSingle $ fReg 21
254
255
256
257 -- horror show -----------------------------------------------------------------
258 freeReg :: RegNo -> FastBool
259 globalRegMaybe :: GlobalReg -> Maybe Reg
260
261
262 #if powerpc_TARGET_ARCH
263 #define r0 0
264 #define r1 1
265 #define r2 2
266 #define r3 3
267 #define r4 4
268 #define r5 5
269 #define r6 6
270 #define r7 7
271 #define r8 8
272 #define r9 9
273 #define r10 10
274 #define r11 11
275 #define r12 12
276 #define r13 13
277 #define r14 14
278 #define r15 15
279 #define r16 16
280 #define r17 17
281 #define r18 18
282 #define r19 19
283 #define r20 20
284 #define r21 21
285 #define r22 22
286 #define r23 23
287 #define r24 24
288 #define r25 25
289 #define r26 26
290 #define r27 27
291 #define r28 28
292 #define r29 29
293 #define r30 30
294 #define r31 31
295
296 #ifdef darwin_TARGET_OS
297 #define f0  32
298 #define f1  33
299 #define f2  34
300 #define f3  35
301 #define f4  36
302 #define f5  37
303 #define f6  38
304 #define f7  39
305 #define f8  40
306 #define f9  41
307 #define f10 42
308 #define f11 43
309 #define f12 44
310 #define f13 45
311 #define f14 46
312 #define f15 47
313 #define f16 48
314 #define f17 49
315 #define f18 50
316 #define f19 51
317 #define f20 52
318 #define f21 53
319 #define f22 54
320 #define f23 55
321 #define f24 56
322 #define f25 57
323 #define f26 58
324 #define f27 59
325 #define f28 60
326 #define f29 61
327 #define f30 62
328 #define f31 63
329 #else
330 #define fr0  32
331 #define fr1  33
332 #define fr2  34
333 #define fr3  35
334 #define fr4  36
335 #define fr5  37
336 #define fr6  38
337 #define fr7  39
338 #define fr8  40
339 #define fr9  41
340 #define fr10 42
341 #define fr11 43
342 #define fr12 44
343 #define fr13 45
344 #define fr14 46
345 #define fr15 47
346 #define fr16 48
347 #define fr17 49
348 #define fr18 50
349 #define fr19 51
350 #define fr20 52
351 #define fr21 53
352 #define fr22 54
353 #define fr23 55
354 #define fr24 56
355 #define fr25 57
356 #define fr26 58
357 #define fr27 59
358 #define fr28 60
359 #define fr29 61
360 #define fr30 62
361 #define fr31 63
362 #endif
363
364
365
366 freeReg 0 = fastBool False -- Hack: r0 can't be used in all insns, but it's actually free
367 freeReg 1 = fastBool False -- The Stack Pointer
368 #if !darwin_TARGET_OS
369  -- most non-darwin powerpc OSes use r2 as a TOC pointer or something like that
370 freeReg 2 = fastBool False
371 #endif
372
373 #ifdef REG_Base
374 freeReg REG_Base = fastBool False
375 #endif
376 #ifdef REG_R1
377 freeReg REG_R1   = fastBool False
378 #endif  
379 #ifdef REG_R2  
380 freeReg REG_R2   = fastBool False
381 #endif  
382 #ifdef REG_R3  
383 freeReg REG_R3   = fastBool False
384 #endif  
385 #ifdef REG_R4  
386 freeReg REG_R4   = fastBool False
387 #endif  
388 #ifdef REG_R5  
389 freeReg REG_R5   = fastBool False
390 #endif  
391 #ifdef REG_R6  
392 freeReg REG_R6   = fastBool False
393 #endif  
394 #ifdef REG_R7  
395 freeReg REG_R7   = fastBool False
396 #endif  
397 #ifdef REG_R8  
398 freeReg REG_R8   = fastBool False
399 #endif
400 #ifdef REG_F1
401 freeReg REG_F1 = fastBool False
402 #endif
403 #ifdef REG_F2
404 freeReg REG_F2 = fastBool False
405 #endif
406 #ifdef REG_F3
407 freeReg REG_F3 = fastBool False
408 #endif
409 #ifdef REG_F4
410 freeReg REG_F4 = fastBool False
411 #endif
412 #ifdef REG_D1
413 freeReg REG_D1 = fastBool False
414 #endif
415 #ifdef REG_D2
416 freeReg REG_D2 = fastBool False
417 #endif
418 #ifdef REG_Sp 
419 freeReg REG_Sp   = fastBool False
420 #endif 
421 #ifdef REG_Su
422 freeReg REG_Su   = fastBool False
423 #endif 
424 #ifdef REG_SpLim 
425 freeReg REG_SpLim = fastBool False
426 #endif 
427 #ifdef REG_Hp 
428 freeReg REG_Hp   = fastBool False
429 #endif
430 #ifdef REG_HpLim
431 freeReg REG_HpLim = fastBool False
432 #endif
433 freeReg _               = fastBool True
434
435
436 --  | Returns 'Nothing' if this global register is not stored
437 -- in a real machine register, otherwise returns @'Just' reg@, where
438 -- reg is the machine register it is stored in.
439
440
441 #ifdef REG_Base
442 globalRegMaybe BaseReg                  = Just (regSingle REG_Base)
443 #endif
444 #ifdef REG_R1
445 globalRegMaybe (VanillaReg 1 _)         = Just (regSingle REG_R1)
446 #endif 
447 #ifdef REG_R2 
448 globalRegMaybe (VanillaReg 2 _)         = Just (regSingle REG_R2)
449 #endif 
450 #ifdef REG_R3 
451 globalRegMaybe (VanillaReg 3 _)         = Just (regSingle REG_R3)
452 #endif 
453 #ifdef REG_R4 
454 globalRegMaybe (VanillaReg 4 _)         = Just (regSingle REG_R4)
455 #endif 
456 #ifdef REG_R5 
457 globalRegMaybe (VanillaReg 5 _)         = Just (regSingle REG_R5)
458 #endif 
459 #ifdef REG_R6 
460 globalRegMaybe (VanillaReg 6 _)         = Just (regSingle REG_R6)
461 #endif 
462 #ifdef REG_R7 
463 globalRegMaybe (VanillaReg 7 _)         = Just (regSingle REG_R7)
464 #endif 
465 #ifdef REG_R8 
466 globalRegMaybe (VanillaReg 8 _)         = Just (regSingle REG_R8)
467 #endif
468 #ifdef REG_R9 
469 globalRegMaybe (VanillaReg 9 _)         = Just (regSingle REG_R9)
470 #endif
471 #ifdef REG_R10 
472 globalRegMaybe (VanillaReg 10 _)        = Just (regSingle REG_R10)
473 #endif
474 #ifdef REG_F1
475 globalRegMaybe (FloatReg 1)             = Just (regSingle REG_F1)
476 #endif                                  
477 #ifdef REG_F2                           
478 globalRegMaybe (FloatReg 2)             = Just (regSingle REG_F2)
479 #endif                                  
480 #ifdef REG_F3                           
481 globalRegMaybe (FloatReg 3)             = Just (regSingle REG_F3)
482 #endif                                  
483 #ifdef REG_F4                           
484 globalRegMaybe (FloatReg 4)             = Just (regSingle REG_F4)
485 #endif                                  
486 #ifdef REG_D1                           
487 globalRegMaybe (DoubleReg 1)            = Just (regSingle REG_D1)
488 #endif                                  
489 #ifdef REG_D2                           
490 globalRegMaybe (DoubleReg 2)            = Just (regSingle REG_D2)
491 #endif
492 #ifdef REG_Sp       
493 globalRegMaybe Sp                       = Just (regSingle REG_Sp)
494 #endif
495 #ifdef REG_Lng1                         
496 globalRegMaybe (LongReg 1)              = Just (regSingle REG_Lng1)
497 #endif                                  
498 #ifdef REG_Lng2                         
499 globalRegMaybe (LongReg 2)              = Just (regSingle REG_Lng2)
500 #endif
501 #ifdef REG_SpLim                                
502 globalRegMaybe SpLim                    = Just (regSingle REG_SpLim)
503 #endif                                  
504 #ifdef REG_Hp                           
505 globalRegMaybe Hp                       = Just (regSingle REG_Hp)
506 #endif                                  
507 #ifdef REG_HpLim                        
508 globalRegMaybe HpLim                    = Just (regSingle REG_HpLim)
509 #endif                                  
510 #ifdef REG_CurrentTSO                           
511 globalRegMaybe CurrentTSO               = Just (regSingle REG_CurrentTSO)
512 #endif                                  
513 #ifdef REG_CurrentNursery                       
514 globalRegMaybe CurrentNursery           = Just (regSingle REG_CurrentNursery)
515 #endif                                  
516 globalRegMaybe _                        = Nothing
517
518
519 #else  /* powerpc_TARGET_ARCH */
520
521 freeReg _               = 0#
522 globalRegMaybe _        = panic "PPC.Regs.globalRegMaybe: not defined"
523
524 #endif /* powerpc_TARGET_ARCH */
525
526
527 -- We map STG registers onto appropriate CmmExprs.  Either they map
528 -- to real machine registers or stored as offsets from BaseReg.  Given
529 -- a GlobalReg, get_GlobalReg_reg_or_addr produces either the real
530 -- register it is in, on this platform, or a CmmExpr denoting the
531 -- address in the register table holding it.
532 -- (See also get_GlobalReg_addr in CgUtils.)
533
534 get_GlobalReg_reg_or_addr :: GlobalReg -> Either Reg CmmExpr
535 get_GlobalReg_reg_or_addr mid
536    = case globalRegMaybe mid of
537         Just rr -> Left rr
538         Nothing -> Right (get_GlobalReg_addr mid)
539
540
541 -- allocatableRegs is allMachRegNos with the fixed-use regs removed.
542 -- i.e., these are the regs for which we are prepared to allow the
543 -- register allocator to attempt to map VRegs to.
544 allocatableRegs :: [RegNo]
545 allocatableRegs
546    = let isFree i = isFastTrue (freeReg i)
547      in  filter isFree allMachRegNos