(partial) Merge branch 'master' into type-nats
[ghc.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 OldCmm
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 argRegs :: RegNo -> [Reg]
213 argRegs 0 = []
214 argRegs 1 = map regSingle [3]
215 argRegs 2 = map regSingle [3,4]
216 argRegs 3 = map regSingle [3..5]
217 argRegs 4 = map regSingle [3..6]
218 argRegs 5 = map regSingle [3..7]
219 argRegs 6 = map regSingle [3..8]
220 argRegs 7 = map regSingle [3..9]
221 argRegs 8 = map regSingle [3..10]
222 argRegs _ = panic "MachRegs.argRegs(powerpc): don't know about >8 arguments!"
223
224
225 allArgRegs :: [Reg]
226 allArgRegs = map regSingle [3..10]
227
228
229 -- these are the regs which we cannot assume stay alive over a C call.
230 callClobberedRegs :: [Reg]
231 #if defined(darwin_TARGET_OS)
232 callClobberedRegs
233 = map regSingle (0:[2..12] ++ map fReg [0..13])
234
235 #elif defined(linux_TARGET_OS)
236 callClobberedRegs
237 = map regSingle (0:[2..13] ++ map fReg [0..13])
238
239 #else
240 callClobberedRegs
241 = panic "PPC.Regs.callClobberedRegs: not defined for this architecture"
242 #endif
243
244
245 allMachRegNos :: [RegNo]
246 allMachRegNos = [0..63]
247
248
249 {-# INLINE classOfRealReg #-}
250 classOfRealReg :: RealReg -> RegClass
251 classOfRealReg (RealRegSingle i)
252 | i < 32 = RcInteger
253 | otherwise = RcDouble
254
255 classOfRealReg (RealRegPair{})
256 = panic "regClass(ppr): no reg pairs on this architecture"
257
258 showReg :: RegNo -> String
259 showReg n
260 | n >= 0 && n <= 31 = "%r" ++ show n
261 | n >= 32 && n <= 63 = "%f" ++ show (n - 32)
262 | otherwise = "%unknown_powerpc_real_reg_" ++ show n
263
264
265
266 -- machine specific ------------------------------------------------------------
267
268 allFPArgRegs :: [Reg]
269 #if defined(darwin_TARGET_OS)
270 allFPArgRegs = map (regSingle . fReg) [1..13]
271
272 #elif defined(linux_TARGET_OS)
273 allFPArgRegs = map (regSingle . fReg) [1..8]
274
275 #else
276 allFPArgRegs = panic "PPC.Regs.allFPArgRegs: not defined for this architecture"
277
278 #endif
279
280 fits16Bits :: Integral a => a -> Bool
281 fits16Bits x = x >= -32768 && x < 32768
282
283 makeImmediate :: Integral a => Width -> Bool -> a -> Maybe Imm
284 makeImmediate rep signed x = fmap ImmInt (toI16 rep signed)
285 where
286 narrow W32 False = fromIntegral (fromIntegral x :: Word32)
287 narrow W16 False = fromIntegral (fromIntegral x :: Word16)
288 narrow W8 False = fromIntegral (fromIntegral x :: Word8)
289 narrow W32 True = fromIntegral (fromIntegral x :: Int32)
290 narrow W16 True = fromIntegral (fromIntegral x :: Int16)
291 narrow W8 True = fromIntegral (fromIntegral x :: Int8)
292 narrow _ _ = panic "PPC.Regs.narrow: no match"
293
294 narrowed = narrow rep signed
295
296 toI16 W32 True
297 | narrowed >= -32768 && narrowed < 32768 = Just narrowed
298 | otherwise = Nothing
299 toI16 W32 False
300 | narrowed >= 0 && narrowed < 65536 = Just narrowed
301 | otherwise = Nothing
302 toI16 _ _ = Just narrowed
303
304
305 {-
306 The PowerPC has 64 registers of interest; 32 integer registers and 32 floating
307 point registers.
308 -}
309
310 fReg :: Int -> RegNo
311 fReg x = (32 + x)
312
313 sp, r3, r4, r27, r28, f1, f20, f21 :: Reg
314 sp = regSingle 1
315 r3 = regSingle 3
316 r4 = regSingle 4
317 r27 = regSingle 27
318 r28 = regSingle 28
319 f1 = regSingle $ fReg 1
320 f20 = regSingle $ fReg 20
321 f21 = regSingle $ fReg 21
322
323
324
325 -- horror show -----------------------------------------------------------------
326 freeReg :: RegNo -> FastBool
327 globalRegMaybe :: GlobalReg -> Maybe Reg
328
329
330 #if powerpc_TARGET_ARCH
331 #define r0 0
332 #define r1 1
333 #define r2 2
334 #define r3 3
335 #define r4 4
336 #define r5 5
337 #define r6 6
338 #define r7 7
339 #define r8 8
340 #define r9 9
341 #define r10 10
342 #define r11 11
343 #define r12 12
344 #define r13 13
345 #define r14 14
346 #define r15 15
347 #define r16 16
348 #define r17 17
349 #define r18 18
350 #define r19 19
351 #define r20 20
352 #define r21 21
353 #define r22 22
354 #define r23 23
355 #define r24 24
356 #define r25 25
357 #define r26 26
358 #define r27 27
359 #define r28 28
360 #define r29 29
361 #define r30 30
362 #define r31 31
363
364 #ifdef darwin_TARGET_OS
365 #define f0 32
366 #define f1 33
367 #define f2 34
368 #define f3 35
369 #define f4 36
370 #define f5 37
371 #define f6 38
372 #define f7 39
373 #define f8 40
374 #define f9 41
375 #define f10 42
376 #define f11 43
377 #define f12 44
378 #define f13 45
379 #define f14 46
380 #define f15 47
381 #define f16 48
382 #define f17 49
383 #define f18 50
384 #define f19 51
385 #define f20 52
386 #define f21 53
387 #define f22 54
388 #define f23 55
389 #define f24 56
390 #define f25 57
391 #define f26 58
392 #define f27 59
393 #define f28 60
394 #define f29 61
395 #define f30 62
396 #define f31 63
397 #else
398 #define fr0 32
399 #define fr1 33
400 #define fr2 34
401 #define fr3 35
402 #define fr4 36
403 #define fr5 37
404 #define fr6 38
405 #define fr7 39
406 #define fr8 40
407 #define fr9 41
408 #define fr10 42
409 #define fr11 43
410 #define fr12 44
411 #define fr13 45
412 #define fr14 46
413 #define fr15 47
414 #define fr16 48
415 #define fr17 49
416 #define fr18 50
417 #define fr19 51
418 #define fr20 52
419 #define fr21 53
420 #define fr22 54
421 #define fr23 55
422 #define fr24 56
423 #define fr25 57
424 #define fr26 58
425 #define fr27 59
426 #define fr28 60
427 #define fr29 61
428 #define fr30 62
429 #define fr31 63
430 #endif
431
432
433
434 freeReg 0 = fastBool False -- Hack: r0 can't be used in all insns, but it's actually free
435 freeReg 1 = fastBool False -- The Stack Pointer
436 #if !darwin_TARGET_OS
437 -- most non-darwin powerpc OSes use r2 as a TOC pointer or something like that
438 freeReg 2 = fastBool False
439 #endif
440
441 #ifdef REG_Base
442 freeReg REG_Base = fastBool False
443 #endif
444 #ifdef REG_R1
445 freeReg REG_R1 = fastBool False
446 #endif
447 #ifdef REG_R2
448 freeReg REG_R2 = fastBool False
449 #endif
450 #ifdef REG_R3
451 freeReg REG_R3 = fastBool False
452 #endif
453 #ifdef REG_R4
454 freeReg REG_R4 = fastBool False
455 #endif
456 #ifdef REG_R5
457 freeReg REG_R5 = fastBool False
458 #endif
459 #ifdef REG_R6
460 freeReg REG_R6 = fastBool False
461 #endif
462 #ifdef REG_R7
463 freeReg REG_R7 = fastBool False
464 #endif
465 #ifdef REG_R8
466 freeReg REG_R8 = fastBool False
467 #endif
468 #ifdef REG_F1
469 freeReg REG_F1 = fastBool False
470 #endif
471 #ifdef REG_F2
472 freeReg REG_F2 = fastBool False
473 #endif
474 #ifdef REG_F3
475 freeReg REG_F3 = fastBool False
476 #endif
477 #ifdef REG_F4
478 freeReg REG_F4 = fastBool False
479 #endif
480 #ifdef REG_D1
481 freeReg REG_D1 = fastBool False
482 #endif
483 #ifdef REG_D2
484 freeReg REG_D2 = fastBool False
485 #endif
486 #ifdef REG_Sp
487 freeReg REG_Sp = fastBool False
488 #endif
489 #ifdef REG_Su
490 freeReg REG_Su = fastBool False
491 #endif
492 #ifdef REG_SpLim
493 freeReg REG_SpLim = fastBool False
494 #endif
495 #ifdef REG_Hp
496 freeReg REG_Hp = fastBool False
497 #endif
498 #ifdef REG_HpLim
499 freeReg REG_HpLim = fastBool False
500 #endif
501 freeReg _ = fastBool True
502
503
504 -- | Returns 'Nothing' if this global register is not stored
505 -- in a real machine register, otherwise returns @'Just' reg@, where
506 -- reg is the machine register it is stored in.
507
508
509 #ifdef REG_Base
510 globalRegMaybe BaseReg = Just (regSingle REG_Base)
511 #endif
512 #ifdef REG_R1
513 globalRegMaybe (VanillaReg 1 _) = Just (regSingle REG_R1)
514 #endif
515 #ifdef REG_R2
516 globalRegMaybe (VanillaReg 2 _) = Just (regSingle REG_R2)
517 #endif
518 #ifdef REG_R3
519 globalRegMaybe (VanillaReg 3 _) = Just (regSingle REG_R3)
520 #endif
521 #ifdef REG_R4
522 globalRegMaybe (VanillaReg 4 _) = Just (regSingle REG_R4)
523 #endif
524 #ifdef REG_R5
525 globalRegMaybe (VanillaReg 5 _) = Just (regSingle REG_R5)
526 #endif
527 #ifdef REG_R6
528 globalRegMaybe (VanillaReg 6 _) = Just (regSingle REG_R6)
529 #endif
530 #ifdef REG_R7
531 globalRegMaybe (VanillaReg 7 _) = Just (regSingle REG_R7)
532 #endif
533 #ifdef REG_R8
534 globalRegMaybe (VanillaReg 8 _) = Just (regSingle REG_R8)
535 #endif
536 #ifdef REG_R9
537 globalRegMaybe (VanillaReg 9 _) = Just (regSingle REG_R9)
538 #endif
539 #ifdef REG_R10
540 globalRegMaybe (VanillaReg 10 _) = Just (regSingle REG_R10)
541 #endif
542 #ifdef REG_F1
543 globalRegMaybe (FloatReg 1) = Just (regSingle REG_F1)
544 #endif
545 #ifdef REG_F2
546 globalRegMaybe (FloatReg 2) = Just (regSingle REG_F2)
547 #endif
548 #ifdef REG_F3
549 globalRegMaybe (FloatReg 3) = Just (regSingle REG_F3)
550 #endif
551 #ifdef REG_F4
552 globalRegMaybe (FloatReg 4) = Just (regSingle REG_F4)
553 #endif
554 #ifdef REG_D1
555 globalRegMaybe (DoubleReg 1) = Just (regSingle REG_D1)
556 #endif
557 #ifdef REG_D2
558 globalRegMaybe (DoubleReg 2) = Just (regSingle REG_D2)
559 #endif
560 #ifdef REG_Sp
561 globalRegMaybe Sp = Just (regSingle REG_Sp)
562 #endif
563 #ifdef REG_Lng1
564 globalRegMaybe (LongReg 1) = Just (regSingle REG_Lng1)
565 #endif
566 #ifdef REG_Lng2
567 globalRegMaybe (LongReg 2) = Just (regSingle REG_Lng2)
568 #endif
569 #ifdef REG_SpLim
570 globalRegMaybe SpLim = Just (regSingle REG_SpLim)
571 #endif
572 #ifdef REG_Hp
573 globalRegMaybe Hp = Just (regSingle REG_Hp)
574 #endif
575 #ifdef REG_HpLim
576 globalRegMaybe HpLim = Just (regSingle REG_HpLim)
577 #endif
578 #ifdef REG_CurrentTSO
579 globalRegMaybe CurrentTSO = Just (regSingle REG_CurrentTSO)
580 #endif
581 #ifdef REG_CurrentNursery
582 globalRegMaybe CurrentNursery = Just (regSingle REG_CurrentNursery)
583 #endif
584 globalRegMaybe _ = Nothing
585
586
587 #else /* powerpc_TARGET_ARCH */
588
589 freeReg _ = 0#
590 globalRegMaybe _ = panic "PPC.Regs.globalRegMaybe: not defined"
591
592 #endif /* powerpc_TARGET_ARCH */
593
594
595 -- allocatableRegs is allMachRegNos with the fixed-use regs removed.
596 -- i.e., these are the regs for which we are prepared to allow the
597 -- register allocator to attempt to map VRegs to.
598 allocatableRegs :: [RealReg]
599 allocatableRegs
600 = let isFree i = isFastTrue (freeReg i)
601 in map RealRegSingle $ filter isFree allMachRegNos