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,
48 #include "nativeGen/NCG.h"
49 #include "HsVersions.h"
51 #include "../includes/stg/MachRegs.h"
58 import CLabel ( CLabel )
60 import Outputable ( panic )
65 #if defined(i386_TARGET_ARCH) || defined(x86_64_TARGET_ARCH)
70 -- | regSqueeze_class reg
71 -- Calculuate the maximum number of register colors that could be
72 -- denied to a node of this class due to having this reg
75 {-# INLINE virtualRegSqueeze #-}
76 virtualRegSqueeze :: RegClass -> VirtualReg -> FastInt
78 virtualRegSqueeze cls vr
82 VirtualRegI{} -> _ILIT(1)
83 VirtualRegHi{} -> _ILIT(1)
88 VirtualRegD{} -> _ILIT(1)
89 VirtualRegF{} -> _ILIT(0)
94 VirtualRegSSE{} -> _ILIT(1)
99 {-# INLINE realRegSqueeze #-}
100 realRegSqueeze :: RegClass -> RealReg -> FastInt
101 realRegSqueeze cls rr
106 | regNo < firstfake -> _ILIT(1)
107 | otherwise -> _ILIT(0)
109 RealRegPair{} -> _ILIT(0)
114 | regNo >= firstfake && regNo <= lastfake -> _ILIT(1)
115 | otherwise -> _ILIT(0)
117 RealRegPair{} -> _ILIT(0)
121 RealRegSingle regNo | regNo >= firstxmm -> _ILIT(1)
122 _otherwise -> _ILIT(0)
126 -- -----------------------------------------------------------------------------
131 | ImmInteger Integer -- Sigh.
132 | ImmCLbl CLabel -- AbstractC Label (with baggage)
133 | ImmLit Doc -- Simple string
134 | ImmIndex CLabel Int
137 | ImmConstantSum Imm Imm
138 | ImmConstantDiff Imm Imm
141 strImmLit :: String -> Imm
142 strImmLit s = ImmLit (text s)
145 litToImm :: CmmLit -> Imm
146 litToImm (CmmInt i w) = ImmInteger (narrowS w i)
147 -- narrow to the width: a CmmInt might be out of
148 -- range, but we assume that ImmInteger only contains
149 -- in-range values. A signed value should be fine here.
150 litToImm (CmmFloat f W32) = ImmFloat f
151 litToImm (CmmFloat f W64) = ImmDouble f
152 litToImm (CmmLabel l) = ImmCLbl l
153 litToImm (CmmLabelOff l off) = ImmIndex l off
154 litToImm (CmmLabelDiffOff l1 l2 off)
156 (ImmConstantDiff (ImmCLbl l1) (ImmCLbl l2))
158 litToImm (CmmBlock id) = ImmCLbl (infoTblLbl id)
159 litToImm _ = panic "X86.Regs.litToImm: no match"
161 -- addressing modes ------------------------------------------------------------
164 = AddrBaseIndex EABase EAIndex Displacement
167 data EABase = EABaseNone | EABaseReg Reg | EABaseRip
168 data EAIndex = EAIndexNone | EAIndex Reg Int
169 type Displacement = Imm
172 addrOffset :: AddrMode -> Int -> Maybe AddrMode
175 ImmAddr i off0 -> Just (ImmAddr i (off0 + off))
177 AddrBaseIndex r i (ImmInt n) -> Just (AddrBaseIndex r i (ImmInt (n + off)))
178 AddrBaseIndex r i (ImmInteger n)
179 -> Just (AddrBaseIndex r i (ImmInt (fromInteger (n + toInteger off))))
181 AddrBaseIndex r i (ImmCLbl lbl)
182 -> Just (AddrBaseIndex r i (ImmIndex lbl off))
184 AddrBaseIndex r i (ImmIndex lbl ix)
185 -> Just (AddrBaseIndex r i (ImmIndex lbl (ix+off)))
187 _ -> Nothing -- in theory, shouldn't happen
190 addrModeRegs :: AddrMode -> [Reg]
191 addrModeRegs (AddrBaseIndex b i _) = b_regs ++ i_regs
193 b_regs = case b of { EABaseReg r -> [r]; _ -> [] }
194 i_regs = case i of { EAIndex r _ -> [r]; _ -> [] }
198 -- registers -------------------------------------------------------------------
200 -- @spRel@ gives us a stack relative addressing mode for volatile
201 -- temporaries and for excess call arguments. @fpRel@, where
202 -- applicable, is the same but for the frame pointer.
205 spRel :: Int -- ^ desired stack offset in words, positive or negative
209 spRel n = AddrBaseIndex (EABaseReg esp) EAIndexNone (ImmInt (n * wORD_SIZE))
211 #elif x86_64_TARGET_ARCH
212 spRel n = AddrBaseIndex (EABaseReg rsp) EAIndexNone (ImmInt (n * wORD_SIZE))
215 spRel _ = panic "X86.Regs.spRel: not defined for this architecture"
219 -- The register numbers must fit into 32 bits on x86, so that we can
220 -- use a Word32 to represent the set of free registers in the register
223 firstfake, lastfake :: RegNo
227 firstxmm, lastxmm :: RegNo
237 lastint = 7 -- not %r8..%r15
242 intregnos, fakeregnos, xmmregnos, floatregnos :: [RegNo]
243 intregnos = [0..lastint]
244 fakeregnos = [firstfake .. lastfake]
245 xmmregnos = [firstxmm .. lastxmm]
246 floatregnos = fakeregnos ++ xmmregnos;
249 -- argRegs is the set of regs which are read for an n-argument call to C.
250 -- For archs which pass all args on the stack (x86), is empty.
251 -- Sparc passes up to the first 6 args in regs.
252 argRegs :: RegNo -> [Reg]
253 argRegs _ = panic "MachRegs.argRegs(x86): should not be used!"
255 -- | The complete set of machine registers.
256 allMachRegNos :: [RegNo]
257 allMachRegNos = intregnos ++ floatregnos
259 -- | Take the class of a register.
260 {-# INLINE classOfRealReg #-}
261 classOfRealReg :: RealReg -> RegClass
262 -- On x86, we might want to have an 8-bit RegClass, which would
263 -- contain just regs 1-4 (the others don't have 8-bit versions).
264 -- However, we can get away without this at the moment because the
265 -- only allocatable integer regs are also 8-bit compatible (1, 3, 4).
269 | i <= lastint -> RcInteger
270 | i <= lastfake -> RcDouble
271 | otherwise -> RcDoubleSSE
273 RealRegPair{} -> panic "X86.Regs.classOfRealReg: RegPairs on this arch"
275 -- | Get the name of the register with this number.
276 showReg :: RegNo -> String
278 | n >= firstxmm = "%xmm" ++ show (n-firstxmm)
279 | n >= firstfake = "%fake" ++ show (n-firstfake)
280 | n >= 8 = "%r" ++ show n
281 | otherwise = regNames !! n
286 = ["%eax", "%ebx", "%ecx", "%edx", "%esi", "%edi", "%ebp", "%esp"]
287 #elif x86_64_TARGET_ARCH
288 = ["%rax", "%rbx", "%rcx", "%rdx", "%rsi", "%rdi", "%rbp", "%rsp" ]
295 -- machine specific ------------------------------------------------------------
299 Intel x86 architecture:
300 - All registers except 7 (esp) are available for use.
301 - Only ebx, esi, edi and esp are available across a C call (they are callee-saves).
302 - Registers 0-7 have 16-bit counterparts (ax, bx etc.)
303 - Registers 0-3 have 8 bit counterparts (ah, bh etc.)
304 - Registers fake0..fake5 are fakes; we pretend x86 has 6 conventionally-addressable
305 fp registers, and 3-operand insns for them, and we translate this into
306 real stack-based x86 fp code after register allocation.
308 The fp registers are all Double registers; we don't have any RcFloat class
309 regs. @regClass@ barfs if you give it a VirtualRegF, and mkVReg above should
313 fake0, fake1, fake2, fake3, fake4, fake5,
314 eax, ebx, ecx, edx, esp, ebp, esi, edi :: Reg
334 AMD x86_64 architecture:
335 - Registers 0-16 have 32-bit counterparts (eax, ebx etc.)
336 - Registers 0-7 have 16-bit counterparts (ax, bx etc.)
337 - Registers 0-3 have 8 bit counterparts (ah, bh etc.)
341 rax, rbx, rcx, rdx, rsp, rbp, rsi, rdi,
342 r8, r9, r10, r11, r12, r13, r14, r15,
343 xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7,
344 xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15 :: Reg
379 allFPArgRegs :: [Reg]
380 allFPArgRegs = map regSingle [firstxmm .. firstxmm+7]
382 ripRel :: Displacement -> AddrMode
383 ripRel imm = AddrBaseIndex EABaseRip EAIndexNone imm
386 -- so we can re-use some x86 code:
399 xmm n = regSingle (firstxmm+n)
404 -- horror show -----------------------------------------------------------------
405 freeReg :: RegNo -> FastBool
406 globalRegMaybe :: GlobalReg -> Maybe RealReg
408 callClobberedRegs :: [Reg]
410 #if defined(i386_TARGET_ARCH) || defined(x86_64_TARGET_ARCH)
423 #if x86_64_TARGET_ARCH
467 freeReg esp = fastBool False -- %esp is the C stack pointer
470 #if x86_64_TARGET_ARCH
471 freeReg rsp = fastBool False -- %rsp is the C stack pointer
475 freeReg REG_Base = fastBool False
478 freeReg REG_R1 = fastBool False
481 freeReg REG_R2 = fastBool False
484 freeReg REG_R3 = fastBool False
487 freeReg REG_R4 = fastBool False
490 freeReg REG_R5 = fastBool False
493 freeReg REG_R6 = fastBool False
496 freeReg REG_R7 = fastBool False
499 freeReg REG_R8 = fastBool False
502 freeReg REG_F1 = fastBool False
505 freeReg REG_F2 = fastBool False
508 freeReg REG_F3 = fastBool False
511 freeReg REG_F4 = fastBool False
514 freeReg REG_D1 = fastBool False
517 freeReg REG_D2 = fastBool False
520 freeReg REG_Sp = fastBool False
523 freeReg REG_Su = fastBool False
526 freeReg REG_SpLim = fastBool False
529 freeReg REG_Hp = fastBool False
532 freeReg REG_HpLim = fastBool False
534 freeReg _ = fastBool True
537 -- | Returns 'Nothing' if this global register is not stored
538 -- in a real machine register, otherwise returns @'Just' reg@, where
539 -- reg is the machine register it is stored in.
542 globalRegMaybe BaseReg = Just (RealRegSingle REG_Base)
545 globalRegMaybe (VanillaReg 1 _) = Just (RealRegSingle REG_R1)
548 globalRegMaybe (VanillaReg 2 _) = Just (RealRegSingle REG_R2)
551 globalRegMaybe (VanillaReg 3 _) = Just (RealRegSingle REG_R3)
554 globalRegMaybe (VanillaReg 4 _) = Just (RealRegSingle REG_R4)
557 globalRegMaybe (VanillaReg 5 _) = Just (RealRegSingle REG_R5)
560 globalRegMaybe (VanillaReg 6 _) = Just (RealRegSingle REG_R6)
563 globalRegMaybe (VanillaReg 7 _) = Just (RealRegSingle REG_R7)
566 globalRegMaybe (VanillaReg 8 _) = Just (RealRegSingle REG_R8)
569 globalRegMaybe (VanillaReg 9 _) = Just (RealRegSingle REG_R9)
572 globalRegMaybe (VanillaReg 10 _) = Just (RealRegSingle REG_R10)
575 globalRegMaybe (FloatReg 1) = Just (RealRegSingle REG_F1)
578 globalRegMaybe (FloatReg 2) = Just (RealRegSingle REG_F2)
581 globalRegMaybe (FloatReg 3) = Just (RealRegSingle REG_F3)
584 globalRegMaybe (FloatReg 4) = Just (RealRegSingle REG_F4)
587 globalRegMaybe (DoubleReg 1) = Just (RealRegSingle REG_D1)
590 globalRegMaybe (DoubleReg 2) = Just (RealRegSingle REG_D2)
593 globalRegMaybe Sp = Just (RealRegSingle REG_Sp)
596 globalRegMaybe (LongReg 1) = Just (RealRegSingle REG_Lng1)
599 globalRegMaybe (LongReg 2) = Just (RealRegSingle REG_Lng2)
602 globalRegMaybe SpLim = Just (RealRegSingle REG_SpLim)
605 globalRegMaybe Hp = Just (RealRegSingle REG_Hp)
608 globalRegMaybe HpLim = Just (RealRegSingle REG_HpLim)
610 #ifdef REG_CurrentTSO
611 globalRegMaybe CurrentTSO = Just (RealRegSingle REG_CurrentTSO)
613 #ifdef REG_CurrentNursery
614 globalRegMaybe CurrentNursery = Just (RealRegSingle REG_CurrentNursery)
616 globalRegMaybe _ = Nothing
621 allArgRegs = panic "X86.Regs.allArgRegs: should not be used!"
623 #elif x86_64_TARGET_ARCH
624 allArgRegs = map regSingle [rdi,rsi,rdx,rcx,r8,r9]
627 allArgRegs = panic "X86.Regs.allArgRegs: not defined for this architecture"
631 -- | these are the regs which we cannot assume stay alive over a C call.
634 -- caller-saves registers
636 = map regSingle ([eax,ecx,edx] ++ floatregnos)
638 #elif x86_64_TARGET_ARCH
639 -- all xmm regs are caller-saves
640 -- caller-saves registers
642 = map regSingle ([rax,rcx,rdx,rsi,rdi,r8,r9,r10,r11] ++ floatregnos)
646 = panic "X86.Regs.callClobberedRegs: not defined for this architecture"
649 #else /* i386_TARGET_ARCH || x86_64_TARGET_ARCH */
654 globalRegMaybe _ = panic "X86.Regs.globalRegMaybe: not defined"
656 allArgRegs = panic "X86.Regs.globalRegMaybe: not defined"
657 callClobberedRegs = panic "X86.Regs.globalRegMaybe: not defined"
662 -- allocatableRegs is allMachRegNos with the fixed-use regs removed.
663 -- i.e., these are the regs for which we are prepared to allow the
664 -- register allocator to attempt to map VRegs to.
665 allocatableRegs :: [RealReg]
667 = let isFree i = isFastTrue (freeReg i)
668 in map RealRegSingle $ filter isFree allMachRegNos