2 -- squeese functions for the graph allocator
25 EABase(..), EAIndex(..), addrModeRegs,
27 eax, ebx, ecx, edx, esi, edi, ebp, esp,
28 fake0, fake1, fake2, fake3, fake4, fake5,
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,
43 get_GlobalReg_reg_or_addr,
49 #include "nativeGen/NCG.h"
50 #include "HsVersions.h"
52 #include "../includes/stg/MachRegs.h"
57 import CgUtils ( get_GlobalReg_addr )
60 import CLabel ( CLabel )
62 import Outputable ( panic )
67 #if defined(i386_TARGET_ARCH) || defined(x86_64_TARGET_ARCH)
72 -- | regSqueeze_class reg
73 -- Calculuate the maximum number of register colors that could be
74 -- denied to a node of this class due to having this reg
77 {-# INLINE virtualRegSqueeze #-}
78 virtualRegSqueeze :: RegClass -> VirtualReg -> FastInt
80 virtualRegSqueeze cls vr
84 VirtualRegI{} -> _ILIT(1)
85 VirtualRegHi{} -> _ILIT(1)
90 VirtualRegD{} -> _ILIT(1)
91 VirtualRegF{} -> _ILIT(0)
96 VirtualRegSSE{} -> _ILIT(1)
101 {-# INLINE realRegSqueeze #-}
102 realRegSqueeze :: RegClass -> RealReg -> FastInt
103 realRegSqueeze cls rr
108 | regNo < 16 -> _ILIT(1) -- first xmm reg is 16
109 | otherwise -> _ILIT(0)
111 RealRegPair{} -> _ILIT(0)
116 | regNo >= 16 && regNo < 24 -> _ILIT(1)
117 | otherwise -> _ILIT(0)
119 RealRegPair{} -> _ILIT(0)
123 RealRegSingle regNo | regNo >= 24 -> _ILIT(1)
124 _otherwise -> _ILIT(0)
128 -- -----------------------------------------------------------------------------
133 | ImmInteger Integer -- Sigh.
134 | ImmCLbl CLabel -- AbstractC Label (with baggage)
135 | ImmLit Doc -- Simple string
136 | ImmIndex CLabel Int
139 | ImmConstantSum Imm Imm
140 | ImmConstantDiff Imm Imm
143 strImmLit :: String -> Imm
144 strImmLit s = ImmLit (text s)
147 litToImm :: CmmLit -> Imm
148 litToImm (CmmInt i w) = ImmInteger (narrowS w i)
149 -- narrow to the width: a CmmInt might be out of
150 -- range, but we assume that ImmInteger only contains
151 -- in-range values. A signed value should be fine here.
152 litToImm (CmmFloat f W32) = ImmFloat f
153 litToImm (CmmFloat f W64) = ImmDouble f
154 litToImm (CmmLabel l) = ImmCLbl l
155 litToImm (CmmLabelOff l off) = ImmIndex l off
156 litToImm (CmmLabelDiffOff l1 l2 off)
158 (ImmConstantDiff (ImmCLbl l1) (ImmCLbl l2))
160 litToImm (CmmBlock id) = ImmCLbl (infoTblLbl id)
161 litToImm _ = panic "X86.Regs.litToImm: no match"
163 -- addressing modes ------------------------------------------------------------
166 = AddrBaseIndex EABase EAIndex Displacement
169 data EABase = EABaseNone | EABaseReg Reg | EABaseRip
170 data EAIndex = EAIndexNone | EAIndex Reg Int
171 type Displacement = Imm
174 addrOffset :: AddrMode -> Int -> Maybe AddrMode
177 ImmAddr i off0 -> Just (ImmAddr i (off0 + off))
179 AddrBaseIndex r i (ImmInt n) -> Just (AddrBaseIndex r i (ImmInt (n + off)))
180 AddrBaseIndex r i (ImmInteger n)
181 -> Just (AddrBaseIndex r i (ImmInt (fromInteger (n + toInteger off))))
183 AddrBaseIndex r i (ImmCLbl lbl)
184 -> Just (AddrBaseIndex r i (ImmIndex lbl off))
186 AddrBaseIndex r i (ImmIndex lbl ix)
187 -> Just (AddrBaseIndex r i (ImmIndex lbl (ix+off)))
189 _ -> Nothing -- in theory, shouldn't happen
192 addrModeRegs :: AddrMode -> [Reg]
193 addrModeRegs (AddrBaseIndex b i _) = b_regs ++ i_regs
195 b_regs = case b of { EABaseReg r -> [r]; _ -> [] }
196 i_regs = case i of { EAIndex r _ -> [r]; _ -> [] }
200 -- registers -------------------------------------------------------------------
202 -- @spRel@ gives us a stack relative addressing mode for volatile
203 -- temporaries and for excess call arguments. @fpRel@, where
204 -- applicable, is the same but for the frame pointer.
207 spRel :: Int -- ^ desired stack offset in words, positive or negative
211 spRel n = AddrBaseIndex (EABaseReg esp) EAIndexNone (ImmInt (n * wORD_SIZE))
213 #elif x86_64_TARGET_ARCH
214 spRel n = AddrBaseIndex (EABaseReg rsp) EAIndexNone (ImmInt (n * wORD_SIZE))
217 spRel _ = panic "X86.Regs.spRel: not defined for this architecture"
222 -- argRegs is the set of regs which are read for an n-argument call to C.
223 -- For archs which pass all args on the stack (x86), is empty.
224 -- Sparc passes up to the first 6 args in regs.
225 -- Dunno about Alpha.
226 argRegs :: RegNo -> [Reg]
227 argRegs _ = panic "MachRegs.argRegs(x86): should not be used!"
229 -- | The complete set of machine registers.
230 allMachRegNos :: [RegNo]
232 allMachRegNos = [0..7] ++ floatregs -- not %r8..%r15
234 allMachRegNos = [0..15] ++ floatregs
236 where floatregs = fakes ++ xmms; fakes = [16..21]; xmms = [24..39]
238 -- | Take the class of a register.
239 {-# INLINE classOfRealReg #-}
240 classOfRealReg :: RealReg -> RegClass
241 -- On x86, we might want to have an 8-bit RegClass, which would
242 -- contain just regs 1-4 (the others don't have 8-bit versions).
243 -- However, we can get away without this at the moment because the
244 -- only allocatable integer regs are also 8-bit compatible (1, 3, 4).
248 | i < 16 -> RcInteger
250 | otherwise -> RcDoubleSSE
252 RealRegPair{} -> panic "X86.Regs.classOfRealReg: RegPairs on this arch"
254 -- | Get the name of the register with this number.
255 showReg :: RegNo -> String
257 | n >= 24 = "%xmm" ++ show (n-24)
258 | n >= 16 = "%fake" ++ show (n-16)
259 | n >= 8 = "%r" ++ show n
260 | otherwise = regNames !! n
265 = ["%eax", "%ebx", "%ecx", "%edx", "%esi", "%edi", "%ebp", "%esp"]
266 #elif x86_64_TARGET_ARCH
267 = ["%rax", "%rbx", "%rcx", "%rdx", "%rsi", "%rdi", "%rbp", "%rsp" ]
271 -- machine specific ------------------------------------------------------------
275 Intel x86 architecture:
276 - All registers except 7 (esp) are available for use.
277 - Only ebx, esi, edi and esp are available across a C call (they are callee-saves).
278 - Registers 0-7 have 16-bit counterparts (ax, bx etc.)
279 - Registers 0-3 have 8 bit counterparts (ah, bh etc.)
280 - Registers 8-13 are fakes; we pretend x86 has 6 conventionally-addressable
281 fp registers, and 3-operand insns for them, and we translate this into
282 real stack-based x86 fp code after register allocation.
284 The fp registers are all Double registers; we don't have any RcFloat class
285 regs. @regClass@ barfs if you give it a VirtualRegF, and mkVReg above should
289 fake0, fake1, fake2, fake3, fake4, fake5,
290 eax, ebx, ecx, edx, esp, ebp, esi, edi :: Reg
310 AMD x86_64 architecture:
311 - Registers 0-16 have 32-bit counterparts (eax, ebx etc.)
312 - Registers 0-7 have 16-bit counterparts (ax, bx etc.)
313 - Registers 0-3 have 8 bit counterparts (ah, bh etc.)
317 rax, rbx, rcx, rdx, rsp, rbp, rsi, rdi,
318 r8, r9, r10, r11, r12, r13, r14, r15,
319 xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7,
320 xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15 :: Reg
355 allFPArgRegs :: [Reg]
356 allFPArgRegs = map regSingle [24 .. 31]
358 ripRel :: Displacement -> AddrMode
359 ripRel imm = AddrBaseIndex EABaseRip EAIndexNone imm
362 -- so we can re-use some x86 code:
375 xmm n = regSingle (24+n)
380 -- horror show -----------------------------------------------------------------
381 freeReg :: RegNo -> FastBool
382 globalRegMaybe :: GlobalReg -> Maybe RealReg
384 callClobberedRegs :: [Reg]
386 #if defined(i386_TARGET_ARCH) || defined(x86_64_TARGET_ARCH)
399 #if x86_64_TARGET_ARCH
444 freeReg esp = fastBool False -- %esp is the C stack pointer
447 #if x86_64_TARGET_ARCH
448 freeReg rsp = fastBool False -- %rsp is the C stack pointer
452 freeReg REG_Base = fastBool False
455 freeReg REG_R1 = fastBool False
458 freeReg REG_R2 = fastBool False
461 freeReg REG_R3 = fastBool False
464 freeReg REG_R4 = fastBool False
467 freeReg REG_R5 = fastBool False
470 freeReg REG_R6 = fastBool False
473 freeReg REG_R7 = fastBool False
476 freeReg REG_R8 = fastBool False
479 freeReg REG_F1 = fastBool False
482 freeReg REG_F2 = fastBool False
485 freeReg REG_F3 = fastBool False
488 freeReg REG_F4 = fastBool False
491 freeReg REG_D1 = fastBool False
494 freeReg REG_D2 = fastBool False
497 freeReg REG_Sp = fastBool False
500 freeReg REG_Su = fastBool False
503 freeReg REG_SpLim = fastBool False
506 freeReg REG_Hp = fastBool False
509 freeReg REG_HpLim = fastBool False
511 freeReg _ = fastBool True
514 -- | Returns 'Nothing' if this global register is not stored
515 -- in a real machine register, otherwise returns @'Just' reg@, where
516 -- reg is the machine register it is stored in.
519 globalRegMaybe BaseReg = Just (RealRegSingle REG_Base)
522 globalRegMaybe (VanillaReg 1 _) = Just (RealRegSingle REG_R1)
525 globalRegMaybe (VanillaReg 2 _) = Just (RealRegSingle REG_R2)
528 globalRegMaybe (VanillaReg 3 _) = Just (RealRegSingle REG_R3)
531 globalRegMaybe (VanillaReg 4 _) = Just (RealRegSingle REG_R4)
534 globalRegMaybe (VanillaReg 5 _) = Just (RealRegSingle REG_R5)
537 globalRegMaybe (VanillaReg 6 _) = Just (RealRegSingle REG_R6)
540 globalRegMaybe (VanillaReg 7 _) = Just (RealRegSingle REG_R7)
543 globalRegMaybe (VanillaReg 8 _) = Just (RealRegSingle REG_R8)
546 globalRegMaybe (VanillaReg 9 _) = Just (RealRegSingle REG_R9)
549 globalRegMaybe (VanillaReg 10 _) = Just (RealRegSingle REG_R10)
552 globalRegMaybe (FloatReg 1) = Just (RealRegSingle REG_F1)
555 globalRegMaybe (FloatReg 2) = Just (RealRegSingle REG_F2)
558 globalRegMaybe (FloatReg 3) = Just (RealRegSingle REG_F3)
561 globalRegMaybe (FloatReg 4) = Just (RealRegSingle REG_F4)
564 globalRegMaybe (DoubleReg 1) = Just (RealRegSingle REG_D1)
567 globalRegMaybe (DoubleReg 2) = Just (RealRegSingle REG_D2)
570 globalRegMaybe Sp = Just (RealRegSingle REG_Sp)
573 globalRegMaybe (LongReg 1) = Just (RealRegSingle REG_Lng1)
576 globalRegMaybe (LongReg 2) = Just (RealRegSingle REG_Lng2)
579 globalRegMaybe SpLim = Just (RealRegSingle REG_SpLim)
582 globalRegMaybe Hp = Just (RealRegSingle REG_Hp)
585 globalRegMaybe HpLim = Just (RealRegSingle REG_HpLim)
587 #ifdef REG_CurrentTSO
588 globalRegMaybe CurrentTSO = Just (RealRegSingle REG_CurrentTSO)
590 #ifdef REG_CurrentNursery
591 globalRegMaybe CurrentNursery = Just (RealRegSingle REG_CurrentNursery)
593 globalRegMaybe _ = Nothing
598 allArgRegs = panic "X86.Regs.allArgRegs: should not be used!"
600 #elif x86_64_TARGET_ARCH
601 allArgRegs = map regSingle [rdi,rsi,rdx,rcx,r8,r9]
604 allArgRegs = panic "X86.Regs.allArgRegs: not defined for this architecture"
608 -- | these are the regs which we cannot assume stay alive over a C call.
611 -- caller-saves registers
613 = map regSingle ([eax,ecx,edx] ++ [16..39])
615 #elif x86_64_TARGET_ARCH
616 -- all xmm regs are caller-saves
617 -- caller-saves registers
619 = map regSingle ([rax,rcx,rdx,rsi,rdi,r8,r9,r10,r11] ++ [16..39])
623 = panic "X86.Regs.callClobberedRegs: not defined for this architecture"
626 #else /* i386_TARGET_ARCH || x86_64_TARGET_ARCH */
631 globalRegMaybe _ = panic "X86.Regs.globalRegMaybe: not defined"
633 allArgRegs = panic "X86.Regs.globalRegMaybe: not defined"
634 callClobberedRegs = panic "X86.Regs.globalRegMaybe: not defined"
639 -- We map STG registers onto appropriate CmmExprs. Either they map
640 -- to real machine registers or stored as offsets from BaseReg. Given
641 -- a GlobalReg, get_GlobalReg_reg_or_addr produces either the real
642 -- register it is in, on this platform, or a CmmExpr denoting the
643 -- address in the register table holding it.
644 -- (See also get_GlobalReg_addr in CgUtils.)
646 get_GlobalReg_reg_or_addr :: GlobalReg -> Either RealReg CmmExpr
647 get_GlobalReg_reg_or_addr mid
648 = case globalRegMaybe mid of
650 Nothing -> Right (get_GlobalReg_addr mid)
653 -- allocatableRegs is allMachRegNos with the fixed-use regs removed.
654 -- i.e., these are the regs for which we are prepared to allow the
655 -- register allocator to attempt to map VRegs to.
656 allocatableRegs :: [RealReg]
658 = let isFree i = isFastTrue (freeReg i)
659 in map RealRegSingle $ filter isFree allMachRegNos