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