Remove dead Alpha native backend.
[ghc-hetmet.git] / compiler / nativeGen / X86 / Regs.hs
1 module X86.Regs (
2         -- squeese functions for the graph allocator
3         virtualRegSqueeze,
4         realRegSqueeze,
5
6         -- immediates
7         Imm(..),
8         strImmLit,
9         litToImm,
10
11         -- addressing modes
12         AddrMode(..),
13         addrOffset,
14
15         -- registers
16         spRel,
17         argRegs,
18         allArgRegs,
19         callClobberedRegs,
20         allMachRegNos,
21         classOfRealReg,
22         showReg,        
23
24         -- machine specific
25         EABase(..), EAIndex(..), addrModeRegs,
26
27         eax, ebx, ecx, edx, esi, edi, ebp, esp,
28         fake0, fake1, fake2, fake3, fake4, fake5, firstfake,
29
30         rax, rbx, rcx, rdx, rsi, rdi, rbp, rsp,
31         r8,  r9,  r10, r11, r12, r13, r14, r15,
32         xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7,
33         xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15,
34         xmm,
35
36         ripRel,
37         allFPArgRegs,
38
39         -- horror show
40         freeReg,
41         globalRegMaybe,
42         
43         allocatableRegs
44 )
45
46 where
47
48 #include "nativeGen/NCG.h"
49 #include "HsVersions.h"
50
51 #include "../includes/stg/MachRegs.h"
52
53 import Reg
54 import RegClass
55
56 import BlockId
57 import OldCmm
58 import CLabel           ( CLabel )
59 import Pretty
60 import Outputable       ( panic )
61 import FastTypes
62 import FastBool
63
64
65 #if  defined(i386_TARGET_ARCH) || defined(x86_64_TARGET_ARCH)
66 import Constants
67 #endif
68
69
70 -- | regSqueeze_class reg
71 --      Calculuate the maximum number of register colors that could be
72 --      denied to a node of this class due to having this reg 
73 --      as a neighbour.
74 --
75 {-# INLINE virtualRegSqueeze #-}
76 virtualRegSqueeze :: RegClass -> VirtualReg -> FastInt
77
78 virtualRegSqueeze cls vr
79  = case cls of
80         RcInteger
81          -> case vr of
82                 VirtualRegI{}           -> _ILIT(1)
83                 VirtualRegHi{}          -> _ILIT(1)
84                 _other                  -> _ILIT(0)
85
86         RcDouble
87          -> case vr of
88                 VirtualRegD{}           -> _ILIT(1)
89                 VirtualRegF{}           -> _ILIT(0)
90                 _other                  -> _ILIT(0)
91
92         RcDoubleSSE
93          -> case vr of
94                 VirtualRegSSE{}         -> _ILIT(1)
95                 _other                  -> _ILIT(0)
96
97         _other -> _ILIT(0)
98
99 {-# INLINE realRegSqueeze #-}
100 realRegSqueeze :: RegClass -> RealReg -> FastInt
101 realRegSqueeze cls rr
102  = case cls of
103         RcInteger
104          -> case rr of
105                 RealRegSingle regNo
106                         | regNo < firstfake -> _ILIT(1)
107                         | otherwise     -> _ILIT(0)
108                         
109                 RealRegPair{}           -> _ILIT(0)
110
111         RcDouble
112          -> case rr of
113                 RealRegSingle regNo
114                         | regNo >= firstfake && regNo <= lastfake -> _ILIT(1)
115                         | otherwise     -> _ILIT(0)
116                         
117                 RealRegPair{}           -> _ILIT(0)
118
119         RcDoubleSSE
120          -> case rr of
121                 RealRegSingle regNo | regNo >= firstxmm -> _ILIT(1)
122                 _otherwise                        -> _ILIT(0)
123
124         _other -> _ILIT(0)
125
126 -- -----------------------------------------------------------------------------
127 -- Immediates
128
129 data Imm
130   = ImmInt      Int
131   | ImmInteger  Integer     -- Sigh.
132   | ImmCLbl     CLabel      -- AbstractC Label (with baggage)
133   | ImmLit      Doc         -- Simple string
134   | ImmIndex    CLabel Int
135   | ImmFloat    Rational
136   | ImmDouble   Rational
137   | ImmConstantSum Imm Imm
138   | ImmConstantDiff Imm Imm
139
140
141 strImmLit :: String -> Imm
142 strImmLit s = ImmLit (text s)
143
144
145 litToImm :: CmmLit -> Imm
146 litToImm (CmmInt i w)        = ImmInteger (narrowS w i)
147                 -- narrow to the width: a CmmInt might be out of
148                 -- range, but we assume that ImmInteger only contains
149                 -- in-range values.  A signed value should be fine here.
150 litToImm (CmmFloat f W32)    = ImmFloat f
151 litToImm (CmmFloat f W64)    = ImmDouble f
152 litToImm (CmmLabel l)        = ImmCLbl l
153 litToImm (CmmLabelOff l off) = ImmIndex l off
154 litToImm (CmmLabelDiffOff l1 l2 off)
155                              = ImmConstantSum
156                                (ImmConstantDiff (ImmCLbl l1) (ImmCLbl l2))
157                                (ImmInt off)
158 litToImm (CmmBlock id)       = ImmCLbl (infoTblLbl id)
159 litToImm _                   = panic "X86.Regs.litToImm: no match"
160
161 -- addressing modes ------------------------------------------------------------
162
163 data AddrMode
164         = AddrBaseIndex EABase EAIndex Displacement
165         | ImmAddr Imm Int
166
167 data EABase       = EABaseNone  | EABaseReg Reg | EABaseRip
168 data EAIndex      = EAIndexNone | EAIndex Reg Int
169 type Displacement = Imm
170
171
172 addrOffset :: AddrMode -> Int -> Maybe AddrMode
173 addrOffset addr off
174   = case addr of
175       ImmAddr i off0      -> Just (ImmAddr i (off0 + off))
176
177       AddrBaseIndex r i (ImmInt n) -> Just (AddrBaseIndex r i (ImmInt (n + off)))
178       AddrBaseIndex r i (ImmInteger n)
179         -> Just (AddrBaseIndex r i (ImmInt (fromInteger (n + toInteger off))))
180
181       AddrBaseIndex r i (ImmCLbl lbl)
182         -> Just (AddrBaseIndex r i (ImmIndex lbl off))
183
184       AddrBaseIndex r i (ImmIndex lbl ix)
185         -> Just (AddrBaseIndex r i (ImmIndex lbl (ix+off)))
186
187       _ -> Nothing  -- in theory, shouldn't happen
188
189
190 addrModeRegs :: AddrMode -> [Reg]
191 addrModeRegs (AddrBaseIndex b i _) =  b_regs ++ i_regs
192   where
193    b_regs = case b of { EABaseReg r -> [r]; _ -> [] }
194    i_regs = case i of { EAIndex r _ -> [r]; _ -> [] }
195 addrModeRegs _ = []
196
197
198 -- registers -------------------------------------------------------------------
199
200 -- @spRel@ gives us a stack relative addressing mode for volatile
201 -- temporaries and for excess call arguments.  @fpRel@, where
202 -- applicable, is the same but for the frame pointer.
203
204
205 spRel :: Int            -- ^ desired stack offset in words, positive or negative
206       -> AddrMode
207
208 #if   i386_TARGET_ARCH
209 spRel n = AddrBaseIndex (EABaseReg esp) EAIndexNone (ImmInt (n * wORD_SIZE))
210
211 #elif x86_64_TARGET_ARCH
212 spRel n = AddrBaseIndex (EABaseReg rsp) EAIndexNone (ImmInt (n * wORD_SIZE))
213
214 #else
215 spRel _ = panic "X86.Regs.spRel: not defined for this architecture"
216
217 #endif
218
219 -- The register numbers must fit into 32 bits on x86, so that we can
220 -- use a Word32 to represent the set of free registers in the register
221 -- allocator.
222
223 firstfake, lastfake :: RegNo
224 firstfake = 16
225 lastfake  = 21
226
227 firstxmm, lastxmm :: RegNo
228 firstxmm  = 24
229 #if i386_TARGET_ARCH
230 lastxmm   = 31
231 #else
232 lastxmm   = 39
233 #endif
234
235 lastint :: RegNo
236 #if i386_TARGET_ARCH
237 lastint = 7 -- not %r8..%r15
238 #else
239 lastint = 15
240 #endif
241
242 intregnos, fakeregnos, xmmregnos, floatregnos :: [RegNo]
243 intregnos   = [0..lastint]
244 fakeregnos  = [firstfake .. lastfake]
245 xmmregnos   = [firstxmm  .. lastxmm]
246 floatregnos = fakeregnos ++ xmmregnos;
247
248
249 -- argRegs is the set of regs which are read for an n-argument call to C.
250 -- For archs which pass all args on the stack (x86), is empty.
251 -- Sparc passes up to the first 6 args in regs.
252 argRegs :: RegNo -> [Reg]
253 argRegs _       = panic "MachRegs.argRegs(x86): should not be used!"
254
255 -- | The complete set of machine registers.
256 allMachRegNos :: [RegNo]
257 allMachRegNos  = intregnos ++ floatregnos
258
259 -- | Take the class of a register.
260 {-# INLINE classOfRealReg      #-}
261 classOfRealReg :: RealReg -> RegClass
262 -- On x86, we might want to have an 8-bit RegClass, which would
263 -- contain just regs 1-4 (the others don't have 8-bit versions).
264 -- However, we can get away without this at the moment because the
265 -- only allocatable integer regs are also 8-bit compatible (1, 3, 4).
266 classOfRealReg reg
267  = case reg of
268         RealRegSingle i
269           | i <= lastint  -> RcInteger
270           | i <= lastfake -> RcDouble
271           | otherwise     -> RcDoubleSSE
272
273         RealRegPair{}   -> panic "X86.Regs.classOfRealReg: RegPairs on this arch"
274
275 -- | Get the name of the register with this number.
276 showReg :: RegNo -> String
277 showReg n
278         | n >= firstxmm  = "%xmm" ++ show (n-firstxmm)
279         | n >= firstfake = "%fake" ++ show (n-firstfake)
280         | n >= 8         = "%r" ++ show n
281         | otherwise      = regNames !! n
282
283 regNames :: [String]
284 regNames 
285 #if   i386_TARGET_ARCH
286    = ["%eax", "%ebx", "%ecx", "%edx", "%esi", "%edi", "%ebp", "%esp"]
287 #elif x86_64_TARGET_ARCH
288    = ["%rax", "%rbx", "%rcx", "%rdx", "%rsi", "%rdi", "%rbp", "%rsp" ]
289 #else
290    = []
291 #endif
292
293
294
295 -- machine specific ------------------------------------------------------------
296
297
298 {-
299 Intel x86 architecture:
300 - All registers except 7 (esp) are available for use.
301 - Only ebx, esi, edi and esp are available across a C call (they are callee-saves).
302 - Registers 0-7 have 16-bit counterparts (ax, bx etc.)
303 - Registers 0-3 have 8 bit counterparts (ah, bh etc.)
304 - Registers fake0..fake5 are fakes; we pretend x86 has 6 conventionally-addressable
305   fp registers, and 3-operand insns for them, and we translate this into
306   real stack-based x86 fp code after register allocation.
307
308 The fp registers are all Double registers; we don't have any RcFloat class
309 regs.  @regClass@ barfs if you give it a VirtualRegF, and mkVReg above should
310 never generate them.
311 -}
312
313 fake0, fake1, fake2, fake3, fake4, fake5, 
314        eax, ebx, ecx, edx, esp, ebp, esi, edi :: Reg
315
316 eax   = regSingle 0
317 ebx   = regSingle 1
318 ecx   = regSingle 2
319 edx   = regSingle 3
320 esi   = regSingle 4
321 edi   = regSingle 5
322 ebp   = regSingle 6
323 esp   = regSingle 7
324 fake0 = regSingle 16
325 fake1 = regSingle 17
326 fake2 = regSingle 18
327 fake3 = regSingle 19
328 fake4 = regSingle 20
329 fake5 = regSingle 21
330
331
332
333 {-
334 AMD x86_64 architecture:
335 - Registers 0-16 have 32-bit counterparts (eax, ebx etc.)
336 - Registers 0-7 have 16-bit counterparts (ax, bx etc.)
337 - Registers 0-3 have 8 bit counterparts (ah, bh etc.)
338
339 -}
340
341 rax, rbx, rcx, rdx, rsp, rbp, rsi, rdi, 
342   r8, r9, r10, r11, r12, r13, r14, r15,
343   xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7,
344   xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15 :: Reg
345
346 rax   = regSingle 0
347 rbx   = regSingle 1
348 rcx   = regSingle 2
349 rdx   = regSingle 3
350 rsi   = regSingle 4
351 rdi   = regSingle 5
352 rbp   = regSingle 6
353 rsp   = regSingle 7
354 r8    = regSingle 8
355 r9    = regSingle 9
356 r10   = regSingle 10
357 r11   = regSingle 11
358 r12   = regSingle 12
359 r13   = regSingle 13
360 r14   = regSingle 14
361 r15   = regSingle 15
362 xmm0  = regSingle 24
363 xmm1  = regSingle 25
364 xmm2  = regSingle 26
365 xmm3  = regSingle 27
366 xmm4  = regSingle 28
367 xmm5  = regSingle 29
368 xmm6  = regSingle 30
369 xmm7  = regSingle 31
370 xmm8  = regSingle 32
371 xmm9  = regSingle 33
372 xmm10 = regSingle 34
373 xmm11 = regSingle 35
374 xmm12 = regSingle 36
375 xmm13 = regSingle 37
376 xmm14 = regSingle 38
377 xmm15 = regSingle 39
378
379 allFPArgRegs :: [Reg]
380 allFPArgRegs    = map regSingle [firstxmm .. firstxmm+7]
381
382 ripRel :: Displacement -> AddrMode
383 ripRel imm      = AddrBaseIndex EABaseRip EAIndexNone imm
384
385
386  -- so we can re-use some x86 code:
387 {-
388 eax = rax
389 ebx = rbx
390 ecx = rcx
391 edx = rdx
392 esi = rsi
393 edi = rdi
394 ebp = rbp
395 esp = rsp
396 -}
397
398 xmm :: RegNo -> Reg
399 xmm n = regSingle (firstxmm+n)
400
401
402
403
404 -- horror show -----------------------------------------------------------------
405 freeReg                 :: RegNo -> FastBool
406 globalRegMaybe          :: GlobalReg -> Maybe RealReg
407 allArgRegs              :: [Reg]
408 callClobberedRegs       :: [Reg]
409
410 #if defined(i386_TARGET_ARCH) || defined(x86_64_TARGET_ARCH)
411
412 #if i386_TARGET_ARCH
413 #define eax 0
414 #define ebx 1
415 #define ecx 2
416 #define edx 3
417 #define esi 4
418 #define edi 5
419 #define ebp 6
420 #define esp 7
421 #endif
422
423 #if x86_64_TARGET_ARCH
424 #define rax   0
425 #define rbx   1
426 #define rcx   2
427 #define rdx   3
428 #define rsi   4
429 #define rdi   5
430 #define rbp   6
431 #define rsp   7
432 #define r8    8
433 #define r9    9
434 #define r10   10
435 #define r11   11
436 #define r12   12
437 #define r13   13
438 #define r14   14
439 #define r15   15
440 #endif
441
442 #define fake0 16
443 #define fake1 17
444 #define fake2 18
445 #define fake3 19
446 #define fake4 20
447 #define fake5 21
448
449 #define xmm0  24
450 #define xmm1  25
451 #define xmm2  26
452 #define xmm3  27
453 #define xmm4  28
454 #define xmm5  29
455 #define xmm6  30
456 #define xmm7  31
457 #define xmm8  32
458 #define xmm9  33
459 #define xmm10 34
460 #define xmm11 35
461 #define xmm12 36
462 #define xmm13 37
463 #define xmm14 38
464 #define xmm15 39
465
466 #if i386_TARGET_ARCH
467 freeReg esp = fastBool False  --        %esp is the C stack pointer
468 #endif
469
470 #if x86_64_TARGET_ARCH
471 freeReg rsp = fastBool False  --        %rsp is the C stack pointer
472 #endif
473
474 #ifdef REG_Base
475 freeReg REG_Base = fastBool False
476 #endif
477 #ifdef REG_R1
478 freeReg REG_R1   = fastBool False
479 #endif  
480 #ifdef REG_R2  
481 freeReg REG_R2   = fastBool False
482 #endif  
483 #ifdef REG_R3  
484 freeReg REG_R3   = fastBool False
485 #endif  
486 #ifdef REG_R4  
487 freeReg REG_R4   = fastBool False
488 #endif  
489 #ifdef REG_R5  
490 freeReg REG_R5   = fastBool False
491 #endif  
492 #ifdef REG_R6  
493 freeReg REG_R6   = fastBool False
494 #endif  
495 #ifdef REG_R7  
496 freeReg REG_R7   = fastBool False
497 #endif  
498 #ifdef REG_R8  
499 freeReg REG_R8   = fastBool False
500 #endif
501 #ifdef REG_F1
502 freeReg REG_F1 = fastBool False
503 #endif
504 #ifdef REG_F2
505 freeReg REG_F2 = fastBool False
506 #endif
507 #ifdef REG_F3
508 freeReg REG_F3 = fastBool False
509 #endif
510 #ifdef REG_F4
511 freeReg REG_F4 = fastBool False
512 #endif
513 #ifdef REG_D1
514 freeReg REG_D1 = fastBool False
515 #endif
516 #ifdef REG_D2
517 freeReg REG_D2 = fastBool False
518 #endif
519 #ifdef REG_Sp 
520 freeReg REG_Sp   = fastBool False
521 #endif 
522 #ifdef REG_Su
523 freeReg REG_Su   = fastBool False
524 #endif 
525 #ifdef REG_SpLim 
526 freeReg REG_SpLim = fastBool False
527 #endif 
528 #ifdef REG_Hp 
529 freeReg REG_Hp   = fastBool False
530 #endif
531 #ifdef REG_HpLim
532 freeReg REG_HpLim = fastBool False
533 #endif
534 freeReg _               = fastBool True
535
536
537 --  | Returns 'Nothing' if this global register is not stored
538 -- in a real machine register, otherwise returns @'Just' reg@, where
539 -- reg is the machine register it is stored in.
540
541 #ifdef REG_Base
542 globalRegMaybe BaseReg                  = Just (RealRegSingle REG_Base)
543 #endif
544 #ifdef REG_R1
545 globalRegMaybe (VanillaReg 1 _)         = Just (RealRegSingle REG_R1)
546 #endif 
547 #ifdef REG_R2 
548 globalRegMaybe (VanillaReg 2 _)         = Just (RealRegSingle REG_R2)
549 #endif 
550 #ifdef REG_R3 
551 globalRegMaybe (VanillaReg 3 _)         = Just (RealRegSingle REG_R3)
552 #endif 
553 #ifdef REG_R4 
554 globalRegMaybe (VanillaReg 4 _)         = Just (RealRegSingle REG_R4)
555 #endif 
556 #ifdef REG_R5 
557 globalRegMaybe (VanillaReg 5 _)         = Just (RealRegSingle REG_R5)
558 #endif 
559 #ifdef REG_R6 
560 globalRegMaybe (VanillaReg 6 _)         = Just (RealRegSingle REG_R6)
561 #endif 
562 #ifdef REG_R7 
563 globalRegMaybe (VanillaReg 7 _)         = Just (RealRegSingle REG_R7)
564 #endif 
565 #ifdef REG_R8 
566 globalRegMaybe (VanillaReg 8 _)         = Just (RealRegSingle REG_R8)
567 #endif
568 #ifdef REG_R9 
569 globalRegMaybe (VanillaReg 9 _)         = Just (RealRegSingle REG_R9)
570 #endif
571 #ifdef REG_R10 
572 globalRegMaybe (VanillaReg 10 _)        = Just (RealRegSingle REG_R10)
573 #endif
574 #ifdef REG_F1
575 globalRegMaybe (FloatReg 1)             = Just (RealRegSingle REG_F1)
576 #endif                                  
577 #ifdef REG_F2                           
578 globalRegMaybe (FloatReg 2)             = Just (RealRegSingle REG_F2)
579 #endif                                  
580 #ifdef REG_F3                           
581 globalRegMaybe (FloatReg 3)             = Just (RealRegSingle REG_F3)
582 #endif                                  
583 #ifdef REG_F4                           
584 globalRegMaybe (FloatReg 4)             = Just (RealRegSingle REG_F4)
585 #endif                                  
586 #ifdef REG_D1                           
587 globalRegMaybe (DoubleReg 1)            = Just (RealRegSingle REG_D1)
588 #endif                                  
589 #ifdef REG_D2                           
590 globalRegMaybe (DoubleReg 2)            = Just (RealRegSingle REG_D2)
591 #endif
592 #ifdef REG_Sp       
593 globalRegMaybe Sp                       = Just (RealRegSingle REG_Sp)
594 #endif
595 #ifdef REG_Lng1                         
596 globalRegMaybe (LongReg 1)              = Just (RealRegSingle REG_Lng1)
597 #endif                                  
598 #ifdef REG_Lng2                         
599 globalRegMaybe (LongReg 2)              = Just (RealRegSingle REG_Lng2)
600 #endif
601 #ifdef REG_SpLim                                
602 globalRegMaybe SpLim                    = Just (RealRegSingle REG_SpLim)
603 #endif                                  
604 #ifdef REG_Hp                           
605 globalRegMaybe Hp                       = Just (RealRegSingle REG_Hp)
606 #endif                                  
607 #ifdef REG_HpLim                        
608 globalRegMaybe HpLim                    = Just (RealRegSingle REG_HpLim)
609 #endif                                  
610 #ifdef REG_CurrentTSO                           
611 globalRegMaybe CurrentTSO               = Just (RealRegSingle REG_CurrentTSO)
612 #endif                                  
613 #ifdef REG_CurrentNursery                       
614 globalRegMaybe CurrentNursery           = Just (RealRegSingle REG_CurrentNursery)
615 #endif                                  
616 globalRegMaybe _                        = Nothing
617
618 -- 
619
620 #if   i386_TARGET_ARCH
621 allArgRegs = panic "X86.Regs.allArgRegs: should not be used!"
622
623 #elif x86_64_TARGET_ARCH
624 allArgRegs = map regSingle [rdi,rsi,rdx,rcx,r8,r9]
625
626 #else
627 allArgRegs  = panic "X86.Regs.allArgRegs: not defined for this architecture"
628 #endif
629
630
631 -- | these are the regs which we cannot assume stay alive over a C call.  
632
633 #if   i386_TARGET_ARCH
634 -- caller-saves registers
635 callClobberedRegs
636   = map regSingle ([eax,ecx,edx]  ++ floatregnos)
637
638 #elif x86_64_TARGET_ARCH
639 -- all xmm regs are caller-saves
640 -- caller-saves registers
641 callClobberedRegs    
642   = map regSingle ([rax,rcx,rdx,rsi,rdi,r8,r9,r10,r11] ++ floatregnos)
643
644 #else
645 callClobberedRegs
646   = panic "X86.Regs.callClobberedRegs: not defined for this architecture"
647 #endif
648
649 #else /* i386_TARGET_ARCH || x86_64_TARGET_ARCH */
650
651
652
653 freeReg _               = 0#
654 globalRegMaybe _        = panic "X86.Regs.globalRegMaybe: not defined"
655
656 allArgRegs              = panic "X86.Regs.globalRegMaybe: not defined"
657 callClobberedRegs       = panic "X86.Regs.globalRegMaybe: not defined"
658
659
660 #endif
661
662 -- allocatableRegs is allMachRegNos with the fixed-use regs removed.
663 -- i.e., these are the regs for which we are prepared to allow the
664 -- register allocator to attempt to map VRegs to.
665 allocatableRegs :: [RealReg]
666 allocatableRegs
667    = let isFree i = isFastTrue (freeReg i)
668      in  map RealRegSingle $ filter isFree allMachRegNos
669
670