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 - All 16 integer registers are addressable as 8, 16, 32 and 64-bit values:
338 ---------------------
355 rax, rbx, rcx, rdx, rsp, rbp, rsi, rdi,
356 r8, r9, r10, r11, r12, r13, r14, r15,
357 xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7,
358 xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15 :: Reg
393 allFPArgRegs :: [Reg]
394 allFPArgRegs = map regSingle [firstxmm .. firstxmm+7]
396 ripRel :: Displacement -> AddrMode
397 ripRel imm = AddrBaseIndex EABaseRip EAIndexNone imm
400 -- so we can re-use some x86 code:
413 xmm n = regSingle (firstxmm+n)
418 -- horror show -----------------------------------------------------------------
419 freeReg :: RegNo -> FastBool
420 globalRegMaybe :: GlobalReg -> Maybe RealReg
422 callClobberedRegs :: [Reg]
424 #if defined(i386_TARGET_ARCH) || defined(x86_64_TARGET_ARCH)
437 #if x86_64_TARGET_ARCH
481 freeReg esp = fastBool False -- %esp is the C stack pointer
484 #if x86_64_TARGET_ARCH
485 freeReg rsp = fastBool False -- %rsp is the C stack pointer
489 freeReg REG_Base = fastBool False
492 freeReg REG_R1 = fastBool False
495 freeReg REG_R2 = fastBool False
498 freeReg REG_R3 = fastBool False
501 freeReg REG_R4 = fastBool False
504 freeReg REG_R5 = fastBool False
507 freeReg REG_R6 = fastBool False
510 freeReg REG_R7 = fastBool False
513 freeReg REG_R8 = fastBool False
516 freeReg REG_F1 = fastBool False
519 freeReg REG_F2 = fastBool False
522 freeReg REG_F3 = fastBool False
525 freeReg REG_F4 = fastBool False
528 freeReg REG_D1 = fastBool False
531 freeReg REG_D2 = fastBool False
534 freeReg REG_Sp = fastBool False
537 freeReg REG_Su = fastBool False
540 freeReg REG_SpLim = fastBool False
543 freeReg REG_Hp = fastBool False
546 freeReg REG_HpLim = fastBool False
548 freeReg _ = fastBool True
551 -- | Returns 'Nothing' if this global register is not stored
552 -- in a real machine register, otherwise returns @'Just' reg@, where
553 -- reg is the machine register it is stored in.
556 globalRegMaybe BaseReg = Just (RealRegSingle REG_Base)
559 globalRegMaybe (VanillaReg 1 _) = Just (RealRegSingle REG_R1)
562 globalRegMaybe (VanillaReg 2 _) = Just (RealRegSingle REG_R2)
565 globalRegMaybe (VanillaReg 3 _) = Just (RealRegSingle REG_R3)
568 globalRegMaybe (VanillaReg 4 _) = Just (RealRegSingle REG_R4)
571 globalRegMaybe (VanillaReg 5 _) = Just (RealRegSingle REG_R5)
574 globalRegMaybe (VanillaReg 6 _) = Just (RealRegSingle REG_R6)
577 globalRegMaybe (VanillaReg 7 _) = Just (RealRegSingle REG_R7)
580 globalRegMaybe (VanillaReg 8 _) = Just (RealRegSingle REG_R8)
583 globalRegMaybe (VanillaReg 9 _) = Just (RealRegSingle REG_R9)
586 globalRegMaybe (VanillaReg 10 _) = Just (RealRegSingle REG_R10)
589 globalRegMaybe (FloatReg 1) = Just (RealRegSingle REG_F1)
592 globalRegMaybe (FloatReg 2) = Just (RealRegSingle REG_F2)
595 globalRegMaybe (FloatReg 3) = Just (RealRegSingle REG_F3)
598 globalRegMaybe (FloatReg 4) = Just (RealRegSingle REG_F4)
601 globalRegMaybe (DoubleReg 1) = Just (RealRegSingle REG_D1)
604 globalRegMaybe (DoubleReg 2) = Just (RealRegSingle REG_D2)
607 globalRegMaybe Sp = Just (RealRegSingle REG_Sp)
610 globalRegMaybe (LongReg 1) = Just (RealRegSingle REG_Lng1)
613 globalRegMaybe (LongReg 2) = Just (RealRegSingle REG_Lng2)
616 globalRegMaybe SpLim = Just (RealRegSingle REG_SpLim)
619 globalRegMaybe Hp = Just (RealRegSingle REG_Hp)
622 globalRegMaybe HpLim = Just (RealRegSingle REG_HpLim)
624 #ifdef REG_CurrentTSO
625 globalRegMaybe CurrentTSO = Just (RealRegSingle REG_CurrentTSO)
627 #ifdef REG_CurrentNursery
628 globalRegMaybe CurrentNursery = Just (RealRegSingle REG_CurrentNursery)
630 globalRegMaybe _ = Nothing
635 allArgRegs = panic "X86.Regs.allArgRegs: should not be used!"
637 #elif x86_64_TARGET_ARCH
638 allArgRegs = map regSingle [rdi,rsi,rdx,rcx,r8,r9]
641 allArgRegs = panic "X86.Regs.allArgRegs: not defined for this architecture"
645 -- | these are the regs which we cannot assume stay alive over a C call.
648 -- caller-saves registers
650 = map regSingle ([eax,ecx,edx] ++ floatregnos)
652 #elif x86_64_TARGET_ARCH
653 -- all xmm regs are caller-saves
654 -- caller-saves registers
656 = map regSingle ([rax,rcx,rdx,rsi,rdi,r8,r9,r10,r11] ++ floatregnos)
660 = panic "X86.Regs.callClobberedRegs: not defined for this architecture"
663 #else /* i386_TARGET_ARCH || x86_64_TARGET_ARCH */
668 globalRegMaybe _ = panic "X86.Regs.globalRegMaybe: not defined"
670 allArgRegs = panic "X86.Regs.globalRegMaybe: not defined"
671 callClobberedRegs = panic "X86.Regs.globalRegMaybe: not defined"
676 -- allocatableRegs is allMachRegNos with the fixed-use regs removed.
677 -- i.e., these are the regs for which we are prepared to allow the
678 -- register allocator to attempt to map VRegs to.
679 allocatableRegs :: [RealReg]
681 = let isFree i = isFastTrue (freeReg i)
682 in map RealRegSingle $ filter isFree allMachRegNos