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