21 EABase(..), EAIndex(..), addrModeRegs,
23 eax, ebx, ecx, edx, esi, edi, ebp, esp,
24 fake0, fake1, fake2, fake3, fake4, fake5,
26 rax, rbx, rcx, rdx, rsi, rdi, rbp, rsp,
27 r8, r9, r10, r11, r12, r13, r14, r15,
28 xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7,
29 xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15,
39 get_GlobalReg_reg_or_addr,
45 #include "nativeGen/NCG.h"
46 #include "HsVersions.h"
49 # define STOLEN_X86_REGS 4
50 -- HACK: go for the max
53 #include "../includes/MachRegs.h"
58 import CgUtils ( get_GlobalReg_addr )
61 import CLabel ( CLabel )
63 import Outputable ( panic )
64 import qualified Outputable
67 #if defined(i386_TARGET_ARCH) || defined(x86_64_TARGET_ARCH)
72 -- -----------------------------------------------------------------------------
77 | ImmInteger Integer -- Sigh.
78 | ImmCLbl CLabel -- AbstractC Label (with baggage)
79 | ImmLit Doc -- Simple string
83 | ImmConstantSum Imm Imm
84 | ImmConstantDiff Imm Imm
87 strImmLit :: String -> Imm
88 strImmLit s = ImmLit (text s)
91 litToImm :: CmmLit -> Imm
92 litToImm (CmmInt i w) = ImmInteger (narrowS w i)
93 -- narrow to the width: a CmmInt might be out of
94 -- range, but we assume that ImmInteger only contains
95 -- in-range values. A signed value should be fine here.
96 litToImm (CmmFloat f W32) = ImmFloat f
97 litToImm (CmmFloat f W64) = ImmDouble f
98 litToImm (CmmLabel l) = ImmCLbl l
99 litToImm (CmmLabelOff l off) = ImmIndex l off
100 litToImm (CmmLabelDiffOff l1 l2 off)
102 (ImmConstantDiff (ImmCLbl l1) (ImmCLbl l2))
104 litToImm (CmmBlock id) = ImmCLbl (infoTblLbl id)
105 litToImm _ = panic "X86.Regs.litToImm: no match"
107 -- addressing modes ------------------------------------------------------------
110 = AddrBaseIndex EABase EAIndex Displacement
113 data EABase = EABaseNone | EABaseReg Reg | EABaseRip
114 data EAIndex = EAIndexNone | EAIndex Reg Int
115 type Displacement = Imm
118 addrOffset :: AddrMode -> Int -> Maybe AddrMode
121 ImmAddr i off0 -> Just (ImmAddr i (off0 + off))
123 AddrBaseIndex r i (ImmInt n) -> Just (AddrBaseIndex r i (ImmInt (n + off)))
124 AddrBaseIndex r i (ImmInteger n)
125 -> Just (AddrBaseIndex r i (ImmInt (fromInteger (n + toInteger off))))
127 AddrBaseIndex r i (ImmCLbl lbl)
128 -> Just (AddrBaseIndex r i (ImmIndex lbl off))
130 AddrBaseIndex r i (ImmIndex lbl ix)
131 -> Just (AddrBaseIndex r i (ImmIndex lbl (ix+off)))
133 _ -> Nothing -- in theory, shouldn't happen
136 addrModeRegs :: AddrMode -> [Reg]
137 addrModeRegs (AddrBaseIndex b i _) = b_regs ++ i_regs
139 b_regs = case b of { EABaseReg r -> [r]; _ -> [] }
140 i_regs = case i of { EAIndex r _ -> [r]; _ -> [] }
144 -- registers -------------------------------------------------------------------
146 -- @spRel@ gives us a stack relative addressing mode for volatile
147 -- temporaries and for excess call arguments. @fpRel@, where
148 -- applicable, is the same but for the frame pointer.
151 spRel :: Int -- ^ desired stack offset in words, positive or negative
155 spRel n = AddrBaseIndex (EABaseReg esp) EAIndexNone (ImmInt (n * wORD_SIZE))
157 #elif x86_64_TARGET_ARCH
158 spRel n = AddrBaseIndex (EABaseReg rsp) EAIndexNone (ImmInt (n * wORD_SIZE))
161 spRel _ = panic "X86.Regs.spRel: not defined for this architecture"
166 -- argRegs is the set of regs which are read for an n-argument call to C.
167 -- For archs which pass all args on the stack (x86), is empty.
168 -- Sparc passes up to the first 6 args in regs.
169 -- Dunno about Alpha.
170 argRegs :: RegNo -> [Reg]
171 argRegs _ = panic "MachRegs.argRegs(x86): should not be used!"
177 -- | The complete set of machine registers.
178 allMachRegNos :: [RegNo]
181 allMachRegNos = [0..13]
183 #elif x86_64_TARGET_ARCH
184 allMachRegNos = [0..31]
187 allMachRegNos = panic "X86.Regs.callClobberedRegs: not defined for this architecture"
192 -- | Take the class of a register.
193 {-# INLINE regClass #-}
194 regClass :: Reg -> RegClass
197 -- On x86, we might want to have an 8-bit RegClass, which would
198 -- contain just regs 1-4 (the others don't have 8-bit versions).
199 -- However, we can get away without this at the moment because the
200 -- only allocatable integer regs are also 8-bit compatible (1, 3, 4).
201 regClass (RealReg i) = if i < 8 then RcInteger else RcDouble
202 regClass (VirtualRegI _) = RcInteger
203 regClass (VirtualRegHi _) = RcInteger
204 regClass (VirtualRegD _) = RcDouble
205 regClass (VirtualRegF u) = pprPanic ("regClass(x86):VirtualRegF") (ppr u)
207 #elif x86_64_TARGET_ARCH
208 -- On x86, we might want to have an 8-bit RegClass, which would
209 -- contain just regs 1-4 (the others don't have 8-bit versions).
210 -- However, we can get away without this at the moment because the
211 -- only allocatable integer regs are also 8-bit compatible (1, 3, 4).
212 regClass (RealReg i) = if i < 16 then RcInteger else RcDouble
213 regClass (VirtualRegI _) = RcInteger
214 regClass (VirtualRegHi _) = RcInteger
215 regClass (VirtualRegD _) = RcDouble
216 regClass (VirtualRegF u) = pprPanic "regClass(x86_64):VirtualRegF" (ppr u)
219 regClass _ = panic "X86.Regs.regClass: not defined for this architecture"
224 -- | Get the name of the register with this number.
225 showReg :: RegNo -> String
229 = if n >= 0 && n < 14
231 else "%unknown_x86_real_reg_" ++ show n
235 = ["%eax", "%ebx", "%ecx", "%edx", "%esi", "%edi", "%ebp", "%esp",
236 "%fake0", "%fake1", "%fake2", "%fake3", "%fake4", "%fake5", "%fake6"]
238 #elif x86_64_TARGET_ARCH
240 | n >= 16 = "%xmm" ++ show (n-16)
241 | n >= 8 = "%r" ++ show n
242 | otherwise = regNames !! n
246 = ["%rax", "%rbx", "%rcx", "%rdx", "%rsi", "%rdi", "%rbp", "%rsp" ]
249 showReg _ = panic "X86.Regs.showReg: not defined for this architecture"
256 -- machine specific ------------------------------------------------------------
260 Intel x86 architecture:
261 - All registers except 7 (esp) are available for use.
262 - Only ebx, esi, edi and esp are available across a C call (they are callee-saves).
263 - Registers 0-7 have 16-bit counterparts (ax, bx etc.)
264 - Registers 0-3 have 8 bit counterparts (ah, bh etc.)
265 - Registers 8-13 are fakes; we pretend x86 has 6 conventionally-addressable
266 fp registers, and 3-operand insns for them, and we translate this into
267 real stack-based x86 fp code after register allocation.
269 The fp registers are all Double registers; we don't have any RcFloat class
270 regs. @regClass@ barfs if you give it a VirtualRegF, and mkVReg above should
274 fake0, fake1, fake2, fake3, fake4, fake5,
275 eax, ebx, ecx, edx, esp, ebp, esi, edi :: Reg
295 AMD x86_64 architecture:
296 - Registers 0-16 have 32-bit counterparts (eax, ebx etc.)
297 - Registers 0-7 have 16-bit counterparts (ax, bx etc.)
298 - Registers 0-3 have 8 bit counterparts (ah, bh etc.)
302 rax, rbx, rcx, rdx, rsp, rbp, rsi, rdi,
303 r8, r9, r10, r11, r12, r13, r14, r15,
304 xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7,
305 xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15 :: Reg
340 allFPArgRegs :: [Reg]
341 allFPArgRegs = map RealReg [16 .. 23]
343 ripRel :: Displacement -> AddrMode
344 ripRel imm = AddrBaseIndex EABaseRip EAIndexNone imm
347 -- so we can re-use some x86 code:
360 xmm n = RealReg (16+n)
365 -- horror show -----------------------------------------------------------------
366 freeReg :: RegNo -> FastBool
367 globalRegMaybe :: GlobalReg -> Maybe Reg
369 callClobberedRegs :: [Reg]
371 #if defined(i386_TARGET_ARCH) || defined(x86_64_TARGET_ARCH)
390 #if x86_64_TARGET_ARCH
428 freeReg esp = fastBool False -- %esp is the C stack pointer
431 #if x86_64_TARGET_ARCH
432 freeReg rsp = fastBool False -- %rsp is the C stack pointer
436 freeReg REG_Base = fastBool False
439 freeReg REG_R1 = fastBool False
442 freeReg REG_R2 = fastBool False
445 freeReg REG_R3 = fastBool False
448 freeReg REG_R4 = fastBool False
451 freeReg REG_R5 = fastBool False
454 freeReg REG_R6 = fastBool False
457 freeReg REG_R7 = fastBool False
460 freeReg REG_R8 = fastBool False
463 freeReg REG_F1 = fastBool False
466 freeReg REG_F2 = fastBool False
469 freeReg REG_F3 = fastBool False
472 freeReg REG_F4 = fastBool False
475 freeReg REG_D1 = fastBool False
478 freeReg REG_D2 = fastBool False
481 freeReg REG_Sp = fastBool False
484 freeReg REG_Su = fastBool False
487 freeReg REG_SpLim = fastBool False
490 freeReg REG_Hp = fastBool False
493 freeReg REG_HpLim = fastBool False
495 freeReg _ = fastBool True
498 -- | Returns 'Nothing' if this global register is not stored
499 -- in a real machine register, otherwise returns @'Just' reg@, where
500 -- reg is the machine register it is stored in.
503 globalRegMaybe BaseReg = Just (RealReg REG_Base)
506 globalRegMaybe (VanillaReg 1 _) = Just (RealReg REG_R1)
509 globalRegMaybe (VanillaReg 2 _) = Just (RealReg REG_R2)
512 globalRegMaybe (VanillaReg 3 _) = Just (RealReg REG_R3)
515 globalRegMaybe (VanillaReg 4 _) = Just (RealReg REG_R4)
518 globalRegMaybe (VanillaReg 5 _) = Just (RealReg REG_R5)
521 globalRegMaybe (VanillaReg 6 _) = Just (RealReg REG_R6)
524 globalRegMaybe (VanillaReg 7 _) = Just (RealReg REG_R7)
527 globalRegMaybe (VanillaReg 8 _) = Just (RealReg REG_R8)
530 globalRegMaybe (VanillaReg 9 _) = Just (RealReg REG_R9)
533 globalRegMaybe (VanillaReg 10 _) = Just (RealReg REG_R10)
536 globalRegMaybe (FloatReg 1) = Just (RealReg REG_F1)
539 globalRegMaybe (FloatReg 2) = Just (RealReg REG_F2)
542 globalRegMaybe (FloatReg 3) = Just (RealReg REG_F3)
545 globalRegMaybe (FloatReg 4) = Just (RealReg REG_F4)
548 globalRegMaybe (DoubleReg 1) = Just (RealReg REG_D1)
551 globalRegMaybe (DoubleReg 2) = Just (RealReg REG_D2)
554 globalRegMaybe Sp = Just (RealReg REG_Sp)
557 globalRegMaybe (LongReg 1) = Just (RealReg REG_Lng1)
560 globalRegMaybe (LongReg 2) = Just (RealReg REG_Lng2)
563 globalRegMaybe SpLim = Just (RealReg REG_SpLim)
566 globalRegMaybe Hp = Just (RealReg REG_Hp)
569 globalRegMaybe HpLim = Just (RealReg REG_HpLim)
571 #ifdef REG_CurrentTSO
572 globalRegMaybe CurrentTSO = Just (RealReg REG_CurrentTSO)
574 #ifdef REG_CurrentNursery
575 globalRegMaybe CurrentNursery = Just (RealReg REG_CurrentNursery)
577 globalRegMaybe _ = Nothing
582 allArgRegs = panic "X86.Regs.allArgRegs: should not be used!"
584 #elif x86_64_TARGET_ARCH
585 allArgRegs = map RealReg [rdi,rsi,rdx,rcx,r8,r9]
588 allArgRegs = panic "X86.Regs.allArgRegs: not defined for this architecture"
592 -- | these are the regs which we cannot assume stay alive over a C call.
595 -- caller-saves registers
597 = map RealReg [eax,ecx,edx,fake0,fake1,fake2,fake3,fake4,fake5]
599 #elif x86_64_TARGET_ARCH
600 -- all xmm regs are caller-saves
601 -- caller-saves registers
603 = map RealReg ([rax,rcx,rdx,rsi,rdi,r8,r9,r10,r11] ++ [16..31])
607 = panic "X86.Regs.callClobberedRegs: not defined for this architecture"
610 #else /* i386_TARGET_ARCH || x86_64_TARGET_ARCH */
615 globalRegMaybe _ = panic "X86.Regs.globalRegMaybe: not defined"
617 allArgRegs = panic "X86.Regs.globalRegMaybe: not defined"
618 callClobberedRegs = panic "X86.Regs.globalRegMaybe: not defined"
623 -- We map STG registers onto appropriate CmmExprs. Either they map
624 -- to real machine registers or stored as offsets from BaseReg. Given
625 -- a GlobalReg, get_GlobalReg_reg_or_addr produces either the real
626 -- register it is in, on this platform, or a CmmExpr denoting the
627 -- address in the register table holding it.
628 -- (See also get_GlobalReg_addr in CgUtils.)
630 get_GlobalReg_reg_or_addr :: GlobalReg -> Either Reg CmmExpr
631 get_GlobalReg_reg_or_addr mid
632 = case globalRegMaybe mid of
634 Nothing -> Right (get_GlobalReg_addr mid)
637 -- allocatableRegs is allMachRegNos with the fixed-use regs removed.
638 -- i.e., these are the regs for which we are prepared to allow the
639 -- register allocator to attempt to map VRegs to.
640 allocatableRegs :: [RegNo]
642 = let isFree i = isFastTrue (freeReg i)
643 in filter isFree allMachRegNos