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