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 -- Dunno about Alpha.
253 argRegs :: RegNo -> [Reg]
254 argRegs _ = panic "MachRegs.argRegs(x86): should not be used!"
256 -- | The complete set of machine registers.
257 allMachRegNos :: [RegNo]
258 allMachRegNos = intregnos ++ floatregnos
260 -- | Take the class of a register.
261 {-# INLINE classOfRealReg #-}
262 classOfRealReg :: RealReg -> RegClass
263 -- On x86, we might want to have an 8-bit RegClass, which would
264 -- contain just regs 1-4 (the others don't have 8-bit versions).
265 -- However, we can get away without this at the moment because the
266 -- only allocatable integer regs are also 8-bit compatible (1, 3, 4).
270 | i <= lastint -> RcInteger
271 | i <= lastfake -> RcDouble
272 | otherwise -> RcDoubleSSE
274 RealRegPair{} -> panic "X86.Regs.classOfRealReg: RegPairs on this arch"
276 -- | Get the name of the register with this number.
277 showReg :: RegNo -> String
279 | n >= firstxmm = "%xmm" ++ show (n-firstxmm)
280 | n >= firstfake = "%fake" ++ show (n-firstfake)
281 | n >= 8 = "%r" ++ show n
282 | otherwise = regNames !! n
287 = ["%eax", "%ebx", "%ecx", "%edx", "%esi", "%edi", "%ebp", "%esp"]
288 #elif x86_64_TARGET_ARCH
289 = ["%rax", "%rbx", "%rcx", "%rdx", "%rsi", "%rdi", "%rbp", "%rsp" ]
296 -- machine specific ------------------------------------------------------------
300 Intel x86 architecture:
301 - All registers except 7 (esp) are available for use.
302 - Only ebx, esi, edi and esp are available across a C call (they are callee-saves).
303 - Registers 0-7 have 16-bit counterparts (ax, bx etc.)
304 - Registers 0-3 have 8 bit counterparts (ah, bh etc.)
305 - Registers fake0..fake5 are fakes; we pretend x86 has 6 conventionally-addressable
306 fp registers, and 3-operand insns for them, and we translate this into
307 real stack-based x86 fp code after register allocation.
309 The fp registers are all Double registers; we don't have any RcFloat class
310 regs. @regClass@ barfs if you give it a VirtualRegF, and mkVReg above should
314 fake0, fake1, fake2, fake3, fake4, fake5,
315 eax, ebx, ecx, edx, esp, ebp, esi, edi :: Reg
335 AMD x86_64 architecture:
336 - Registers 0-16 have 32-bit counterparts (eax, ebx etc.)
337 - Registers 0-7 have 16-bit counterparts (ax, bx etc.)
338 - Registers 0-3 have 8 bit counterparts (ah, bh etc.)
342 rax, rbx, rcx, rdx, rsp, rbp, rsi, rdi,
343 r8, r9, r10, r11, r12, r13, r14, r15,
344 xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7,
345 xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15 :: Reg
380 allFPArgRegs :: [Reg]
381 allFPArgRegs = map regSingle [firstxmm .. firstxmm+7]
383 ripRel :: Displacement -> AddrMode
384 ripRel imm = AddrBaseIndex EABaseRip EAIndexNone imm
387 -- so we can re-use some x86 code:
400 xmm n = regSingle (firstxmm+n)
405 -- horror show -----------------------------------------------------------------
406 freeReg :: RegNo -> FastBool
407 globalRegMaybe :: GlobalReg -> Maybe RealReg
409 callClobberedRegs :: [Reg]
411 #if defined(i386_TARGET_ARCH) || defined(x86_64_TARGET_ARCH)
424 #if x86_64_TARGET_ARCH
468 freeReg esp = fastBool False -- %esp is the C stack pointer
471 #if x86_64_TARGET_ARCH
472 freeReg rsp = fastBool False -- %rsp is the C stack pointer
476 freeReg REG_Base = fastBool False
479 freeReg REG_R1 = fastBool False
482 freeReg REG_R2 = fastBool False
485 freeReg REG_R3 = fastBool False
488 freeReg REG_R4 = fastBool False
491 freeReg REG_R5 = fastBool False
494 freeReg REG_R6 = fastBool False
497 freeReg REG_R7 = fastBool False
500 freeReg REG_R8 = fastBool False
503 freeReg REG_F1 = fastBool False
506 freeReg REG_F2 = fastBool False
509 freeReg REG_F3 = fastBool False
512 freeReg REG_F4 = fastBool False
515 freeReg REG_D1 = fastBool False
518 freeReg REG_D2 = fastBool False
521 freeReg REG_Sp = fastBool False
524 freeReg REG_Su = fastBool False
527 freeReg REG_SpLim = fastBool False
530 freeReg REG_Hp = fastBool False
533 freeReg REG_HpLim = fastBool False
535 freeReg _ = fastBool True
538 -- | Returns 'Nothing' if this global register is not stored
539 -- in a real machine register, otherwise returns @'Just' reg@, where
540 -- reg is the machine register it is stored in.
543 globalRegMaybe BaseReg = Just (RealRegSingle REG_Base)
546 globalRegMaybe (VanillaReg 1 _) = Just (RealRegSingle REG_R1)
549 globalRegMaybe (VanillaReg 2 _) = Just (RealRegSingle REG_R2)
552 globalRegMaybe (VanillaReg 3 _) = Just (RealRegSingle REG_R3)
555 globalRegMaybe (VanillaReg 4 _) = Just (RealRegSingle REG_R4)
558 globalRegMaybe (VanillaReg 5 _) = Just (RealRegSingle REG_R5)
561 globalRegMaybe (VanillaReg 6 _) = Just (RealRegSingle REG_R6)
564 globalRegMaybe (VanillaReg 7 _) = Just (RealRegSingle REG_R7)
567 globalRegMaybe (VanillaReg 8 _) = Just (RealRegSingle REG_R8)
570 globalRegMaybe (VanillaReg 9 _) = Just (RealRegSingle REG_R9)
573 globalRegMaybe (VanillaReg 10 _) = Just (RealRegSingle REG_R10)
576 globalRegMaybe (FloatReg 1) = Just (RealRegSingle REG_F1)
579 globalRegMaybe (FloatReg 2) = Just (RealRegSingle REG_F2)
582 globalRegMaybe (FloatReg 3) = Just (RealRegSingle REG_F3)
585 globalRegMaybe (FloatReg 4) = Just (RealRegSingle REG_F4)
588 globalRegMaybe (DoubleReg 1) = Just (RealRegSingle REG_D1)
591 globalRegMaybe (DoubleReg 2) = Just (RealRegSingle REG_D2)
594 globalRegMaybe Sp = Just (RealRegSingle REG_Sp)
597 globalRegMaybe (LongReg 1) = Just (RealRegSingle REG_Lng1)
600 globalRegMaybe (LongReg 2) = Just (RealRegSingle REG_Lng2)
603 globalRegMaybe SpLim = Just (RealRegSingle REG_SpLim)
606 globalRegMaybe Hp = Just (RealRegSingle REG_Hp)
609 globalRegMaybe HpLim = Just (RealRegSingle REG_HpLim)
611 #ifdef REG_CurrentTSO
612 globalRegMaybe CurrentTSO = Just (RealRegSingle REG_CurrentTSO)
614 #ifdef REG_CurrentNursery
615 globalRegMaybe CurrentNursery = Just (RealRegSingle REG_CurrentNursery)
617 globalRegMaybe _ = Nothing
622 allArgRegs = panic "X86.Regs.allArgRegs: should not be used!"
624 #elif x86_64_TARGET_ARCH
625 allArgRegs = map regSingle [rdi,rsi,rdx,rcx,r8,r9]
628 allArgRegs = panic "X86.Regs.allArgRegs: not defined for this architecture"
632 -- | these are the regs which we cannot assume stay alive over a C call.
635 -- caller-saves registers
637 = map regSingle ([eax,ecx,edx] ++ floatregnos)
639 #elif x86_64_TARGET_ARCH
640 -- all xmm regs are caller-saves
641 -- caller-saves registers
643 = map regSingle ([rax,rcx,rdx,rsi,rdi,r8,r9,r10,r11] ++ floatregnos)
647 = panic "X86.Regs.callClobberedRegs: not defined for this architecture"
650 #else /* i386_TARGET_ARCH || x86_64_TARGET_ARCH */
655 globalRegMaybe _ = panic "X86.Regs.globalRegMaybe: not defined"
657 allArgRegs = panic "X86.Regs.globalRegMaybe: not defined"
658 callClobberedRegs = panic "X86.Regs.globalRegMaybe: not defined"
663 -- allocatableRegs is allMachRegNos with the fixed-use regs removed.
664 -- i.e., these are the regs for which we are prepared to allow the
665 -- register allocator to attempt to map VRegs to.
666 allocatableRegs :: [RealReg]
668 = let isFree i = isFastTrue (freeReg i)
669 in map RealRegSingle $ filter isFree allMachRegNos