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 < firstfake -> _ILIT(1) -- first fake reg is 16
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 firstfake, lastfake :: RegNo
225 firstxmm, lastxmm :: RegNo
231 lastint = 7 -- not %r8..%r15
236 intregnos, fakeregnos, xmmregnos, floatregnos :: [RegNo]
237 intregnos = [0..lastint]
238 fakeregnos = [firstfake .. lastfake]
239 xmmregnos = [firstxmm .. lastxmm]
240 floatregnos = fakeregnos ++ xmmregnos;
243 -- argRegs is the set of regs which are read for an n-argument call to C.
244 -- For archs which pass all args on the stack (x86), is empty.
245 -- Sparc passes up to the first 6 args in regs.
246 -- Dunno about Alpha.
247 argRegs :: RegNo -> [Reg]
248 argRegs _ = panic "MachRegs.argRegs(x86): should not be used!"
250 -- | The complete set of machine registers.
251 allMachRegNos :: [RegNo]
252 allMachRegNos = intregnos ++ floatregnos
254 -- | Take the class of a register.
255 {-# INLINE classOfRealReg #-}
256 classOfRealReg :: RealReg -> RegClass
257 -- On x86, we might want to have an 8-bit RegClass, which would
258 -- contain just regs 1-4 (the others don't have 8-bit versions).
259 -- However, we can get away without this at the moment because the
260 -- only allocatable integer regs are also 8-bit compatible (1, 3, 4).
264 | i <= lastint -> RcInteger
265 | i <= lastfake -> RcDouble
266 | otherwise -> RcDoubleSSE
268 RealRegPair{} -> panic "X86.Regs.classOfRealReg: RegPairs on this arch"
270 -- | Get the name of the register with this number.
271 showReg :: RegNo -> String
273 | n >= firstxmm = "%xmm" ++ show (n-firstxmm)
274 | n >= firstfake = "%fake" ++ show (n-firstfake)
275 | n >= 8 = "%r" ++ show n
276 | otherwise = regNames !! n
281 = ["%eax", "%ebx", "%ecx", "%edx", "%esi", "%edi", "%ebp", "%esp"]
282 #elif x86_64_TARGET_ARCH
283 = ["%rax", "%rbx", "%rcx", "%rdx", "%rsi", "%rdi", "%rbp", "%rsp" ]
287 -- machine specific ------------------------------------------------------------
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 8-13 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.
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
305 fake0, fake1, fake2, fake3, fake4, fake5,
306 eax, ebx, ecx, edx, esp, ebp, esi, edi :: Reg
326 AMD x86_64 architecture:
327 - Registers 0-16 have 32-bit counterparts (eax, ebx etc.)
328 - Registers 0-7 have 16-bit counterparts (ax, bx etc.)
329 - Registers 0-3 have 8 bit counterparts (ah, bh etc.)
333 rax, rbx, rcx, rdx, rsp, rbp, rsi, rdi,
334 r8, r9, r10, r11, r12, r13, r14, r15,
335 xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7,
336 xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15 :: Reg
371 allFPArgRegs :: [Reg]
372 allFPArgRegs = map regSingle [24 .. 31]
374 ripRel :: Displacement -> AddrMode
375 ripRel imm = AddrBaseIndex EABaseRip EAIndexNone imm
378 -- so we can re-use some x86 code:
391 xmm n = regSingle (24+n)
396 -- horror show -----------------------------------------------------------------
397 freeReg :: RegNo -> FastBool
398 globalRegMaybe :: GlobalReg -> Maybe RealReg
400 callClobberedRegs :: [Reg]
402 #if defined(i386_TARGET_ARCH) || defined(x86_64_TARGET_ARCH)
415 #if x86_64_TARGET_ARCH
460 freeReg esp = fastBool False -- %esp is the C stack pointer
463 #if x86_64_TARGET_ARCH
464 freeReg rsp = fastBool False -- %rsp is the C stack pointer
468 freeReg REG_Base = fastBool False
471 freeReg REG_R1 = fastBool False
474 freeReg REG_R2 = fastBool False
477 freeReg REG_R3 = fastBool False
480 freeReg REG_R4 = fastBool False
483 freeReg REG_R5 = fastBool False
486 freeReg REG_R6 = fastBool False
489 freeReg REG_R7 = fastBool False
492 freeReg REG_R8 = fastBool False
495 freeReg REG_F1 = fastBool False
498 freeReg REG_F2 = fastBool False
501 freeReg REG_F3 = fastBool False
504 freeReg REG_F4 = fastBool False
507 freeReg REG_D1 = fastBool False
510 freeReg REG_D2 = fastBool False
513 freeReg REG_Sp = fastBool False
516 freeReg REG_Su = fastBool False
519 freeReg REG_SpLim = fastBool False
522 freeReg REG_Hp = fastBool False
525 freeReg REG_HpLim = fastBool False
527 freeReg _ = fastBool True
530 -- | Returns 'Nothing' if this global register is not stored
531 -- in a real machine register, otherwise returns @'Just' reg@, where
532 -- reg is the machine register it is stored in.
535 globalRegMaybe BaseReg = Just (RealRegSingle REG_Base)
538 globalRegMaybe (VanillaReg 1 _) = Just (RealRegSingle REG_R1)
541 globalRegMaybe (VanillaReg 2 _) = Just (RealRegSingle REG_R2)
544 globalRegMaybe (VanillaReg 3 _) = Just (RealRegSingle REG_R3)
547 globalRegMaybe (VanillaReg 4 _) = Just (RealRegSingle REG_R4)
550 globalRegMaybe (VanillaReg 5 _) = Just (RealRegSingle REG_R5)
553 globalRegMaybe (VanillaReg 6 _) = Just (RealRegSingle REG_R6)
556 globalRegMaybe (VanillaReg 7 _) = Just (RealRegSingle REG_R7)
559 globalRegMaybe (VanillaReg 8 _) = Just (RealRegSingle REG_R8)
562 globalRegMaybe (VanillaReg 9 _) = Just (RealRegSingle REG_R9)
565 globalRegMaybe (VanillaReg 10 _) = Just (RealRegSingle REG_R10)
568 globalRegMaybe (FloatReg 1) = Just (RealRegSingle REG_F1)
571 globalRegMaybe (FloatReg 2) = Just (RealRegSingle REG_F2)
574 globalRegMaybe (FloatReg 3) = Just (RealRegSingle REG_F3)
577 globalRegMaybe (FloatReg 4) = Just (RealRegSingle REG_F4)
580 globalRegMaybe (DoubleReg 1) = Just (RealRegSingle REG_D1)
583 globalRegMaybe (DoubleReg 2) = Just (RealRegSingle REG_D2)
586 globalRegMaybe Sp = Just (RealRegSingle REG_Sp)
589 globalRegMaybe (LongReg 1) = Just (RealRegSingle REG_Lng1)
592 globalRegMaybe (LongReg 2) = Just (RealRegSingle REG_Lng2)
595 globalRegMaybe SpLim = Just (RealRegSingle REG_SpLim)
598 globalRegMaybe Hp = Just (RealRegSingle REG_Hp)
601 globalRegMaybe HpLim = Just (RealRegSingle REG_HpLim)
603 #ifdef REG_CurrentTSO
604 globalRegMaybe CurrentTSO = Just (RealRegSingle REG_CurrentTSO)
606 #ifdef REG_CurrentNursery
607 globalRegMaybe CurrentNursery = Just (RealRegSingle REG_CurrentNursery)
609 globalRegMaybe _ = Nothing
614 allArgRegs = panic "X86.Regs.allArgRegs: should not be used!"
616 #elif x86_64_TARGET_ARCH
617 allArgRegs = map regSingle [rdi,rsi,rdx,rcx,r8,r9]
620 allArgRegs = panic "X86.Regs.allArgRegs: not defined for this architecture"
624 -- | these are the regs which we cannot assume stay alive over a C call.
627 -- caller-saves registers
629 = map regSingle ([eax,ecx,edx] ++ floatregnos)
631 #elif x86_64_TARGET_ARCH
632 -- all xmm regs are caller-saves
633 -- caller-saves registers
635 = map regSingle ([rax,rcx,rdx,rsi,rdi,r8,r9,r10,r11] ++ floatregnos)
639 = panic "X86.Regs.callClobberedRegs: not defined for this architecture"
642 #else /* i386_TARGET_ARCH || x86_64_TARGET_ARCH */
647 globalRegMaybe _ = panic "X86.Regs.globalRegMaybe: not defined"
649 allArgRegs = panic "X86.Regs.globalRegMaybe: not defined"
650 callClobberedRegs = panic "X86.Regs.globalRegMaybe: not defined"
655 -- We map STG registers onto appropriate CmmExprs. Either they map
656 -- to real machine registers or stored as offsets from BaseReg. Given
657 -- a GlobalReg, get_GlobalReg_reg_or_addr produces either the real
658 -- register it is in, on this platform, or a CmmExpr denoting the
659 -- address in the register table holding it.
660 -- (See also get_GlobalReg_addr in CgUtils.)
662 get_GlobalReg_reg_or_addr :: GlobalReg -> Either RealReg CmmExpr
663 get_GlobalReg_reg_or_addr mid
664 = case globalRegMaybe mid of
666 Nothing -> Right (get_GlobalReg_addr mid)
669 -- allocatableRegs is allMachRegNos with the fixed-use regs removed.
670 -- i.e., these are the regs for which we are prepared to allow the
671 -- register allocator to attempt to map VRegs to.
672 allocatableRegs :: [RealReg]
674 = let isFree i = isFastTrue (freeReg i)
675 in map RealRegSingle $ filter isFree allMachRegNos