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