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, firstfake,
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 < firstfake -> _ILIT(1)
109 | otherwise -> _ILIT(0)
111 RealRegPair{} -> _ILIT(0)
116 | regNo >= firstfake && regNo < lastfake -> _ILIT(1)
117 | otherwise -> _ILIT(0)
119 RealRegPair{} -> _ILIT(0)
123 RealRegSingle regNo | regNo >= firstxmm -> _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"
221 -- The register numbers must fit into 32 bits on x86, so that we can
222 -- use a Word32 to represent the set of free registers in the register
225 firstfake, lastfake :: RegNo
229 firstxmm, lastxmm :: RegNo
239 lastint = 7 -- not %r8..%r15
244 intregnos, fakeregnos, xmmregnos, floatregnos :: [RegNo]
245 intregnos = [0..lastint]
246 fakeregnos = [firstfake .. lastfake]
247 xmmregnos = [firstxmm .. lastxmm]
248 floatregnos = fakeregnos ++ xmmregnos;
251 -- argRegs is the set of regs which are read for an n-argument call to C.
252 -- For archs which pass all args on the stack (x86), is empty.
253 -- Sparc passes up to the first 6 args in regs.
254 -- Dunno about Alpha.
255 argRegs :: RegNo -> [Reg]
256 argRegs _ = panic "MachRegs.argRegs(x86): should not be used!"
258 -- | The complete set of machine registers.
259 allMachRegNos :: [RegNo]
260 allMachRegNos = intregnos ++ floatregnos
262 -- | Take the class of a register.
263 {-# INLINE classOfRealReg #-}
264 classOfRealReg :: RealReg -> RegClass
265 -- On x86, we might want to have an 8-bit RegClass, which would
266 -- contain just regs 1-4 (the others don't have 8-bit versions).
267 -- However, we can get away without this at the moment because the
268 -- only allocatable integer regs are also 8-bit compatible (1, 3, 4).
272 | i <= lastint -> RcInteger
273 | i <= lastfake -> RcDouble
274 | otherwise -> RcDoubleSSE
276 RealRegPair{} -> panic "X86.Regs.classOfRealReg: RegPairs on this arch"
278 -- | Get the name of the register with this number.
279 showReg :: RegNo -> String
281 | n >= firstxmm = "%xmm" ++ show (n-firstxmm)
282 | n >= firstfake = "%fake" ++ show (n-firstfake)
283 | n >= 8 = "%r" ++ show n
284 | otherwise = regNames !! n
289 = ["%eax", "%ebx", "%ecx", "%edx", "%esi", "%edi", "%ebp", "%esp"]
290 #elif x86_64_TARGET_ARCH
291 = ["%rax", "%rbx", "%rcx", "%rdx", "%rsi", "%rdi", "%rbp", "%rsp" ]
298 -- machine specific ------------------------------------------------------------
302 Intel x86 architecture:
303 - All registers except 7 (esp) are available for use.
304 - Only ebx, esi, edi and esp are available across a C call (they are callee-saves).
305 - Registers 0-7 have 16-bit counterparts (ax, bx etc.)
306 - Registers 0-3 have 8 bit counterparts (ah, bh etc.)
307 - Registers fake0..fake5 are fakes; we pretend x86 has 6 conventionally-addressable
308 fp registers, and 3-operand insns for them, and we translate this into
309 real stack-based x86 fp code after register allocation.
311 The fp registers are all Double registers; we don't have any RcFloat class
312 regs. @regClass@ barfs if you give it a VirtualRegF, and mkVReg above should
316 fake0, fake1, fake2, fake3, fake4, fake5,
317 eax, ebx, ecx, edx, esp, ebp, esi, edi :: Reg
337 AMD x86_64 architecture:
338 - Registers 0-16 have 32-bit counterparts (eax, ebx etc.)
339 - Registers 0-7 have 16-bit counterparts (ax, bx etc.)
340 - Registers 0-3 have 8 bit counterparts (ah, bh etc.)
344 rax, rbx, rcx, rdx, rsp, rbp, rsi, rdi,
345 r8, r9, r10, r11, r12, r13, r14, r15,
346 xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7,
347 xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15 :: Reg
382 allFPArgRegs :: [Reg]
383 allFPArgRegs = map regSingle [firstxmm .. firstxmm+7]
385 ripRel :: Displacement -> AddrMode
386 ripRel imm = AddrBaseIndex EABaseRip EAIndexNone imm
389 -- so we can re-use some x86 code:
402 xmm n = regSingle (firstxmm+n)
407 -- horror show -----------------------------------------------------------------
408 freeReg :: RegNo -> FastBool
409 globalRegMaybe :: GlobalReg -> Maybe RealReg
411 callClobberedRegs :: [Reg]
413 #if defined(i386_TARGET_ARCH) || defined(x86_64_TARGET_ARCH)
426 #if x86_64_TARGET_ARCH
470 freeReg esp = fastBool False -- %esp is the C stack pointer
473 #if x86_64_TARGET_ARCH
474 freeReg rsp = fastBool False -- %rsp is the C stack pointer
478 freeReg REG_Base = fastBool False
481 freeReg REG_R1 = fastBool False
484 freeReg REG_R2 = fastBool False
487 freeReg REG_R3 = fastBool False
490 freeReg REG_R4 = fastBool False
493 freeReg REG_R5 = fastBool False
496 freeReg REG_R6 = fastBool False
499 freeReg REG_R7 = fastBool False
502 freeReg REG_R8 = fastBool False
505 freeReg REG_F1 = fastBool False
508 freeReg REG_F2 = fastBool False
511 freeReg REG_F3 = fastBool False
514 freeReg REG_F4 = fastBool False
517 freeReg REG_D1 = fastBool False
520 freeReg REG_D2 = fastBool False
523 freeReg REG_Sp = fastBool False
526 freeReg REG_Su = fastBool False
529 freeReg REG_SpLim = fastBool False
532 freeReg REG_Hp = fastBool False
535 freeReg REG_HpLim = fastBool False
537 freeReg _ = fastBool True
540 -- | Returns 'Nothing' if this global register is not stored
541 -- in a real machine register, otherwise returns @'Just' reg@, where
542 -- reg is the machine register it is stored in.
545 globalRegMaybe BaseReg = Just (RealRegSingle REG_Base)
548 globalRegMaybe (VanillaReg 1 _) = Just (RealRegSingle REG_R1)
551 globalRegMaybe (VanillaReg 2 _) = Just (RealRegSingle REG_R2)
554 globalRegMaybe (VanillaReg 3 _) = Just (RealRegSingle REG_R3)
557 globalRegMaybe (VanillaReg 4 _) = Just (RealRegSingle REG_R4)
560 globalRegMaybe (VanillaReg 5 _) = Just (RealRegSingle REG_R5)
563 globalRegMaybe (VanillaReg 6 _) = Just (RealRegSingle REG_R6)
566 globalRegMaybe (VanillaReg 7 _) = Just (RealRegSingle REG_R7)
569 globalRegMaybe (VanillaReg 8 _) = Just (RealRegSingle REG_R8)
572 globalRegMaybe (VanillaReg 9 _) = Just (RealRegSingle REG_R9)
575 globalRegMaybe (VanillaReg 10 _) = Just (RealRegSingle REG_R10)
578 globalRegMaybe (FloatReg 1) = Just (RealRegSingle REG_F1)
581 globalRegMaybe (FloatReg 2) = Just (RealRegSingle REG_F2)
584 globalRegMaybe (FloatReg 3) = Just (RealRegSingle REG_F3)
587 globalRegMaybe (FloatReg 4) = Just (RealRegSingle REG_F4)
590 globalRegMaybe (DoubleReg 1) = Just (RealRegSingle REG_D1)
593 globalRegMaybe (DoubleReg 2) = Just (RealRegSingle REG_D2)
596 globalRegMaybe Sp = Just (RealRegSingle REG_Sp)
599 globalRegMaybe (LongReg 1) = Just (RealRegSingle REG_Lng1)
602 globalRegMaybe (LongReg 2) = Just (RealRegSingle REG_Lng2)
605 globalRegMaybe SpLim = Just (RealRegSingle REG_SpLim)
608 globalRegMaybe Hp = Just (RealRegSingle REG_Hp)
611 globalRegMaybe HpLim = Just (RealRegSingle REG_HpLim)
613 #ifdef REG_CurrentTSO
614 globalRegMaybe CurrentTSO = Just (RealRegSingle REG_CurrentTSO)
616 #ifdef REG_CurrentNursery
617 globalRegMaybe CurrentNursery = Just (RealRegSingle REG_CurrentNursery)
619 globalRegMaybe _ = Nothing
624 allArgRegs = panic "X86.Regs.allArgRegs: should not be used!"
626 #elif x86_64_TARGET_ARCH
627 allArgRegs = map regSingle [rdi,rsi,rdx,rcx,r8,r9]
630 allArgRegs = panic "X86.Regs.allArgRegs: not defined for this architecture"
634 -- | these are the regs which we cannot assume stay alive over a C call.
637 -- caller-saves registers
639 = map regSingle ([eax,ecx,edx] ++ floatregnos)
641 #elif x86_64_TARGET_ARCH
642 -- all xmm regs are caller-saves
643 -- caller-saves registers
645 = map regSingle ([rax,rcx,rdx,rsi,rdi,r8,r9,r10,r11] ++ floatregnos)
649 = panic "X86.Regs.callClobberedRegs: not defined for this architecture"
652 #else /* i386_TARGET_ARCH || x86_64_TARGET_ARCH */
657 globalRegMaybe _ = panic "X86.Regs.globalRegMaybe: not defined"
659 allArgRegs = panic "X86.Regs.globalRegMaybe: not defined"
660 callClobberedRegs = panic "X86.Regs.globalRegMaybe: not defined"
665 -- We map STG registers onto appropriate CmmExprs. Either they map
666 -- to real machine registers or stored as offsets from BaseReg. Given
667 -- a GlobalReg, get_GlobalReg_reg_or_addr produces either the real
668 -- register it is in, on this platform, or a CmmExpr denoting the
669 -- address in the register table holding it.
670 -- (See also get_GlobalReg_addr in CgUtils.)
672 get_GlobalReg_reg_or_addr :: GlobalReg -> Either RealReg CmmExpr
673 get_GlobalReg_reg_or_addr mid
674 = case globalRegMaybe mid of
676 Nothing -> Right (get_GlobalReg_addr mid)
679 -- allocatableRegs is allMachRegNos with the fixed-use regs removed.
680 -- i.e., these are the regs for which we are prepared to allow the
681 -- register allocator to attempt to map VRegs to.
682 allocatableRegs :: [RealReg]
684 = let isFree i = isFastTrue (freeReg i)
685 in map RealRegSingle $ filter isFree allMachRegNos