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